summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2018-02-26 11:58:50 +0100
committerOlivier Bertrand <bertrandop@gmail.com>2018-02-26 11:58:50 +0100
commitc195e05132466fb017730d6b19c46681b33a6909 (patch)
tree6918f2a42f8fe1d731d75d1345d0c291379461a5
parenta88bdbdc630cbe8ff93f1d8178794186264ea60a (diff)
parented5e84eddb82d46adeb109c41f85810977eebe94 (diff)
downloadmariadb-git-c195e05132466fb017730d6b19c46681b33a6909.tar.gz
Merge branch 'ob-10.1' into 10.1
-rw-r--r--CMakeLists.txt10
-rw-r--r--CREDITS3
-rw-r--r--VERSION2
-rw-r--r--client/mysql.cc21
-rw-r--r--client/mysql_upgrade.c4
-rw-r--r--client/mysqladmin.cc8
-rw-r--r--client/mysqlbinlog.cc24
-rw-r--r--client/mysqlcheck.c8
-rw-r--r--client/mysqldump.c8
-rw-r--r--client/mysqlimport.c8
-rw-r--r--client/mysqlshow.c8
-rw-r--r--client/mysqlslap.c8
-rw-r--r--client/mysqltest.cc6
-rw-r--r--cmake/bison.cmake20
-rw-r--r--cmake/build_configurations/mysql_release.cmake1
-rw-r--r--cmake/check_compiler_flag.cmake14
-rw-r--r--cmake/cpack_rpm.cmake11
-rw-r--r--cmake/dtrace.cmake3
-rw-r--r--cmake/install_layout.cmake6
-rw-r--r--cmake/install_macros.cmake64
-rw-r--r--cmake/maintainer.cmake59
-rw-r--r--cmake/pcre.cmake16
-rw-r--r--cmake/plugin.cmake3
-rw-r--r--cmake/sign.cmake.in18
-rw-r--r--cmake/wsrep.cmake2
-rw-r--r--config.h.cmake1
-rw-r--r--configure.cmake12
-rw-r--r--debian/additions/debian-start.inc.sh2
-rw-r--r--debian/libmariadbclient18.links3
-rwxr-xr-xdebian/patches/50_mysql-test__db_test.dpatch18
-rw-r--r--extra/mariabackup/backup_copy.cc32
-rw-r--r--extra/mariabackup/backup_wsrep.h (renamed from extra/mariabackup/wsrep.h)4
-rw-r--r--extra/mariabackup/changed_page_bitmap.cc8
-rw-r--r--extra/mariabackup/crc/crc_glue.c2
-rw-r--r--extra/mariabackup/fil_cur.cc18
-rw-r--r--extra/mariabackup/write_filt.cc25
-rw-r--r--extra/mariabackup/write_filt.h2
-rw-r--r--extra/mariabackup/wsrep.cc7
-rw-r--r--extra/mariabackup/xtrabackup.cc535
-rw-r--r--extra/my_print_defaults.c24
-rw-r--r--extra/replace.c2
-rw-r--r--extra/yassl/CMakeLists.txt5
-rw-r--r--extra/yassl/README8
-rw-r--r--extra/yassl/include/openssl/ssl.h5
-rw-r--r--extra/yassl/src/yassl_imp.cpp6
-rw-r--r--extra/yassl/src/yassl_int.cpp14
-rw-r--r--extra/yassl/taocrypt/CMakeLists.txt4
-rw-r--r--include/m_string.h9
-rw-r--r--include/ma_dyncol.h9
-rw-r--r--include/my_compare.h24
-rw-r--r--include/my_global.h8
-rw-r--r--include/my_valgrind.h26
-rw-r--r--include/mysql.h.pp2
-rw-r--r--include/typelib.h2
-rw-r--r--include/welcome_copyright_notice.h2
-rw-r--r--libmysql/CMakeLists.txt15
-rw-r--r--libmysql/libmysql_versions.ld.in2
-rw-r--r--libmysqld/CMakeLists.txt9
-rw-r--r--libmysqld/libmysqld.c3
-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/README101
-rw-r--r--mysql-test/extra/rpl_tests/rpl_cant_read_event_incident.inc2
-rw-r--r--mysql-test/extra/rpl_tests/rpl_checksum.inc2
-rw-r--r--mysql-test/extra/rpl_tests/rpl_incident.inc2
-rw-r--r--mysql-test/extra/rpl_tests/rpl_init_slave_errors.inc2
-rw-r--r--mysql-test/extra/rpl_tests/rpl_loaddata.test2
-rw-r--r--mysql-test/extra/rpl_tests/rpl_log.test2
-rw-r--r--mysql-test/extra/rpl_tests/rpl_packet.inc3
-rw-r--r--mysql-test/extra/rpl_tests/rpl_skip_replication.inc2
-rw-r--r--mysql-test/extra/rpl_tests/rpl_stm_relay_ign_space.inc2
-rw-r--r--mysql-test/extra/rpl_tests/rpl_sync.inc2
-rw-r--r--mysql-test/include/check-testcase.test2
-rw-r--r--mysql-test/include/fail_start_mysqld.inc18
-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.inc6
-rw-r--r--mysql-test/include/have_xtradb.inc7
-rw-r--r--mysql-test/include/innodb_encrypt_log.combinations7
-rw-r--r--mysql-test/include/innodb_encrypt_log.inc4
-rw-r--r--mysql-test/include/not_embedded.inc6
-rw-r--r--mysql-test/include/not_windows.inc8
-rw-r--r--mysql-test/include/restart_mysqld.inc2
-rw-r--r--mysql-test/include/search_pattern_in_file++.inc81
-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/shutdown_mysqld.inc16
-rw-r--r--mysql-test/include/truncate_file.inc11
-rw-r--r--mysql-test/lib/My/SafeProcess.pm2
-rwxr-xr-xmysql-test/mysql-test-run.pl206
-rw-r--r--mysql-test/r/alter_table.result109
-rw-r--r--mysql-test/r/case.result16
-rw-r--r--mysql-test/r/contributors.result3
-rw-r--r--mysql-test/r/count_distinct.result25
-rw-r--r--mysql-test/r/create.result138
-rw-r--r--mysql-test/r/ctype_gbk.result18
-rw-r--r--mysql-test/r/ctype_latin1.result18
-rw-r--r--mysql-test/r/ctype_ucs.result30
-rw-r--r--mysql-test/r/ctype_utf32.result15
-rw-r--r--mysql-test/r/ctype_utf8.result66
-rw-r--r--mysql-test/r/ctype_utf8mb4.result30
-rw-r--r--mysql-test/r/ctype_utf8mb4_heap.result4
-rw-r--r--mysql-test/r/ctype_utf8mb4_innodb.result4
-rw-r--r--mysql-test/r/ctype_utf8mb4_myisam.result4
-rw-r--r--mysql-test/r/delete_returning.result12
-rw-r--r--mysql-test/r/delimiter_command_case_sensitivity.result2
-rw-r--r--mysql-test/r/derived.result41
-rw-r--r--mysql-test/r/dyncol.result20
-rw-r--r--mysql-test/r/errors.result2
-rw-r--r--mysql-test/r/explain_json.result6
-rw-r--r--mysql-test/r/fulltext.result20
-rw-r--r--mysql-test/r/func_concat.result6
-rw-r--r--mysql-test/r/func_in.result12
-rw-r--r--mysql-test/r/func_isnull.result84
-rw-r--r--mysql-test/r/func_misc.result31
-rw-r--r--mysql-test/r/func_regexp_pcre.result18
-rw-r--r--mysql-test/r/func_set.result24
-rw-r--r--mysql-test/r/func_str.result21
-rw-r--r--mysql-test/r/func_time.result28
-rw-r--r--mysql-test/r/gis-precise.result19
-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.result32
-rw-r--r--mysql-test/r/insert.result34
-rw-r--r--mysql-test/r/join_cache.result60
-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/log_tables-big.result9
-rw-r--r--mysql-test/r/mdev13607.result469
-rw-r--r--mysql-test/r/mdev_14586.result44
-rw-r--r--mysql-test/r/merge.result4
-rw-r--r--mysql-test/r/myisam.result9
-rw-r--r--mysql-test/r/myisam_optimize.result14
-rw-r--r--mysql-test/r/mysqlbinlog.result1
-rw-r--r--mysql-test/r/mysqld--help.result2
-rw-r--r--mysql-test/r/mysqldump-nl.result43
-rw-r--r--mysql-test/r/not_windows.require2
-rw-r--r--mysql-test/r/old-mode.result45
-rw-r--r--mysql-test/r/order_by.result46
-rw-r--r--mysql-test/r/partition.result13
-rw-r--r--mysql-test/r/partition_datatype.result8
-rw-r--r--mysql-test/r/partition_symlink.result6
-rw-r--r--mysql-test/r/partition_windows.result4
-rw-r--r--mysql-test/r/ps.result161
-rw-r--r--mysql-test/r/query_cache_debug.result26
-rw-r--r--mysql-test/r/range_vs_index_merge.result81
-rw-r--r--mysql-test/r/range_vs_index_merge_innodb.result81
-rw-r--r--mysql-test/r/read_only.result3
-rw-r--r--mysql-test/r/repair.result17
-rw-r--r--mysql-test/r/show_check.result4
-rw-r--r--mysql-test/r/show_function_with_pad_char_to_full_length.result24
-rw-r--r--mysql-test/r/sp.result163
-rw-r--r--mysql-test/r/strict.result4
-rw-r--r--mysql-test/r/subselect.result26
-rw-r--r--mysql-test/r/subselect_exists2in.result37
-rw-r--r--mysql-test/r/subselect_mat_cost_bugs.result17
-rw-r--r--mysql-test/r/subselect_no_exists_to_in.result26
-rw-r--r--mysql-test/r/subselect_no_mat.result26
-rw-r--r--mysql-test/r/subselect_no_opts.result26
-rw-r--r--mysql-test/r/subselect_no_scache.result26
-rw-r--r--mysql-test/r/subselect_no_semijoin.result26
-rw-r--r--mysql-test/r/symlink.result12
-rw-r--r--mysql-test/r/tc_heuristic_recover.result37
-rw-r--r--mysql-test/r/trigger.result17
-rw-r--r--mysql-test/r/type_bit.result24
-rw-r--r--mysql-test/r/type_blob.result2
-rw-r--r--mysql-test/r/type_date.result11
-rw-r--r--mysql-test/r/type_time_6065.result44
-rw-r--r--mysql-test/r/type_varchar.result71
-rw-r--r--mysql-test/r/union.result37
-rw-r--r--mysql-test/r/update_innodb.result10
-rw-r--r--mysql-test/r/user_var.result16
-rw-r--r--mysql-test/r/variables.result4
-rw-r--r--mysql-test/r/view.result17
-rw-r--r--mysql-test/r/xa.result11
-rw-r--r--mysql-test/r/xml.result12
-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/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/encryption/disabled.def1
-rw-r--r--mysql-test/suite/encryption/r/encryption_force.result4
-rw-r--r--mysql-test/suite/encryption/r/filekeys_encfile.result2
-rw-r--r--mysql-test/suite/encryption/r/filekeys_encfile_file.result2
-rw-r--r--mysql-test/suite/encryption/r/innodb-bad-key-change.result48
-rw-r--r--mysql-test/suite/encryption/r/innodb-encryption-alter.result5
-rw-r--r--mysql-test/suite/encryption/r/innodb_encryption-page-compression.result15
-rw-r--r--mysql-test/suite/encryption/r/innodb_encryption.result12
-rw-r--r--mysql-test/suite/encryption/r/innodb_encryption_filekeys.result24
-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/encryption_force.test6
-rw-r--r--mysql-test/suite/encryption/t/filekeys_goodtest.inc4
-rw-r--r--mysql-test/suite/encryption/t/innodb-bad-key-change.test42
-rw-r--r--mysql-test/suite/encryption/t/innodb-encryption-alter.test4
-rw-r--r--mysql-test/suite/encryption/t/innodb_encryption-page-compression.test22
-rw-r--r--mysql-test/suite/encryption/t/innodb_encryption.test9
-rw-r--r--mysql-test/suite/encryption/t/innodb_encryption_filekeys.test35
-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/engines/funcs/t/rpl_insert.test2
-rw-r--r--mysql-test/suite/federated/net_thd_crash-12951.result11
-rw-r--r--mysql-test/suite/federated/net_thd_crash-12951.test23
-rw-r--r--mysql-test/suite/galera/disabled.def5
-rw-r--r--mysql-test/suite/galera/r/MW-388.result46
-rw-r--r--mysql-test/suite/galera/r/MW-402.result192
-rw-r--r--mysql-test/suite/galera/r/galera_bf_lock_wait.result18
-rw-r--r--mysql-test/suite/galera/r/galera_defaults.result2
-rw-r--r--mysql-test/suite/galera/r/galera_gtid_slave.result26
-rw-r--r--mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result130
-rw-r--r--mysql-test/suite/galera/r/galera_mdev_13787.result3
-rw-r--r--mysql-test/suite/galera/r/sql_log_bin.result1
-rw-r--r--mysql-test/suite/galera/t/MW-388.test76
-rw-r--r--mysql-test/suite/galera/t/MW-402.test228
-rw-r--r--mysql-test/suite/galera/t/galera_bf_lock_wait.test52
-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_mdev_13787.opt1
-rw-r--r--mysql-test/suite/galera/t/galera_mdev_13787.test6
-rw-r--r--mysql-test/suite/galera/t/galera_suspend_slave.test4
-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/galera_3nodes.cnf3
-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/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/innodb/include/import.inc40
-rw-r--r--mysql-test/suite/innodb/include/innodb_dict.inc9
-rw-r--r--mysql-test/suite/innodb/r/alter_rename_existing.result96
-rw-r--r--mysql-test/suite/innodb/r/create-index-debug.result26
-rw-r--r--mysql-test/suite/innodb/r/index_tree_operation.result55
-rw-r--r--mysql-test/suite/innodb/r/innodb-16k.result10
-rw-r--r--mysql-test/suite/innodb/r/innodb-32k.result3
-rw-r--r--mysql-test/suite/innodb/r/innodb-64k.result3
-rw-r--r--mysql-test/suite/innodb/r/innodb-alter-autoinc.result174
-rw-r--r--mysql-test/suite/innodb/r/innodb-alter-table.result41
-rw-r--r--mysql-test/suite/innodb/r/innodb-alter.result861
-rw-r--r--mysql-test/suite/innodb/r/innodb-autoinc.result18
-rw-r--r--mysql-test/suite/innodb/r/innodb-enlarge-blob.result32
-rw-r--r--mysql-test/suite/innodb/r/innodb-get-fk.result3
-rw-r--r--mysql-test/suite/innodb/r/innodb-index-debug.result91
-rw-r--r--mysql-test/suite/innodb/r/innodb-index-online,crypt.rdiff20
-rw-r--r--mysql-test/suite/innodb/r/innodb-index-online-delete.result13
-rw-r--r--mysql-test/suite/innodb/r/innodb-index-online-fk.result604
-rw-r--r--mysql-test/suite/innodb/r/innodb-index-online-purge.result36
-rw-r--r--mysql-test/suite/innodb/r/innodb-index-online.result447
-rw-r--r--mysql-test/suite/innodb/r/innodb-lru-force-no-free-page.result10
-rw-r--r--mysql-test/suite/innodb/r/innodb-page_compression_tables.result5
-rw-r--r--mysql-test/suite/innodb/r/innodb-replace-debug.result14
-rw-r--r--mysql-test/suite/innodb/r/innodb-table-online,crypt.rdiff20
-rw-r--r--mysql-test/suite/innodb/r/innodb-table-online.result446
-rw-r--r--mysql-test/suite/innodb/r/innodb-wl5522-debug.result30
-rw-r--r--mysql-test/suite/innodb/r/innodb-wl5980-alter.result1409
-rw-r--r--mysql-test/suite/innodb/r/innodb.result82
-rw-r--r--mysql-test/suite/innodb/r/innodb_corrupt_bit.result45
-rw-r--r--mysql-test/suite/innodb/r/mvcc.result26
-rw-r--r--mysql-test/suite/innodb/r/read_only_recover_committed.result43
-rw-r--r--mysql-test/suite/innodb/r/recovery_shutdown.result56
-rw-r--r--mysql-test/suite/innodb/r/table_definition_cache_debug.result16
-rw-r--r--mysql-test/suite/innodb/r/undo_log.result142
-rw-r--r--mysql-test/suite/innodb/t/alter_rename_existing.test93
-rw-r--r--mysql-test/suite/innodb/t/create-index-debug.test34
-rw-r--r--mysql-test/suite/innodb/t/index_tree_operation.opt1
-rw-r--r--mysql-test/suite/innodb/t/index_tree_operation.test74
-rw-r--r--mysql-test/suite/innodb/t/innodb-16k.test10
-rw-r--r--mysql-test/suite/innodb/t/innodb-32k.test3
-rw-r--r--mysql-test/suite/innodb/t/innodb-64k.test3
-rw-r--r--mysql-test/suite/innodb/t/innodb-alter-autoinc.test104
-rw-r--r--mysql-test/suite/innodb/t/innodb-alter-table.test33
-rw-r--r--mysql-test/suite/innodb/t/innodb-alter.opt3
-rw-r--r--mysql-test/suite/innodb/t/innodb-alter.test483
-rw-r--r--mysql-test/suite/innodb/t/innodb-autoinc.test17
-rw-r--r--mysql-test/suite/innodb/t/innodb-enlarge-blob.opt3
-rw-r--r--mysql-test/suite/innodb/t/innodb-enlarge-blob.test33
-rw-r--r--mysql-test/suite/innodb/t/innodb-get-fk.test5
-rw-r--r--mysql-test/suite/innodb/t/innodb-index-debug.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb-index-debug.test122
-rw-r--r--mysql-test/suite/innodb/t/innodb-index-online-delete.test36
-rw-r--r--mysql-test/suite/innodb/t/innodb-index-online-fk.opt4
-rw-r--r--mysql-test/suite/innodb/t/innodb-index-online-fk.test484
-rw-r--r--mysql-test/suite/innodb/t/innodb-index-online-purge.test73
-rw-r--r--mysql-test/suite/innodb/t/innodb-index-online.opt6
-rw-r--r--mysql-test/suite/innodb/t/innodb-index-online.test508
-rw-r--r--mysql-test/suite/innodb/t/innodb-lru-force-no-free-page.test25
-rw-r--r--mysql-test/suite/innodb/t/innodb-master.opt2
-rw-r--r--mysql-test/suite/innodb/t/innodb-page_compression_tables.test4
-rw-r--r--mysql-test/suite/innodb/t/innodb-replace-debug.test16
-rw-r--r--mysql-test/suite/innodb/t/innodb-table-online-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb-table-online.test454
-rw-r--r--mysql-test/suite/innodb/t/innodb-wl5522-debug.test93
-rw-r--r--mysql-test/suite/innodb/t/innodb-wl5980-alter.opt3
-rw-r--r--mysql-test/suite/innodb/t/innodb-wl5980-alter.test593
-rw-r--r--mysql-test/suite/innodb/t/innodb.test103
-rw-r--r--mysql-test/suite/innodb/t/innodb_corrupt_bit.test8
-rw-r--r--mysql-test/suite/innodb/t/log_data_file_size.test21
-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/read_only_recover_committed.test68
-rw-r--r--mysql-test/suite/innodb/t/recovery_shutdown.test61
-rw-r--r--mysql-test/suite/innodb/t/table_definition_cache_debug.opt1
-rw-r--r--mysql-test/suite/innodb/t/table_definition_cache_debug.test66
-rw-r--r--mysql-test/suite/innodb/t/undo_log.test139
-rw-r--r--mysql-test/suite/innodb_fts/r/concurrent_insert.result8
-rw-r--r--mysql-test/suite/innodb_fts/r/fulltext.result56
-rw-r--r--mysql-test/suite/innodb_fts/t/concurrent_insert.test20
-rw-r--r--mysql-test/suite/innodb_fts/t/fulltext.test46
-rw-r--r--mysql-test/suite/innodb_zip/r/innodb_prefix_index_liftedlimit.result8
-rw-r--r--mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result (renamed from mysql-test/suite/innodb/r/innodb-wl5522-debug-zip.result)39
-rw-r--r--mysql-test/suite/innodb_zip/t/innodb_prefix_index_liftedlimit.test8
-rw-r--r--mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test (renamed from mysql-test/suite/innodb/t/innodb-wl5522-debug-zip.test)125
-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.result20
-rw-r--r--mysql-test/suite/maria/maria.test18
-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.result33
-rw-r--r--mysql-test/suite/mariabackup/apply-log-only-incr.test70
-rw-r--r--mysql-test/suite/mariabackup/apply-log-only.result10
-rw-r--r--mysql-test/suite/mariabackup/apply-log-only.test25
-rw-r--r--mysql-test/suite/mariabackup/compress_qpress.result15
-rw-r--r--mysql-test/suite/mariabackup/compress_qpress.test24
-rw-r--r--mysql-test/suite/mariabackup/data_directory.result13
-rw-r--r--mysql-test/suite/mariabackup/data_directory.test23
-rw-r--r--mysql-test/suite/mariabackup/huge_lsn.opt6
-rw-r--r--mysql-test/suite/mariabackup/huge_lsn.result19
-rw-r--r--mysql-test/suite/mariabackup/huge_lsn.test54
-rw-r--r--mysql-test/suite/mariabackup/incremental_backup.result10
-rw-r--r--mysql-test/suite/mariabackup/incremental_backup.test16
-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.test27
-rw-r--r--mysql-test/suite/mariabackup/partition_datadir.opt1
-rw-r--r--mysql-test/suite/mariabackup/partition_datadir.result22
-rw-r--r--mysql-test/suite/mariabackup/partition_datadir.test24
-rw-r--r--mysql-test/suite/mariabackup/suite.pm4
-rw-r--r--mysql-test/suite/parts/inc/part_alter_values.inc37
-rw-r--r--mysql-test/suite/parts/inc/part_exch_drop_tabs.inc3
-rw-r--r--mysql-test/suite/parts/inc/part_exch_tabs.inc103
-rw-r--r--mysql-test/suite/parts/r/partition_alter_innodb.result49
-rw-r--r--mysql-test/suite/parts/r/partition_alter_maria.result62
-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_exch_myisam_innodb.result55
-rw-r--r--mysql-test/suite/parts/r/partition_exch_qa_14.result310
-rw-r--r--mysql-test/suite/parts/r/partition_exch_qa_15.result57
-rw-r--r--mysql-test/suite/parts/r/partition_exch_qa_2.result63
-rw-r--r--mysql-test/suite/parts/r/partition_exch_qa_3.result155
-rw-r--r--mysql-test/suite/parts/r/partition_exch_qa_6.result69
-rw-r--r--mysql-test/suite/parts/t/partition_alter_innodb.test4
-rw-r--r--mysql-test/suite/parts/t/partition_alter_maria.test21
-rw-r--r--mysql-test/suite/parts/t/partition_alter_myisam.test22
-rw-r--r--mysql-test/suite/parts/t/partition_basic_symlink_innodb.test143
-rw-r--r--mysql-test/suite/parts/t/partition_exch_myisam_innodb.test14
-rw-r--r--mysql-test/suite/parts/t/partition_exch_qa_14.test142
-rw-r--r--mysql-test/suite/parts/t/partition_exch_qa_15.test18
-rw-r--r--mysql-test/suite/parts/t/partition_exch_qa_2.test61
-rw-r--r--mysql-test/suite/parts/t/partition_exch_qa_3.test36
-rw-r--r--mysql-test/suite/parts/t/partition_exch_qa_6.test48
-rw-r--r--mysql-test/suite/parts/t/rpl_partition.test2
-rw-r--r--mysql-test/suite/perfschema/r/misc.result16
-rw-r--r--mysql-test/suite/perfschema/r/start_server_low_digest.result4
-rw-r--r--mysql-test/suite/perfschema/t/misc.test15
-rw-r--r--mysql-test/suite/plugins/r/binlog-simple_plugin_check.result19
-rw-r--r--mysql-test/suite/plugins/r/server_audit.result9
-rw-r--r--mysql-test/suite/plugins/r/thread_pool_server_audit.result9
-rw-r--r--mysql-test/suite/plugins/t/binlog-simple_plugin_check.test31
-rw-r--r--mysql-test/suite/plugins/t/server_audit.test5
-rw-r--r--mysql-test/suite/plugins/t/thread_pool_server_audit.test5
-rw-r--r--mysql-test/suite/roles/definer.result114
-rw-r--r--mysql-test/suite/roles/definer.test122
-rw-r--r--mysql-test/suite/roles/flush_roles-12366.result539
-rw-r--r--mysql-test/suite/roles/flush_roles-12366.test379
-rw-r--r--mysql-test/suite/roles/rpl_grant_revoke_current_role-8638.test2
-rw-r--r--mysql-test/suite/roles/set_role-13655.result50
-rw-r--r--mysql-test/suite/roles/set_role-13655.test49
-rw-r--r--mysql-test/suite/rpl/r/rpl_gtid_delete_domain.result30
-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_sp_variables.result24
-rw-r--r--mysql-test/suite/rpl/r/rpl_stm_log.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_temporal_format_mariadb53_to_mysql56_dst.result28
-rw-r--r--mysql-test/suite/rpl/t/rpl_alter_extra_persistent.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_auto_increment_bug45679.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_blackhole.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_concurrency_error.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_conditional_comments.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_empty_master_host.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_extra_col_master_innodb.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_flush_logs.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_geometry.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_grant.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_gtid_delete_domain.test95
-rw-r--r--mysql-test/suite/rpl/t/rpl_gtid_mdev4484.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_heartbeat_debug.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_innodb_bug68220.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_insert.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_invoked_features.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_loaddata_symlink.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_manual_change_index_file.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_mdev-11092.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_mdev8193.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_mixed_binlog_max_cache_size.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_mixed_implicit_commit_binlog.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_mixed_mixing_engines.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_non_direct_mixed_mixing_engines.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_not_null_innodb.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_not_null_myisam.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_performance_schema.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_read_only.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_report_port.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_binlog_max_cache_size.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_colSize.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_corruption.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_create_table.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_find_row.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_implicit_commit_binlog.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_index_choice.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_merge_engine.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_rec_comp_innodb.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_show_relaylog_events.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_trunc_temp.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_utf16.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_wide_table.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_savepoint.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_server_id_ignore.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_set_null_innodb.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_skip_error.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_skip_incident.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_slave_skip.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_slow_query_log.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_sp_variables.test28
-rw-r--r--mysql-test/suite/rpl/t/rpl_stm_binlog_max_cache_size.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_stm_drop_create_temp_table.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_stm_implicit_commit_binlog.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_stm_loadfile.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_stm_start_stop_slave.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_stm_user_variables.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_temporal_format_mariadb53_to_mysql56_dst.test37
-rw-r--r--mysql-test/suite/rpl/t/rpl_temporary_errors.test2
-rw-r--r--mysql-test/suite/rpl/t/sec_behind_master-5114.test2
-rw-r--r--mysql-test/suite/sys_vars/inc/explicit_defaults_for_timestamp.inc13
-rw-r--r--mysql-test/suite/sys_vars/r/explicit_defaults_for_timestamp_off.result13
-rw-r--r--mysql-test/suite/sys_vars/r/explicit_defaults_for_timestamp_on.result15
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_now_basic.result7
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result3
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_buffer_pool_load_now_basic.result6
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_print_lock_wait_timeout_info_basic.result104
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff18
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff34
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_innodb.result2
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_now_basic.test31
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_pct_basic.test18
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.opt1
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.test44
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_print_lock_wait_timeout_info_basic.test89
-rw-r--r--mysql-test/suite/sys_vars/t/wsrep_on_basic.opt1
-rw-r--r--mysql-test/suite/vcol/r/vcol_misc.result21
-rw-r--r--mysql-test/suite/vcol/t/vcol_misc.test22
-rw-r--r--mysql-test/t/alter_table.test90
-rw-r--r--mysql-test/t/case.test12
-rw-r--r--mysql-test/t/count_distinct.test29
-rw-r--r--mysql-test/t/create.test143
-rw-r--r--mysql-test/t/create_or_replace2.test2
-rw-r--r--mysql-test/t/ctype_gbk.test14
-rw-r--r--mysql-test/t/ctype_latin1.test16
-rw-r--r--mysql-test/t/ctype_ucs.test23
-rw-r--r--mysql-test/t/ctype_utf32.test13
-rw-r--r--mysql-test/t/ctype_utf8.test40
-rw-r--r--mysql-test/t/ctype_utf8mb4.test18
-rw-r--r--mysql-test/t/delete_returning.test15
-rw-r--r--mysql-test/t/delimiter_case_mdev_10728.sql3
-rw-r--r--mysql-test/t/delimiter_command_case_sensitivity.test4
-rw-r--r--mysql-test/t/derived.test38
-rw-r--r--mysql-test/t/dyncol.test17
-rw-r--r--mysql-test/t/fulltext.test15
-rw-r--r--mysql-test/t/func_concat.test6
-rw-r--r--mysql-test/t/func_in.test13
-rw-r--r--mysql-test/t/func_isnull.test48
-rw-r--r--mysql-test/t/func_misc.test27
-rw-r--r--mysql-test/t/func_regexp_pcre.test8
-rw-r--r--mysql-test/t/func_set.test18
-rw-r--r--mysql-test/t/func_str.test13
-rw-r--r--mysql-test/t/func_time.test26
-rw-r--r--mysql-test/t/gis-precise.test19
-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.test26
-rw-r--r--mysql-test/t/insert.test39
-rw-r--r--mysql-test/t/join_cache.test45
-rw-r--r--mysql-test/t/join_outer.test14
-rw-r--r--mysql-test/t/log_tables-big.test9
-rw-r--r--mysql-test/t/mdev13607.test60
-rw-r--r--mysql-test/t/mdev_14586.test27
-rw-r--r--mysql-test/t/merge.test4
-rw-r--r--mysql-test/t/myisam.test3
-rw-r--r--mysql-test/t/myisam_optimize.test17
-rw-r--r--mysql-test/t/mysqlbinlog.test6
-rw-r--r--mysql-test/t/mysqldump-nl.test20
-rw-r--r--mysql-test/t/old-mode.test34
-rw-r--r--mysql-test/t/order_by.test38
-rw-r--r--mysql-test/t/partition.test15
-rw-r--r--mysql-test/t/partition_datatype.test8
-rw-r--r--mysql-test/t/partition_symlink.test3
-rw-r--r--mysql-test/t/ps.test144
-rw-r--r--mysql-test/t/query_cache_debug.test52
-rw-r--r--mysql-test/t/range_vs_index_merge.test53
-rw-r--r--mysql-test/t/read_only.test5
-rw-r--r--mysql-test/t/repair.test23
-rw-r--r--mysql-test/t/show_function_with_pad_char_to_full_length.test23
-rw-r--r--mysql-test/t/sp.test197
-rw-r--r--mysql-test/t/stat_tables_repl.test2
-rw-r--r--mysql-test/t/subselect.test27
-rw-r--r--mysql-test/t/subselect_exists2in.test40
-rw-r--r--mysql-test/t/subselect_mat_cost_bugs.test19
-rw-r--r--mysql-test/t/symlink.test25
-rw-r--r--mysql-test/t/tc_heuristic_recover.test106
-rw-r--r--mysql-test/t/trigger.test24
-rw-r--r--mysql-test/t/type_bit.test19
-rw-r--r--mysql-test/t/type_date.test9
-rw-r--r--mysql-test/t/type_time_6065.test23
-rw-r--r--mysql-test/t/type_varchar.test46
-rw-r--r--mysql-test/t/union.test37
-rw-r--r--mysql-test/t/update_innodb.test12
-rw-r--r--mysql-test/t/user_var.test10
-rw-r--r--mysql-test/t/view.test18
-rw-r--r--mysql-test/t/xa.test14
-rw-r--r--mysql-test/t/xml.test13
-rw-r--r--mysql-test/unstable-tests347
-rw-r--r--mysys/ma_dyncol.c61
-rw-r--r--mysys/mf_iocache.c4
-rw-r--r--mysys/my_addr_resolve.c156
-rw-r--r--mysys/my_alloc.c11
-rw-r--r--mysys/my_default.c11
-rw-r--r--mysys/my_lib.c10
-rw-r--r--mysys/my_malloc.c2
-rw-r--r--mysys/my_new.cc10
-rw-r--r--mysys/my_thr_init.c1
-rw-r--r--mysys/my_winerr.c4
-rw-r--r--mysys/thr_alarm.c4
-rw-r--r--mysys/typelib.c12
-rw-r--r--mysys_ssl/my_crypt.cc23
-rw-r--r--mysys_ssl/yassl.cc1
-rw-r--r--pcre/CMakeLists.txt6
-rw-r--r--pcre/pcre_compile.c5
-rw-r--r--pcre/pcre_exec.c8
-rw-r--r--plugin/handler_socket/CMakeLists.txt6
-rw-r--r--plugin/metadata_lock_info/metadata_lock_info.cc8
-rw-r--r--plugin/server_audit/server_audit.c55
-rw-r--r--scripts/CMakeLists.txt5
-rw-r--r--scripts/galera_recovery.sh4
-rw-r--r--scripts/mysql_install_db.sh64
-rw-r--r--scripts/mysqld_safe.sh10
-rw-r--r--scripts/wsrep_sst_common.sh54
-rw-r--r--scripts/wsrep_sst_mysqldump.sh12
-rw-r--r--scripts/wsrep_sst_rsync.sh14
-rw-r--r--scripts/wsrep_sst_xtrabackup-v2.sh111
-rw-r--r--scripts/wsrep_sst_xtrabackup.sh55
-rw-r--r--sql-common/client.c9
-rw-r--r--sql/CMakeLists.txt94
-rw-r--r--sql/contributors.h3
-rw-r--r--sql/datadict.cc15
-rw-r--r--sql/event_data_objects.cc30
-rw-r--r--sql/events.cc27
-rw-r--r--sql/field.cc55
-rw-r--r--sql/field.h11
-rw-r--r--sql/field_conv.cc27
-rw-r--r--sql/filesort.cc3
-rw-r--r--sql/filesort_utils.cc2
-rw-r--r--sql/ha_partition.cc77
-rw-r--r--sql/ha_partition.h4
-rw-r--r--sql/handler.cc83
-rw-r--r--sql/handler.h7
-rw-r--r--sql/item.cc61
-rw-r--r--sql/item.h42
-rw-r--r--sql/item_cmpfunc.cc91
-rw-r--r--sql/item_cmpfunc.h17
-rw-r--r--sql/item_func.cc7
-rw-r--r--sql/item_func.h8
-rw-r--r--sql/item_geofunc.cc10
-rw-r--r--sql/item_inetfunc.cc7
-rw-r--r--sql/item_inetfunc.h6
-rw-r--r--sql/item_row.cc6
-rw-r--r--sql/item_row.h13
-rw-r--r--sql/item_strfunc.cc216
-rw-r--r--sql/item_strfunc.h9
-rw-r--r--sql/item_subselect.cc30
-rw-r--r--sql/item_subselect.h4
-rw-r--r--sql/item_sum.cc2
-rw-r--r--sql/item_timefunc.cc17
-rw-r--r--sql/item_timefunc.h10
-rw-r--r--sql/item_xmlfunc.cc10
-rw-r--r--sql/item_xmlfunc.h1
-rw-r--r--sql/key.cc6
-rw-r--r--sql/lex.h1
-rw-r--r--sql/log.cc309
-rw-r--r--sql/log.h15
-rw-r--r--sql/log_event.cc26
-rw-r--r--sql/mf_iocache_encr.cc5
-rw-r--r--sql/mysqld.cc26
-rw-r--r--sql/net_serv.cc4
-rw-r--r--sql/opt_range.cc41
-rw-r--r--sql/opt_subselect.cc129
-rw-r--r--sql/partition_info.cc23
-rw-r--r--sql/partition_info.h1
-rw-r--r--sql/rpl_gtid.cc151
-rw-r--r--sql/rpl_gtid.h9
-rw-r--r--sql/share/errmsg-utf8.txt52
-rw-r--r--sql/slave.cc1
-rw-r--r--sql/sp_head.cc23
-rw-r--r--sql/sql_acl.cc114
-rw-r--r--sql/sql_acl.h8
-rw-r--r--sql/sql_admin.cc4
-rw-r--r--sql/sql_base.cc18
-rw-r--r--sql/sql_base.h5
-rw-r--r--sql/sql_cache.cc22
-rw-r--r--sql/sql_class.cc28
-rw-r--r--sql/sql_class.h68
-rw-r--r--sql/sql_connect.cc49
-rw-r--r--sql/sql_const.h13
-rw-r--r--sql/sql_cursor.cc2
-rw-r--r--sql/sql_delete.cc2
-rw-r--r--sql/sql_derived.cc77
-rw-r--r--sql/sql_do.cc2
-rw-r--r--sql/sql_explain.h6
-rw-r--r--sql/sql_insert.cc16
-rw-r--r--sql/sql_join_cache.cc5
-rw-r--r--sql/sql_lex.cc10
-rw-r--r--sql/sql_lex.h22
-rw-r--r--sql/sql_lifo_buffer.h4
-rw-r--r--sql/sql_list.h4
-rw-r--r--sql/sql_load.cc10
-rw-r--r--sql/sql_parse.cc115
-rw-r--r--sql/sql_partition.cc66
-rw-r--r--sql/sql_partition.h3
-rw-r--r--sql/sql_partition_admin.cc7
-rw-r--r--sql/sql_plugin.cc89
-rw-r--r--sql/sql_prepare.cc29
-rw-r--r--sql/sql_reload.cc5
-rw-r--r--sql/sql_repl.cc68
-rw-r--r--sql/sql_repl.h1
-rw-r--r--sql/sql_select.cc105
-rw-r--r--sql/sql_select.h2
-rw-r--r--sql/sql_show.cc51
-rw-r--r--sql/sql_string.h2
-rw-r--r--sql/sql_table.cc21
-rw-r--r--sql/sql_trigger.cc12
-rw-r--r--sql/sql_union.cc16
-rw-r--r--sql/sql_update.cc6
-rw-r--r--sql/sql_view.cc13
-rw-r--r--sql/sql_yacc.yy42
-rw-r--r--sql/structs.h2
-rw-r--r--sql/sys_vars.cc3
-rw-r--r--sql/table.cc53
-rw-r--r--sql/table.h9
-rw-r--r--sql/transaction.cc12
-rw-r--r--sql/uniques.cc16
-rw-r--r--sql/unireg.cc15
-rw-r--r--sql/wsrep_binlog.cc2
-rw-r--r--sql/wsrep_hton.cc4
-rw-r--r--sql/wsrep_mysqld.cc70
-rw-r--r--sql/wsrep_sst.cc21
-rw-r--r--sql/wsrep_sst.h3
-rw-r--r--sql/wsrep_utils.cc1
-rw-r--r--sql/wsrep_var.cc19
-rw-r--r--sql/wsrep_var.h3
-rw-r--r--storage/connect/CMakeLists.txt61
-rw-r--r--storage/connect/array.cpp2
-rw-r--r--storage/connect/colblk.cpp1
-rw-r--r--storage/connect/connect.cc3
-rw-r--r--storage/connect/csort.cpp16
-rw-r--r--storage/connect/domdoc.cpp3
-rw-r--r--storage/connect/filamap.cpp12
-rw-r--r--storage/connect/filamgz.cpp8
-rw-r--r--storage/connect/filamtxt.cpp11
-rw-r--r--storage/connect/filamzip.cpp4
-rw-r--r--storage/connect/filter.cpp4
-rw-r--r--storage/connect/fmdlex.c26
-rw-r--r--storage/connect/global.h2
-rw-r--r--storage/connect/ha_connect.cc132
-rw-r--r--storage/connect/jdbconn.cpp62
-rw-r--r--storage/connect/json.cpp35
-rw-r--r--storage/connect/json.h8
-rw-r--r--storage/connect/jsonudf.cpp838
-rw-r--r--storage/connect/jsonudf.h4
-rw-r--r--storage/connect/macutil.cpp4
-rw-r--r--storage/connect/myconn.cpp7
-rw-r--r--storage/connect/mysql-test/connect/disabled.def1
-rw-r--r--storage/connect/mysql-test/connect/r/json_udf.result10
-rw-r--r--storage/connect/mysql-test/connect/r/json_udf_bin.result3
-rw-r--r--storage/connect/mysql-test/connect/r/vcol.result29
-rw-r--r--storage/connect/mysql-test/connect/std_data/Mongo2.jarbin3461358 -> 623907 bytes
-rw-r--r--storage/connect/mysql-test/connect/std_data/Mongo3.jarbin1705776 -> 1705776 bytes
-rw-r--r--storage/connect/mysql-test/connect/t/json_udf.test6
-rw-r--r--storage/connect/mysql-test/connect/t/vcol.test31
-rw-r--r--storage/connect/odbconn.cpp6
-rw-r--r--storage/connect/plgdbutl.cpp2
-rw-r--r--storage/connect/plugutil.cpp4
-rw-r--r--storage/connect/preparse.h2
-rw-r--r--storage/connect/rcmsg.c7
-rw-r--r--storage/connect/rcmsg.h2
-rw-r--r--storage/connect/reldef.cpp14
-rw-r--r--storage/connect/tabdos.cpp9
-rw-r--r--storage/connect/tabfmt.cpp6
-rw-r--r--storage/connect/tabjson.cpp4
-rw-r--r--storage/connect/tabjson.h4
-rw-r--r--storage/connect/tabmac.cpp4
-rw-r--r--storage/connect/tabmul.cpp4
-rw-r--r--storage/connect/tabmysql.cpp6
-rw-r--r--storage/connect/tabmysql.h2
-rw-r--r--storage/connect/tabodbc.cpp2
-rw-r--r--storage/connect/tabtbl.cpp2
-rw-r--r--storage/connect/tabxml.cpp2
-rw-r--r--storage/connect/value.cpp6
-rw-r--r--storage/connect/xobject.cpp5
-rw-r--r--storage/federated/ha_federated.cc9
-rw-r--r--storage/federatedx/federatedx_io_mysql.cc9
-rw-r--r--storage/federatedx/ha_federatedx.h2
-rw-r--r--storage/heap/ha_heap.cc9
-rw-r--r--storage/innobase/CMakeLists.txt9
-rw-r--r--storage/innobase/api/api0api.cc2
-rw-r--r--storage/innobase/btr/btr0btr.cc88
-rw-r--r--storage/innobase/btr/btr0cur.cc50
-rw-r--r--storage/innobase/btr/btr0pcur.cc2
-rw-r--r--storage/innobase/btr/btr0scrub.cc12
-rw-r--r--storage/innobase/btr/btr0sea.cc4
-rw-r--r--storage/innobase/buf/buf0buddy.cc3
-rw-r--r--storage/innobase/buf/buf0buf.cc96
-rw-r--r--storage/innobase/buf/buf0dblwr.cc2
-rw-r--r--storage/innobase/buf/buf0dump.cc11
-rw-r--r--storage/innobase/buf/buf0flu.cc3
-rw-r--r--storage/innobase/buf/buf0lru.cc370
-rw-r--r--storage/innobase/data/data0type.cc10
-rw-r--r--storage/innobase/dict/dict0dict.cc59
-rw-r--r--storage/innobase/dict/dict0mem.cc9
-rw-r--r--storage/innobase/dict/dict0stats_bg.cc31
-rw-r--r--storage/innobase/fil/fil0crypt.cc10
-rw-r--r--storage/innobase/fil/fil0fil.cc191
-rw-r--r--storage/innobase/fil/fil0pagecompress.cc15
-rw-r--r--storage/innobase/fts/fts0fts.cc180
-rw-r--r--storage/innobase/fts/fts0opt.cc11
-rw-r--r--storage/innobase/fts/fts0que.cc29
-rw-r--r--storage/innobase/handler/ha_innodb.cc61
-rw-r--r--storage/innobase/handler/handler0alter.cc244
-rw-r--r--storage/innobase/handler/i_s.cc27
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.cc40
-rw-r--r--storage/innobase/include/btr0btr.ic2
-rw-r--r--storage/innobase/include/btr0cur.h12
-rw-r--r--storage/innobase/include/btr0scrub.h11
-rw-r--r--storage/innobase/include/buf0buf.h21
-rw-r--r--storage/innobase/include/buf0lru.h18
-rw-r--r--storage/innobase/include/buf0types.h11
-rw-r--r--storage/innobase/include/data0type.h50
-rw-r--r--storage/innobase/include/data0type.ic58
-rw-r--r--storage/innobase/include/dict0dict.h25
-rw-r--r--storage/innobase/include/dict0dict.ic57
-rw-r--r--storage/innobase/include/dict0mem.h15
-rw-r--r--storage/innobase/include/dict0stats_bg.h4
-rw-r--r--storage/innobase/include/fil0fil.h17
-rw-r--r--storage/innobase/include/fts0fts.h17
-rw-r--r--storage/innobase/include/lock0lock.h4
-rw-r--r--storage/innobase/include/log0crypt.h48
-rw-r--r--storage/innobase/include/mem0mem.ic12
-rw-r--r--storage/innobase/include/mtr0log.ic2
-rw-r--r--storage/innobase/include/mtr0mtr.h16
-rw-r--r--storage/innobase/include/mtr0mtr.ic6
-rw-r--r--storage/innobase/include/os0file.h4
-rw-r--r--storage/innobase/include/page0page.ic2
-rw-r--r--storage/innobase/include/page0zip.ic2
-rw-r--r--storage/innobase/include/que0que.h3
-rw-r--r--storage/innobase/include/rem0rec.ic3
-rw-r--r--storage/innobase/include/row0ftsort.h3
-rw-r--r--storage/innobase/include/row0merge.h33
-rw-r--r--storage/innobase/include/row0mysql.h12
-rw-r--r--storage/innobase/include/row0upd.h4
-rw-r--r--storage/innobase/include/row0upd.ic4
-rw-r--r--storage/innobase/include/srv0srv.h17
-rw-r--r--storage/innobase/include/trx0rec.h9
-rw-r--r--storage/innobase/include/trx0roll.h9
-rw-r--r--storage/innobase/include/trx0sys.h7
-rw-r--r--storage/innobase/include/trx0sys.ic3
-rw-r--r--storage/innobase/include/trx0undo.h13
-rw-r--r--storage/innobase/include/univ.i8
-rw-r--r--storage/innobase/include/ut0timer.ic2
-rw-r--r--storage/innobase/include/ut0ut.h3
-rw-r--r--storage/innobase/lock/lock0lock.cc115
-rw-r--r--storage/innobase/lock/lock0wait.cc39
-rw-r--r--storage/innobase/log/log0crypt.cc177
-rw-r--r--storage/innobase/log/log0log.cc7
-rw-r--r--storage/innobase/log/log0recv.cc7
-rw-r--r--storage/innobase/mem/mem0mem.cc13
-rw-r--r--storage/innobase/os/os0file.cc49
-rw-r--r--storage/innobase/page/page0cur.cc2
-rw-r--r--storage/innobase/page/page0page.cc17
-rw-r--r--storage/innobase/rem/rem0rec.cc18
-rw-r--r--storage/innobase/row/row0ext.cc3
-rw-r--r--storage/innobase/row/row0ftsort.cc55
-rw-r--r--storage/innobase/row/row0import.cc50
-rw-r--r--storage/innobase/row/row0ins.cc50
-rw-r--r--storage/innobase/row/row0log.cc180
-rw-r--r--storage/innobase/row/row0merge.cc341
-rw-r--r--storage/innobase/row/row0mysql.cc207
-rw-r--r--storage/innobase/row/row0purge.cc4
-rw-r--r--storage/innobase/row/row0quiesce.cc10
-rw-r--r--storage/innobase/row/row0row.cc9
-rw-r--r--storage/innobase/row/row0sel.cc50
-rw-r--r--storage/innobase/row/row0umod.cc16
-rw-r--r--storage/innobase/row/row0undo.cc8
-rw-r--r--storage/innobase/row/row0upd.cc26
-rw-r--r--storage/innobase/srv/srv0srv.cc10
-rw-r--r--storage/innobase/srv/srv0start.cc9
-rw-r--r--storage/innobase/trx/trx0purge.cc26
-rw-r--r--storage/innobase/trx/trx0rec.cc53
-rw-r--r--storage/innobase/trx/trx0roll.cc167
-rw-r--r--storage/innobase/trx/trx0sys.cc17
-rw-r--r--storage/innobase/trx/trx0trx.cc10
-rw-r--r--storage/innobase/trx/trx0undo.cc44
-rw-r--r--storage/innobase/ut/ut0dbg.cc2
-rw-r--r--storage/innobase/ut/ut0ut.cc7
-rw-r--r--storage/maria/ha_maria.cc7
-rw-r--r--storage/maria/ma_blockrec.c20
-rw-r--r--storage/maria/ma_create.c38
-rw-r--r--storage/maria/ma_extra.c3
-rw-r--r--storage/maria/ma_loghandler.c3
-rw-r--r--storage/maria/ma_page.c40
-rw-r--r--storage/maria/ma_recovery.c2
-rw-r--r--storage/maria/ma_search.c14
-rw-r--r--storage/maria/ma_state.c24
-rw-r--r--storage/maria/ma_state.h1
-rw-r--r--storage/maria/ma_write.c2
-rw-r--r--storage/maria/maria_def.h3
-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/mroonga/CMakeLists.txt152
-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.cpp2854
-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.cpp63
-rw-r--r--storage/mroonga/lib/mrn_column_name.hpp38
-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.h243
-rw-r--r--storage/mroonga/mrn_table.cpp68
-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.inc (renamed from storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_100.inc)8
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_10_0_or_later.inc21
-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_or_later.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)8
-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.result25
-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_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.result21
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_alter_drop.result21
-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_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_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/suite.pm2
-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)9
-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.test16
-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_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.result10
-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/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_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.result11
-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/suite.pm2
-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.txt222
-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.cpp2
-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.c21
-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/ha_myisam.cc62
-rw-r--r--storage/myisam/mi_extra.c2
-rw-r--r--storage/myisam/mi_locking.c8
-rw-r--r--storage/myisam/mi_search.c14
-rw-r--r--storage/oqgraph/graphcore.cc14
-rw-r--r--storage/oqgraph/mysql-test/oqgraph/general-Aria.result99
-rw-r--r--storage/oqgraph/mysql-test/oqgraph/general-MyISAM.result99
-rw-r--r--storage/oqgraph/mysql-test/oqgraph/general-innodb.result99
-rw-r--r--storage/oqgraph/mysql-test/oqgraph/regression_1196036.result6
-rw-r--r--storage/oqgraph/mysql-test/oqgraph/regression_1213120.result71
-rw-r--r--storage/oqgraph/oqgraph_shim.h6
-rw-r--r--storage/perfschema/pfs.cc6
-rw-r--r--storage/sphinx/ha_sphinx.cc12
-rw-r--r--storage/spider/spd_db_conn.cc2
-rw-r--r--storage/tokudb/CMakeLists.txt11
-rw-r--r--storage/tokudb/PerconaFT/CMakeLists.txt7
-rw-r--r--storage/tokudb/PerconaFT/buildheader/make_tdb.cc15
-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_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.h328
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_pthread.h450
-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-internal.h9
-rw-r--r--storage/tokudb/PerconaFT/src/ydb.cc31
-rw-r--r--storage/tokudb/PerconaFT/src/ydb_cursor.cc108
-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/third_party/snappy-1.1.2/CMakeLists.txt1
-rwxr-xr-xstorage/tokudb/PerconaFT/third_party/xz-4.999.9beta/configure92
-rw-r--r--storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/configure.ac57
-rw-r--r--storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/m4/libtool.m46
-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.cc147
-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_row_log_tokudb.result293
-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/t/rpl_row_log_tokudb-master.opt2
-rw-r--r--storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb.test14
-rw-r--r--storage/tokudb/mysql-test/tokudb/disabled.def1
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/card_scale_percent.result11
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/dir_per_db.result10
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-1.result13
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-2.result17
-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/type_blob.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/card_scale_percent.test6
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/dir_per_db.test17
-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_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_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.h298
-rw-r--r--storage/xtradb/CMakeLists.txt6
-rw-r--r--storage/xtradb/api/api0api.cc6
-rw-r--r--storage/xtradb/btr/btr0btr.cc88
-rw-r--r--storage/xtradb/btr/btr0cur.cc57
-rw-r--r--storage/xtradb/btr/btr0pcur.cc3
-rw-r--r--storage/xtradb/btr/btr0scrub.cc12
-rw-r--r--storage/xtradb/btr/btr0sea.cc4
-rw-r--r--storage/xtradb/buf/buf0buddy.cc3
-rw-r--r--storage/xtradb/buf/buf0buf.cc100
-rw-r--r--storage/xtradb/buf/buf0dblwr.cc2
-rw-r--r--storage/xtradb/buf/buf0dump.cc4
-rw-r--r--storage/xtradb/buf/buf0flu.cc3
-rw-r--r--storage/xtradb/buf/buf0lru.cc437
-rw-r--r--storage/xtradb/buf/buf0rea.cc35
-rw-r--r--storage/xtradb/data/data0type.cc10
-rw-r--r--storage/xtradb/dict/dict0dict.cc58
-rw-r--r--storage/xtradb/dict/dict0mem.cc5
-rw-r--r--storage/xtradb/dict/dict0stats_bg.cc31
-rw-r--r--storage/xtradb/fil/fil0crypt.cc10
-rw-r--r--storage/xtradb/fil/fil0fil.cc211
-rw-r--r--storage/xtradb/fil/fil0pagecompress.cc15
-rw-r--r--storage/xtradb/fts/fts0fts.cc166
-rw-r--r--storage/xtradb/fts/fts0opt.cc11
-rw-r--r--storage/xtradb/fts/fts0que.cc13
-rw-r--r--storage/xtradb/handler/ha_innodb.cc127
-rw-r--r--storage/xtradb/handler/ha_innodb.h6
-rw-r--r--storage/xtradb/handler/handler0alter.cc243
-rw-r--r--storage/xtradb/handler/i_s.cc27
-rw-r--r--storage/xtradb/ibuf/ibuf0ibuf.cc40
-rw-r--r--storage/xtradb/include/btr0btr.ic2
-rw-r--r--storage/xtradb/include/btr0cur.h12
-rw-r--r--storage/xtradb/include/btr0scrub.h11
-rw-r--r--storage/xtradb/include/buf0buf.h22
-rw-r--r--storage/xtradb/include/buf0lru.h18
-rw-r--r--storage/xtradb/include/buf0types.h11
-rw-r--r--storage/xtradb/include/data0type.h51
-rw-r--r--storage/xtradb/include/data0type.ic58
-rw-r--r--storage/xtradb/include/dict0dict.h25
-rw-r--r--storage/xtradb/include/dict0dict.ic57
-rw-r--r--storage/xtradb/include/dict0mem.h15
-rw-r--r--storage/xtradb/include/dict0stats_bg.h4
-rw-r--r--storage/xtradb/include/fil0fil.h41
-rw-r--r--storage/xtradb/include/fts0fts.h17
-rw-r--r--storage/xtradb/include/lock0lock.h2
-rw-r--r--storage/xtradb/include/log0crypt.h48
-rw-r--r--storage/xtradb/include/log0online.h6
-rw-r--r--storage/xtradb/include/mem0mem.ic12
-rw-r--r--storage/xtradb/include/mtr0log.ic2
-rw-r--r--storage/xtradb/include/mtr0mtr.h16
-rw-r--r--storage/xtradb/include/mtr0mtr.ic6
-rw-r--r--storage/xtradb/include/os0file.h39
-rw-r--r--storage/xtradb/include/os0file.ic5
-rw-r--r--storage/xtradb/include/page0page.ic2
-rw-r--r--storage/xtradb/include/page0zip.ic2
-rw-r--r--storage/xtradb/include/que0que.h3
-rw-r--r--storage/xtradb/include/rem0rec.ic3
-rw-r--r--storage/xtradb/include/row0ftsort.h3
-rw-r--r--storage/xtradb/include/row0merge.h37
-rw-r--r--storage/xtradb/include/row0mysql.h14
-rw-r--r--storage/xtradb/include/row0sel.h14
-rw-r--r--storage/xtradb/include/row0upd.h4
-rw-r--r--storage/xtradb/include/row0upd.ic4
-rw-r--r--storage/xtradb/include/srv0srv.h27
-rw-r--r--storage/xtradb/include/trx0rec.h11
-rw-r--r--storage/xtradb/include/trx0roll.h9
-rw-r--r--storage/xtradb/include/trx0sys.h5
-rw-r--r--storage/xtradb/include/trx0sys.ic3
-rw-r--r--storage/xtradb/include/trx0undo.h13
-rw-r--r--storage/xtradb/include/univ.i12
-rw-r--r--storage/xtradb/include/ut0timer.ic2
-rw-r--r--storage/xtradb/lock/lock0lock.cc112
-rw-r--r--storage/xtradb/lock/lock0wait.cc97
-rw-r--r--storage/xtradb/log/log0crypt.cc177
-rw-r--r--storage/xtradb/log/log0log.cc9
-rw-r--r--storage/xtradb/log/log0online.cc6
-rw-r--r--storage/xtradb/log/log0recv.cc12
-rw-r--r--storage/xtradb/mem/mem0mem.cc13
-rw-r--r--storage/xtradb/os/os0file.cc195
-rw-r--r--storage/xtradb/page/page0cur.cc2
-rw-r--r--storage/xtradb/page/page0page.cc19
-rw-r--r--storage/xtradb/rem/rem0rec.cc19
-rw-r--r--storage/xtradb/row/row0ext.cc3
-rw-r--r--storage/xtradb/row/row0ftsort.cc55
-rw-r--r--storage/xtradb/row/row0import.cc50
-rw-r--r--storage/xtradb/row/row0ins.cc50
-rw-r--r--storage/xtradb/row/row0log.cc180
-rw-r--r--storage/xtradb/row/row0merge.cc354
-rw-r--r--storage/xtradb/row/row0mysql.cc207
-rw-r--r--storage/xtradb/row/row0purge.cc4
-rw-r--r--storage/xtradb/row/row0quiesce.cc10
-rw-r--r--storage/xtradb/row/row0row.cc9
-rw-r--r--storage/xtradb/row/row0sel.cc114
-rw-r--r--storage/xtradb/row/row0umod.cc16
-rw-r--r--storage/xtradb/row/row0undo.cc8
-rw-r--r--storage/xtradb/row/row0upd.cc26
-rw-r--r--storage/xtradb/srv/srv0srv.cc18
-rw-r--r--storage/xtradb/srv/srv0start.cc17
-rw-r--r--storage/xtradb/trx/trx0purge.cc26
-rw-r--r--storage/xtradb/trx/trx0rec.cc52
-rw-r--r--storage/xtradb/trx/trx0roll.cc167
-rw-r--r--storage/xtradb/trx/trx0rseg.cc2
-rw-r--r--storage/xtradb/trx/trx0sys.cc16
-rw-r--r--storage/xtradb/trx/trx0trx.cc10
-rw-r--r--storage/xtradb/trx/trx0undo.cc46
-rw-r--r--storage/xtradb/ut/ut0dbg.cc2
-rw-r--r--strings/CMakeLists.txt9
-rw-r--r--strings/ctype-tis620.c8
-rw-r--r--strings/ctype-utf8.c3
-rw-r--r--strings/dtoa.c8
-rw-r--r--strings/my_vsnprintf.c6
-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/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--unittest/mysys/base64-t.c3
-rw-r--r--vio/CMakeLists.txt4
-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.cpp45
-rw-r--r--zlib/CMakeLists.txt5
2993 files changed, 204879 insertions, 119349 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1ff14c94a74..b4de70a283d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -56,9 +56,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)
@@ -479,6 +479,12 @@ ENDIF()
INCLUDE(CPack)
+IF(WIN32 AND SIGNCODE)
+ # Configure post-install script for authenticode signing
+ CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/cmake/sign.cmake.in sign.cmake @ONLY)
+ INSTALL(SCRIPT ${PROJECT_BINARY_DIR}/sign.cmake)
+ENDIF()
+
IF(NON_DISTRIBUTABLE_WARNING)
MESSAGE(WARNING "
You have linked MariaDB with GPLv3 libraries! You may not distribute the resulting binary. If you do, you will put yourself into a legal problem with Free Software Foundation.")
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/VERSION b/VERSION
index b44db15ffd8..95c724d2776 100644
--- a/VERSION
+++ b/VERSION
@@ -1,3 +1,3 @@
MYSQL_VERSION_MAJOR=10
MYSQL_VERSION_MINOR=1
-MYSQL_VERSION_PATCH=27
+MYSQL_VERSION_PATCH=32
diff --git a/client/mysql.cc b/client/mysql.cc
index 1c344c7e54c..7973c3c7fc3 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1065,8 +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 &buffer, char *line, ulong line_length,
- char *in_string, bool *ml_comment, bool truncated);
+static bool add_line(String &, char *, ulong, 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);
@@ -1078,7 +1077,7 @@ static ulong start_timer(void);
static void end_timer(ulong start_time,char *buff);
static void mysql_end_timer(ulong start_time,char *buff);
static void nice_time(double sec,char *buff,bool part_second);
-extern "C" sig_handler mysql_end(int sig);
+extern "C" sig_handler mysql_end(int sig) __attribute__ ((noreturn));
extern "C" sig_handler handle_sigint(int sig);
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
static sig_handler window_resize(int sig);
@@ -1095,7 +1094,7 @@ inline bool is_delimiter_command(char *name, ulong len)
only name(first DELIMITER_NAME_LEN bytes) is checked.
*/
return (len >= DELIMITER_NAME_LEN &&
- !my_strnncoll(charset_info, (uchar*) name, DELIMITER_NAME_LEN,
+ !my_strnncoll(&my_charset_latin1, (uchar*) name, DELIMITER_NAME_LEN,
(uchar *) DELIMITER_NAME, DELIMITER_NAME_LEN));
}
@@ -1141,6 +1140,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
@@ -1201,6 +1201,7 @@ 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));
@@ -1794,8 +1795,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:
@@ -4590,8 +4592,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_upgrade.c b/client/mysql_upgrade.c
index c10dc20e7d7..cbdd398c1e1 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 ffdc73f99ad..897c2eb41c3 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -298,8 +298,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;
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 7a4b34c40c6..b871a70ef01 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -1649,8 +1649,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
remote_opt= 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;
case OPT_START_DATETIME:
start_datetime= convert_str_to_timestamp(start_datetime_str);
@@ -1663,8 +1667,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
@@ -2670,10 +2681,11 @@ int main(int argc, char** argv)
if (!argc || opt_version)
{
- if (!argc)
- usage();
if (!opt_version)
+ {
+ usage();
retval= ERROR_STOP;
+ }
goto err;
}
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index c4ac58973f8..47cb38751eb 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;
}
diff --git a/client/mysqldump.c b/client/mysqldump.c
index aead4caf506..5c0ec2a5510 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -956,8 +956,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;
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index 7f03cb355f8..9c84d4a62a6 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");
diff --git a/client/mysqlshow.c b/client/mysqlshow.c
index 6f434d6770d..f851c15106e 100644
--- a/client/mysqlshow.c
+++ b/client/mysqlshow.c
@@ -328,8 +328,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");
diff --git a/client/mysqlslap.c b/client/mysqlslap.c
index a78bf35d51b..6a0b214305c 100644
--- a/client/mysqlslap.c
+++ b/client/mysqlslap.c
@@ -779,8 +779,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);
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 155d0c4c092..844a2d7bbf8 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -1523,7 +1523,6 @@ static void cleanup_and_exit(int exit_code)
}
}
- sf_leaking_memory= 0; /* all memory should be freed by now */
exit(exit_code);
}
@@ -7292,8 +7291,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 '?':
diff --git a/cmake/bison.cmake b/cmake/bison.cmake
index d5c725fbbde..0892a213d04 100644
--- a/cmake/bison.cmake
+++ b/cmake/bison.cmake
@@ -47,6 +47,21 @@ MACRO (RUN_BISON input_yy output_cc output_h)
ENDIF()
ENDIF()
IF(BISON_USABLE)
+ # Workaround for VS regenerating output even
+ # when outputs are up-to-date. At least, fix output timestamp
+ # after build so that files that depend on generated header are
+ # not rebuilt.
+ IF(CMAKE_GENERATOR MATCHES "Visual Studio")
+ FIND_PROGRAM(TOUCH_EXECUTABLE touch DOC "Path to touch executable"
+ PATHS "C:/Program Files/Git/usr/bin"
+ "C:/Program Files (x86)/Git/usr/bin")
+ IF(TOUCH_EXECUTABLE)
+ SET(VS_FIX_OUTPUT_TIMESTAMPS
+ COMMAND ${TOUCH_EXECUTABLE} -r ${input_yy} ${output_cc}
+ COMMAND ${TOUCH_EXECUTABLE} -r ${input_yy} ${output_h})
+ ENDIF()
+ ENDIF()
+
ADD_CUSTOM_COMMAND(
OUTPUT ${output_cc}
${output_h}
@@ -54,8 +69,9 @@ MACRO (RUN_BISON input_yy output_cc output_h)
--output=${output_cc}
--defines=${output_h}
${input_yy}
- DEPENDS ${input_yy}
- )
+ ${VS_FIX_OUTPUT_TIMESTAMPS}
+ DEPENDS ${input_yy}
+ )
ELSE()
# Bison is missing or not usable, e.g too old
IF(EXISTS ${output_cc} AND EXISTS ${output_h})
diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake
index c07de46fc16..04860a40dbb 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
diff --git a/cmake/check_compiler_flag.cmake b/cmake/check_compiler_flag.cmake
index ef675959059..673361ab8fe 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 e886cea1cc1..e80fb199f03 100644
--- a/cmake/cpack_rpm.cmake
+++ b/cmake/cpack_rpm.cmake
@@ -168,9 +168,14 @@ SETA(CPACK_RPM_server_PACKAGE_REQUIRES
"MariaDB-client")
IF(WITH_WSREP)
-SETA(CPACK_RPM_server_PACKAGE_REQUIRES
- "galera" "rsync" "lsof" "grep" "gawk" "iproute"
- "coreutils" "findutils" "tar" "which")
+ 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)
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..5484691e94a 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
@@ -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/install_macros.cmake b/cmake/install_macros.cmake
index 7db0492cb88..121825f8f3c 100644
--- a/cmake/install_macros.cmake
+++ b/cmake/install_macros.cmake
@@ -32,17 +32,8 @@ FUNCTION (INSTALL_DEBUG_SYMBOLS)
ENDIF()
SET(targets ${ARG_DEFAULT_ARGS})
FOREACH(target ${targets})
- GET_TARGET_PROPERTY(type ${target} TYPE)
- GET_TARGET_PROPERTY(location ${target} LOCATION)
- STRING(REPLACE ".exe" ".pdb" pdb_location ${location})
- STRING(REPLACE ".dll" ".pdb" pdb_location ${pdb_location})
- STRING(REPLACE ".lib" ".pdb" pdb_location ${pdb_location})
- IF(CMAKE_GENERATOR MATCHES "Visual Studio")
- STRING(REPLACE
- "${CMAKE_CFG_INTDIR}" "\${CMAKE_INSTALL_CONFIG_NAME}"
- pdb_location ${pdb_location})
- ENDIF()
-
+ GET_TARGET_PROPERTY(target_type ${target} TYPE)
+
set(comp "")
IF(target MATCHES "mysqld" OR type MATCHES "MODULE")
@@ -61,11 +52,9 @@ FUNCTION (INSTALL_DEBUG_SYMBOLS)
IF(NOT comp)
SET(comp Debuginfo_archive_only) # not in MSI
ENDIF()
- IF(type MATCHES "STATIC")
- # PDB for static libraries might be unsupported http://public.kitware.com/Bug/view.php?id=14600
- SET(opt OPTIONAL)
- ENDIF()
- INSTALL(FILES ${pdb_location} DESTINATION ${ARG_INSTALL_LOCATION} COMPONENT ${comp} ${opt})
+ IF(NOT target_type MATCHES "STATIC")
+ INSTALL(FILES $<TARGET_PDB_FILE:${target}> DESTINATION ${ARG_INSTALL_LOCATION} COMPONENT ${comp})
+ ENDIF()
ENDFOREACH()
ENDIF()
ENDFUNCTION()
@@ -211,37 +200,22 @@ IF(WIN32)
ENDIF()
ENDIF()
-MACRO(SIGN_TARGET)
- MYSQL_PARSE_ARGUMENTS(ARG "COMPONENT" "" ${ARGN})
- SET(target ${ARG_DEFAULT_ARGS})
- IF(ARG_COMPONENT)
- SET(comp COMPONENT ${ARG_COMPONENT})
- ELSE()
- SET(comp)
- ENDIF()
- GET_TARGET_PROPERTY(target_type ${target} TYPE)
- IF(target_type AND NOT target_type MATCHES "STATIC")
- GET_TARGET_PROPERTY(target_location ${target} LOCATION)
- IF(CMAKE_GENERATOR MATCHES "Visual Studio")
- STRING(REPLACE "${CMAKE_CFG_INTDIR}" "\${CMAKE_INSTALL_CONFIG_NAME}"
- target_location ${target_location})
- ENDIF()
- INSTALL(CODE
- "EXECUTE_PROCESS(COMMAND
- \"${SIGNTOOL_EXECUTABLE}\" verify /pa /q \"${target_location}\"
- RESULT_VARIABLE ERR)
- IF(NOT \${ERR} EQUAL 0)
- EXECUTE_PROCESS(COMMAND
- \"${SIGNTOOL_EXECUTABLE}\" sign ${SIGNTOOL_PARAMETERS} \"${target_location}\"
- RESULT_VARIABLE ERR)
+
+FUNCTION(SIGN_TARGET target)
+ IF(NOT SIGNCODE)
+ RETURN()
ENDIF()
- IF(NOT \${ERR} EQUAL 0)
- MESSAGE(FATAL_ERROR \"Error signing '${target_location}'\")
+ GET_TARGET_PROPERTY(target_type ${target} TYPE)
+ IF((NOT target_type) OR (target_type MATCHES "STATIC"))
+ RETURN()
ENDIF()
- " ${comp})
- ENDIF()
-ENDMACRO()
-
+ # Mark executable for signing by creating empty *.signme file
+ # The actual signing happens in preinstall step
+ # (which traverses
+ ADD_CUSTOM_COMMAND(TARGET ${target} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E touch "$<TARGET_FILE:${target}>.signme"
+ )
+ENDFUNCTION()
# Installs targets, also installs pdbs on Windows.
#
diff --git a/cmake/maintainer.cmake b/cmake/maintainer.cmake
index 367b78afd0d..4e902d7fed8 100644
--- a/cmake/maintainer.cmake
+++ b/cmake/maintainer.cmake
@@ -14,49 +14,32 @@
# 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()
-
-# 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")
-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()
+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
+ -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/pcre.cmake b/cmake/pcre.cmake
index 894bde38974..4c113929866 100644
--- a/cmake/pcre.cmake
+++ b/cmake/pcre.cmake
@@ -1,11 +1,23 @@
+INCLUDE (CheckCSourceRuns)
+
SET(WITH_PCRE "auto" CACHE STRING
"Which pcre to use (possible values are 'bundled', 'system', or 'auto')")
MACRO (CHECK_PCRE)
IF(WITH_PCRE STREQUAL "system" OR WITH_PCRE STREQUAL "auto")
- CHECK_LIBRARY_EXISTS(pcre pcre_stack_guard "" HAVE_PCRE)
+ CHECK_LIBRARY_EXISTS(pcre pcre_stack_guard "" HAVE_PCRE_STACK_GUARD)
+ IF(NOT CMAKE_CROSSCOMPILING)
+ SET(CMAKE_REQUIRED_LIBRARIES "pcre")
+ CHECK_C_SOURCE_RUNS("
+ #include <pcre.h>
+ int main() {
+ return -pcre_exec(NULL, NULL, NULL, -999, -999, 0, NULL, 0) < 256;
+ }" PCRE_STACK_SIZE_OK)
+ SET(CMAKE_REQUIRED_LIBRARIES)
+ ENDIF()
ENDIF()
- IF(NOT HAVE_PCRE OR WITH_PCRE STREQUAL "bundled")
+ IF(NOT HAVE_PCRE_STACK_GUARD OR NOT PCRE_STACK_SIZE_OK OR
+ WITH_PCRE STREQUAL "bundled")
IF (WITH_PCRE STREQUAL "system")
MESSAGE(FATAL_ERROR "system pcre is not found or unusable")
ENDIF()
diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake
index 3e7c5804f77..591c448a793 100644
--- a/cmake/plugin.cmake
+++ b/cmake/plugin.cmake
@@ -222,7 +222,8 @@ MACRO(MYSQL_ADD_PLUGIN)
# Install dynamic library
IF(ARG_COMPONENT)
IF(CPACK_COMPONENTS_ALL AND
- NOT CPACK_COMPONENTS_ALL MATCHES ${ARG_COMPONENT})
+ NOT CPACK_COMPONENTS_ALL MATCHES ${ARG_COMPONENT}
+ AND INSTALL_SYSCONF2DIR)
IF (ARG_STORAGE_ENGINE)
SET(ver " = %{version}-%{release}")
ELSE()
diff --git a/cmake/sign.cmake.in b/cmake/sign.cmake.in
new file mode 100644
index 00000000000..61ae38d152d
--- /dev/null
+++ b/cmake/sign.cmake.in
@@ -0,0 +1,18 @@
+FILE(GLOB_RECURSE files "@CMAKE_BINARY_DIR@/*.signme")
+MESSAGE(STATUS "signing files")
+FOREACH(f ${files})
+ STRING(REPLACE ".signme" "" exe_location "${f}")
+
+ string (REPLACE ";" " " params "@SIGNTOOL_PARAMETERS@")
+ #MESSAGE("@SIGNTOOL_EXECUTABLE@" sign ${params} "${exe_location}")
+
+ EXECUTE_PROCESS(COMMAND
+ "@SIGNTOOL_EXECUTABLE@" sign @SIGNTOOL_PARAMETERS@ "${exe_location}"
+ RESULT_VARIABLE ERR)
+ IF(NOT ${ERR} EQUAL 0)
+ MESSAGE( "Error ${ERR} signing ${exe_location}")
+ ELSE()
+ FILE(REMOVE ${f})
+ ENDIF()
+
+ENDFOREACH()
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 8ef512c7071..b1a9d813767 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -150,6 +150,7 @@
#cmakedefine HAVE_CUSERID 1
#cmakedefine HAVE_CXX_NEW 1
#cmakedefine HAVE_DIRECTIO 1
+#cmakedefine HAVE_DLADDR 1
#cmakedefine HAVE_DLERROR 1
#cmakedefine HAVE_DLOPEN 1
#cmakedefine HAVE_DOPRNT 1
diff --git a/configure.cmake b/configure.cmake
index 0057c7fb100..a1cddbb37fa 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -344,6 +344,7 @@ CHECK_FUNCTION_EXISTS (ftruncate HAVE_FTRUNCATE)
CHECK_FUNCTION_EXISTS (getline HAVE_GETLINE)
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)
@@ -407,7 +408,6 @@ CHECK_FUNCTION_EXISTS (pthread_sigmask HAVE_PTHREAD_SIGMASK)
CHECK_FUNCTION_EXISTS (pthread_threadmask HAVE_PTHREAD_THREADMASK)
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 (re_comp HAVE_RE_COMP)
CHECK_FUNCTION_EXISTS (regcomp HAVE_REGCOMP)
@@ -465,6 +465,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)
#--------------------------------------------------------------------
diff --git a/debian/additions/debian-start.inc.sh b/debian/additions/debian-start.inc.sh
index f50712882c1..08ec339bcba 100644
--- a/debian/additions/debian-start.inc.sh
+++ b/debian/additions/debian-start.inc.sh
@@ -65,7 +65,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/libmariadbclient18.links b/debian/libmariadbclient18.links
new file mode 100644
index 00000000000..b2e8a48302f
--- /dev/null
+++ b/debian/libmariadbclient18.links
@@ -0,0 +1,3 @@
+usr/lib/libmysqlclient.so.18.0.0 usr/lib/libmariadbclient.so.18.0.0
+usr/lib/libmysqlclient.so.18 usr/lib/libmariadbclient.so.18
+usr/lib/libmysqlclient.so usr/lib/libmariadbclient.so
diff --git a/debian/patches/50_mysql-test__db_test.dpatch b/debian/patches/50_mysql-test__db_test.dpatch
index 670afbf14ac..14c0fc4acf6 100755
--- a/debian/patches/50_mysql-test__db_test.dpatch
+++ b/debian/patches/50_mysql-test__db_test.dpatch
@@ -11,14 +11,14 @@
--- 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 {
- mtr_appendfile_to_file("$sql_dir/mysql_system_tables_data.sql",
- $bootstrap_sql_file);
+ 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, "-- 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");
+
- # Add test data for timezone - this is just a subset, on a real
- # system these tables will be populated either by mysql_tzinfo_to_sql
- # or by downloading the timezone table package from our website
++
+ # Add test data for timezone - this is just a subset, on a real
+ # system these tables will be populated either by mysql_tzinfo_to_sql
+ # or by downloading the timezone table package from our website
diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc
index 156e0b20e7c..c019209faad 100644
--- a/extra/mariabackup/backup_copy.cc
+++ b/extra/mariabackup/backup_copy.cc
@@ -1700,26 +1700,28 @@ copy_back()
ut_crc32_init();
/* copy undo tablespaces */
- if (srv_undo_tablespaces > 0) {
- dst_dir = (srv_undo_dir && *srv_undo_dir)
- ? srv_undo_dir : mysql_data_home;
- ds_data = ds_create(dst_dir, DS_TYPE_LOCAL);
+ dst_dir = (srv_undo_dir && *srv_undo_dir)
+ ? srv_undo_dir : mysql_data_home;
- for (i = 1; i <= srv_undo_tablespaces; i++) {
- char filename[20];
- sprintf(filename, "undo%03u", (uint)i);
- if (!(ret = copy_or_move_file(filename, filename,
- dst_dir, 1))) {
- goto cleanup;
- }
- }
+ ds_data = ds_create(dst_dir, DS_TYPE_LOCAL);
- ds_destroy(ds_data);
- ds_data = NULL;
+ for (i = 1; ; i++) {
+ char filename[20];
+ sprintf(filename, "undo%03u", (uint)i);
+ if (!file_exists(filename)) {
+ break;
+ }
+ if (!(ret = copy_or_move_file(filename, filename,
+ dst_dir, 1))) {
+ goto cleanup;
+ }
}
+ ds_destroy(ds_data);
+ ds_data = NULL;
+
/* copy redo logs */
dst_dir = (srv_log_group_home_dir && *srv_log_group_home_dir)
@@ -1844,7 +1846,7 @@ copy_back()
}
}
- /* copy buufer pool dump */
+ /* copy buffer pool dump */
if (innobase_buffer_pool_filename) {
const char *src_name;
diff --git a/extra/mariabackup/wsrep.h b/extra/mariabackup/backup_wsrep.h
index 7638d1f2b54..5fa261f8db5 100644
--- a/extra/mariabackup/wsrep.h
+++ b/extra/mariabackup/backup_wsrep.h
@@ -19,8 +19,8 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*******************************************************/
-#ifndef WSREP_H
-#define WSREP_H
+#ifndef MARIABACKUP_WSREP_H
+#define MARIABACKUP_WSREP_H
/***********************************************************************
Store Galera checkpoint info in the 'xtrabackup_galera_info' file, if that
diff --git a/extra/mariabackup/changed_page_bitmap.cc b/extra/mariabackup/changed_page_bitmap.cc
index 86a873ef69c..d5185b18971 100644
--- a/extra/mariabackup/changed_page_bitmap.cc
+++ b/extra/mariabackup/changed_page_bitmap.cc
@@ -538,7 +538,7 @@ xb_msg_missing_lsn_data(
lsn_t missing_interval_start, /*!<in: interval start */
lsn_t missing_interval_end) /*!<in: interval end */
{
- msg("xtrabackup: warning: changed page data missing for LSNs between "
+ msg("mariabackup: warning: changed page data missing for LSNs between "
LSN_PF " and " LSN_PF "\n", missing_interval_start,
missing_interval_end);
}
@@ -615,7 +615,7 @@ xb_page_bitmap_init(void)
if (UNIV_UNLIKELY(bmp_start_lsn > bmp_end_lsn)) {
- msg("xtrabackup: incremental backup LSN " LSN_PF
+ msg("mariabackup: incremental backup LSN " LSN_PF
" is larger than than the last checkpoint LSN " LSN_PF
"\n", bmp_start_lsn, bmp_end_lsn);
return NULL;
@@ -700,7 +700,7 @@ xb_page_bitmap_init(void)
&current_page_end_lsn,
bmp_start_lsn))) {
- msg("xtrabackup: Warning: changed page bitmap file "
+ msg("mariabackup: Warning: changed page bitmap file "
"\'%s\' corrupted\n", bitmap_file.name);
rbt_free(result);
free(bitmap_files.files);
@@ -805,7 +805,7 @@ xb_page_bitmap_init(void)
if (UNIV_UNLIKELY(!last_page_ok)) {
- msg("xtrabackup: warning: changed page bitmap file "
+ msg("mariabackup: warning: changed page bitmap file "
"\'%s\' corrupted.\n", bitmap_file.name);
rbt_free(result);
free(bitmap_files.files);
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/fil_cur.cc b/extra/mariabackup/fil_cur.cc
index 820d8e10c29..54700ce6837 100644
--- a/extra/mariabackup/fil_cur.cc
+++ b/extra/mariabackup/fil_cur.cc
@@ -1,5 +1,5 @@
/******************************************************
-XtraBackup: hot backup tool for InnoDB
+MariaBackup: hot backup tool for InnoDB
(c) 2009-2013 Percona LLC and/or its affiliates.
Originally Created 3/3/2009 Yasufumi Kinoshita
Written by Alexey Kopytov, Aleksandr Kuzminsky, Stewart Smith, Vadim Tkachenko,
@@ -173,7 +173,7 @@ xb_fil_cur_open(
/* The following call prints an error message */
os_file_get_last_error(TRUE);
- msg("[%02u] xtrabackup: error: cannot open "
+ msg("[%02u] mariabackup: error: cannot open "
"tablespace %s\n",
thread_n, cursor->abs_path);
@@ -202,7 +202,7 @@ xb_fil_cur_open(
cursor->file = node->handle;
if (stat(cursor->abs_path, &cursor->statinfo)) {
- msg("[%02u] xtrabackup: error: cannot stat %s\n",
+ msg("[%02u] mariabackup: error: cannot stat %s\n",
thread_n, cursor->abs_path);
xb_fil_cur_close(cursor);
@@ -229,7 +229,7 @@ xb_fil_cur_open(
msg("[%02u] %s is compressed with page size = "
"%lu bytes\n", thread_n, node->name, page_size);
if (page_size_shift < 10 || page_size_shift > 14) {
- msg("[%02u] xtrabackup: Error: Invalid "
+ msg("[%02u] mariabackup: Error: Invalid "
"page size: %lu.\n", thread_n, page_size);
ut_error;
}
@@ -300,9 +300,9 @@ xb_fil_cur_read(
offset + to_read == cursor->statinfo.st_size) {
if (to_read < (ib_int64_t) cursor->page_size) {
- msg("[%02u] xtrabackup: Warning: junk at the end of "
+ msg("[%02u] mariabackup: Warning: junk at the end of "
"%s:\n", cursor->thread_n, cursor->abs_path);
- msg("[%02u] xtrabackup: Warning: offset = %llu, "
+ msg("[%02u] mariabackup: Warning: offset = %llu, "
"to_read = %llu\n",
cursor->thread_n,
(unsigned long long) offset,
@@ -356,13 +356,13 @@ read_retry:
page_no < (ib_int64_t) FSP_EXTENT_SIZE * 3) {
/* skip doublewrite buffer pages */
xb_a(cursor->page_size == UNIV_PAGE_SIZE);
- msg("[%02u] xtrabackup: "
+ msg("[%02u] mariabackup: "
"Page %lu is a doublewrite buffer page, "
"skipping.\n", cursor->thread_n, page_no);
} else {
retry_count--;
if (retry_count == 0) {
- msg("[%02u] xtrabackup: "
+ msg("[%02u] mariabackup: "
"Error: failed to read page after "
"10 retries. File %s seems to be "
"corrupted.\n", cursor->thread_n,
@@ -370,7 +370,7 @@ read_retry:
ret = XB_FIL_CUR_ERROR;
break;
}
- msg("[%02u] xtrabackup: "
+ msg("[%02u] mariabackup: "
"Database page corruption detected at page "
"%lu, retrying...\n", cursor->thread_n,
page_no);
diff --git a/extra/mariabackup/write_filt.cc b/extra/mariabackup/write_filt.cc
index cf7753bf380..05981489bb6 100644
--- a/extra/mariabackup/write_filt.cc
+++ b/extra/mariabackup/write_filt.cc
@@ -1,5 +1,5 @@
/******************************************************
-XtraBackup: hot backup tool for InnoDB
+MariaBackup: hot backup tool for InnoDB
(c) 2009-2013 Percona LLC and/or its affiliates.
Originally Created 3/3/2009 Yasufumi Kinoshita
Written by Alexey Kopytov, Aleksandr Kuzminsky, Stewart Smith, Vadim Tkachenko,
@@ -27,6 +27,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,18 +69,21 @@ wf_incremental_init(xb_write_filt_ctxt_t *ctxt, char *dst_name,
{
char meta_name[FN_REFLEN];
xb_delta_info_t info;
- 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 / 4 + 1) * cursor->page_size;
- cp->delta_buf_base = static_cast<byte *>(ut_malloc(buf_size));
- memset(cp->delta_buf_base, 0, buf_size);
- cp->delta_buf = static_cast<byte *>
- (ut_align(cp->delta_buf_base, UNIV_PAGE_SIZE_MAX));
+ cp->delta_buf_size = (cursor->page_size / 4) * cursor->page_size;
+ 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,
@@ -88,7 +92,7 @@ wf_incremental_init(xb_write_filt_ctxt_t *ctxt, char *dst_name,
info.zip_size = cursor->zip_size;
info.space_id = cursor->space_id;
if (!xb_write_delta_metadata(meta_name, &info)) {
- msg("[%02u] xtrabackup: Error: "
+ msg("[%02u] mariabackup: Error: "
"failed to write meta info for %s\n",
cursor->thread_n, cursor->rel_path);
return(FALSE);
@@ -183,10 +187,7 @@ static void
wf_incremental_deinit(xb_write_filt_ctxt_t *ctxt)
{
xb_wf_incremental_ctxt_t *cp = &(ctxt->u.wf_incremental_ctxt);
-
- if (cp->delta_buf_base != NULL) {
- ut_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 be11e058255..3baa9e660d7 100644
--- a/extra/mariabackup/wsrep.cc
+++ b/extra/mariabackup/wsrep.cc
@@ -46,6 +46,7 @@ permission notice:
#include <trx0sys.h>
#include "common.h"
+#include "backup_wsrep.h"
#ifdef WITH_WSREP
#define WSREP_XID_PREFIX "WSREPXid"
#define WSREP_XID_PREFIX_LEN MYSQL_XID_PREFIX_LEN
@@ -194,7 +195,7 @@ xb_write_galera_info(bool incremental_prepare)
fp = fopen(XB_GALERA_INFO_FILENAME, "w");
if (fp == NULL) {
- msg("xtrabackup: error: "
+ msg("mariabackup: error: "
"could not create " XB_GALERA_INFO_FILENAME
", errno = %d\n",
errno);
@@ -203,12 +204,12 @@ xb_write_galera_info(bool incremental_prepare)
seqno = wsrep_xid_seqno(&xid);
- msg("xtrabackup: Recovered WSREP position: %s:%lld\n",
+ msg("mariabackup: Recovered WSREP position: %s:%lld\n",
uuid_str, (long long) seqno);
if (fprintf(fp, "%s:%lld", uuid_str, (long long) seqno) < 0) {
- msg("xtrabackup: error: "
+ msg("mariabackup: error: "
"could not write to " XB_GALERA_INFO_FILENAME
", errno = %d\n",
errno);
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index c746b469329..2228e542dc7 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -1,5 +1,5 @@
/******************************************************
-XtraBackup: hot backup tool for InnoDB
+MariaBackup: hot backup tool for InnoDB
(c) 2009-2017 Percona LLC and/or its affiliates
Originally Created 3/3/2009 Yasufumi Kinoshita
Written by Alexey Kopytov, Aleksandr Kuzminsky, Stewart Smith, Vadim Tkachenko,
@@ -85,7 +85,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "xbstream.h"
#include "changed_page_bitmap.h"
#include "read_filt.h"
-#include "wsrep.h"
+#include "backup_wsrep.h"
#include "innobackupex.h"
#include "backup_mysql.h"
#include "backup_copy.h"
@@ -95,6 +95,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <sql_plugin.h>
#include <srv0srv.h>
#include <crc_glue.h>
+#include <log.h>
/* TODO: replace with appropriate macros used in InnoDB 5.6 */
#define PAGE_ZIP_MIN_SIZE_SHIFT 10
@@ -836,6 +837,11 @@ struct my_option xb_client_options[] =
(uchar*) &opt_incremental_history_uuid, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"remove-original", OPT_REMOVE_ORIGINAL, "Remove .qp files after decompression.",
+ (uchar *) &opt_remove_original,
+ (uchar *) &opt_remove_original,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+
{"ftwrl-wait-query-type", OPT_LOCK_WAIT_QUERY_TYPE,
"This option specifies which types of queries are allowed to complete "
"before innobackupex will issue the global lock. Default is all.",
@@ -1097,11 +1103,13 @@ Disable with --skip-innodb-doublewrite.", (G_PTR*) &innobase_use_doublewrite,
(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 },
@@ -1153,13 +1161,13 @@ debug_sync_point(const char *name)
xtrabackup_target_dir);
fp = fopen(pid_path, "w");
if (fp == NULL) {
- msg("xtrabackup: Error: cannot open %s\n", pid_path);
+ msg("mariabackup: Error: cannot open %s\n", pid_path);
exit(EXIT_FAILURE);
}
fprintf(fp, "%u\n", (uint) pid);
fclose(fp);
- msg("xtrabackup: DEBUG: Suspending at debug sync point '%s'. "
+ msg("mariabackup: DEBUG: Suspending at debug sync point '%s'. "
"Resume with 'kill -SIGCONT %u'.\n", name, (uint) pid);
debug_sync_resumed= 0;
@@ -1169,16 +1177,16 @@ debug_sync_point(const char *name)
}
/* On resume */
- msg("xtrabackup: DEBUG: removing the pid file.\n");
+ msg("mariabackup: DEBUG: removing the pid file.\n");
my_delete(pid_path, MYF(MY_WME));
#endif
}
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)
{
@@ -1205,7 +1213,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);
@@ -1372,8 +1380,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"
@@ -1464,19 +1476,19 @@ innodb_init_param(void)
/* Check that values don't overflow on 32-bit systems. */
if (sizeof(ulint) == 4) {
if (xtrabackup_use_memory > UINT_MAX32) {
- msg("xtrabackup: use-memory can't be over 4GB"
+ msg("mariabackup: use-memory can't be over 4GB"
" on 32-bit systems\n");
}
if (innobase_buffer_pool_size > UINT_MAX32) {
- msg("xtrabackup: innobase_buffer_pool_size can't be "
+ msg("mariabackup: innobase_buffer_pool_size can't be "
"over 4GB on 32-bit systems\n");
goto error;
}
if (innobase_log_file_size > UINT_MAX32) {
- msg("xtrabackup: innobase_log_file_size can't be "
+ msg("mariabackup: innobase_log_file_size can't be "
"over 4GB on 32-bit systemsi\n");
goto error;
@@ -1503,9 +1515,9 @@ innodb_init_param(void)
read from MySQL .cnf file */
if (xtrabackup_backup) {
- msg("xtrabackup: using the following InnoDB configuration:\n");
+ msg("mariabackup: using the following InnoDB configuration:\n");
} else {
- msg("xtrabackup: using the following InnoDB configuration "
+ msg("mariabackup: using the following InnoDB configuration "
"for recovery:\n");
}
@@ -1515,7 +1527,7 @@ innodb_init_param(void)
srv_data_home = (xtrabackup_backup && innobase_data_home_dir
? innobase_data_home_dir : default_path);
- msg("xtrabackup: innodb_data_home_dir = %s\n", srv_data_home);
+ msg("mariabackup: innodb_data_home_dir = %s\n", srv_data_home);
/* Set default InnoDB data file size to 10 MB and let it be
auto-extending. Thus users can use InnoDB in >= 4.0 without having
@@ -1524,7 +1536,7 @@ innodb_init_param(void)
if (!innobase_data_file_path) {
innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
}
- msg("xtrabackup: innodb_data_file_path = %s\n",
+ msg("mariabackup: innodb_data_file_path = %s\n",
innobase_data_file_path);
/* Since InnoDB edits the argument in the next call, we make another
@@ -1535,7 +1547,7 @@ innodb_init_param(void)
ret = (my_bool) srv_parse_data_file_paths_and_sizes(
internal_innobase_data_file_path);
if (ret == FALSE) {
- msg("xtrabackup: syntax error in innodb_data_file_path\n");
+ msg("mariabackup: syntax error in innodb_data_file_path\n");
mem_free_and_error:
free(internal_innobase_data_file_path);
internal_innobase_data_file_path = NULL;
@@ -1568,7 +1580,7 @@ mem_free_and_error:
if (xtrabackup_prepare && xtrabackup_incremental_dir) {
srv_log_group_home_dir = xtrabackup_incremental_dir;
}
- msg("xtrabackup: innodb_log_group_home_dir = %s\n",
+ msg("mariabackup: innodb_log_group_home_dir = %s\n",
srv_log_group_home_dir);
srv_normalize_path_for_win(srv_log_group_home_dir);
@@ -1590,9 +1602,9 @@ mem_free_and_error:
srv_n_log_files = (ulint) innobase_log_files_in_group;
srv_log_file_size = (ulint) innobase_log_file_size;
- msg("xtrabackup: innodb_log_files_in_group = %ld\n",
+ msg("mariabackup: innodb_log_files_in_group = %ld\n",
srv_n_log_files);
- msg("xtrabackup: innodb_log_file_size = %lld\n",
+ msg("mariabackup: innodb_log_file_size = %lld\n",
(long long int) srv_log_file_size);
srv_log_buffer_size = (ulint) innobase_log_buffer_size;
@@ -1723,7 +1735,7 @@ mem_free_and_error:
return(FALSE);
error:
- msg("xtrabackup: innodb_init_param(): Error occured.\n");
+ msg("mariabackup: innodb_init_param(): Error occured.\n");
return(TRUE);
}
@@ -1754,7 +1766,7 @@ innodb_init(void)
return(FALSE);
error:
- msg("xtrabackup: innodb_init(): Error occured.\n");
+ msg("mariabackup: innodb_init(): Error occured.\n");
return(TRUE);
}
@@ -1764,7 +1776,7 @@ innodb_end()
srv_fast_shutdown = (ulint) innobase_fast_shutdown;
innodb_inited = 0;
- msg("xtrabackup: starting shutdown with innodb_fast_shutdown = %lu\n",
+ msg("mariabackup: starting shutdown with innodb_fast_shutdown = %lu\n",
srv_fast_shutdown);
innodb_shutdown();
@@ -1795,7 +1807,7 @@ xtrabackup_read_metadata(char *filename)
fp = fopen(filename,"r");
if(!fp) {
- msg("xtrabackup: Error: cannot open %s\n", filename);
+ msg("mariabackup: Error: cannot open %s\n", filename);
return(FALSE);
}
@@ -1874,7 +1886,7 @@ xtrabackup_stream_metadata(ds_ctxt_t *ds_ctxt)
stream = ds_open(ds_ctxt, XTRABACKUP_METADATA_FILENAME, &mystat);
if (stream == NULL) {
- msg("xtrabackup: Error: cannot open output stream "
+ msg("mariabackup: Error: cannot open output stream "
"for %s\n", XTRABACKUP_METADATA_FILENAME);
return(FALSE);
}
@@ -1907,7 +1919,7 @@ xtrabackup_write_metadata(const char *filepath)
fp = fopen(filepath, "w");
if(!fp) {
- msg("xtrabackup: Error: cannot open %s\n", filepath);
+ msg("mariabackup: Error: cannot open %s\n", filepath);
return(FALSE);
}
if (fwrite(buf, len, 1, fp) < 1) {
@@ -1957,11 +1969,11 @@ xb_read_delta_metadata(const char *filepath, xb_delta_info_t *info)
fclose(fp);
if (info->page_size == ULINT_UNDEFINED) {
- msg("xtrabackup: page_size is required in %s\n", filepath);
+ msg("mariabackup: page_size is required in %s\n", filepath);
r = FALSE;
}
if (info->space_id == ULINT_UNDEFINED) {
- msg("xtrabackup: Warning: This backup was taken with XtraBackup 2.0.1 "
+ msg("mariabackup: Warning: This backup was taken with XtraBackup 2.0.1 "
"or earlier, some DDL operations between full and incremental "
"backups may be handled incorrectly\n");
}
@@ -1993,7 +2005,7 @@ xb_write_delta_metadata(const char *filename, const xb_delta_info_t *info)
f = ds_open(ds_meta, filename, &mystat);
if (f == NULL) {
- msg("xtrabackup: Error: cannot open output stream for %s\n",
+ msg("mariabackup: Error: cannot open output stream for %s\n",
filename);
return(FALSE);
}
@@ -2364,14 +2376,14 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n)
if (write_filter->init != NULL &&
!write_filter->init(&write_filt_ctxt, dst_name, &cursor)) {
- msg("[%02u] xtrabackup: error: "
+ msg("[%02u] mariabackup: error: "
"failed to initialize page write filter.\n", thread_n);
goto error;
}
dstfile = ds_open(ds_data, dst_name, &cursor.statinfo);
if (dstfile == NULL) {
- msg("[%02u] xtrabackup: error: "
+ msg("[%02u] mariabackup: error: "
"cannot open the destination stream for %s\n",
thread_n, dst_name);
goto error;
@@ -2421,7 +2433,7 @@ error:
if (write_filter && write_filter->deinit) {
write_filter->deinit(&write_filt_ctxt);;
}
- msg("[%02u] xtrabackup: Error: "
+ msg("[%02u] mariabackup: Error: "
"xtrabackup_copy_datafile() failed.\n", thread_n);
return(TRUE); /*ERROR*/
@@ -2433,10 +2445,10 @@ skip:
if (write_filter && write_filter->deinit) {
write_filter->deinit(&write_filt_ctxt);
}
- msg("[%02u] xtrabackup: Warning: We assume the "
+ msg("[%02u] mariabackup: Warning: We assume the "
"table was dropped during xtrabackup execution "
"and ignore the file.\n", thread_n);
- msg("[%02u] xtrabackup: Warning: skipping tablespace %s.\n",
+ msg("[%02u] mariabackup: Warning: skipping tablespace %s.\n",
thread_n, node_name);
return(FALSE);
}
@@ -2549,8 +2561,9 @@ xtrabackup_scan_log_recs(
to this lsn */
lsn_t* group_scanned_lsn,/*!< out: scanning succeeded up to
this lsn */
- bool* finished) /*!< out: false if is not able to scan
+ bool* finished, /*!< out: false if is not able to scan
any more in this log group */
+ bool* must_reread_log) /*!< out: should re-read buffer from disk, incomplete read*/
{
lsn_t scanned_lsn;
ulint data_len;
@@ -2560,6 +2573,7 @@ xtrabackup_scan_log_recs(
ulint scanned_checkpoint_no = 0;
*finished = false;
+ *must_reread_log = false;
scanned_lsn = start_lsn;
log_block = log_sys->buf;
@@ -2587,14 +2601,14 @@ xtrabackup_scan_log_recs(
break;
}
- msg("xtrabackup: error:"
+ msg("mariabackup: error:"
" log block numbers mismatch:\n"
- "xtrabackup: error: expected log block no. %lu,"
+ "mariabackup: error: expected log block no. %lu,"
" but got no. %lu from the log file.\n",
(ulong) scanned_no, (ulong) no);
if ((no - scanned_no) % blocks_in_group == 0) {
- msg("xtrabackup: error:"
+ msg("mariabackup: error:"
" it looks like InnoDB log has wrapped"
" around before xtrabackup could"
" process all records due to either"
@@ -2606,18 +2620,20 @@ xtrabackup_scan_log_recs(
} else if (!checksum_is_ok) {
/* Garbage or an incompletely written log block */
- msg("xtrabackup: warning: Log block checksum mismatch"
+ msg("mariabackup: warning: Log block checksum mismatch"
" (block no %lu at lsn " LSN_PF "): \n"
"expected %lu, calculated checksum %lu\n",
(ulong) no,
scanned_lsn,
(ulong) log_block_get_checksum(log_block),
(ulong) log_block_calc_checksum(log_block));
- msg("xtrabackup: warning: this is possible when the "
+ msg("mariabackup: warning: this is possible when the "
"log block has not been fully written by the "
"server, will retry later.\n");
- *finished = true;
- break;
+ *finished = false;
+ *must_reread_log = true;
+ my_sleep(1000);
+ return false;
}
if (log_block_get_flush_bit(log_block)) {
@@ -2682,11 +2698,11 @@ xtrabackup_scan_log_recs(
if (srv_encrypt_log) {
log_encrypt_before_write(scanned_checkpoint_no,
- log_sys->buf, write_size);
+ log_sys->buf, start_lsn, write_size);
}
if (ds_write(dst_log_file, log_sys->buf, write_size)) {
- msg("xtrabackup: Error: "
+ msg("mariabackup: Error: "
"write to logfile failed\n");
return(false);
}
@@ -2729,14 +2745,23 @@ xtrabackup_copy_logfile(lsn_t from_lsn, my_bool is_last)
mutex_enter(&log_sys->mutex);
- log_group_read_log_seg(LOG_RECOVER, log_sys->buf,
- group, start_lsn, end_lsn, false);
+ bool scan_ok = false;
+ bool must_reread_log;
+ int retries = 0;
+ do {
+
+ log_group_read_log_seg(LOG_RECOVER, log_sys->buf,
+ group, start_lsn, end_lsn, false);
+
+ scan_ok = xtrabackup_scan_log_recs(group, is_last,
+ start_lsn, &contiguous_lsn, &group_scanned_lsn,
+ &finished, &must_reread_log);
+
+ } while (!scan_ok && must_reread_log && retries++ < 100);
- if (!xtrabackup_scan_log_recs(group, is_last,
- start_lsn, &contiguous_lsn, &group_scanned_lsn,
- &finished)) {
+ if (!scan_ok) {
goto error;
- }
+ }
mutex_exit(&log_sys->mutex);
@@ -2767,7 +2792,7 @@ xtrabackup_copy_logfile(lsn_t from_lsn, my_bool is_last)
error:
mutex_exit(&log_sys->mutex);
ds_close(dst_log_file);
- msg("xtrabackup: Error: xtrabackup_copy_logfile() failed.\n");
+ msg("mariabackup: Error: xtrabackup_copy_logfile() failed.\n");
return(TRUE);
}
@@ -2910,7 +2935,7 @@ data_copy_thread_func(
/* copy the datafile */
if(xtrabackup_copy_datafile(node, num)) {
- msg("[%02u] xtrabackup: Error: "
+ msg("[%02u] mariabackup: Error: "
"failed to copy datafile.\n", num);
exit(EXIT_FAILURE);
}
@@ -3082,25 +3107,25 @@ xb_load_tablespaces(void)
&flushed_lsn,
&sum_of_new_sizes);
if (err != DB_SUCCESS) {
- msg("xtrabackup: Could not open or create data files.\n"
- "xtrabackup: If you tried to add new data files, and it "
+ msg("mariabackup: Could not open or create data files.\n"
+ "mariabackup: If you tried to add new data files, and it "
"failed here,\n"
- "xtrabackup: you should now edit innodb_data_file_path in "
+ "mariabackup: you should now edit innodb_data_file_path in "
"my.cnf back\n"
- "xtrabackup: to what it was, and remove the new ibdata "
+ "mariabackup: to what it was, and remove the new ibdata "
"files InnoDB created\n"
- "xtrabackup: in this failed attempt. InnoDB only wrote "
+ "mariabackup: in this failed attempt. InnoDB only wrote "
"those files full of\n"
- "xtrabackup: zeros, but did not yet use them in any way. "
+ "mariabackup: zeros, but did not yet use them in any way. "
"But be careful: do not\n"
- "xtrabackup: remove old data files which contain your "
+ "mariabackup: remove old data files which contain your "
"precious data!\n");
return(err);
}
/* create_new_db must not be TRUE.. */
if (create_new_db) {
- msg("xtrabackup: could not find data files at the "
+ msg("mariabackup: could not find data files at the "
"specified datadir\n");
return(DB_ERROR);
}
@@ -3119,7 +3144,7 @@ xb_load_tablespaces(void)
srv_undo_tablespaces_init(), because fil_is_user_tablespace_id() *
relies on srv_undo_tablespaces_open to be properly initialized */
- msg("xtrabackup: Generating a list of tablespaces\n");
+ msg("mariabackup: Generating a list of tablespaces\n");
err = fil_load_single_table_tablespaces(xb_check_if_open_tablespace);
if (err != DB_SUCCESS) {
@@ -3167,7 +3192,7 @@ xb_data_files_close(void)
}
if (i == 1000) {
- msg("xtrabackup: Warning: %lu threads created by InnoDB"
+ msg("mariabackup: Warning: %lu threads created by InnoDB"
" had not exited at shutdown!\n",
(ulong) os_thread_count);
}
@@ -3253,12 +3278,12 @@ xb_validate_name(
/* perform only basic validation. validate length and
path symbols */
if (len > NAME_LEN) {
- msg("xtrabackup: name `%s` is too long.\n", name);
+ msg("mariabackup: name `%s` is too long.\n", name);
exit(EXIT_FAILURE);
}
p = strpbrk(name, "/\\~");
if (p && p - name < NAME_LEN) {
- msg("xtrabackup: name `%s` is not valid.\n", name);
+ msg("mariabackup: name `%s` is not valid.\n", name);
exit(EXIT_FAILURE);
}
}
@@ -3337,7 +3362,7 @@ xb_register_table(
const char* name) /*!< in: name of table */
{
if (strchr(name, '.') == NULL) {
- msg("xtrabackup: `%s` is not fully qualified name.\n", name);
+ msg("mariabackup: `%s` is not fully qualified name.\n", name);
exit(EXIT_FAILURE);
}
@@ -3359,7 +3384,7 @@ xb_add_regex_to_list(
if (ret != 0) {
regerror(ret, &compiled_regex, errbuf, sizeof(errbuf));
- msg("xtrabackup: error: %s regcomp(%s): %s\n",
+ msg("mariabackup: error: %s regcomp(%s): %s\n",
error_context, regex, errbuf);
exit(EXIT_FAILURE);
}
@@ -3428,7 +3453,7 @@ xb_load_list_file(
/* read and store the filenames */
fp = fopen(filename, "r");
if (!fp) {
- msg("xtrabackup: cannot open %s\n",
+ msg("mariabackup: cannot open %s\n",
filename);
exit(EXIT_FAILURE);
}
@@ -3437,7 +3462,7 @@ xb_load_list_file(
if (p) {
*p = '\0';
} else {
- msg("xtrabackup: `%s...` name is too long", name_buf);
+ msg("mariabackup: `%s...` name is too long", name_buf);
exit(EXIT_FAILURE);
}
@@ -3729,19 +3754,19 @@ xtrabackup_backup_func(void)
data_thread_ctxt_t *data_threads;
#ifdef USE_POSIX_FADVISE
- msg("xtrabackup: uses posix_fadvise().\n");
+ msg("mariabackup: uses posix_fadvise().\n");
#endif
/* cd to datadir */
if (my_setwd(mysql_real_data_home,MYF(MY_WME)))
{
- msg("xtrabackup: cannot my_setwd %s\n", mysql_real_data_home);
+ msg("mariabackup: cannot my_setwd %s\n", mysql_real_data_home);
exit(EXIT_FAILURE);
}
- msg("xtrabackup: cd to %s\n", mysql_real_data_home);
+ msg("mariabackup: cd to %s\n", mysql_real_data_home);
- msg("xtrabackup: open files limit requested %u, set to %u\n",
+ msg("mariabackup: open files limit requested %u, set to %u\n",
(uint) xb_open_files_limit,
xb_set_max_open_files(xb_open_files_limit));
@@ -3756,7 +3781,7 @@ xtrabackup_backup_func(void)
srv_close_files = (bool)xb_close_files;
if (srv_close_files)
- msg("xtrabackup: warning: close-files specified. Use it "
+ msg("mariabackup: warning: close-files specified. Use it "
"at your own risk. If there are DDL operations like table DROP TABLE "
"or RENAME TABLE during the backup, inconsistent backup will be "
"produced.\n");
@@ -3778,7 +3803,7 @@ xtrabackup_backup_func(void)
} else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DIRECT")) {
srv_unix_file_flush_method = SRV_UNIX_O_DIRECT;
- msg("xtrabackup: using O_DIRECT\n");
+ msg("mariabackup: using O_DIRECT\n");
} else if (0 == ut_strcmp(srv_file_flush_method_str, "littlesync")) {
srv_unix_file_flush_method = SRV_UNIX_LITTLESYNC;
@@ -3786,23 +3811,17 @@ xtrabackup_backup_func(void)
srv_unix_file_flush_method = SRV_UNIX_NOSYNC;
} else if (0 == ut_strcmp(srv_file_flush_method_str, "ALL_O_DIRECT")) {
srv_unix_file_flush_method = SRV_UNIX_ALL_O_DIRECT;
- msg("xtrabackup: using ALL_O_DIRECT\n");
+ msg("mariabackup: using ALL_O_DIRECT\n");
} else if (0 == ut_strcmp(srv_file_flush_method_str,
"O_DIRECT_NO_FSYNC")) {
srv_unix_file_flush_method = SRV_UNIX_O_DIRECT_NO_FSYNC;
- msg("xtrabackup: using O_DIRECT_NO_FSYNC\n");
+ msg("mariabackup: using O_DIRECT_NO_FSYNC\n");
} else {
- msg("xtrabackup: Unrecognized value %s for "
+ msg("mariabackup: Unrecognized value %s for "
"innodb_flush_method\n", srv_file_flush_method_str);
exit(EXIT_FAILURE);
}
- /* We can only use synchronous unbuffered IO on Windows for now */
- if (srv_file_flush_method_str != NULL) {
- msg("xtrabackupp: Warning: "
- "ignoring innodb_flush_method = %s on Windows.\n", srv_file_flush_method_str);
- }
-
#ifdef _WIN32
srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
srv_use_native_aio = FALSE;
@@ -3865,12 +3884,12 @@ xtrabackup_backup_func(void)
}
if ((log_opened && log_created)) {
msg(
- "xtrabackup: Error: all log files must be created at the same time.\n"
- "xtrabackup: All log files must be created also in database creation.\n"
- "xtrabackup: If you want bigger or smaller log files, shut down the\n"
- "xtrabackup: database and make sure there were no errors in shutdown.\n"
- "xtrabackup: Then delete the existing log files. Edit the .cnf file\n"
- "xtrabackup: and start the database again.\n");
+ "mariabackup: Error: all log files must be created at the same time.\n"
+ "mariabackup: All log files must be created also in database creation.\n"
+ "mariabackup: If you want bigger or smaller log files, shut down the\n"
+ "mariabackup: database and make sure there were no errors in shutdown.\n"
+ "mariabackup: Then delete the existing log files. Edit the .cnf file\n"
+ "mariabackup: and start the database again.\n");
//return(DB_ERROR);
exit(EXIT_FAILURE);
@@ -3879,7 +3898,7 @@ xtrabackup_backup_func(void)
/* log_file_created must not be TRUE, if online */
if (log_file_created) {
- msg("xtrabackup: Something wrong with source files...\n");
+ msg("mariabackup: Something wrong with source files...\n");
exit(EXIT_FAILURE);
}
@@ -3889,7 +3908,7 @@ xtrabackup_backup_func(void)
if (xtrabackup_extra_lsndir
&&!my_stat(xtrabackup_extra_lsndir,&stat_info,MYF(0))
&& (my_mkdir(xtrabackup_extra_lsndir,0777,MYF(0)) < 0)) {
- msg("xtrabackup: Error: cannot mkdir %d: %s\n",
+ msg("mariabackup: Error: cannot mkdir %d: %s\n",
my_errno, xtrabackup_extra_lsndir);
exit(EXIT_FAILURE);
}
@@ -3897,7 +3916,7 @@ xtrabackup_backup_func(void)
/* create target dir if not exist */
if (!xtrabackup_stream_str && !my_stat(xtrabackup_target_dir,&stat_info,MYF(0))
&& (my_mkdir(xtrabackup_target_dir,0777,MYF(0)) < 0)){
- msg("xtrabackup: Error: cannot mkdir %d: %s\n",
+ msg("mariabackup: Error: cannot mkdir %d: %s\n",
my_errno, xtrabackup_target_dir);
exit(EXIT_FAILURE);
}
@@ -3983,7 +4002,7 @@ reread_log_header:
memset(&stat_info, 0, sizeof(MY_STAT));
dst_log_file = ds_open(ds_redo, XB_LOG_FILENAME, &stat_info);
if (dst_log_file == NULL) {
- msg("xtrabackup: error: failed to open the target stream for "
+ msg("mariabackup: error: failed to open the target stream for "
"'%s'.\n", XB_LOG_FILENAME);
ut_free(log_hdr_buf_);
exit(EXIT_FAILURE);
@@ -3997,7 +4016,7 @@ reread_log_header:
+ (sizeof "xtrabkup ") - 1));
if (ds_write(dst_log_file, log_hdr_buf, LOG_FILE_HDR_SIZE)) {
- msg("xtrabackup: error: write to logfile failed\n");
+ msg("mariabackup: error: write to logfile failed\n");
ut_free(log_hdr_buf_);
exit(EXIT_FAILURE);
}
@@ -4033,7 +4052,7 @@ reread_log_header:
/* Populate fil_system with tablespaces to copy */
err = xb_load_tablespaces();
if (err != DB_SUCCESS) {
- msg("xtrabackup: error: xb_load_tablespaces() failed with"
+ msg("mariabackup: error: xb_load_tablespaces() failed with"
"error code %lu\n", err);
exit(EXIT_FAILURE);
}
@@ -4049,25 +4068,25 @@ reread_log_header:
changed_page_bitmap = xb_page_bitmap_init();
}
if (!changed_page_bitmap) {
- msg("xtrabackup: using the full scan for incremental "
+ msg("mariabackup: using the full scan for incremental "
"backup\n");
} else if (incremental_lsn != checkpoint_lsn_start) {
/* Do not print that bitmaps are used when dummy bitmap
is build for an empty LSN range. */
- msg("xtrabackup: using the changed page bitmap\n");
+ msg("mariabackup: using the changed page bitmap\n");
}
}
ut_a(xtrabackup_parallel > 0);
if (xtrabackup_parallel > 1) {
- msg("xtrabackup: Starting %u threads for parallel data "
+ msg("mariabackup: Starting %u threads for parallel data "
"files transfer\n", xtrabackup_parallel);
}
it = datafiles_iter_new(f_system);
if (it == NULL) {
- msg("xtrabackup: Error: datafiles_iter_new() failed.\n");
+ msg("mariabackup: Error: datafiles_iter_new() failed.\n");
exit(EXIT_FAILURE);
}
@@ -4122,7 +4141,7 @@ reread_log_header:
err = recv_find_max_checkpoint(&max_cp_group, &max_cp_field);
if (err != DB_SUCCESS) {
- msg("xtrabackup: Error: recv_find_max_checkpoint() failed.\n");
+ msg("mariabackup: Error: recv_find_max_checkpoint() failed.\n");
mutex_exit(&log_sys->mutex);
goto skip_last_cp;
}
@@ -4136,14 +4155,14 @@ reread_log_header:
mutex_exit(&log_sys->mutex);
- msg("xtrabackup: The latest check point (for incremental): "
+ msg("mariabackup: The latest check point (for incremental): "
"'" LSN_PF "'\n", latest_cp);
}
skip_last_cp:
/* stop log_copying_thread */
log_copying = FALSE;
os_event_set(log_copying_stop);
- msg("xtrabackup: Stopping log copying thread.\n");
+ msg("mariabackup: Stopping log copying thread.\n");
while (log_copying_running) {
msg(".");
os_thread_sleep(200000); /*0.2 sec*/
@@ -4166,7 +4185,7 @@ skip_last_cp:
metadata_last_lsn = log_copy_scanned_lsn;
if (!xtrabackup_stream_metadata(ds_meta)) {
- msg("xtrabackup: Error: failed to stream metadata.\n");
+ msg("mariabackup: Error: failed to stream metadata.\n");
exit(EXIT_FAILURE);
}
if (xtrabackup_extra_lsndir) {
@@ -4175,7 +4194,7 @@ skip_last_cp:
sprintf(filename, "%s/%s", xtrabackup_extra_lsndir,
XTRABACKUP_METADATA_FILENAME);
if (!xtrabackup_write_metadata(filename)) {
- msg("xtrabackup: Error: failed to write metadata "
+ msg("mariabackup: Error: failed to write metadata "
"to '%s'.\n", filename);
exit(EXIT_FAILURE);
}
@@ -4197,7 +4216,7 @@ skip_last_cp:
wait_throttle = NULL;
}
- msg("xtrabackup: Transaction log of lsn (" LSN_PF ") to (" LSN_PF
+ msg("mariabackup: Transaction log of lsn (" LSN_PF ") to (" LSN_PF
") was copied.\n", checkpoint_lsn_start, log_copy_scanned_lsn);
xb_filters_free();
@@ -4205,7 +4224,7 @@ skip_last_cp:
/* Make sure that the latest checkpoint made it to xtrabackup_logfile */
if (latest_cp > log_copy_scanned_lsn) {
- msg("xtrabackup: error: last checkpoint LSN (" LSN_PF
+ msg("mariabackup: error: last checkpoint LSN (" LSN_PF
") is larger than last copied LSN (" LSN_PF ").\n",
latest_cp, log_copy_scanned_lsn);
exit(EXIT_FAILURE);
@@ -4227,16 +4246,11 @@ xtrabackup_init_temp_log(void)
ib_int64_t file_size;
- lsn_t max_no;
- lsn_t max_lsn;
- lsn_t checkpoint_no;
+ lsn_t max_no = 0;
+ lsn_t max_lsn = 0;
ulint fold;
- bool checkpoint_found;
-
- max_no = 0;
-
if (!log_buf) {
goto error;
}
@@ -4266,7 +4280,7 @@ retry:
/* The following call prints an error message */
os_file_get_last_error(TRUE);
- msg("xtrabackup: Warning: cannot open %s. will try to find.\n",
+ msg("mariabackup: Warning: cannot open %s. will try to find.\n",
src_path);
/* check if ib_logfile0 may be xtrabackup_logfile */
@@ -4276,7 +4290,7 @@ retry:
&success,0);
if (!success) {
os_file_get_last_error(TRUE);
- msg(" xtrabackup: Fatal error: cannot find %s.\n",
+ msg("mariabackup: Fatal error: cannot find %s.\n",
src_path);
goto error;
@@ -4290,7 +4304,7 @@ retry:
if ( ut_memcmp(log_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
(byte*)"xtrabkup", (sizeof "xtrabkup") - 1) == 0) {
- msg(" xtrabackup: 'ib_logfile0' seems to be "
+ msg("mariabackup: 'ib_logfile0' seems to be "
"'xtrabackup_logfile'. will retry.\n");
os_file_close(src_file);
@@ -4305,8 +4319,7 @@ retry:
goto retry;
}
- msg(" xtrabackup: Fatal error: cannot find %s.\n",
- src_path);
+ msg("mariabackup: Fatal error: cannot find %s.\n", src_path);
os_file_close(src_file);
src_file = XB_FILE_UNDEFINED;
@@ -4327,7 +4340,7 @@ retry:
if ( ut_memcmp(log_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
(byte*)"xtrabkup", (sizeof "xtrabkup") - 1) != 0 ) {
- msg("xtrabackup: notice: xtrabackup_logfile was already used "
+ msg("mariabackup: notice: xtrabackup_logfile was already used "
"to '--prepare'.\n");
goto skip_modify;
} else {
@@ -4336,35 +4349,29 @@ retry:
// ' ', 4);
}
- checkpoint_found = false;
-
/* read last checkpoint lsn */
for (field = LOG_CHECKPOINT_1; field <= LOG_CHECKPOINT_2;
field += LOG_CHECKPOINT_2 - LOG_CHECKPOINT_1) {
if (!recv_check_cp_is_consistent(const_cast<const byte *>
(log_buf + field)))
- goto not_consistent;
+ continue;
- checkpoint_no = mach_read_from_8(log_buf + field +
- LOG_CHECKPOINT_NO);
+ lsn_t checkpoint_no = mach_read_from_8(log_buf + field +
+ LOG_CHECKPOINT_NO);
if (checkpoint_no >= max_no) {
max_no = checkpoint_no;
max_lsn = mach_read_from_8(log_buf + field +
LOG_CHECKPOINT_LSN);
- checkpoint_found = true;
}
-not_consistent:
- ;
}
- if (!checkpoint_found) {
- msg("xtrabackup: No valid checkpoint found.\n");
+ if (!max_lsn) {
+ msg("mariabackup: No valid checkpoint found.\n");
goto error;
}
-
/* It seems to be needed to overwrite the both checkpoint area. */
mach_write_to_8(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_LSN,
max_lsn);
@@ -4466,7 +4473,7 @@ not_consistent:
file_size = os_file_get_size(src_file);
}
- msg("xtrabackup: xtrabackup_logfile detected: size=" INT64PF ", "
+ msg("mariabackup: xtrabackup_logfile detected: size=" INT64PF ", "
"start_lsn=(" LSN_PF ")\n", file_size, max_lsn);
os_file_close(src_file);
@@ -4502,7 +4509,7 @@ error:
free(log_buf);
if (src_file != XB_FILE_UNDEFINED)
os_file_close(src_file);
- msg("xtrabackup: Error: xtrabackup_init_temp_log() failed.\n");
+ msg("mariabackup: Error: xtrabackup_init_temp_log() failed.\n");
return(TRUE); /*ERROR*/
}
@@ -4554,14 +4561,14 @@ xb_space_create_file(
OS_FILE_READ_WRITE,
&ret,0);
if (!ret) {
- msg("xtrabackup: cannot create file %s\n", path);
+ msg("mariabackup: cannot create file %s\n", path);
return ret;
}
ret = os_file_set_size(path, *file,
FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE);
if (!ret) {
- msg("xtrabackup: cannot set size for file %s\n", path);
+ msg("mariabackup: cannot set size for file %s\n", path);
os_file_close(*file);
os_file_delete(0, path);
return ret;
@@ -4605,7 +4612,7 @@ xb_space_create_file(
ut_free(buf);
if (!ret) {
- msg("xtrabackup: could not write the first page to %s\n",
+ msg("mariabackup: could not write the first page to %s\n",
path);
os_file_close(*file);
os_file_delete(0, path);
@@ -4669,7 +4676,7 @@ xb_delta_open_matching_space(
/* Create the database directory if it doesn't exist yet */
if (!os_file_create_directory(dest_dir, FALSE)) {
- msg("xtrabackup: error: cannot create dir %s\n", dest_dir);
+ msg("mariabackup: error: cannot create dir %s\n", dest_dir);
return file;
}
@@ -4702,13 +4709,13 @@ xb_delta_open_matching_space(
snprintf(tmpname, FN_REFLEN, "%s/xtrabackup_tmp_#%lu",
dbname, fil_space->id);
- msg("xtrabackup: Renaming %s to %s.ibd\n",
+ msg("mariabackup: Renaming %s to %s.ibd\n",
fil_space->name, tmpname);
if (!fil_rename_tablespace(NULL, fil_space->id,
tmpname, NULL))
{
- msg("xtrabackup: Cannot rename %s to %s\n",
+ msg("mariabackup: Cannot rename %s to %s\n",
fil_space->name, tmpname);
goto exit;
}
@@ -4717,7 +4724,7 @@ xb_delta_open_matching_space(
if (space_id == ULINT_UNDEFINED)
{
- msg("xtrabackup: Error: Cannot handle DDL operation on tablespace "
+ msg("mariabackup: Error: Cannot handle DDL operation on tablespace "
"%s\n", dest_space_name);
exit(EXIT_FAILURE);
}
@@ -4729,13 +4736,13 @@ xb_delta_open_matching_space(
strncpy(tmpname, dest_space_name, FN_REFLEN);
- msg("xtrabackup: Renaming %s to %s\n",
+ msg("mariabackup: Renaming %s to %s\n",
fil_space->name, dest_space_name);
if (!fil_rename_tablespace(NULL, fil_space->id, tmpname,
NULL))
{
- msg("xtrabackup: Cannot rename %s to %s\n",
+ msg("mariabackup: Cannot rename %s to %s\n",
fil_space->name, dest_space_name);
goto exit;
}
@@ -4747,7 +4754,7 @@ xb_delta_open_matching_space(
if (!fil_space_create(dest_space_name, space_id, 0,
FIL_TABLESPACE, 0, false)) {
- msg("xtrabackup: Cannot create tablespace %s\n",
+ msg("mariabackup: Cannot create tablespace %s\n",
dest_space_name);
goto exit;
}
@@ -4781,7 +4788,7 @@ found:
if (ok) {
*success = TRUE;
} else {
- msg("xtrabackup: Cannot open file %s\n", real_name);
+ msg("mariabackup: Cannot open file %s\n", real_name);
}
exit:
@@ -4853,11 +4860,11 @@ xtrabackup_apply_delta(
page_size = info.page_size;
page_size_shift = get_bit_shift(page_size);
- msg("xtrabackup: page size for %s is %lu bytes\n",
+ msg("mariabackup: page size for %s is %lu bytes\n",
src_path, page_size);
if (page_size_shift < 10 ||
page_size_shift > UNIV_PAGE_SIZE_SHIFT_MAX) {
- msg("xtrabackup: error: invalid value of page_size "
+ msg("mariabackup: error: invalid value of page_size "
"(%lu bytes) read from %s\n", page_size, meta_path);
goto error;
}
@@ -4868,7 +4875,7 @@ xtrabackup_apply_delta(
&success,0);
if (!success) {
os_file_get_last_error(TRUE);
- msg("xtrabackup: error: cannot open %s\n", src_path);
+ msg("mariabackup: error: cannot open %s\n", src_path);
goto error;
}
@@ -4880,7 +4887,7 @@ xtrabackup_apply_delta(
dbname, space_name, info.space_id, info.zip_size,
dst_path, sizeof(dst_path), &success);
if (!success) {
- msg("xtrabackup: error: cannot open %s\n", dst_path);
+ msg("mariabackup: error: cannot open %s\n", dst_path);
goto error;
}
@@ -4919,7 +4926,7 @@ xtrabackup_apply_delta(
last_buffer = TRUE;
break;
default:
- msg("xtrabackup: error: %s seems not "
+ msg("mariabackup: error: %s seems not "
".delta file.\n", src_path);
goto error;
}
@@ -4952,12 +4959,36 @@ xtrabackup_apply_delta(
if (offset_on_page == 0xFFFFFFFFUL)
break;
- success = os_file_write(dst_path, dst_file,
- incremental_buffer +
- page_in_buffer * page_size,
- (offset_on_page <<
- page_size_shift),
- page_size);
+ uchar *buf = incremental_buffer + page_in_buffer * page_size;
+ const os_offset_t off = os_offset_t(offset_on_page)*page_size;
+
+ if (off == 0) {
+ /* Read tablespace size from page 0,
+ extend the tablespace to specified size. */
+ os_offset_t n_pages = mach_read_from_4(buf + FSP_HEADER_OFFSET + FSP_SIZE);
+ ulint space_id = mach_read_from_4(buf + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
+ if (space_id != TRX_SYS_SPACE) {
+ if (!os_file_set_size(dst_path, dst_file, n_pages*page_size))
+ goto error;
+ } else {
+ /* System tablespace needs special handling , since
+ it can consist of multiple files. The first one has full
+ tablespace size in page 0, but only last file should be extended. */
+ mutex_enter(&fil_system->mutex);
+ fil_space_t* space = fil_space_get_by_id(space_id);
+ mutex_exit(&fil_system->mutex);
+ DBUG_ASSERT(space);
+ fil_node_t* n = UT_LIST_GET_FIRST(space->chain);
+ if(strcmp(n->name, dst_path) == 0) {
+ /* Got first tablespace file, with correct size */
+ ulint actual_size;
+ if (!fil_extend_space_to_desired_size(&actual_size, 0, (ulint)n_pages))
+ goto error;
+ }
+ }
+ }
+
+ success = os_file_write(dst_path, dst_file, buf, off, page_size);
if (!success) {
goto error;
}
@@ -4968,8 +4999,11 @@ xtrabackup_apply_delta(
if (incremental_buffer_base)
ut_free(incremental_buffer_base);
- if (src_file != XB_FILE_UNDEFINED)
+ if (src_file != XB_FILE_UNDEFINED) {
os_file_close(src_file);
+ /* Remove .delta file after it was successfully applied.*/
+ os_file_delete(0,src_path);
+ }
if (dst_file != XB_FILE_UNDEFINED)
os_file_close(dst_file);
return TRUE;
@@ -4981,7 +5015,7 @@ error:
os_file_close(src_file);
if (dst_file != XB_FILE_UNDEFINED)
os_file_close(dst_file);
- msg("xtrabackup: Error: xtrabackup_apply_delta(): "
+ msg("mariabackup: Error: xtrabackup_apply_delta(): "
"failed to apply %s to %s.\n", src_path, dst_path);
return FALSE;
}
@@ -5045,7 +5079,7 @@ xb_process_datadir(
callback */
{
ulint ret;
- char dbpath[FN_REFLEN];
+ char dbpath[OS_FILE_MAX_PATH];
os_file_dir_t dir;
os_file_dir_t dbdir;
os_file_stat_t dbinfo;
@@ -5090,7 +5124,7 @@ next_file_item_1:
os_file_closedir(dbdir);
} else {
- msg("xtrabackup: Cannot open dir %s\n",
+ msg("mariabackup: Cannot open dir %s\n",
path);
}
@@ -5098,7 +5132,7 @@ next_file_item_1:
dir = os_file_opendir(path, FALSE);
if (dir == NULL) {
- msg("xtrabackup: Cannot open dir %s\n",
+ msg("mariabackup: Cannot open dir %s\n",
path);
}
@@ -5111,8 +5145,7 @@ next_file_item_1:
goto next_datadir_item;
}
- sprintf(dbpath, "%s/%s", path,
- dbinfo.name);
+ snprintf(dbpath, sizeof(dbpath), "%s/%s", path, dbinfo.name);
srv_normalize_path_for_win(dbpath);
dbdir = os_file_opendir(dbpath, FALSE);
@@ -5241,7 +5274,7 @@ xtrabackup_close_temp_log(my_bool clear_flag)
error:
if (src_file != XB_FILE_UNDEFINED)
os_file_close(src_file);
- msg("xtrabackup: Error: xtrabackup_close_temp_log() failed.\n");
+ msg("mariabackup: Error: xtrabackup_close_temp_log() failed.\n");
return(TRUE); /*ERROR*/
}
@@ -5270,7 +5303,7 @@ xb_export_cfg_write_index_fields(
if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) {
- msg("xtrabackup: Error: writing index fields.");
+ msg("mariabackup: Error: writing index fields.");
return(false);
}
@@ -5284,7 +5317,7 @@ xb_export_cfg_write_index_fields(
if (fwrite(row, 1, sizeof(len), file) != sizeof(len)
|| fwrite(field->name, 1, len, file) != len) {
- msg("xtrabackup: Error: writing index column.");
+ msg("mariabackup: Error: writing index column.");
return(false);
}
@@ -5311,7 +5344,7 @@ xb_export_cfg_write_indexes(
mach_write_to_4(row, UT_LIST_GET_LEN(table->indexes));
if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) {
- msg("xtrabackup: Error: writing index count.");
+ msg("mariabackup: Error: writing index count.");
return(false);
}
@@ -5359,7 +5392,7 @@ xb_export_cfg_write_indexes(
if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) {
- msg("xtrabackup: Error: writing index meta-data.");
+ msg("mariabackup: Error: writing index meta-data.");
return(false);
}
@@ -5374,7 +5407,7 @@ xb_export_cfg_write_indexes(
if (fwrite(row, 1, sizeof(len), file) != sizeof(len)
|| fwrite(index->name, 1, len, file) != len) {
- msg("xtrabackup: Error: writing index name.");
+ msg("mariabackup: Error: writing index name.");
return(false);
}
@@ -5415,7 +5448,12 @@ xb_export_cfg_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);
@@ -5427,7 +5465,7 @@ xb_export_cfg_write_table(
mach_write_to_4(ptr, col->max_prefix);
if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) {
- msg("xtrabackup: Error: writing table column data.");
+ msg("mariabackup: Error: writing table column data.");
return(false);
}
@@ -5448,7 +5486,7 @@ xb_export_cfg_write_table(
if (fwrite(row, 1, sizeof(len), file) != sizeof(len)
|| fwrite(col_name, 1, len, file) != len) {
- msg("xtrabackup: Error: writing column name.");
+ msg("mariabackup: Error: writing column name.");
return(false);
}
@@ -5474,7 +5512,7 @@ xb_export_cfg_write_header(
mach_write_to_4(value, IB_EXPORT_CFG_VERSION_V1);
if (fwrite(&value, 1, sizeof(value), file) != sizeof(value)) {
- msg("xtrabackup: Error: writing meta-data version number.");
+ msg("mariabackup: Error: writing meta-data version number.");
return(false);
}
@@ -5490,7 +5528,7 @@ xb_export_cfg_write_header(
if (fwrite(&value, 1, sizeof(value), file) != sizeof(value)
|| fwrite(hostname, 1, len, file) != len) {
- msg("xtrabackup: Error: writing hostname.");
+ msg("mariabackup: Error: writing hostname.");
return(false);
}
@@ -5505,7 +5543,7 @@ xb_export_cfg_write_header(
if (fwrite(&value, 1, sizeof(value), file) != sizeof(value)
|| fwrite(table->name, 1, len, file) != len) {
- msg("xtrabackup: Error: writing table name.");
+ msg("mariabackup: Error: writing table name.");
return(false);
}
@@ -5516,7 +5554,7 @@ xb_export_cfg_write_header(
mach_write_to_8(row, table->autoinc);
if (fwrite(row, 1, sizeof(ib_uint64_t), file) != sizeof(ib_uint64_t)) {
- msg("xtrabackup: Error: writing table autoinc value.");
+ msg("mariabackup: Error: writing table autoinc value.");
return(false);
}
@@ -5535,7 +5573,7 @@ xb_export_cfg_write_header(
mach_write_to_4(ptr, table->n_cols);
if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) {
- msg("xtrabackup: Error: writing table meta-data.");
+ msg("mariabackup: Error: writing table meta-data.");
return(false);
}
@@ -5563,7 +5601,7 @@ xb_export_cfg_write(
file = fopen(file_path, "w+b");
if (file == NULL) {
- msg("xtrabackup: Error: cannot open %s\n", node->name);
+ msg("mariabackup: Error: cannot open %s\n", node->name);
success = false;
} else {
@@ -5579,7 +5617,7 @@ xb_export_cfg_write(
}
if (fclose(file) != 0) {
- msg("xtrabackup: Error: cannot close %s\n", node->name);
+ msg("mariabackup: Error: cannot close %s\n", node->name);
success = false;
}
@@ -5617,7 +5655,7 @@ store_binlog_info(
fp = fopen(filename, "w");
if (!fp) {
- msg("xtrabackup: failed to open '%s'\n", filename);
+ msg("mariabackup: failed to open '%s'\n", filename);
return(false);
}
@@ -5641,11 +5679,11 @@ xtrabackup_prepare_func(int argc, char ** argv)
if (my_setwd(xtrabackup_real_target_dir,MYF(MY_WME)))
{
- msg("xtrabackup: cannot my_setwd %s\n",
+ msg("mariabackup: cannot my_setwd %s\n",
xtrabackup_real_target_dir);
exit(EXIT_FAILURE);
}
- msg("xtrabackup: cd to %s\n", xtrabackup_real_target_dir);
+ msg("mariabackup: cd to %s\n", xtrabackup_real_target_dir);
encryption_plugin_prepare_init(argc, argv);
@@ -5660,36 +5698,36 @@ xtrabackup_prepare_func(int argc, char ** argv)
XTRABACKUP_METADATA_FILENAME);
if (!xtrabackup_read_metadata(metadata_path)) {
- msg("xtrabackup: Error: failed to read metadata from '%s'\n",
+ msg("mariabackup: Error: failed to read metadata from '%s'\n",
metadata_path);
exit(EXIT_FAILURE);
}
if (!strcmp(metadata_type, "full-backuped")) {
- msg("xtrabackup: This target seems to be not prepared yet.\n");
+ msg("mariabackup: This target seems to be not prepared yet.\n");
} else if (!strcmp(metadata_type, "log-applied")) {
- msg("xtrabackup: This target seems to be already "
+ msg("mariabackup: This target seems to be already "
"prepared with --apply-log-only.\n");
goto skip_check;
} else if (!strcmp(metadata_type, "full-prepared")) {
- msg("xtrabackup: This target seems to be already prepared.\n");
+ msg("mariabackup: This target seems to be already prepared.\n");
} else {
- msg("xtrabackup: This target seems not to have correct "
+ msg("mariabackup: This target seems not to have correct "
"metadata...\n");
exit(EXIT_FAILURE);
}
if (xtrabackup_incremental) {
- msg("xtrabackup: error: applying incremental backup "
+ msg("mariabackup: error: applying incremental backup "
"needs target prepared with --apply-log-only.\n");
exit(EXIT_FAILURE);
}
skip_check:
if (xtrabackup_incremental
&& metadata_to_lsn != incremental_lsn) {
- msg("xtrabackup: error: This incremental backup seems "
+ msg("mariabackup: error: This incremental backup seems "
"not to be proper for the target.\n"
- "xtrabackup: Check 'to_lsn' of the target and "
+ "mariabackup: Check 'to_lsn' of the target and "
"'from_lsn' of the incremental.\n");
exit(EXIT_FAILURE);
}
@@ -5726,7 +5764,7 @@ skip_check:
if (xtrabackup_incremental) {
err = xb_data_files_init();
if (err != DB_SUCCESS) {
- msg("xtrabackup: error: xb_data_files_init() failed "
+ msg("mariabackup: error: xb_data_files_init() failed "
"with error code %lu\n", err);
goto error_cleanup;
}
@@ -5776,8 +5814,8 @@ skip_check:
srv_n_write_io_threads = 4;
}
- msg("xtrabackup: Starting InnoDB instance for recovery.\n"
- "xtrabackup: Using %lld bytes for buffer pool "
+ msg("mariabackup: Starting InnoDB instance for recovery.\n"
+ "mariabackup: Using %lld bytes for buffer pool "
"(set by --use-memory parameter)\n", xtrabackup_use_memory);
srv_max_buf_pool_modified_pct = (double)max_buf_pool_modified_pct;
@@ -5789,54 +5827,8 @@ skip_check:
if(innodb_init())
goto error_cleanup;
- if (xtrabackup_incremental) {
-
- it = datafiles_iter_new(fil_system);
- if (it == NULL) {
- msg("xtrabackup: Error: datafiles_iter_new() failed.\n");
- exit(EXIT_FAILURE);
- }
-
- while ((node = datafiles_iter_next(it)) != NULL) {
- byte *header;
- ulint size;
- ulint actual_size;
- mtr_t mtr;
- buf_block_t *block;
- ulint flags;
-
- space = node->space;
-
- /* Align space sizes along with fsp header. We want to process
- each space once, so skip all nodes except the first one in a
- multi-node space. */
- if (UT_LIST_GET_PREV(chain, node) != NULL) {
- continue;
- }
-
- mtr_start(&mtr);
-
- mtr_s_lock(fil_space_get_latch(space->id, &flags), &mtr);
-
- block = buf_page_get(space->id,
- dict_tf_get_zip_size(flags),
- 0, RW_S_LATCH, &mtr);
- header = FSP_HEADER_OFFSET + buf_block_get_frame(block);
-
- size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES,
- &mtr);
-
- mtr_commit(&mtr);
-
- fil_extend_space_to_desired_size(&actual_size, space->id, size);
- }
-
- datafiles_iter_free(it);
-
- } /* if (xtrabackup_incremental) */
-
if (xtrabackup_export) {
- msg("xtrabackup: export option is specified.\n");
+ msg("mariabackup: export option is specified.\n");
pfs_os_file_t info_file;
char info_file_path[FN_REFLEN];
ibool success;
@@ -5853,7 +5845,7 @@ skip_check:
it = datafiles_iter_new(fil_system);
if (it == NULL) {
- msg("xtrabackup: Error: datafiles_iter_new() "
+ msg("mariabackup: Error: datafiles_iter_new() "
"failed.\n");
exit(EXIT_FAILURE);
}
@@ -5900,7 +5892,7 @@ skip_check:
table = dict_table_get_low(table_name);
if (!table) {
- msg("xtrabackup: error: "
+ msg("mariabackup: error: "
"cannot find dictionary "
"record of table %s\n",
table_name);
@@ -5915,7 +5907,7 @@ skip_check:
index = dict_table_get_first_index(table);
n_index = UT_LIST_GET_LEN(table->indexes);
if (n_index > 31) {
- msg("xtrabackup: warning: table '%s' has more "
+ msg("mariabackup: warning: table '%s' has more "
"than 31 indexes, .exp file was not "
"generated. Table will fail to import "
"on server version prior to 5.6.\n",
@@ -5931,7 +5923,7 @@ skip_check:
strncpy((char *) page + 12,
table_name, 500);
- msg("xtrabackup: export metadata of "
+ msg("mariabackup: export metadata of "
"table '%s' to file `%s` "
"(%lu indexes)\n",
table_name, info_file_path,
@@ -5945,7 +5937,7 @@ skip_check:
strncpy((char *) page + n_index * 512 +
12, index->name, 500);
- msg("xtrabackup: name=%s, "
+ msg("mariabackup: name=%s, "
"id.low=%lu, page=%lu\n",
index->name,
(ulint)(index->id &
@@ -6009,17 +6001,17 @@ next_node:
&& srv_start_lsn < incremental_to_lsn)
||(!xtrabackup_incremental
&& srv_start_lsn < metadata_to_lsn)) {
- msg("xtrabackup: error: "
+ msg("mariabackup: error: "
"The transaction log file is corrupted.\n"
- "xtrabackup: error: "
+ "mariabackup: error: "
"The log was not applied to the intended LSN!\n");
- msg("xtrabackup: Log applied to lsn " LSN_PF "\n",
+ msg("mariabackup: Log applied to lsn " LSN_PF "\n",
srv_start_lsn);
if (xtrabackup_incremental) {
- msg("xtrabackup: The intended lsn is " LSN_PF "\n",
+ msg("mariabackup: The intended lsn is " LSN_PF "\n",
incremental_to_lsn);
} else {
- msg("xtrabackup: The intended lsn is " LSN_PF "\n",
+ msg("mariabackup: The intended lsn is " LSN_PF "\n",
metadata_to_lsn);
}
exit(EXIT_FAILURE);
@@ -6060,7 +6052,7 @@ next_node:
sprintf(filename, "%s/%s", xtrabackup_target_dir, XTRABACKUP_METADATA_FILENAME);
if (!xtrabackup_write_metadata(filename)) {
- msg("xtrabackup: Error: failed to write metadata "
+ msg("mariabackup: Error: failed to write metadata "
"to '%s'\n", filename);
exit(EXIT_FAILURE);
}
@@ -6068,7 +6060,7 @@ next_node:
if(xtrabackup_extra_lsndir) {
sprintf(filename, "%s/%s", xtrabackup_extra_lsndir, XTRABACKUP_METADATA_FILENAME);
if (!xtrabackup_write_metadata(filename)) {
- msg("xtrabackup: Error: failed to write "
+ msg("mariabackup: Error: failed to write "
"metadata to '%s'\n", filename);
exit(EXIT_FAILURE);
}
@@ -6167,9 +6159,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;
@@ -6380,7 +6382,7 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server)
if (optend - argv[i] == 15 &&
!strncmp(argv[i], "--defaults-file", optend - argv[i])) {
- msg("xtrabackup: Error: --defaults-file "
+ msg("mariabackup: Error: --defaults-file "
"must be specified first on the command "
"line\n");
exit(EXIT_FAILURE);
@@ -6389,7 +6391,7 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server)
!strncmp(argv[i], "--defaults-extra-file",
optend - argv[i])) {
- msg("xtrabackup: Error: --defaults-extra-file "
+ msg("mariabackup: Error: --defaults-extra-file "
"must be specified first on the command "
"line\n");
exit(EXIT_FAILURE);
@@ -6440,7 +6442,7 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server)
}
if (!server_option) {
- msg("xtrabackup: Error:"
+ msg("mariabackup: Error:"
" unknown argument: '%s'\n", opt);
exit(EXIT_FAILURE);
}
@@ -6483,6 +6485,11 @@ int main(int argc, char **argv)
system_charset_info = &my_charset_utf8_general_ci;
key_map_full.set_all();
+ logger.init_base();
+ logger.set_handlers(LOG_FILE, LOG_NONE, LOG_NONE);
+ mysql_mutex_init(key_LOCK_error_log, &LOCK_error_log,
+ MY_MUTEX_INIT_FAST);
+
handle_options(argc, argv, &client_defaults, &server_defaults);
int argc_server;
@@ -6501,7 +6508,7 @@ int main(int argc, char **argv)
if ((!xtrabackup_print_param) && (!xtrabackup_prepare) && (strcmp(mysql_data_home, "./") == 0)) {
if (!xtrabackup_print_param)
usage();
- msg("\nxtrabackup: Error: Please set parameter 'datadir'\n");
+ msg("\nmariabackup: Error: Please set parameter 'datadir'\n");
exit(EXIT_FAILURE);
}
@@ -6570,7 +6577,7 @@ int main(int argc, char **argv)
error = 1;
if (error) {
- msg("xtrabackup: value '%s' may be wrong format for "
+ msg("mariabackup: value '%s' may be wrong format for "
"incremental option.\n", xtrabackup_incremental);
exit(EXIT_FAILURE);
}
@@ -6580,7 +6587,7 @@ int main(int argc, char **argv)
sprintf(filename, "%s/%s", xtrabackup_incremental_basedir, XTRABACKUP_METADATA_FILENAME);
if (!xtrabackup_read_metadata(filename)) {
- msg("xtrabackup: error: failed to read metadata from "
+ msg("mariabackup: error: failed to read metadata from "
"%s\n", filename);
exit(EXIT_FAILURE);
}
@@ -6593,7 +6600,7 @@ int main(int argc, char **argv)
sprintf(filename, "%s/%s", xtrabackup_incremental_dir, XTRABACKUP_METADATA_FILENAME);
if (!xtrabackup_read_metadata(filename)) {
- msg("xtrabackup: error: failed to read metadata from "
+ msg("mariabackup: error: failed to read metadata from "
"%s\n", filename);
exit(EXIT_FAILURE);
}
@@ -6630,7 +6637,7 @@ int main(int argc, char **argv)
}
if (xtrabackup_export && innobase_file_per_table == FALSE) {
- msg("xtrabackup: auto-enabling --innodb-file-per-table due to "
+ msg("mariabackup: auto-enabling --innodb-file-per-table due to "
"the --export option\n");
innobase_file_per_table = TRUE;
}
diff --git a/extra/my_print_defaults.c b/extra/my_print_defaults.c
index bfd0c3c635a..78940e02ca4 100644
--- a/extra/my_print_defaults.c
+++ b/extra/my_print_defaults.c
@@ -98,18 +98,23 @@ static struct my_option my_long_options[] =
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
-void cleanup_and_exit(int exit_code)
+static void cleanup_and_exit(int exit_code) __attribute__ ((noreturn));
+static void cleanup_and_exit(int exit_code)
{
my_end(0);
exit(exit_code);
}
-static void usage(my_bool version)
+static void version()
{
- printf("%s Ver 1.6 for %s at %s\n",my_progname,SYSTEM_TYPE,
- MACHINE_TYPE);
- if (version)
- return;
+ printf("%s Ver 1.6 for %s at %s\n",my_progname,SYSTEM_TYPE, MACHINE_TYPE);
+}
+
+
+static void usage() __attribute__ ((noreturn));
+static void usage()
+{
+ version();
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
puts("Prints all arguments that is give to some program using the default files");
printf("Usage: %s [OPTIONS] [groups]\n", my_progname);
@@ -133,12 +138,13 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
cleanup_and_exit(0);
case 'I':
case '?':
- usage(0);
+ usage();
case 'v':
verbose++;
break;
case 'V':
- usage(1);
+ version();
+ /* fall through */
case '#':
DBUG_PUSH(argument ? argument : default_dbug_option);
break;
@@ -186,7 +192,7 @@ int main(int argc, char **argv)
nargs+= array_elements(mysqld_groups);
if (nargs < 2)
- usage(0);
+ usage();
load_default_groups=(char**) my_malloc(nargs*sizeof(char*), MYF(MY_WME));
if (!load_default_groups)
diff --git a/extra/replace.c b/extra/replace.c
index b8c328f2902..eabf953837b 100644
--- a/extra/replace.c
+++ b/extra/replace.c
@@ -174,7 +174,7 @@ register char **argv[];
break;
case 'V':
version=1;
- /* fall through */
+ /* fall through */
case 'I':
case '?':
help=1; /* Help text written */
diff --git a/extra/yassl/CMakeLists.txt b/extra/yassl/CMakeLists.txt
index f3232896c6a..c456af9be15 100644
--- a/extra/yassl/CMakeLists.txt
+++ b/extra/yassl/CMakeLists.txt
@@ -30,8 +30,3 @@ SET(YASSL_SOURCES src/buffer.cpp src/cert_wrapper.cpp src/crypto_wrapper.cpp sr
ADD_CONVENIENCE_LIBRARY(yassl ${YASSL_SOURCES})
RESTRICT_SYMBOL_EXPORTS(yassl)
-IF(MSVC)
- INSTALL_DEBUG_TARGET(yassl DESTINATION ${INSTALL_LIBDIR}/debug)
-ENDIF()
-
-
diff --git a/extra/yassl/README b/extra/yassl/README
index a3d4f60f561..de1bf5132aa 100644
--- a/extra/yassl/README
+++ b/extra/yassl/README
@@ -12,6 +12,14 @@ before calling SSL_new();
*** end Note ***
+yaSSL Release notes, version 2.4.4 (8/8/2017)
+ This release of yaSSL fixes an interop issue. A fix for detecting cipher
+ suites with non leading zeros is included as yaSSL only supports cipher
+ suites with leading zeros. Thanks for the report from Security Innovation
+ and Oracle.
+
+ Users interoping with other SSL stacks should update.
+
yaSSL Release notes, version 2.4.2 (9/22/2016)
This release of yaSSL fixes a medium security vulnerability. A fix for
potential AES side channel leaks is included that a local user monitoring
diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h
index 9ec99b46c1f..a5ccef102b9 100644
--- a/extra/yassl/include/openssl/ssl.h
+++ b/extra/yassl/include/openssl/ssl.h
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2005, 2014, Oracle and/or its affiliates.
+ Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ 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
@@ -34,7 +35,7 @@
#include "rsa.h"
-#define YASSL_VERSION "2.4.2"
+#define YASSL_VERSION "2.4.4"
#if defined(__cplusplus)
diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp
index a481812b3e0..971a5b6654e 100644
--- a/extra/yassl/src/yassl_imp.cpp
+++ b/extra/yassl/src/yassl_imp.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2014, Oracle and/or its affiliates
+ Copyright (c) 2005, 2017, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1578,6 +1578,10 @@ void ServerHello::Process(input_buffer& input, SSL& ssl)
ssl.SetError(badVersion_error);
return;
}
+ if (cipher_suite_[0] != 0x00) {
+ ssl.SetError(unknown_cipher);
+ return;
+ }
ssl.set_pending(cipher_suite_[1]);
ssl.set_random(random_, server_end);
if (id_len_)
diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp
index ff9c8155d0c..884e8b5fa9d 100644
--- a/extra/yassl/src/yassl_int.cpp
+++ b/extra/yassl/src/yassl_int.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2014, Oracle and/or its affiliates
+ Copyright (c) 2005, 2017, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1399,12 +1399,17 @@ void SSL::matchSuite(const opaque* peer, uint length)
// start with best, if a match we are good, Ciphers are at odd index
// since all SSL and TLS ciphers have 0x00 first byte
for (uint i = 1; i < secure_.get_parms().suites_size_; i += 2)
- for (uint j = 1; j < length; j+= 2)
- if (secure_.use_parms().suites_[i] == peer[j]) {
+ for (uint j = 0; (j + 1) < length; j+= 2) {
+ if (peer[j] != 0x00) {
+ continue; // only 0x00 first byte supported
+ }
+
+ if (secure_.use_parms().suites_[i] == peer[j + 1]) {
secure_.use_parms().suite_[0] = 0x00;
- secure_.use_parms().suite_[1] = peer[j];
+ secure_.use_parms().suite_[1] = peer[j + 1];
return;
}
+ }
SetError(match_error);
}
@@ -2697,4 +2702,3 @@ extern "C" void yaSSL_CleanUp()
yaSSL::sessionsInstance = 0;
yaSSL::errorsInstance = 0;
}
-
diff --git a/extra/yassl/taocrypt/CMakeLists.txt b/extra/yassl/taocrypt/CMakeLists.txt
index eeed35fd6f4..7d95348c6e7 100644
--- a/extra/yassl/taocrypt/CMakeLists.txt
+++ b/extra/yassl/taocrypt/CMakeLists.txt
@@ -32,7 +32,3 @@ SET(TAOCRYPT_SOURCES src/aes.cpp src/aestables.cpp src/algebra.cpp src/arc4.cpp
ADD_CONVENIENCE_LIBRARY(taocrypt ${TAOCRYPT_SOURCES})
RESTRICT_SYMBOL_EXPORTS(taocrypt)
-IF(MSVC)
- INSTALL_DEBUG_TARGET(taocrypt DESTINATION ${INSTALL_LIBDIR}/debug)
-ENDIF()
-
diff --git a/include/m_string.h b/include/m_string.h
index 7437ea8b7cd..d088b510de5 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -64,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))
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_compare.h b/include/my_compare.h
index 3440d9ef920..1c50ff93791 100644
--- a/include/my_compare.h
+++ b/include/my_compare.h
@@ -91,17 +91,19 @@ typedef struct st_HA_KEYSEG /* Key-portion */
#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 uint16 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) \
diff --git a/include/my_global.h b/include/my_global.h
index b9284b99577..acc54398cf8 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -1091,11 +1091,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_valgrind.h b/include/my_valgrind.h
index 3fb93350213..e3aa11ee355 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,7 +33,13 @@
# 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 */
+#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)
@@ -33,11 +47,9 @@
#endif /* HAVE_VALGRIND */
#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)
+#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,B,0x8F)
-#define TRASH(A,B) TRASH_FREE(A,B)
-
+#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.pp b/include/mysql.h.pp
index 32d87b7391c..8936a716b90 100644
--- a/include/mysql.h.pp
+++ b/include/mysql.h.pp
@@ -221,8 +221,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/typelib.h b/include/typelib.h
index 4504bea4ff7..ab5a0f0d258 100644
--- a/include/typelib.h
+++ b/include/typelib.h
@@ -29,8 +29,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 (1 << 0)
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/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
index 8e60d267521..001bd884865 100644
--- a/libmysql/CMakeLists.txt
+++ b/libmysql/CMakeLists.txt
@@ -391,6 +391,10 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
*;
};
+ libmariadbclient_18 {
+ /* empty here. aliases are added above */
+ };
+
libmysqlclient_16 {
/* empty here. aliases are added above */
};
@@ -399,16 +403,23 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
SET (CLIENT_API_5_1_LIST)
SET (CLIENT_API_5_1_ALIASES)
+ SET (DEBIAN9_ALIASES)
FOREACH (f ${CLIENT_API_FUNCTIONS_5_1} ${CLIENT_API_5_1_EXTRA})
SET(CLIENT_API_5_1_LIST "${CLIENT_API_5_1_LIST}\t${f};\n")
SET(CLIENT_API_5_1_ALIASES "${CLIENT_API_5_1_ALIASES}\"${f}@libmysqlclient_16\" = ${f};\n")
+ SET(DEBIAN9_ALIASES "${DEBIAN9_ALIASES}\"${f}@libmariadbclient_18\" = ${f};\n")
ENDFOREACH()
SET (CLIENT_API_5_5_LIST)
FOREACH (f ${CLIENT_API_FUNCTIONS_5_5} ${CLIENT_API_5_5_EXTRA})
SET(CLIENT_API_5_5_LIST "${CLIENT_API_5_5_LIST}\t${f};\n")
+ SET(DEBIAN9_ALIASES "${DEBIAN9_ALIASES}\"${f}@libmariadbclient_18\" = ${f};\n")
ENDFOREACH()
+ IF(NOT DEB)
+ SET (DEBIAN9_ALIASES)
+ ENDIF()
+
ELSE (NOT DISABLE_LIBMYSQLCLIENT_SYMBOL_VERSIONING)
SET (CLIENT_API_5_1_ALIASES "/* Versioning disabled per user request. MDEV-5982 */")
ENDIF (NOT DISABLE_LIBMYSQLCLIENT_SYMBOL_VERSIONING)
@@ -489,14 +500,14 @@ IF(NOT DISABLE_SHARED)
OUTPUT_NAME mysqlclient
VERSION "${OS_SHARED_LIB_VERSION}"
SOVERSION "${SHARED_LIB_MAJOR_VERSION}")
- IF(LINK_FLAG_NO_UNDEFINED OR VERSION_SCRIPT_LINK_FLAGS)
+ IF(VERSION_SCRIPT_LINK_FLAGS)
GET_TARGET_PROPERTY(libmysql_link_flags libmysql LINK_FLAGS)
IF(NOT libmysql_link_flags)
# Avoid libmysql_link_flags-NOTFOUND
SET(libmysql_link_flags)
ENDIF()
SET_TARGET_PROPERTIES(libmysql PROPERTIES LINK_FLAGS
- "${libmysql_link_flags} ${LINK_FLAG_NO_UNDEFINED} ${VERSION_SCRIPT_LINK_FLAGS}")
+ "${libmysql_link_flags} ${VERSION_SCRIPT_LINK_FLAGS}")
ENDIF()
# clean direct output needs to be set several targets have the same name
#(mysqlclient in this case)
diff --git a/libmysql/libmysql_versions.ld.in b/libmysql/libmysql_versions.ld.in
index 0cf5b45cc18..f3b27e1cd1f 100644
--- a/libmysql/libmysql_versions.ld.in
+++ b/libmysql/libmysql_versions.ld.in
@@ -16,6 +16,8 @@
@CLIENT_API_5_1_ALIASES@
+@DEBIAN9_ALIASES@
+
/*
On Fedora the following symbols are exported, but renamed into a mysql_
namespace. We export them as aliases, but keep original symbols too. See
diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt
index 07bee9848b6..433897acc89 100644
--- a/libmysqld/CMakeLists.txt
+++ b/libmysqld/CMakeLists.txt
@@ -156,15 +156,6 @@ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
INSTALL(FILES embedded_priv.h DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT ${COMPONENT_MYSQLSERVER})
-# Visual Studio users need debug static library
-IF(MSVC)
- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR}/debug)
-ENDIF()
-
-IF(UNIX)
- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
- ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
-ENDIF()
# List of exported functions in embedded (client api except client plugin or
# async (*_start/*_cont functions)
diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c
index 36728cf573c..543ab86643e 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/man/mysql_upgrade.1 b/man/mysql_upgrade.1
index 48ea44a5ac9..f04fa122383 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 d1fdfd9d5aa..cfda6f1c421 100644
--- a/man/mysqladmin.1
+++ b/man/mysqladmin.1
@@ -1,6 +1,6 @@
'\" t
.\"
-.TH "\FBMYSQLADMIN\FR" "1" "14/12/2015" "MariaDB 10\&.1" "MariaDB Database System"
+.TH "\FBMYSQLADMIN\FR" "1" "28 December 2017" "MariaDB 10\&.1" "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 1c7cfaf81da..c03f0c35838 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/README b/mysql-test/README
index 0fba1cc07e3..c4ded4e8e79 100644
--- a/mysql-test/README
+++ b/mysql-test/README
@@ -1,74 +1,93 @@
-This directory contains a test suite for the MySQL daemon. To run
-the currently existing test cases, simply execute ./mysql-test-run in
-this directory. It will fire up the newly built mysqld and test it.
+This directory contains test suites for the MariaDB server. To run
+currently existing test cases, execute ./mysql-test-run in this directory.
-Note that you do not have to have to do "make install", and you could
-actually have a co-existing MySQL installation. The tests will not
-conflict with it. To run the test suite in a source directory, you
-must do make first.
+Some tests are known to fail on some platforms or be otherwise unreliable.
+The file "unstable-tests" contains the list of such tests along with
+a comment for every test.
+To exclude them from the test run, execute
+ # ./mysql-test-run --skip-test-list=unstable-tests
-All tests must pass. If one or more of them fail on your system, please
-read the following manual section for instructions on how to report the
-problem:
+In general you do not have to have to do "make install", and you can have
+a co-existing MariaDB installation, the tests will not conflict with it.
+To run the tests in a source directory, you must do "make" first.
+
+In Red Hat distributions, you should run the script as user "mysql".
+The user is created with nologin shell, so the best bet is something like
+ # su -
+ # cd /usr/share/mysql-test
+ # su -s /bin/bash mysql -c "./mysql-test-run --skip-test-list=unstable-tests"
+
+This will use the installed MariaDB executables, but will run a private
+copy of the server process (using data files within /usr/share/mysql-test),
+so you need not start the mysqld service beforehand.
+
+You can omit --skip-test-list option if you want to check whether
+the listed failures occur for you.
+
+To clean up afterwards, remove the created "var" subdirectory, e.g.
+ # su -s /bin/bash - mysql -c "rm -rf /usr/share/mysql-test/var"
+
+If one or more tests fail on your system on reasons other than listed
+in lists of unstable tests, please read the following manual section
+for instructions on how to report the problem:
https://mariadb.com/kb/en/reporting-bugs
If you want to use an already running MySQL server for specific tests,
use the --extern option to mysql-test-run. Please note that in this mode,
-the test suite expects you to provide the names of the tests to run.
+you are expected to provide names of the tests to run.
+
For example, here is the command to run the "alias" and "analyze" tests
with an external server:
-mysql-test-run --extern socket=/tmp/mysql.sock alias analyze
+ # mysql-test-run --extern socket=/tmp/mysql.sock alias analyze
-To match your setup, you might also need to provide --socket, --user, and
-other relevant options.
+To match your setup, you might need to provide other relevant options.
-With no test cases named on the command line, mysql-test-run falls back
-to the normal "non-extern" behavior. The reason for this is that some
-tests cannot run with an external server.
+With no test names on the command line, mysql-test-run will attempt
+to execute the default set of tests, which will certainly fail, because
+many tests cannot run with an external server (they need to control the
+options with which the server is started, restart the server during
+execution, etc.)
You can create your own test cases. To create a test case, create a new
file in the t subdirectory using a text editor. The file should have a .test
extension. For example:
- xemacs t/test_case_name.test
+ # xemacs t/test_case_name.test
- In the file, put a set of SQL statements that create some tables,
- load test data, and run some queries to manipulate it.
+In the file, put a set of SQL statements that create some tables,
+load test data, and run some queries to manipulate it.
- We would appreciate it if you name your test tables t1, t2, t3 ... (to not
- conflict too much with existing tables).
+Your test should begin by dropping the tables you are going to create and
+end by dropping them again. This ensures that you can run the test over
+and over again.
- Your test should begin by dropping the tables you are going to create and
- end by dropping them again. This ensures that you can run the test over
- and over again.
-
- If you are using mysqltest commands (like result file names) in your
- test case, you should create the result file as follows:
+If you are using mysqltest commands in your test case, you should create
+the result file as follows:
- mysql-test-run --record test_case_name
+ # mysql-test-run --record test_case_name
- or
+ or
- mysqltest --record < t/test_case_name.test
+ # mysqltest --record < t/test_case_name.test
- If you only have a simple test cases consisting of SQL statements and
- comments, you can create the test case in one of the following ways:
+If you only have a simple test case consisting of SQL statements and
+comments, you can create the result file in one of the following ways:
- mysql-test-run --record test_case_name
+ # mysql-test-run --record test_case_name
- mysql test < t/test_case_name.test > r/test_case_name.result
+ # mysql test < t/test_case_name.test > r/test_case_name.result
- mysqltest --record --database test --result-file=r/test_case_name.result < t/test_case_name.test
+ # mysqltest --record --database test --result-file=r/test_case_name.result < t/test_case_name.test
- When this is done, take a look at r/test_case_name.result
- - If the result is incorrect, you have found a bug. In this case, you should
- edit the test result to the correct results so that we can verify
- that the bug is corrected in future releases.
+When this is done, take a look at r/test_case_name.result .
+If the result is incorrect, you have found a bug. In this case, you should
+edit the test result to the correct results so that we can verify that
+the bug is corrected in future releases.
If you want to submit your test case you can send it
-to maria-developers@lists.launchpad.com or attach it to a bug report on
+to maria-developers@lists.launchpad.net or attach it to a bug report on
http://mariadb.org/jira/.
If the test case is really big or if it contains 'not public' data,
diff --git a/mysql-test/extra/rpl_tests/rpl_cant_read_event_incident.inc b/mysql-test/extra/rpl_tests/rpl_cant_read_event_incident.inc
index a9534a999e2..7dfef023947 100644
--- a/mysql-test/extra/rpl_tests/rpl_cant_read_event_incident.inc
+++ b/mysql-test/extra/rpl_tests/rpl_cant_read_event_incident.inc
@@ -18,8 +18,8 @@
# and replication is started from it.
#
---source include/master-slave.inc
--source include/have_binlog_format_mixed.inc
+--source include/master-slave.inc
--connection slave
# Make sure the slave is stopped while we are messing with master.
diff --git a/mysql-test/extra/rpl_tests/rpl_checksum.inc b/mysql-test/extra/rpl_tests/rpl_checksum.inc
index 8423d2fc1cb..c77610522a1 100644
--- a/mysql-test/extra/rpl_tests/rpl_checksum.inc
+++ b/mysql-test/extra/rpl_tests/rpl_checksum.inc
@@ -7,9 +7,9 @@
# WL2540 replication events checksum
# Testing configuration parameters
---source include/master-slave.inc
--source include/have_debug.inc
--source include/have_binlog_format_mixed.inc
+--source include/master-slave.inc
call mtr.add_suppression('Slave can not handle replication events with the checksum that master is configured to log');
call mtr.add_suppression('Replication event checksum verification failed');
diff --git a/mysql-test/extra/rpl_tests/rpl_incident.inc b/mysql-test/extra/rpl_tests/rpl_incident.inc
index 189240e3b75..47b145214bc 100644
--- a/mysql-test/extra/rpl_tests/rpl_incident.inc
+++ b/mysql-test/extra/rpl_tests/rpl_incident.inc
@@ -4,8 +4,8 @@
# Please check all dependent tests after modifying it
#
---source include/master-slave.inc
--source include/have_debug.inc
+--source include/master-slave.inc
--echo **** On Master ****
CREATE TABLE t1 (a INT);
diff --git a/mysql-test/extra/rpl_tests/rpl_init_slave_errors.inc b/mysql-test/extra/rpl_tests/rpl_init_slave_errors.inc
index a8ac4e3cd6e..4fdea651edd 100644
--- a/mysql-test/extra/rpl_tests/rpl_init_slave_errors.inc
+++ b/mysql-test/extra/rpl_tests/rpl_init_slave_errors.inc
@@ -35,8 +35,8 @@
# Configuring the Environment
######################################################################
source include/have_debug.inc;
-source include/master-slave.inc;
source include/have_log_bin.inc;
+source include/master-slave.inc;
connection slave;
diff --git a/mysql-test/extra/rpl_tests/rpl_loaddata.test b/mysql-test/extra/rpl_tests/rpl_loaddata.test
index 67eb137bdf4..d04cefd175a 100644
--- a/mysql-test/extra/rpl_tests/rpl_loaddata.test
+++ b/mysql-test/extra/rpl_tests/rpl_loaddata.test
@@ -11,8 +11,8 @@
# check if START SLAVE, RESET SLAVE, CHANGE MASTER reset Last_slave_error and
# Last_slave_errno in SHOW SLAVE STATUS (1st and 3rd commands did not: bug 986)
--- source include/master-slave.inc
source include/have_innodb.inc;
+source include/master-slave.inc;
--disable_query_log
CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
diff --git a/mysql-test/extra/rpl_tests/rpl_log.test b/mysql-test/extra/rpl_tests/rpl_log.test
index 01e8497e4de..934f40306ab 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_packet.inc b/mysql-test/extra/rpl_tests/rpl_packet.inc
index 41bb374b802..cbde486bcbb 100644
--- a/mysql-test/extra/rpl_tests/rpl_packet.inc
+++ b/mysql-test/extra/rpl_tests/rpl_packet.inc
@@ -15,8 +15,9 @@
# BUG#55322: SHOW BINLOG EVENTS increases @@SESSION.MAX_ALLOWED_PACKET
# max-out size db name
-source include/master-slave.inc;
source include/have_binlog_format_row.inc;
+source include/master-slave.inc;
+
call mtr.add_suppression("Slave I/O: Got a packet bigger than 'slave_max_allowed_packet' bytes, .*error.* 1153");
call mtr.add_suppression("Log entry on master is longer than slave_max_allowed_packet");
let $db= DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________;
diff --git a/mysql-test/extra/rpl_tests/rpl_skip_replication.inc b/mysql-test/extra/rpl_tests/rpl_skip_replication.inc
index 14e3339ff5e..ac0beef414d 100644
--- a/mysql-test/extra/rpl_tests/rpl_skip_replication.inc
+++ b/mysql-test/extra/rpl_tests/rpl_skip_replication.inc
@@ -16,8 +16,8 @@
# so if it is needed, it should be set explicitly before each call.
#
---source include/master-slave.inc
--source include/have_innodb.inc
+--source include/master-slave.inc
connection slave;
# Test that SUPER is required to change @@replicate_events_marked_for_skip.
diff --git a/mysql-test/extra/rpl_tests/rpl_stm_relay_ign_space.inc b/mysql-test/extra/rpl_tests/rpl_stm_relay_ign_space.inc
index 82c4b1881bf..41339f539f8 100644
--- a/mysql-test/extra/rpl_tests/rpl_stm_relay_ign_space.inc
+++ b/mysql-test/extra/rpl_tests/rpl_stm_relay_ign_space.inc
@@ -25,8 +25,8 @@
# IO thread does not do it in an uncontrolled manner.
--source include/have_binlog_format_statement.inc
---source include/master-slave.inc
--source include/have_innodb.inc
+--source include/master-slave.inc
--disable_query_log
CREATE TABLE t1 (c1 TEXT) engine=InnoDB;
diff --git a/mysql-test/extra/rpl_tests/rpl_sync.inc b/mysql-test/extra/rpl_tests/rpl_sync.inc
index ede3c3c515f..1e2ec2ca83b 100644
--- a/mysql-test/extra/rpl_tests/rpl_sync.inc
+++ b/mysql-test/extra/rpl_tests/rpl_sync.inc
@@ -32,12 +32,12 @@
# Configuring the environment
########################################################################################
--echo =====Configuring the enviroment=======;
---source include/master-slave.inc
--source include/not_embedded.inc
--source include/not_valgrind.inc
--source include/have_debug.inc
--source include/have_innodb.inc
--source include/not_crashrep.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");
diff --git a/mysql-test/include/check-testcase.test b/mysql-test/include/check-testcase.test
index 20b5ded6e82..435de640c9d 100644
--- a/mysql-test/include/check-testcase.test
+++ b/mysql-test/include/check-testcase.test
@@ -79,6 +79,8 @@ call mtr.check_testcase();
let $datadir=`select @@datadir`;
list_files $datadir mysql_upgrade_info;
+list_files $datadir/test #sql*;
+list_files $datadir/mysql #sql*;
--enable_query_log
diff --git a/mysql-test/include/fail_start_mysqld.inc b/mysql-test/include/fail_start_mysqld.inc
new file mode 100644
index 00000000000..bb1085b5dd7
--- /dev/null
+++ b/mysql-test/include/fail_start_mysqld.inc
@@ -0,0 +1,18 @@
+# ==== Usage ====
+#
+# [--let $restart_parameters= --innodb-force-recovery=0 --innodb-read-only=1]
+# [--let $mysqld_stub_cmd= $MYSQLD_LAST_CMD]
+# [--let $error_log= $MYSQLTEST_VARDIR/log/mysqld.1.err]
+# --source include/fail_restart_mysqld.inc
+
+# Evaluate the default of $error_log
+if (!$error_log)
+{
+ --let $error_log= $MYSQLTEST_VARDIR/log/mysqld.1.err
+}
+
+--error 1
+--exec $mysqld_stub_cmd $restart_parameters >> $error_log 2>&1
+
+# As the server is stopped
+--disable_reconnect
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.inc b/mysql-test/include/have_innodb.inc
index 021970423cd..b89797d5828 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 or xtradb 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_xtradb.inc b/mysql-test/include/have_xtradb.inc
index 478b9926e21..d12802e057d 100644
--- a/mysql-test/include/have_xtradb.inc
+++ b/mysql-test/include/have_xtradb.inc
@@ -2,10 +2,3 @@
# suite.pm will make sure that all tests including this file
# will be skipped unless xtradb is enabled
#
-# The test below is redundant
-
-if (!`SELECT count(*) FROM information_schema.plugins WHERE
- plugin_name = 'innodb' AND plugin_status = 'active' AND
- plugin_description LIKE '%xtradb%'`){
- skip Needs XtraDB engine;
-}
diff --git a/mysql-test/include/innodb_encrypt_log.combinations b/mysql-test/include/innodb_encrypt_log.combinations
new file mode 100644
index 00000000000..fd21a57c3c2
--- /dev/null
+++ b/mysql-test/include/innodb_encrypt_log.combinations
@@ -0,0 +1,7 @@
+[crypt]
+innodb_encrypt_log=ON
+innodb_encryption_rotate_key_age=1
+plugin_load_add=$DEBUG_KEY_MANAGEMENT_SO
+
+[clear]
+skip_innodb_encrypt_log
diff --git a/mysql-test/include/innodb_encrypt_log.inc b/mysql-test/include/innodb_encrypt_log.inc
new file mode 100644
index 00000000000..5beebeae81f
--- /dev/null
+++ b/mysql-test/include/innodb_encrypt_log.inc
@@ -0,0 +1,4 @@
+# The goal of including this file is to enable innodb_encrypt_log combinations
+# (see include/innodb_encrypt_log.combinations)
+
+--source include/have_innodb.inc
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/restart_mysqld.inc b/mysql-test/include/restart_mysqld.inc
index c817694e57a..a0447280ff5 100644
--- a/mysql-test/include/restart_mysqld.inc
+++ b/mysql-test/include/restart_mysqld.inc
@@ -31,7 +31,7 @@ if ($shutdown_timeout == 0)
--exec echo "wait" > $_expect_file_name
# Send shutdown to the connected server and give
-# it 10 seconds to die before zapping it
+# it an opted number of seconds to die before zapping it
shutdown_server $server_shutdown_timeout;
# Write file to make mysql-test-run.pl start up the server again
diff --git a/mysql-test/include/search_pattern_in_file++.inc b/mysql-test/include/search_pattern_in_file++.inc
new file mode 100644
index 00000000000..21192b55efb
--- /dev/null
+++ b/mysql-test/include/search_pattern_in_file++.inc
@@ -0,0 +1,81 @@
+# Purpose:
+# Simple search with Perl for a pattern in some file.
+#
+# The advantages compared to thinkable auxiliary constructs using the
+# mysqltest language and SQL are:
+# 1. We do not need a running MySQL server.
+# 2. SQL causes "noise" during debugging and increases the size of logs.
+# Perl code does not disturb at all.
+#
+# The environment variables SEARCH_FILE and SEARCH_PATTERN must be set
+# before sourcing this routine.
+#
+# Optionally, SEARCH_RANGE can be set to the max number of bytes of the file
+# to search. If negative, it will search that many bytes at the end of the
+# file. By default the search happens from the last CURRENT_TEST:
+# marker till the end of file (appropriate for searching error logs).
+#
+# Optionally, SEARCH_ABORT can be set to "FOUND" or "NOT FOUND" and this
+# will abort if the search result doesn't match the requested one.
+#
+# In case of
+# - SEARCH_FILE and/or SEARCH_PATTERN is not set
+# - SEARCH_FILE cannot be opened
+# the test will abort immediate.
+#
+# Typical use case (check invalid server startup options):
+# let $error_log= $MYSQLTEST_VARDIR/log/my_restart.err;
+# --error 0,1
+# --remove_file $error_log
+# let SEARCH_FILE= $error_log;
+# # Stop the server
+# let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
+# --exec echo "wait" > $restart_file
+# --shutdown_server 10
+# --source include/wait_until_disconnected.inc
+#
+# --error 1
+# --exec $MYSQLD_CMD <whatever wrong setting> > $error_log 2>&1
+# # The server restart aborts
+# let SEARCH_PATTERN= \[ERROR\] Aborting;
+# --source include/search_pattern_in_file.inc
+#
+# Created: 2011-11-11 mleich
+#
+
+perl;
+ use strict;
+ die "SEARCH_FILE not set" unless $ENV{SEARCH_FILE};
+ my @search_files= glob($ENV{SEARCH_FILE});
+ my $search_pattern= $ENV{SEARCH_PATTERN} or die "SEARCH_PATTERN not set";
+ my $search_range= $ENV{SEARCH_RANGE};
+ my $content;
+ foreach my $search_file (@search_files) {
+ open(FILE, '<', $search_file) || die("Can't open file $search_file: $!");
+ my $file_content;
+ if ($search_range > 0) {
+ read(FILE, $file_content, $search_range, 0);
+ } elsif ($search_range < 0) {
+ my $size= -s $search_file;
+ $search_range = -$size if $size > -$search_range;
+ seek(FILE, $search_range, 2);
+ read(FILE, $file_content, -$search_range, 0);
+ } else {
+ while(<FILE>) { # error log
+ if (/^CURRENT_TEST:/) {
+ $content='';
+ } else {
+ $content.=$_;
+ }
+ }
+ }
+ close(FILE);
+ $content.= $file_content;
+ }
+ my @matches=($content =~ m/$search_pattern/gs);
+ my $res=@matches ? "FOUND " . scalar(@matches) : "NOT FOUND";
+ $ENV{SEARCH_FILE} =~ s{^.*?([^/\\]+)$}{$1};
+ print "$res /$search_pattern/ in $ENV{SEARCH_FILE}\n";
+ die "$ENV{SEARCH_ABORT}\n"
+ if $ENV{SEARCH_ABORT} && $res =~ /^$ENV{SEARCH_ABORT}/;
+EOF
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/shutdown_mysqld.inc b/mysql-test/include/shutdown_mysqld.inc
index 54bba1318e7..e28f3c244ca 100644
--- a/mysql-test/include/shutdown_mysqld.inc
+++ b/mysql-test/include/shutdown_mysqld.inc
@@ -1,3 +1,17 @@
+# ==== Usage ====
+#
+# [--let $shutdown_timeout= 30]
+# [--let $allow_rpl_inited= 1]
+# --source include/shutdown_mysqld.inc
+
+# The default value is empty
+--let $server_shutdown_timeout=
+
+if ($shutdown_timeout)
+{
+ --let $server_shutdown_timeout= $shutdown_timeout
+}
+
# This is the first half of include/restart_mysqld.inc.
if ($rpl_inited)
{
@@ -13,6 +27,6 @@ if ($rpl_inited)
--exec echo "wait" > $_expect_file_name
# Send shutdown to the connected server
---shutdown_server
+--shutdown_server $server_shutdown_timeout
--source include/wait_until_disconnected.inc
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/lib/My/SafeProcess.pm b/mysql-test/lib/My/SafeProcess.pm
index f3ee772cca3..2980992290c 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/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 0c142dc15b6..eaec51b82b4 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -742,8 +742,7 @@ sub run_test_server ($$$) {
# Repeat test $opt_repeat number of times
my $repeat= $result->{repeat} || 1;
- # Don't repeat if test was skipped
- if ($repeat < $opt_repeat && $result->{'result'} ne 'MTR_RES_SKIPPED')
+ if ($repeat < $opt_repeat)
{
$result->{retries}= 0;
$result->{rep_failures}++ if $result->{failures};
@@ -1590,6 +1589,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");
@@ -2818,7 +2818,7 @@ 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)/ )
+ "@$extra_opts" =~ /--innodb[-_](?:page[-_]size|checksum[-_]algorithm|undo[-_]tablespaces|log[-_]group[-_]home[-_]dir|data[-_]home[-_]dir)|data[-_]file[-_]path/ )
{
mysql_install_db($mysqld, undef, $extra_opts);
}
@@ -3106,14 +3106,16 @@ sub mysql_install_db {
mtr_add_arg($args, "--bootstrap");
mtr_add_arg($args, "--basedir=%s", $install_basedir);
mtr_add_arg($args, "--datadir=%s", $install_datadir);
+ mtr_add_arg($args, "--plugin-dir=%s", $plugindir);
mtr_add_arg($args, "--default-storage-engine=myisam");
- mtr_add_arg($args, "--skip-plugin-$_") for @optional_plugins;
+ mtr_add_arg($args, "--loose-skip-plugin-$_") for @optional_plugins;
# starting from 10.0 bootstrap scripts require InnoDB
mtr_add_arg($args, "--loose-innodb");
mtr_add_arg($args, "--loose-innodb-log-file-size=5M");
mtr_add_arg($args, "--disable-sync-frm");
mtr_add_arg($args, "--tmpdir=%s", "$opt_vardir/tmp/");
mtr_add_arg($args, "--core-file");
+ mtr_add_arg($args, "--console");
if ( $opt_debug )
{
@@ -3132,13 +3134,6 @@ sub mysql_install_db {
mtr_add_arg($args, $extra_opt);
}
}
- # InnoDB options can come not only from the command line, but also
- # from option files or combinations
- foreach my $extra_opt ( @$extra_opts ) {
- if ($extra_opt =~ /--innodb/) {
- mtr_add_arg($args, $extra_opt);
- }
- }
# If DISABLE_GRANT_OPTIONS is defined when the server is compiled (e.g.,
# configure --disable-grant-options), mysqld will not recognize the
@@ -3153,98 +3148,107 @@ sub mysql_install_db {
# ----------------------------------------------------------------------
$ENV{'MYSQLD_BOOTSTRAP_CMD'}= "$exe_mysqld_bootstrap " . join(" ", @$args);
-
+ # Extra options can come not only from the command line, but also
+ # from option files or combinations. We want them on a command line
+ # that is executed now, because otherwise the datadir might be
+ # incompatible with the test settings, but not on the general
+ # $MYSQLD_BOOTSTRAP_CMD line
+ foreach my $extra_opt ( @$extra_opts ) {
+ mtr_add_arg($args, $extra_opt);
+ }
# ----------------------------------------------------------------------
# Create the bootstrap.sql file
# ----------------------------------------------------------------------
- my $bootstrap_sql_file= "$opt_vardir/tmp/bootstrap.sql";
+ my $bootstrap_sql_file= "$opt_vardir/log/bootstrap.sql";
- if ($opt_boot_gdb) {
- gdb_arguments(\$args, \$exe_mysqld_bootstrap, $mysqld->name(),
- $bootstrap_sql_file);
- }
- if ($opt_boot_dbx) {
- dbx_arguments(\$args, \$exe_mysqld_bootstrap, $mysqld->name(),
- $bootstrap_sql_file);
- }
- if ($opt_boot_ddd) {
- ddd_arguments(\$args, \$exe_mysqld_bootstrap, $mysqld->name(),
- $bootstrap_sql_file);
- }
-
- my $path_sql= my_find_file($install_basedir,
- ["mysql", "sql/share", "share/mariadb",
- "share/mysql", "share", "scripts"],
- "mysql_system_tables.sql",
- NOT_REQUIRED);
-
- if (-f $path_sql )
+ if (! -e $bootstrap_sql_file)
{
- my $sql_dir= dirname($path_sql);
- # Use the mysql database for system tables
- mtr_tofile($bootstrap_sql_file, "use mysql;\n");
-
- # Add the offical mysql system tables
- # for a production system
- mtr_appendfile_to_file("$sql_dir/mysql_system_tables.sql",
- $bootstrap_sql_file);
-
- # Add the performance tables
- # for a production system
- mtr_appendfile_to_file("$sql_dir/mysql_performance_tables.sql",
- $bootstrap_sql_file);
+ if ($opt_boot_gdb) {
+ gdb_arguments(\$args, \$exe_mysqld_bootstrap, $mysqld->name(),
+ $bootstrap_sql_file);
+ }
+ if ($opt_boot_dbx) {
+ dbx_arguments(\$args, \$exe_mysqld_bootstrap, $mysqld->name(),
+ $bootstrap_sql_file);
+ }
+ if ($opt_boot_ddd) {
+ ddd_arguments(\$args, \$exe_mysqld_bootstrap, $mysqld->name(),
+ $bootstrap_sql_file);
+ }
- # Add the mysql system tables initial data
- # for a production system
- mtr_appendfile_to_file("$sql_dir/mysql_system_tables_data.sql",
- $bootstrap_sql_file);
+ my $path_sql= my_find_file($install_basedir,
+ ["mysql", "sql/share", "share/mariadb",
+ "share/mysql", "share", "scripts"],
+ "mysql_system_tables.sql",
+ NOT_REQUIRED);
- # Add test data for timezone - this is just a subset, on a real
- # system these tables will be populated either by mysql_tzinfo_to_sql
- # or by downloading the timezone table package from our website
- mtr_appendfile_to_file("$sql_dir/mysql_test_data_timezone.sql",
- $bootstrap_sql_file);
+ if (-f $path_sql )
+ {
+ my $sql_dir= dirname($path_sql);
+ # Use the mysql database for system tables
+ mtr_tofile($bootstrap_sql_file, "use mysql;\n");
+
+ # Add the offical mysql system tables
+ # for a production system
+ mtr_appendfile_to_file("$sql_dir/mysql_system_tables.sql",
+ $bootstrap_sql_file);
+
+ # Add the performance tables
+ # for a production system
+ 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",
+ $bootstrap_sql_file);
+
+ # Add test data for timezone - this is just a subset, on a real
+ # system these tables will be populated either by mysql_tzinfo_to_sql
+ # or by downloading the timezone table package from our website
+ mtr_appendfile_to_file("$sql_dir/mysql_test_data_timezone.sql",
+ $bootstrap_sql_file);
+
+ # Fill help tables, just an empty file when running from bk repo
+ # but will be replaced by a real fill_help_tables.sql when
+ # building the source dist
+ mtr_appendfile_to_file("$sql_dir/fill_help_tables.sql",
+ $bootstrap_sql_file);
+
+ # mysql.gtid_slave_pos was created in InnoDB, but many tests
+ # run without InnoDB. Alter it to MyISAM now
+ mtr_tofile($bootstrap_sql_file, "ALTER TABLE gtid_slave_pos ENGINE=MyISAM;\n");
+ }
+ else
+ {
+ # Install db from init_db.sql that exist in early 5.1 and 5.0
+ # versions of MySQL
+ my $init_file= "$install_basedir/mysql-test/lib/init_db.sql";
+ mtr_report(" - from '$init_file'");
+ my $text= mtr_grab_file($init_file) or
+ mtr_error("Can't open '$init_file': $!");
+
+ mtr_tofile($bootstrap_sql_file,
+ sql_to_bootstrap($text));
+ }
- # Fill help tables, just an empty file when running from bk repo
- # but will be replaced by a real fill_help_tables.sql when
- # building the source dist
- mtr_appendfile_to_file("$sql_dir/fill_help_tables.sql",
- $bootstrap_sql_file);
+ # Create mtr database
+ mtr_tofile($bootstrap_sql_file,
+ "CREATE DATABASE mtr CHARSET=latin1;\n");
- # mysql.gtid_slave_pos was created in InnoDB, but many tests
- # run without InnoDB. Alter it to MyISAM now
- mtr_tofile($bootstrap_sql_file, "ALTER TABLE gtid_slave_pos ENGINE=MyISAM;\n");
- }
- else
- {
- # Install db from init_db.sql that exist in early 5.1 and 5.0
- # versions of MySQL
- my $init_file= "$install_basedir/mysql-test/lib/init_db.sql";
- mtr_report(" - from '$init_file'");
- my $text= mtr_grab_file($init_file) or
- mtr_error("Can't open '$init_file': $!");
+ # Add help tables and data for warning detection and supression
+ mtr_tofile($bootstrap_sql_file,
+ sql_to_bootstrap(mtr_grab_file("include/mtr_warnings.sql")));
+ # Add procedures for checking server is restored after testcase
mtr_tofile($bootstrap_sql_file,
- sql_to_bootstrap($text));
+ sql_to_bootstrap(mtr_grab_file("include/mtr_check.sql")));
}
- # 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");
-
- # Add help tables and data for warning detection and supression
- mtr_tofile($bootstrap_sql_file,
- sql_to_bootstrap(mtr_grab_file("include/mtr_warnings.sql")));
-
- # Add procedures for checking server is restored after testcase
- mtr_tofile($bootstrap_sql_file,
- sql_to_bootstrap(mtr_grab_file("include/mtr_check.sql")));
-
# Log bootstrap command
my $path_bootstrap_log= "$opt_vardir/log/bootstrap.log";
mtr_tofile($path_bootstrap_log,
@@ -5038,7 +5042,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);
}
@@ -5072,6 +5076,11 @@ sub mysqld_start ($$) {
}
}
+ # "Dynamic" version of MYSQLD_CMD is reevaluated with each mysqld_start.
+ # Use it to restart the server at testing a failing server start (e.g
+ # due to incompatible options).
+ $ENV{'MYSQLD_LAST_CMD'}= "$exe @$args";
+
if ( $opt_gdb || $opt_manual_gdb )
{
gdb_arguments(\$args, \$exe, $mysqld->name());
@@ -5636,11 +5645,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 )
{
@@ -5808,7 +5826,7 @@ sub debugger_arguments {
$$exe= $debugger;
}
- elsif ( $debugger =~ /windbg/ )
+ elsif ( $debugger =~ /windbg|vsjitdebugger/ )
{
# windbg exe arg1 .. argn
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result
index d7e902259df..17e2dc9b009 100644
--- a/mysql-test/r/alter_table.result
+++ b/mysql-test/r/alter_table.result
@@ -1359,6 +1359,58 @@ rename table t2 to t1;
execute stmt1;
deallocate prepare stmt1;
drop table t2;
+#
+# MDEV-8960 Can't refer the same column twice in one ALTER TABLE
+#
+CREATE TABLE t1 (
+`a` int(11) DEFAULT NULL
+) DEFAULT CHARSET=utf8;
+ALTER TABLE t1 ADD COLUMN `consultant_id` integer NOT NULL,
+ALTER COLUMN `consultant_id` DROP DEFAULT;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `consultant_id` int(11) NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=utf8
+DROP TABLE t1;
+CREATE TABLE t1 (
+`a` int(11) DEFAULT NULL
+) DEFAULT CHARSET=utf8;
+ALTER TABLE t1 ADD COLUMN `consultant_id` integer NOT NULL,
+ALTER COLUMN `consultant_id` SET DEFAULT 2;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `consultant_id` int(11) NOT NULL DEFAULT '2'
+) ENGINE=MyISAM DEFAULT CHARSET=utf8
+DROP TABLE t1;
+CREATE TABLE t1 (
+`a` int(11) DEFAULT NULL
+) DEFAULT CHARSET=utf8;
+ALTER TABLE t1 ADD COLUMN `consultant_id` integer NOT NULL DEFAULT 2,
+ALTER COLUMN `consultant_id` DROP DEFAULT;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `consultant_id` int(11) NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=utf8
+DROP TABLE t1;
+CREATE TABLE t1 (
+`a` int(11) DEFAULT NULL
+) DEFAULT CHARSET=utf8;
+ALTER TABLE t1 ADD COLUMN `consultant_id` integer NOT NULL DEFAULT 2,
+ALTER COLUMN `consultant_id` DROP DEFAULT,
+MODIFY COLUMN `consultant_id` BIGINT;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `consultant_id` bigint(20) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=utf8
+DROP TABLE t1;
CREATE TABLE t1 (
id INT(11) NOT NULL,
x_param INT(11) DEFAULT NULL,
@@ -2122,59 +2174,7 @@ t1 CREATE TABLE `t1` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8
DROP TABLE t1;
#
-# MDEV-8960 Can't refer the same column twice in one ALTER TABLE
-#
-CREATE TABLE t1 (
-`a` int(11) DEFAULT NULL
-) DEFAULT CHARSET=utf8;
-ALTER TABLE t1 ADD COLUMN `consultant_id` integer NOT NULL,
-ALTER COLUMN `consultant_id` DROP DEFAULT;
-SHOW CREATE TABLE t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `a` int(11) DEFAULT NULL,
- `consultant_id` int(11) NOT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=utf8
-DROP TABLE t1;
-CREATE TABLE t1 (
-`a` int(11) DEFAULT NULL
-) DEFAULT CHARSET=utf8;
-ALTER TABLE t1 ADD COLUMN `consultant_id` integer NOT NULL,
-ALTER COLUMN `consultant_id` SET DEFAULT 2;
-SHOW CREATE TABLE t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `a` int(11) DEFAULT NULL,
- `consultant_id` int(11) NOT NULL DEFAULT '2'
-) ENGINE=MyISAM DEFAULT CHARSET=utf8
-DROP TABLE t1;
-CREATE TABLE t1 (
-`a` int(11) DEFAULT NULL
-) DEFAULT CHARSET=utf8;
-ALTER TABLE t1 ADD COLUMN `consultant_id` integer NOT NULL DEFAULT 2,
-ALTER COLUMN `consultant_id` DROP DEFAULT;
-SHOW CREATE TABLE t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `a` int(11) DEFAULT NULL,
- `consultant_id` int(11) NOT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=utf8
-DROP TABLE t1;
-CREATE TABLE t1 (
-`a` int(11) DEFAULT NULL
-) DEFAULT CHARSET=utf8;
-ALTER TABLE t1 ADD COLUMN `consultant_id` integer NOT NULL DEFAULT 2,
-ALTER COLUMN `consultant_id` DROP DEFAULT,
-MODIFY COLUMN `consultant_id` BIGINT;
-SHOW CREATE TABLE t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `a` int(11) DEFAULT NULL,
- `consultant_id` bigint(20) DEFAULT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=utf8
-DROP TABLE t1;
-#
-# Start of 10.1 tests
+# End of 10.0 tests
#
#
# MDEV-7374 : Losing connection to MySQL while running ALTER TABLE
@@ -2197,3 +2197,6 @@ t1 CREATE TABLE `t1` (
KEY `i1` (`a`) COMMENT 'comment2'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
+#
+# End of 10.1 tests
+#
diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result
index 9ceb7efde64..6fc1c9628b3 100644
--- a/mysql-test/r/case.result
+++ b/mysql-test/r/case.result
@@ -220,6 +220,22 @@ a d
3 11120436154190595086
drop table t1, t2;
End of 5.0 tests
+#
+# Bug#19875294 ASSERTION `SRC' FAILED IN MY_STRNXFRM_UNICODE
+# (SIG 6 -STRINGS/CTYPE-UTF8.C:5151)
+#
+set @@sql_mode='';
+CREATE TABLE t1(c1 SET('','')CHARACTER SET ucs2);
+Warnings:
+Note 1291 Column 'c1' has duplicated value '' in SET
+INSERT INTO t1 VALUES(990101.102);
+Warnings:
+Warning 1265 Data truncated for column 'c1' at row 1
+SELECT COALESCE(c1)FROM t1 ORDER BY 1;
+COALESCE(c1)
+
+DROP TABLE t1;
+set @@sql_mode=default;
CREATE TABLE t1(a YEAR);
SELECT 1 FROM t1 WHERE a=1 AND CASE 1 WHEN a THEN 1 ELSE 1 END;
1
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/count_distinct.result b/mysql-test/r/count_distinct.result
index d55a232c715..760b2710586 100644
--- a/mysql-test/r/count_distinct.result
+++ b/mysql-test/r/count_distinct.result
@@ -106,3 +106,28 @@ count(distinct user_id)
17
drop table t1;
set @@tmp_table_size = default;
+create table t1 (
+a VARCHAR(1020),
+b int
+);
+insert into t1 values
+( 0 , 1 ),
+( 1 , 2 ),
+( 2 , 3 ),
+( 3 , 4 ),
+( 4 , 5 ),
+( 5 , 6 ),
+( 6 , 7 ),
+( 7 , 8 ),
+( 8 , 9 ),
+( 9 , 10 ),
+( 0 , 11 ),
+( 1 , 12 ),
+( 2 , 13 ),
+( 3 , 14 );
+set @@tmp_table_size=1024;
+select count(distinct a) from t1;
+count(distinct a)
+10
+drop table t1;
+set @@tmp_table_size = default;
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index 14a8788d3ef..4ac8a0e249f 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -1912,6 +1912,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/ctype_gbk.result b/mysql-test/r/ctype_gbk.result
index b5774548d85..d10d5f4bf75 100644
--- a/mysql-test/r/ctype_gbk.result
+++ b/mysql-test/r/ctype_gbk.result
@@ -5100,6 +5100,24 @@ E05B
DROP TABLE t1;
# Start of ctype_E05C.inc
#
+# MDEV-9886 Illegal mix of collations with a view comparing a field to a binary constant
+#
+SET NAMES latin1;
+CREATE TABLE t1 (a TEXT CHARACTER SET gbk);
+INSERT INTO t1 VALUES (0xEE5D);
+SELECT a<>0xEE5D AS a FROM t1;
+a
+0
+CREATE VIEW v1 AS SELECT a<>0xEE5D AS a FROM t1;
+SHOW CREATE VIEW v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select (`t1`.`a` <> 0xee5d) AS `a` from `t1` latin1 latin1_swedish_ci
+SELECT * FROM v1;
+a
+0
+DROP VIEW v1;
+DROP TABLE t1;
+#
# End of 10.0 tests
#
#
diff --git a/mysql-test/r/ctype_latin1.result b/mysql-test/r/ctype_latin1.result
index c6f190101f6..85035982cf9 100644
--- a/mysql-test/r/ctype_latin1.result
+++ b/mysql-test/r/ctype_latin1.result
@@ -7972,6 +7972,24 @@ SELECT _latin1 0x7E, _latin1 X'7E', _latin1 B'01111110';
_latin1 0x7E _latin1 X'7E' _latin1 B'01111110'
~ ~ ~
#
+# MDEV-9886 Illegal mix of collations with a view comparing a field to a binary constant
+#
+SET NAMES latin1;
+CREATE TABLE t1 (a TEXT CHARACTER SET latin1);
+INSERT INTO t1 VALUES (0xC0);
+SELECT a<>0xEE5D AS a FROM t1;
+a
+1
+CREATE VIEW v1 AS SELECT a<>0xC0 AS a FROM t1;
+SHOW CREATE VIEW v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select (`t1`.`a` <> 0xc0) AS `a` from `t1` latin1 latin1_swedish_ci
+SELECT * FROM v1;
+a
+0
+DROP VIEW v1;
+DROP TABLE t1;
+#
# End of 10.0 tests
#
#
diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index 9402acc9e9a..f9f0acf726f 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -4586,6 +4586,36 @@ NO_ENGINE_SUBSTITUTION
SET sql_mode=DEFAULT;
SET NAMES utf8;
#
+# MDEV-13972 crash in Item_func_sec_to_time::get_date
+#
+SELECT SEC_TO_TIME(CONVERT(900*24*60*60 USING ucs2));
+SEC_TO_TIME(CONVERT(900*24*60*60 USING ucs2))
+838:59:59.999999
+Warnings:
+Warning 1292 Truncated incorrect time value: '77760000'
+#
+# MDEV-13530 VARBINARY doesn't convert to to BLOB for sizes 65533, 65534 and 65535
+#
+CREATE TABLE t1 (c1 VARCHAR(32766) CHARACTER SET ucs2);
+DESCRIBE t1;
+Field Type Null Key Default Extra
+c1 varchar(32766) YES NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 VARCHAR(32767) CHARACTER SET ucs2);
+Warnings:
+Note 1246 Converting column 'c1' from VARCHAR to TEXT
+DESCRIBE t1;
+Field Type Null Key Default Extra
+c1 text YES NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 VARCHAR(32768) CHARACTER SET ucs2);
+Warnings:
+Note 1246 Converting column 'c1' from VARCHAR to TEXT
+DESCRIBE t1;
+Field Type Null Key Default Extra
+c1 mediumtext YES NULL
+DROP TABLE t1;
+#
# End of 5.5 tests
#
#
diff --git a/mysql-test/r/ctype_utf32.result b/mysql-test/r/ctype_utf32.result
index 645db153a3e..22b0e9c0fc0 100644
--- a/mysql-test/r/ctype_utf32.result
+++ b/mysql-test/r/ctype_utf32.result
@@ -1678,6 +1678,21 @@ NO_ENGINE_SUBSTITUTION
SET sql_mode=DEFAULT;
SET NAMES utf8;
#
+# MDEV-13530 VARBINARY doesn't convert to to BLOB for sizes 65533, 65534 and 65535
+#
+CREATE TABLE t1 (c1 VARCHAR(16383) CHARACTER SET utf32);
+DESCRIBE t1;
+Field Type Null Key Default Extra
+c1 varchar(16383) YES NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 VARCHAR(16384) CHARACTER SET utf32);
+Warnings:
+Note 1246 Converting column 'c1' from VARCHAR to TEXT
+DESCRIBE t1;
+Field Type Null Key Default Extra
+c1 mediumtext YES NULL
+DROP TABLE t1;
+#
# End of 5.5 tests
#
#
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 2960b648b84..5a77ea3aea5 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -1945,7 +1945,7 @@ Warnings:
Warning 1300 Invalid utf8 character string: 'FD'
select convert(char(0xff,0x8f) using utf8);
convert(char(0xff,0x8f) using utf8)
-NULL
+??
Warnings:
Warning 1300 Invalid utf8 character string: '\xFF\x8F'
select hex(convert(char(2557 using latin1) using utf8));
@@ -2114,7 +2114,7 @@ Warnings:
Warning 1300 Invalid utf8 character string: 'FF'
select hex(convert(0xFF using utf8));
hex(convert(0xFF using utf8))
-NULL
+3F
Warnings:
Warning 1300 Invalid utf8 character string: '\xFF'
select hex(_utf8 0x616263FF);
@@ -6274,6 +6274,28 @@ Warnings:
SET sql_mode=DEFAULT;
DROP TABLE t1;
#
+# MDEV-13530 VARBINARY doesn't convert to to BLOB for sizes 65533, 65534 and 65535
+#
+CREATE TABLE t1 (c1 VARCHAR(21844) CHARACTER SET utf8);
+DESCRIBE t1;
+Field Type Null Key Default Extra
+c1 varchar(21844) YES NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 VARCHAR(21845) CHARACTER SET utf8);
+Warnings:
+Note 1246 Converting column 'c1' from VARCHAR to TEXT
+DESCRIBE t1;
+Field Type Null Key Default Extra
+c1 text YES NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 VARCHAR(21846) CHARACTER SET utf8);
+Warnings:
+Note 1246 Converting column 'c1' from VARCHAR to TEXT
+DESCRIBE t1;
+Field Type Null Key Default Extra
+c1 mediumtext YES NULL
+DROP TABLE t1;
+#
# End of 5.5 tests
#
#
@@ -10242,6 +10264,21 @@ DROP FUNCTION iswellformed;
DROP TABLE allbytes;
# 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
#
#
@@ -10473,5 +10510,30 @@ END
DROP PROCEDURE p1;
SET @@SQL_MODE=default;
#
+# MDEV-10191 non convertible chars convert() resulted in Null instead "?" on Windows
+#
+SET sql_mode='STRICT_TRANS_TABLES';
+SELECT CONVERT(_utf8 0xC499 USING latin1);
+CONVERT(_utf8 0xC499 USING latin1)
+?
+Warnings:
+Warning 1977 Cannot convert 'utf8' character 0xC499 to 'latin1'
+SELECT CAST(_utf8 0xC499 AS CHAR CHARACTER SET latin1);
+CAST(_utf8 0xC499 AS CHAR CHARACTER SET latin1)
+?
+Warnings:
+Warning 1977 Cannot convert 'utf8' character 0xC499 to 'latin1'
+SET sql_mode=default;
+SELECT CONVERT(_utf8 0xC499 USING latin1);
+CONVERT(_utf8 0xC499 USING latin1)
+?
+Warnings:
+Warning 1977 Cannot convert 'utf8' character 0xC499 to 'latin1'
+SELECT CAST(_utf8 0xC499 AS CHAR CHARACTER SET latin1);
+CAST(_utf8 0xC499 AS CHAR CHARACTER SET latin1)
+?
+Warnings:
+Warning 1977 Cannot convert 'utf8' character 0xC499 to 'latin1'
+#
# End of 10.1 tests
#
diff --git a/mysql-test/r/ctype_utf8mb4.result b/mysql-test/r/ctype_utf8mb4.result
index dd1c5249bc7..d45b6b23263 100644
--- a/mysql-test/r/ctype_utf8mb4.result
+++ b/mysql-test/r/ctype_utf8mb4.result
@@ -1970,7 +1970,7 @@ Warnings:
Warning 1300 Invalid utf8mb4 character string: 'FD'
select convert(char(0xff,0x8f) using utf8mb4);
convert(char(0xff,0x8f) using utf8mb4)
-NULL
+??
Warnings:
Warning 1300 Invalid utf8mb4 character string: '\xFF\x8F'
select hex(convert(char(2557 using latin1) using utf8mb4));
@@ -2139,7 +2139,7 @@ Warnings:
Warning 1300 Invalid utf8mb4 character string: 'FF'
select hex(convert(0xFF using utf8mb4));
hex(convert(0xFF using utf8mb4))
-NULL
+3F
Warnings:
Warning 1300 Invalid utf8mb4 character string: '\xFF'
select hex(_utf8mb4 0x616263FF);
@@ -3421,6 +3421,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,
+ `COLUMN_JSON(COLUMN_CREATE('b',1))` longtext CHARACTER SET utf8mb4
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+SET NAMES default;
+#
# End of 10.0 tests
#
#
diff --git a/mysql-test/r/ctype_utf8mb4_heap.result b/mysql-test/r/ctype_utf8mb4_heap.result
index d70e009228e..46b0cc3789f 100644
--- a/mysql-test/r/ctype_utf8mb4_heap.result
+++ b/mysql-test/r/ctype_utf8mb4_heap.result
@@ -1802,7 +1802,7 @@ Warnings:
Warning 1300 Invalid utf8mb4 character string: 'FD'
select convert(char(0xff,0x8f) using utf8mb4);
convert(char(0xff,0x8f) using utf8mb4)
-NULL
+??
Warnings:
Warning 1300 Invalid utf8mb4 character string: '\xFF\x8F'
select hex(convert(char(2557 using latin1) using utf8mb4));
@@ -1971,7 +1971,7 @@ Warnings:
Warning 1300 Invalid utf8mb4 character string: 'FF'
select hex(convert(0xFF using utf8mb4));
hex(convert(0xFF using utf8mb4))
-NULL
+3F
Warnings:
Warning 1300 Invalid utf8mb4 character string: '\xFF'
select hex(_utf8mb4 0x616263FF);
diff --git a/mysql-test/r/ctype_utf8mb4_innodb.result b/mysql-test/r/ctype_utf8mb4_innodb.result
index 7d193f397ac..cfd9bf969ad 100644
--- a/mysql-test/r/ctype_utf8mb4_innodb.result
+++ b/mysql-test/r/ctype_utf8mb4_innodb.result
@@ -1930,7 +1930,7 @@ Warnings:
Warning 1300 Invalid utf8mb4 character string: 'FD'
select convert(char(0xff,0x8f) using utf8mb4);
convert(char(0xff,0x8f) using utf8mb4)
-NULL
+??
Warnings:
Warning 1300 Invalid utf8mb4 character string: '\xFF\x8F'
select hex(convert(char(2557 using latin1) using utf8mb4));
@@ -2099,7 +2099,7 @@ Warnings:
Warning 1300 Invalid utf8mb4 character string: 'FF'
select hex(convert(0xFF using utf8mb4));
hex(convert(0xFF using utf8mb4))
-NULL
+3F
Warnings:
Warning 1300 Invalid utf8mb4 character string: '\xFF'
select hex(_utf8mb4 0x616263FF);
diff --git a/mysql-test/r/ctype_utf8mb4_myisam.result b/mysql-test/r/ctype_utf8mb4_myisam.result
index 28cf36c7492..53ae410046f 100644
--- a/mysql-test/r/ctype_utf8mb4_myisam.result
+++ b/mysql-test/r/ctype_utf8mb4_myisam.result
@@ -1930,7 +1930,7 @@ Warnings:
Warning 1300 Invalid utf8mb4 character string: 'FD'
select convert(char(0xff,0x8f) using utf8mb4);
convert(char(0xff,0x8f) using utf8mb4)
-NULL
+??
Warnings:
Warning 1300 Invalid utf8mb4 character string: '\xFF\x8F'
select hex(convert(char(2557 using latin1) using utf8mb4));
@@ -2099,7 +2099,7 @@ Warnings:
Warning 1300 Invalid utf8mb4 character string: 'FF'
select hex(convert(0xFF using utf8mb4));
hex(convert(0xFF using utf8mb4))
-NULL
+3F
Warnings:
Warning 1300 Invalid utf8mb4 character string: '\xFF'
select hex(_utf8mb4 0x616263FF);
diff --git a/mysql-test/r/delete_returning.result b/mysql-test/r/delete_returning.result
index 0618b495a53..3a95de0cdca 100644
--- a/mysql-test/r/delete_returning.result
+++ b/mysql-test/r/delete_returning.result
@@ -199,3 +199,15 @@ i
2
DROP PROCEDURE p1;
DROP TABLE t1;
+#
+# MDEV-13776: DELETE ... RETURNING with sql_mode='ONLY_FULL_GROUP_BY'
+#
+set @sql_mode_save= @@sql_mode;
+set sql_mode='ONLY_FULL_GROUP_BY';
+CREATE TABLE t1 (id INT);
+INSERT INTO t1 VALUE(1),(2),(3);
+DELETE FROM t1 WHERE id > 2 RETURNING *;
+id
+3
+set sql_mode=@sql_mode_save;
+DROP TABLE t1;
diff --git a/mysql-test/r/delimiter_command_case_sensitivity.result b/mysql-test/r/delimiter_command_case_sensitivity.result
new file mode 100644
index 00000000000..6ed281c757a
--- /dev/null
+++ b/mysql-test/r/delimiter_command_case_sensitivity.result
@@ -0,0 +1,2 @@
+1
+1
diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result
index c8736b557de..687497ceb7e 100644
--- a/mysql-test/r/derived.result
+++ b/mysql-test/r/derived.result
@@ -1036,6 +1036,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/dyncol.result b/mysql-test/r/dyncol.result
index b0d28a81043..fe4ee3f7de2 100644
--- a/mysql-test/r/dyncol.result
+++ b/mysql-test/r/dyncol.result
@@ -1873,5 +1873,25 @@ 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/errors.result b/mysql-test/r/errors.result
index 776fe627875..e1d494d3324 100644
--- a/mysql-test/r/errors.result
+++ b/mysql-test/r/errors.result
@@ -27,7 +27,7 @@ create table t1 (a int(256));
ERROR 42000: Display width out of range for 'a' (max = 255)
set sql_mode='traditional';
create table t1 (a varchar(66000));
-ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead
+ERROR 42000: Column length too big for column 'a' (max = 65532); use BLOB or TEXT instead
set sql_mode=default;
CREATE TABLE t1 (a INT);
SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0)));
diff --git a/mysql-test/r/explain_json.result b/mysql-test/r/explain_json.result
index a46a3bcefa5..9e5515f3cfa 100644
--- a/mysql-test/r/explain_json.result
+++ b/mysql-test/r/explain_json.result
@@ -1524,12 +1524,12 @@ ANALYZE
"key_length": "5",
"used_key_parts": ["a"],
"ref": ["test.t3.a"],
- "r_loops": 0,
+ "r_loops": 1,
"rows": 1,
- "r_rows": null,
+ "r_rows": 10,
"r_total_time_ms": "REPLACED",
"filtered": 100,
- "r_filtered": null,
+ "r_filtered": 100,
"index_condition_bka": "((t4.b + 1) <= (t3.b + 1))"
},
"buffer_type": "flat",
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index 8bf948e0d72..df484363acc 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -742,6 +742,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 <expr_cache><'foo'>(<in_optimizer>('foo',<exists>(select `test`.`t1`.`f` from `test`.`t1` where ((<cache>(convert('foo' using latin1)) = `test`.`t1`.`f`) or isnull(`test`.`t1`.`f`)) having <is_not_null_test>(`test`.`t1`.`f`)))) 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_in.result b/mysql-test/r/func_in.result
index 1855fa72523..c80ea5d13e1 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -811,9 +811,17 @@ PREPARE s FROM "SELECT 1 FROM t1 WHERE 1 < ALL (SELECT @:= (1 IN (SELECT 1 FROM
EXECUTE s;
1
DROP TABLE t1;
+#
# End of 5.3 tests
#
-# Start of 10.0 tests
+create table t1 (a int);
+insert t1 values (1),(2),(3);
+select * from t1 where 1 in (a, name_const('a', null));
+a
+1
+drop table t1;
+#
+# End of 5.5 tests
#
#
# MDEV-10020 InnoDB NOT IN Query Crash When One Item Is NULL
@@ -829,7 +837,7 @@ SELECT * FROM t1 WHERE b NOT IN (NULL, '', 'A');
a b
DROP TABLE t1;
#
-# Start of 10.1 tests
+# End of 10.0 tests
#
#
# MDEV-8755 Equal field propagation is not performed any longer for the IN list when multiple comparison types
diff --git a/mysql-test/r/func_isnull.result b/mysql-test/r/func_isnull.result
index 2dbe3d036f9..88c5bfd5468 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 isnull(`test`.`t1`.`d1`))
+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 isnull(`test`.`t1`.`d1`))
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# End of 5.5 tests
+#
diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result
index 06ea89d9ab8..545d515176d 100644
--- a/mysql-test/r/func_misc.result
+++ b/mysql-test/r/func_misc.result
@@ -1429,3 +1429,34 @@ release_lock('test')
# -- Done.
+#
+# MDEV-13685 Can not replay binary log due to Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8mb4_general_ci,COERCIBLE) for operation 'concat'
+#
+SET NAMES utf8;
+SELECT COERCIBILITY(NAME_CONST('name','test'));
+COERCIBILITY(NAME_CONST('name','test'))
+2
+SELECT COERCIBILITY(NAME_CONST('name',TIME'00:00:00'));
+COERCIBILITY(NAME_CONST('name',TIME'00:00:00'))
+5
+SELECT COERCIBILITY(NAME_CONST('name',15));
+COERCIBILITY(NAME_CONST('name',15))
+5
+SELECT CONCAT(NAME_CONST('name',15),'오');
+CONCAT(NAME_CONST('name',15),'오')
+15오
+SET NAMES latin1;
+#
+# MDEV-14116 INET6_NTOA output is set as null to varchar(39) variable
+#
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE ip_full_addr varchar(39) DEFAULT "";
+SELECT INET6_NTOA(UNHEX('20000000000000000000000000000000')) into ip_full_addr;
+SELECT ip_full_addr;
+END;
+$$
+CALL p1();
+ip_full_addr
+2000::
+DROP PROCEDURE p1;
diff --git a/mysql-test/r/func_regexp_pcre.result b/mysql-test/r/func_regexp_pcre.result
index 7712b76e3ae..cda1c2e7e69 100644
--- a/mysql-test/r/func_regexp_pcre.result
+++ b/mysql-test/r/func_regexp_pcre.result
@@ -883,32 +883,32 @@ SELECT 1 FROM dual WHERE ('Alpha,Bravo,Charlie,Delta,Echo,Foxtrot,StrataCentral,
1
Warnings:
Warning 1139 Got error 'pcre_exec: recursion limit of NUM exceeded' from regexp
-SELECT CONCAT(REPEAT('100,',133),'101') RLIKE '^(([1-9][0-9]*),)*[1-9][0-9]*$';
-CONCAT(REPEAT('100,',133),'101') RLIKE '^(([1-9][0-9]*),)*[1-9][0-9]*$'
+SELECT CONCAT(REPEAT('100,',60),'101') RLIKE '^(([1-9][0-9]*),)*[1-9][0-9]*$';
+CONCAT(REPEAT('100,',60),'101') RLIKE '^(([1-9][0-9]*),)*[1-9][0-9]*$'
1
SELECT CONCAT(REPEAT('100,',200),'101') RLIKE '^(([1-9][0-9]*),)*[1-9][0-9]*$';
CONCAT(REPEAT('100,',200),'101') RLIKE '^(([1-9][0-9]*),)*[1-9][0-9]*$'
0
Warnings:
Warning 1139 Got error 'pcre_exec: recursion limit of NUM exceeded' from regexp
-SELECT REGEXP_INSTR(CONCAT(REPEAT('100,',133),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$');
-REGEXP_INSTR(CONCAT(REPEAT('100,',133),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$')
+SELECT REGEXP_INSTR(CONCAT(REPEAT('100,',60),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$');
+REGEXP_INSTR(CONCAT(REPEAT('100,',60),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$')
1
SELECT REGEXP_INSTR(CONCAT(REPEAT('100,',200),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$');
REGEXP_INSTR(CONCAT(REPEAT('100,',200),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$')
0
Warnings:
Warning 1139 Got error 'pcre_exec: recursion limit of NUM exceeded' from regexp
-SELECT LENGTH(REGEXP_SUBSTR(CONCAT(REPEAT('100,',133),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$'));
-LENGTH(REGEXP_SUBSTR(CONCAT(REPEAT('100,',133),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$'))
-535
+SELECT LENGTH(REGEXP_SUBSTR(CONCAT(REPEAT('100,',60),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$'));
+LENGTH(REGEXP_SUBSTR(CONCAT(REPEAT('100,',60),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$'))
+243
SELECT LENGTH(REGEXP_SUBSTR(CONCAT(REPEAT('100,',200),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$'));
LENGTH(REGEXP_SUBSTR(CONCAT(REPEAT('100,',200),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$'))
0
Warnings:
Warning 1139 Got error 'pcre_exec: recursion limit of NUM exceeded' from regexp
-SELECT LENGTH(REGEXP_REPLACE(CONCAT(REPEAT('100,',133),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$', ''));
-LENGTH(REGEXP_REPLACE(CONCAT(REPEAT('100,',133),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$', ''))
+SELECT LENGTH(REGEXP_REPLACE(CONCAT(REPEAT('100,',60),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$', ''));
+LENGTH(REGEXP_REPLACE(CONCAT(REPEAT('100,',60),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$', ''))
0
SELECT LENGTH(REGEXP_REPLACE(CONCAT(REPEAT('100,',200),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$', ''));
LENGTH(REGEXP_REPLACE(CONCAT(REPEAT('100,',200),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$', ''))
diff --git a/mysql-test/r/func_set.result b/mysql-test/r/func_set.result
index 96af966d367..23931bde1b5 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 d32efe642bb..3c84134d450 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -4547,6 +4547,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
#
#
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index 76daecf82a5..371dffdd3ae 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -2771,7 +2771,33 @@ SELECT 1 MOD ADDTIME( '13:58:57', '00:00:01' ) + 2;
1 MOD ADDTIME( '13:58:57', '00:00:01' ) + 2
3
#
-# Start of 10.0 tests
+# MDEV-11819 NO_ZERO_IN_DATE: Incorrect generated column value
+#
+SET sql_mode='NO_ZERO_IN_DATE';
+CREATE TABLE t1 (a TIME(6));
+INSERT INTO t1 SELECT timediff(timestamp'2008-12-31 23:59:59.000001',timestamp'2008-12-30 01:01:01.000002');
+SELECT * FROM t1;
+a
+46:58:57.999999
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+#
+# MDEV-13972 crash in Item_func_sec_to_time::get_date
+#
+DO TO_DAYS(SEC_TO_TIME(TIME(CEILING(UUID()))));
+DO TO_DAYS(SEC_TO_TIME(MAKEDATE('',RAND(~('')))));
+Warnings:
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect INTEGER value: ''
+Warning 1292 Truncated incorrect time value: '20000101'
+SELECT SEC_TO_TIME(MAKEDATE(0,RAND(~0)));
+SEC_TO_TIME(MAKEDATE(0,RAND(~0)))
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '20000101'
+#
+# End of 5.5 tests
#
#
# MDEV-8205 timediff returns null when comparing decimal time to time string value
diff --git a/mysql-test/r/gis-precise.result b/mysql-test/r/gis-precise.result
index 3824ba6afbb..89e5c237413 100644
--- a/mysql-test/r/gis-precise.result
+++ b/mysql-test/r/gis-precise.result
@@ -486,6 +486,25 @@ ST_Touches(ST_PolygonFromText('POLYGON((0 0,0 5,5 5,5 0,0 0))'),ST_PointFromText
select ST_Touches(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'));
ST_Touches(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'))
0
+SELECT ST_RELATE(
+ST_DIFFERENCE(
+GEOMETRYFROMTEXT('
+ MULTILINESTRING(
+ ( 12841 36140, 8005 31007, 26555 31075, 52765 41191,
+ 28978 6548, 45720 32057, 53345 3221 ),
+ ( 8304 59107, 25233 31592, 40502 25303, 8205 42940 ),
+ ( 7829 7305, 58841 56759, 64115 8512, 37562 54145, 2210 14701 ),
+ ( 20379 2805, 40807 27770, 28147 14883, 26439 29383, 55663 5086 ),
+ ( 35944 64702, 14433 23728, 49317 26241, 790 16941 )
+ )
+ '),
+GEOMETRYFROMTEXT('POINT(46061 13545)')
+),
+GEOMETRYFROMTEXT('POINT(4599 60359)'),
+'F*FFFF**F'
+ ) as relate_res;
+relate_res
+0
DROP TABLE IF EXISTS p1;
CREATE PROCEDURE p1(dist DOUBLE, geom TEXT)
BEGIN
diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result
index 29b3a0ea13b..eb730a8c954 100644
--- a/mysql-test/r/group_by.result
+++ b/mysql-test/r/group_by.result
@@ -2636,6 +2636,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 7fdec5a29cd..f7503597d32 100644
--- a/mysql-test/r/having.result
+++ b/mysql-test/r/having.result
@@ -698,6 +698,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 cee4797617f..2b5a536308a 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -2069,3 +2069,35 @@ Opened_tables 3
drop database mysqltest;
drop database db1;
set global sql_mode=default;
+USE test;
+#
+# End of 10.0 tests
+#
+#
+# Start of 10.1 tests
+#
+#
+# MDEV-13242 Wrong results for queries with row constructors and information_schema
+#
+CREATE TABLE tt1(c1 INT);
+CREATE TABLE tt2(c2 INT);
+SELECT count(*) FROM information_schema.columns WHERE table_schema='test' AND (table_name, column_name) IN (('tt1', 'c1'));
+count(*)
+1
+SELECT count(*) FROM information_schema.columns WHERE table_schema='test' AND (table_name, column_name) IN (('tt2', 'c2'));
+count(*)
+1
+SELECT count(*) FROM information_schema.columns WHERE table_schema='test' AND (table_name, column_name) IN (('tt1','c1'),('tt2', 'c2'));
+count(*)
+2
+SELECT count(*) FROM information_schema.columns WHERE table_schema='test' AND (table_name, column_name) IN (SELECT 'tt1','c1' FROM dual UNION SELECT 'tt2', 'c2' FROM dual);
+count(*)
+2
+SELECT count(*) FROM information_schema.columns WHERE table_schema='test' AND (table_name='tt1' AND column_name='c1') OR (table_name='tt2' AND column_name='c2');
+count(*)
+2
+SELECT column_name FROM information_schema.columns WHERE (table_name, column_name) IN (('tt1','c1'),('tt2', 'c2')) ORDER BY column_name;
+column_name
+c1
+c2
+DROP TABLE tt1, tt2;
diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result
index 59be24dbddc..5a0b6b10db8 100644
--- a/mysql-test/r/insert.result
+++ b/mysql-test/r/insert.result
@@ -717,3 +717,37 @@ insert ignore into t1 values (1,12);
Warnings:
Warning 1062 Duplicate entry '1' for key 'f1'
DROP TABLE t1;
+#
+# MDEV-13290 Assertion Assertion `!is_set() || (m_status == DA_OK_BULK
+# && is_bulk_op())' or `! is_set()' failed
+#
+SET @save_mode= @@sql_mode;
+SET sql_mode= 'STRICT_ALL_TABLES';
+CREATE TABLE t1 (f1 INT DEFAULT 0, f2 INT);
+CREATE ALGORITHM = MERGE VIEW v1 AS SELECT f1, f2 FROM t1 WHERE f1 = 'x' WITH CHECK OPTION;
+REPLACE INTO v1 SET f2 = 1;
+ERROR 22007: Truncated incorrect DOUBLE value: 'x'
+SELECT * from t1;
+f1 f2
+drop view v1;
+CREATE ALGORITHM = MERGE VIEW v1 AS SELECT f1, f2 FROM t1 WHERE f1 = cast('' as decimal) WITH CHECK OPTION;
+REPLACE INTO v1 SET f2 = 1;
+ERROR 22007: Truncated incorrect DECIMAL value: ''
+SELECT * from t1;
+f1 f2
+drop view v1;
+SELECT 0,0 INTO OUTFILE 't1.txt';
+CREATE ALGORITHM = MERGE VIEW v1 AS SELECT f1, f2 FROM t1 WHERE f1 = 'x' WITH CHECK OPTION;
+LOAD DATA INFILE 't1.txt' INTO TABLE v1;
+ERROR 22007: Truncated incorrect DOUBLE value: 'x'
+SELECT * from t1;
+f1 f2
+drop view v1;
+drop table t1;
+SET @@sql_mode= @save_mode;
+CREATE TABLE t1 (f INT);
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE f <=> 'foo' WITH CHECK OPTION;
+REPLACE INTO v1 SET f = NULL;
+ERROR HY000: CHECK OPTION failed 'test.v1'
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result
index a5a24455d9b..9eb1654e2cc 100644
--- a/mysql-test/r/join_cache.result
+++ b/mysql-test/r/join_cache.result
@@ -5864,6 +5864,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;
@@ -5880,7 +5938,7 @@ where c1 = c2-0 and c2 <= (select max(c3) from t3 where c3 = 2 and @counter:=@co
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
-2 UNCACHEABLE SUBQUERY t3 system NULL NULL NULL NULL 1
+2 UNCACHEABLE SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
set @counter=0;
select count(*) from t1 straight_join t2
where c1 = c2-0 and c2 <= (select max(c3) from t3 where c3 = 2 and @counter:=@counter+1);
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result
index 2109d75a14a..78cdfe6ecb1 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -2433,5 +2433,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 69f0c25bb15..861b224043c 100644
--- a/mysql-test/r/join_outer_jcl6.result
+++ b/mysql-test/r/join_outer_jcl6.result
@@ -2444,6 +2444,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/log_tables-big.result b/mysql-test/r/log_tables-big.result
index 1e189a7726f..4435d6d2723 100644
--- a/mysql-test/r/log_tables-big.result
+++ b/mysql-test/r/log_tables-big.result
@@ -1,3 +1,4 @@
+set @log_output.saved = @@global.log_output;
set @@global.log_output = 'TABLE';
set session long_query_time=10;
select get_lock('bug27638', 1);
@@ -7,25 +8,25 @@ set session long_query_time=1;
select get_lock('bug27638', 2);
get_lock('bug27638', 2)
0
-select if (query_time >= '00:00:01', 'OK', 'WRONG') as qt, sql_text from mysql.slow_log
+select if (query_time >= '00:00:01', 'OK', concat('WRONG: ',query_time)) as qt, sql_text from mysql.slow_log
where sql_text = 'select get_lock(\'bug27638\', 2)';
qt sql_text
OK select get_lock('bug27638', 2)
select get_lock('bug27638', 60);
get_lock('bug27638', 60)
0
-select if (query_time >= '00:00:59', 'OK', 'WRONG') as qt, sql_text from mysql.slow_log
+select if (query_time >= '00:00:59', 'OK', concat('WRONG: ',query_time)) as qt, sql_text from mysql.slow_log
where sql_text = 'select get_lock(\'bug27638\', 60)';
qt sql_text
OK select get_lock('bug27638', 60)
select get_lock('bug27638', 101);
get_lock('bug27638', 101)
0
-select if (query_time >= '00:01:40', 'OK', 'WRONG') as qt, sql_text from mysql.slow_log
+select if (query_time >= '00:01:40', 'OK', concat('WRONG: ',query_time)) as qt, sql_text from mysql.slow_log
where sql_text = 'select get_lock(\'bug27638\', 101)';
qt sql_text
OK select get_lock('bug27638', 101)
select release_lock('bug27638');
release_lock('bug27638')
1
-set @@global.log_output=default;
+set @@global.log_output = @log_output.saved;
diff --git a/mysql-test/r/mdev13607.result b/mysql-test/r/mdev13607.result
new file mode 100644
index 00000000000..08848bc645b
--- /dev/null
+++ b/mysql-test/r/mdev13607.result
@@ -0,0 +1,469 @@
+#
+# Bug mdev-13607: overflow of current_record_count
+#
+CREATE TABLE t1 (id INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),
+(11),(12),(13),(14),(15),(16),(17),(18),(19),(20),
+(21),(22),(23),(24),(25),(26),(27),(28),(29),(30),
+(31),(32),(33),(34),(35),(36),(37),(38),(39),(40),
+(41),(42),(43),(44),(45),(46),(47),(48),(49),(50);
+CREATE TABLE t2 (id INT) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1),(2);
+CREATE TABLE t3 (id INT) ENGINE=InnoDB;
+INSERT INTO t3 VALUES (1),(2);
+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
+explain SELECT * FROM
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_1
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_2
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_3
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_4
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_5
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_6
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_7
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_8
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_9
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_10
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_11
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_12
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_13
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_14
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_15
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_16
+;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY r1 ALL NULL NULL NULL NULL 2
+1 PRIMARY d1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY r2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY d2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY r3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY d3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY r4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY d4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY r5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY d5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY r6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY d6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY r7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY d7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY r8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY d8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY p1 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY p2 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY p3 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY p4 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY p5 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY p6 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY p7 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY p8 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY p9 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
+1 PRIMARY <derived4> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
+1 PRIMARY <derived5> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
+1 PRIMARY <derived6> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
+1 PRIMARY <derived7> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
+1 PRIMARY <derived8> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
+1 PRIMARY <derived9> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
+1 PRIMARY <derived10> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
+1 PRIMARY <derived11> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
+1 PRIMARY <derived12> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
+1 PRIMARY <derived13> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
+1 PRIMARY <derived14> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
+1 PRIMARY <derived15> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
+1 PRIMARY <derived16> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
+1 PRIMARY <derived17> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
+17 DERIVED r1 ALL NULL NULL NULL NULL 2
+17 DERIVED d1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+17 DERIVED r2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED d2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED r3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED d3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED r4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED d4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED r5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED d5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED r6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED d6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED r7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED d7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED r8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED d8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED p1 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED p2 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED p3 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED p4 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED p5 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED p6 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED p7 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED p8 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+17 DERIVED p9 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED r1 ALL NULL NULL NULL NULL 2
+16 DERIVED d1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+16 DERIVED r2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED d2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED r3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED d3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED r4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED d4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED r5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED d5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED r6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED d6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED r7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED d7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED r8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED d8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED p1 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED p2 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED p3 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED p4 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED p5 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED p6 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED p7 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED p8 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+16 DERIVED p9 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED r1 ALL NULL NULL NULL NULL 2
+15 DERIVED d1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+15 DERIVED r2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED d2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED r3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED d3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED r4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED d4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED r5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED d5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED r6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED d6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED r7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED d7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED r8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED d8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED p1 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED p2 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED p3 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED p4 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED p5 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED p6 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED p7 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED p8 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+15 DERIVED p9 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED r1 ALL NULL NULL NULL NULL 2
+14 DERIVED d1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+14 DERIVED r2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED d2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED r3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED d3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED r4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED d4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED r5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED d5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED r6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED d6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED r7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED d7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED r8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED d8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED p1 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED p2 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED p3 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED p4 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED p5 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED p6 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED p7 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED p8 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+14 DERIVED p9 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED r1 ALL NULL NULL NULL NULL 2
+13 DERIVED d1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+13 DERIVED r2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED d2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED r3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED d3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED r4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED d4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED r5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED d5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED r6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED d6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED r7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED d7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED r8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED d8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED p1 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED p2 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED p3 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED p4 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED p5 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED p6 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED p7 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED p8 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+13 DERIVED p9 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED r1 ALL NULL NULL NULL NULL 2
+12 DERIVED d1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+12 DERIVED r2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED d2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED r3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED d3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED r4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED d4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED r5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED d5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED r6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED d6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED r7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED d7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED r8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED d8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED p1 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED p2 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED p3 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED p4 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED p5 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED p6 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED p7 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED p8 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+12 DERIVED p9 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED r1 ALL NULL NULL NULL NULL 2
+11 DERIVED d1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+11 DERIVED r2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED d2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED r3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED d3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED r4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED d4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED r5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED d5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED r6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED d6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED r7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED d7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED r8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED d8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED p1 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED p2 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED p3 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED p4 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED p5 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED p6 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED p7 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED p8 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+11 DERIVED p9 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED r1 ALL NULL NULL NULL NULL 2
+10 DERIVED d1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+10 DERIVED r2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED d2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED r3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED d3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED r4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED d4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED r5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED d5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED r6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED d6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED r7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED d7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED r8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED d8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED p1 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED p2 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED p3 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED p4 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED p5 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED p6 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED p7 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED p8 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+10 DERIVED p9 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED r1 ALL NULL NULL NULL NULL 2
+9 DERIVED d1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+9 DERIVED r2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED d2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED r3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED d3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED r4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED d4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED r5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED d5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED r6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED d6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED r7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED d7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED r8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED d8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED p1 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED p2 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED p3 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED p4 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED p5 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED p6 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED p7 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED p8 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+9 DERIVED p9 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED r1 ALL NULL NULL NULL NULL 2
+8 DERIVED d1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+8 DERIVED r2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED d2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED r3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED d3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED r4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED d4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED r5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED d5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED r6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED d6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED r7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED d7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED r8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED d8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED p1 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED p2 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED p3 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED p4 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED p5 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED p6 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED p7 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED p8 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+8 DERIVED p9 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED r1 ALL NULL NULL NULL NULL 2
+7 DERIVED d1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+7 DERIVED r2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED d2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED r3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED d3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED r4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED d4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED r5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED d5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED r6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED d6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED r7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED d7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED r8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED d8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED p1 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED p2 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED p3 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED p4 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED p5 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED p6 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED p7 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED p8 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+7 DERIVED p9 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED r1 ALL NULL NULL NULL NULL 2
+6 DERIVED d1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+6 DERIVED r2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED d2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED r3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED d3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED r4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED d4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED r5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED d5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED r6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED d6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED r7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED d7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED r8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED d8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED p1 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED p2 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED p3 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED p4 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED p5 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED p6 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED p7 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED p8 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+6 DERIVED p9 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED r1 ALL NULL NULL NULL NULL 2
+5 DERIVED d1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+5 DERIVED r2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED d2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED r3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED d3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED r4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED d4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED r5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED d5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED r6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED d6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED r7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED d7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED r8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED d8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED p1 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED p2 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED p3 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED p4 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED p5 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED p6 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED p7 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED p8 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+5 DERIVED p9 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED r1 ALL NULL NULL NULL NULL 2
+4 DERIVED d1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+4 DERIVED r2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED d2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED r3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED d3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED r4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED d4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED r5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED d5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED r6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED d6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED r7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED d7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED r8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED d8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED p1 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED p2 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED p3 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED p4 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED p5 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED p6 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED p7 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED p8 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+4 DERIVED p9 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED r1 ALL NULL NULL NULL NULL 2
+3 DERIVED d1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+3 DERIVED r2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED d2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED r3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED d3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED r4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED d4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED r5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED d5 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED r6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED d6 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED r7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED d7 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED r8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED d8 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED p1 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED p2 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED p3 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED p4 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED p5 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED p6 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED p7 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED p8 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+3 DERIVED p9 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
+DROP TABLE t1,t2,t3;
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 36e196497e5..97c391566dd 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -2167,7 +2167,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
@@ -2204,7 +2204,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 9b6adb214eb..e114f424ede 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -1699,7 +1699,14 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (v varchar(65535));
-ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
+Warnings:
+Note 1246 Converting column 'v' from VARCHAR to TEXT
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` text
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
set storage_engine=MyISAM;
set @save_concurrent_insert=@@concurrent_insert;
set global concurrent_insert=1;
diff --git a/mysql-test/r/myisam_optimize.result b/mysql-test/r/myisam_optimize.result
index ae0c5b59d06..36faba5eaa9 100644
--- a/mysql-test/r/myisam_optimize.result
+++ b/mysql-test/r/myisam_optimize.result
@@ -22,3 +22,17 @@ a left(b,10)
4 CCCCCCCCCC
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/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result
index 94aaee0c574..8463c3074a0 100644
--- a/mysql-test/r/mysqlbinlog.result
+++ b/mysql-test/r/mysqlbinlog.result
@@ -1250,3 +1250,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/mysqld--help.result b/mysql-test/r/mysqld--help.result
index f9aa90ab0ab..e84921bfa0a 100644
--- a/mysql-test/r/mysqld--help.result
+++ b/mysql-test/r/mysqld--help.result
@@ -1177,7 +1177,7 @@ character-sets-dir MYSQL_CHARSETSDIR/
chroot (No default value)
completion-type NO_CHAIN
concurrent-insert AUTO
-console FALSE
+console TRUE
date-format %Y-%m-%d
datetime-format %Y-%m-%d %H:%i:%s
deadlock-search-depth-long 15
diff --git a/mysql-test/r/mysqldump-nl.result b/mysql-test/r/mysqldump-nl.result
index 829bf980103..d397453b071 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/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/old-mode.result b/mysql-test/r/old-mode.result
index c2ee3324ede..b9a3edd4e94 100644
--- a/mysql-test/r/old-mode.result
+++ b/mysql-test/r/old-mode.result
@@ -127,3 +127,48 @@ Warning 1264 Out of range value for column 'a' at row 1
Warning 1264 Out of range value for column 'b' at row 1
DROP TABLE t1;
SET @@global.mysql56_temporal_format=DEFAULT;
+set time_zone='Europe/Moscow';
+set global mysql56_temporal_format=false;
+create table t1 (a timestamp);
+set timestamp=1288477526;
+insert t1 values (null);
+set timestamp=1288481126;
+insert t1 values (null);
+select a, unix_timestamp(a) from t1;
+a unix_timestamp(a)
+2010-10-31 02:25:26 1288477526
+2010-10-31 02:25:26 1288481126
+set global mysql56_temporal_format=true;
+select a, unix_timestamp(a) from t1;
+a unix_timestamp(a)
+2010-10-31 02:25:26 1288477526
+2010-10-31 02:25:26 1288481126
+alter table t1 modify a timestamp;
+select a, unix_timestamp(a) from t1;
+a unix_timestamp(a)
+2010-10-31 02:25:26 1288477526
+2010-10-31 02:25:26 1288481126
+drop table t1;
+set global mysql56_temporal_format=false;
+create table t1 (a timestamp);
+set timestamp=1288477526;
+insert t1 values (null);
+set timestamp=1288481126;
+insert t1 values (null);
+select a, unix_timestamp(a) from t1;
+a unix_timestamp(a)
+2010-10-31 02:25:26 1288477526
+2010-10-31 02:25:26 1288481126
+set global mysql56_temporal_format=true;
+select a, unix_timestamp(a) from t1;
+a unix_timestamp(a)
+2010-10-31 02:25:26 1288477526
+2010-10-31 02:25:26 1288481126
+create table t2 (a timestamp);
+insert t2 select a from t1;
+select a, unix_timestamp(a) from t2;
+a unix_timestamp(a)
+2010-10-31 02:25:26 1288477526
+2010-10-31 02:25:26 1288481126
+drop table t1, t2;
+set time_zone=DEFAULT;
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index 71aa32f0cee..4cd9aebdf49 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -2950,6 +2950,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
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result
index 49ebd1f5979..53f89c9cd55 100644
--- a/mysql-test/r/partition.result
+++ b/mysql-test/r/partition.result
@@ -2634,8 +2634,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_datatype.result b/mysql-test/r/partition_datatype.result
index fa58df3dec3..eb09d81969f 100644
--- a/mysql-test/r/partition_datatype.result
+++ b/mysql-test/r/partition_datatype.result
@@ -314,12 +314,14 @@ bbbb
drop table t1;
create table t1 (a varchar(3070)) partition by key (a);
ERROR HY000: The total length of the partitioning fields is too large
+create table t1 (a varchar(65532) not null) partition by key (a);
+ERROR HY000: The total length of the partitioning fields is too large
create table t1 (a varchar(65533)) partition by key (a);
-ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
+ERROR HY000: A BLOB field is not allowed in partition function
create table t1 (a varchar(65534) not null) partition by key (a);
-ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
+ERROR HY000: A BLOB field is not allowed in partition function
create table t1 (a varchar(65535)) partition by key (a);
-ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
+ERROR HY000: A BLOB field is not allowed in partition function
create table t1 (a bit(27), primary key (a)) engine=myisam
partition by hash (a)
(partition p0, partition p1, partition p2);
diff --git a/mysql-test/r/partition_symlink.result b/mysql-test/r/partition_symlink.result
index 2588a9b10e4..5809512083d 100644
--- a/mysql-test/r/partition_symlink.result
+++ b/mysql-test/r/partition_symlink.result
@@ -33,11 +33,15 @@ t2 CREATE TABLE `t2` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/tmp/' INDEX DIRECTORY='MYSQLTEST_VARDIR/tmp/'
INSERT INTO t1 VALUES (0), (1), (2);
ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE t2;
-ERROR HY000: Tables have different definitions
ALTER TABLE t1 EXCHANGE PARTITION p2 WITH TABLE t2;
ERROR HY000: Tables have different definitions
+SELECT * FROM t1;
+a
+1
+2
SELECT * FROM t2;
a
+0
DROP TABLE t1, t2;
# Creating two non colliding tables mysqltest2.t1 and test.t1
# test.t1 have partitions in mysqltest2-directory!
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/ps.result b/mysql-test/r/ps.result
index b24fe55e1b2..26e7bc37363 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -4189,4 +4189,165 @@ Warnings:
Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`c` AS `c` from `test`.`t1` where 0
deallocate prepare stmt2;
drop table t1;
+#
+# MDEV-9208: Function->Function->View = Mysqld segfault
+# (Server crashes in Dependency_marker::visit_field on 2nd
+# execution with merged subquery)
+#
+CREATE TABLE t1 (i1 INT);
+insert into t1 values(1),(2);
+CREATE TABLE t2 (i2 INT);
+insert into t2 values(1),(2);
+prepare stmt from "
+ select 1 from (
+ select
+ if (i1<0, 0, 0) as f1,
+ (select f1) as f2
+ from t1, t2
+ ) sq
+";
+execute stmt;
+1
+1
+1
+1
+1
+execute stmt;
+1
+1
+1
+1
+1
+drop table t1,t2;
+#
+# MDEV-9619: Assertion `null_ref_table' failed in virtual
+# table_map Item_direct_view_ref::used_tables() const on 2nd
+# execution of PS
+#
+CREATE TABLE t1 (f1 VARCHAR(10)) ENGINE=MyISAM;
+CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES ('a'),('b');
+CREATE TABLE t2 (f2 VARCHAR(10)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('c'),('d');
+PREPARE stmt FROM "SELECT * FROM v1 WHERE f1 = SOME ( SELECT f2 FROM t2 )";
+EXECUTE stmt;
+f1
+EXECUTE stmt;
+f1
+insert into t1 values ('c');
+EXECUTE stmt;
+f1
+c
+EXECUTE stmt;
+f1
+c
+deallocate prepare stmt;
+drop view v1;
+drop table t1,t2;
+CREATE TABLE t1 (f1 VARCHAR(10)) ENGINE=MyISAM;
+CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES ('a'),('b');
+CREATE TABLE t2 (f2 VARCHAR(10)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('c'),('d');
+PREPARE stmt FROM "SELECT * FROM v1 WHERE (f1,f1) = SOME ( SELECT f2,f2 FROM t2 )";
+EXECUTE stmt;
+f1
+EXECUTE stmt;
+f1
+insert into t1 values ('c');
+EXECUTE stmt;
+f1
+c
+EXECUTE stmt;
+f1
+c
+deallocate prepare stmt;
+drop view v1;
+drop table t1,t2;
+CREATE TABLE t1 (column1 INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (3),(9);
+CREATE TABLE t2 (column2 INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1),(4);
+CREATE TABLE t3 (column3 INT) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (6),(8);
+CREATE TABLE t4 (column4 INT) ENGINE=MyISAM;
+INSERT INTO t4 VALUES (2),(5);
+PREPARE stmt FROM "
+SELECT (
+ SELECT MAX( table1.column1 ) AS field1
+ FROM t1 AS table1
+ WHERE (111,table3.column3) IN ( SELECT 111,table2.column2 AS field2 FROM t2 AS table2 )
+) AS sq
+FROM t3 AS table3, t4 AS table4 GROUP BY sq
+";
+EXECUTE stmt;
+sq
+NULL
+EXECUTE stmt;
+sq
+NULL
+deallocate prepare stmt;
+drop table t1,t2,t3,t4;
+create table t1 (a int, b int, c int);
+create table t2 (x int, y int, z int);
+create table t3 as select * from t1;
+insert into t1 values (1,2,3),(4,5,6),(100,200,300),(400,500,600);
+insert into t2 values (1,2,3),(7,8,9),(100,200,300),(400,500,600);
+insert into t3 values (1,2,3),(11,12,13),(100,0,0),(400,500,600);
+set @optimizer_switch_save=@@optimizer_switch;
+set @join_cache_level_save=@@join_cache_level;
+set optimizer_switch='materialization=off';
+set join_cache_level=0;
+select * from t1 where (select a,b from t3 where t3.c=t1.c) in (select x,y from t2 where t1.c= t2.z);
+a b c
+1 2 3
+400 500 600
+prepare stmt from "select * from t1 where (select a,b from t3 where t3.c=t1.c) in (select x,y from t2 where t1.c= t2.z)";
+EXECUTE stmt;
+a b c
+1 2 3
+400 500 600
+EXECUTE stmt;
+a b c
+1 2 3
+400 500 600
+create view v1 as select * from t1;
+create view v2 as select * from t2;
+create view v3 as select * from t3;
+select * from v1 where (select a,b from v3 where v3.c=v1.c) in (select x,y from v2 where v1.c= v2.z);
+a b c
+1 2 3
+400 500 600
+prepare stmt from "select * from v1 where (select a,b from v3 where v3.c=v1.c) in (select x,y from v2 where v1.c= v2.z)";
+EXECUTE stmt;
+a b c
+1 2 3
+400 500 600
+EXECUTE stmt;
+a b c
+1 2 3
+400 500 600
+set optimizer_switch=@optimizer_switch_save;
+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
diff --git a/mysql-test/r/query_cache_debug.result b/mysql-test/r/query_cache_debug.result
index 01c642b325b..b3070761d9c 100644
--- a/mysql-test/r/query_cache_debug.result
+++ b/mysql-test/r/query_cache_debug.result
@@ -221,3 +221,29 @@ 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;
+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;
+set debug_sync="now WAIT_FOR parked";
+SET GLOBAL query_cache_type= 0;
+set debug_sync="now SIGNAL go";
+id
+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_vs_index_merge.result b/mysql-test/r/range_vs_index_merge.result
index 6813c40a5cf..bc46a4fdd0b 100644
--- a/mysql-test/r/range_vs_index_merge.result
+++ b/mysql-test/r/range_vs_index_merge.result
@@ -1807,4 +1807,85 @@ id state capital
7 Pennsylvania Harrisburg
8 Virginia Richmond
DROP TABLE t1;
+#
+# mdev-11574: do not build index merge of two indexes when
+# one index is an infix of the other index
+#
+set names utf8;
+CREATE DATABASE world;
+use world;
+CREATE TABLE Country (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+Population int(11) NOT NULL default '0',
+Capital int(11) default NULL,
+PRIMARY KEY (Code),
+UNIQUE INDEX (Name)
+);
+CREATE TABLE City (
+ID int(11) NOT NULL auto_increment,
+Name char(35) NOT NULL default '',
+Country char(3) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID),
+INDEX (Population),
+INDEX (Country)
+);
+CREATE TABLE CountryLanguage (
+Country char(3) NOT NULL default '',
+Language char(30) NOT NULL default '',
+Percentage float(3,1) NOT NULL default '0.0',
+PRIMARY KEY (Country, Language),
+INDEX (Percentage)
+);
+DROP INDEX Country ON City;
+CREATE INDEX CountryName ON City(Country,Name);
+CREATE INDEX Name ON City(Name);
+select * from City
+where
+Country='FIN' AND Name IN ('Lahti','Imatra') OR
+Country='RUS' AND Name IN ('St Petersburg', 'Moscow') OR
+Country='SWE' AND Name IN ('Stockholm', 'Uppsala') OR
+Country='DEU' AND Name IN ('Berlin', 'Bonn') OR
+Country='BEL' AND Name IN ('Antwerpen', 'Gent') OR
+Country='PRT' AND Name IN ('Braga', 'Porto') OR
+Country='FRA' AND Name IN ('Paris', 'Marcel') OR
+Country='POL' AND Name IN ('Warszawa', 'Wroclaw') OR
+Country='NOR' AND Name IN ('Oslo', 'Bergen') OR
+Country='ITA' AND Name IN ('Napoli', 'Venezia');
+ID Name Country Population
+175 Antwerpen BEL 446525
+176 Gent BEL 224180
+3068 Berlin DEU 3386667
+3087 Bonn DEU 301048
+3242 Lahti FIN 96921
+2974 Paris FRA 2125246
+1466 Napoli ITA 1002619
+1474 Venezia ITA 277305
+2808 Bergen NOR 230948
+2807 Oslo NOR 508726
+2928 Warszawa POL 1615369
+2931 Wroclaw POL 636765
+2918 Braga PRT 90535
+2915 Porto PRT 273060
+3580 Moscow RUS 8389200
+3581 St Petersburg RUS 4694000
+3048 Stockholm SWE 750348
+3051 Uppsala SWE 189569
+explain select * from City
+where
+Country='FIN' AND Name IN ('Lahti','Imatra') OR
+Country='RUS' AND Name IN ('St Petersburg', 'Moscow') OR
+Country='SWE' AND Name IN ('Stockholm', 'Uppsala') OR
+Country='DEU' AND Name IN ('Berlin', 'Bonn') OR
+Country='BEL' AND Name IN ('Antwerpen', 'Gent') OR
+Country='PRT' AND Name IN ('Braga', 'Porto') OR
+Country='FRA' AND Name IN ('Paris', 'Marcel') OR
+Country='POL' AND Name IN ('Warszawa', 'Wroclaw') OR
+Country='NOR' AND Name IN ('Oslo', 'Bergen') OR
+Country='ITA' AND Name IN ('Napoli', 'Venezia');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range CountryName,Name CountryName 38 NULL 22 Using index condition; Using where
+DROP DATABASE world;
set session optimizer_switch='index_merge_sort_intersection=default';
diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result
index 13fbc0ac3ef..a6ec200538d 100644
--- a/mysql-test/r/range_vs_index_merge_innodb.result
+++ b/mysql-test/r/range_vs_index_merge_innodb.result
@@ -1808,5 +1808,86 @@ id state capital
7 Pennsylvania Harrisburg
8 Virginia Richmond
DROP TABLE t1;
+#
+# mdev-11574: do not build index merge of two indexes when
+# one index is an infix of the other index
+#
+set names utf8;
+CREATE DATABASE world;
+use world;
+CREATE TABLE Country (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+Population int(11) NOT NULL default '0',
+Capital int(11) default NULL,
+PRIMARY KEY (Code),
+UNIQUE INDEX (Name)
+);
+CREATE TABLE City (
+ID int(11) NOT NULL auto_increment,
+Name char(35) NOT NULL default '',
+Country char(3) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID),
+INDEX (Population),
+INDEX (Country)
+);
+CREATE TABLE CountryLanguage (
+Country char(3) NOT NULL default '',
+Language char(30) NOT NULL default '',
+Percentage float(3,1) NOT NULL default '0.0',
+PRIMARY KEY (Country, Language),
+INDEX (Percentage)
+);
+DROP INDEX Country ON City;
+CREATE INDEX CountryName ON City(Country,Name);
+CREATE INDEX Name ON City(Name);
+select * from City
+where
+Country='FIN' AND Name IN ('Lahti','Imatra') OR
+Country='RUS' AND Name IN ('St Petersburg', 'Moscow') OR
+Country='SWE' AND Name IN ('Stockholm', 'Uppsala') OR
+Country='DEU' AND Name IN ('Berlin', 'Bonn') OR
+Country='BEL' AND Name IN ('Antwerpen', 'Gent') OR
+Country='PRT' AND Name IN ('Braga', 'Porto') OR
+Country='FRA' AND Name IN ('Paris', 'Marcel') OR
+Country='POL' AND Name IN ('Warszawa', 'Wroclaw') OR
+Country='NOR' AND Name IN ('Oslo', 'Bergen') OR
+Country='ITA' AND Name IN ('Napoli', 'Venezia');
+ID Name Country Population
+175 Antwerpen BEL 446525
+176 Gent BEL 224180
+3068 Berlin DEU 3386667
+3087 Bonn DEU 301048
+3242 Lahti FIN 96921
+2974 Paris FRA 2125246
+1466 Napoli ITA 1002619
+1474 Venezia ITA 277305
+2808 Bergen NOR 230948
+2807 Oslo NOR 508726
+2928 Warszawa POL 1615369
+2931 Wroclaw POL 636765
+2918 Braga PRT 90535
+2915 Porto PRT 273060
+3580 Moscow RUS 8389200
+3581 St Petersburg RUS 4694000
+3048 Stockholm SWE 750348
+3051 Uppsala SWE 189569
+explain select * from City
+where
+Country='FIN' AND Name IN ('Lahti','Imatra') OR
+Country='RUS' AND Name IN ('St Petersburg', 'Moscow') OR
+Country='SWE' AND Name IN ('Stockholm', 'Uppsala') OR
+Country='DEU' AND Name IN ('Berlin', 'Bonn') OR
+Country='BEL' AND Name IN ('Antwerpen', 'Gent') OR
+Country='PRT' AND Name IN ('Braga', 'Porto') OR
+Country='FRA' AND Name IN ('Paris', 'Marcel') OR
+Country='POL' AND Name IN ('Warszawa', 'Wroclaw') OR
+Country='NOR' AND Name IN ('Oslo', 'Bergen') OR
+Country='ITA' AND Name IN ('Napoli', 'Venezia');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range CountryName,Name CountryName 38 NULL 20 Using index condition; Using where
+DROP DATABASE world;
set session optimizer_switch='index_merge_sort_intersection=default';
SET SESSION STORAGE_ENGINE=DEFAULT;
diff --git a/mysql-test/r/read_only.result b/mysql-test/r/read_only.result
index 0673acacfa9..0640360f4f5 100644
--- a/mysql-test/r/read_only.result
+++ b/mysql-test/r/read_only.result
@@ -51,6 +51,9 @@ delete t1 from t1,t3 where t1.a=t3.a;
drop table t1;
insert into t1 values(1);
ERROR HY000: The MariaDB server is running with the --read-only option so it cannot execute this statement
+drop temporary table if exists t1;
+Warnings:
+Note 1051 Unknown table 'test.t1'
connection default;
set global read_only=0;
lock table t1 write;
diff --git a/mysql-test/r/repair.result b/mysql-test/r/repair.result
index 79ee0c7a9b8..8d48d2f8848 100644
--- a/mysql-test/r/repair.result
+++ b/mysql-test/r/repair.result
@@ -114,7 +114,7 @@ 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
@@ -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/show_check.result b/mysql-test/r/show_check.result
index 654b00d68ae..585ab305420 100644
--- a/mysql-test/r/show_check.result
+++ b/mysql-test/r/show_check.result
@@ -962,7 +962,7 @@ def information_schema COLUMNS COLUMNS TABLE_CATALOG TABLE_CATALOG 253 1536 3 N
def information_schema COLUMNS COLUMNS TABLE_SCHEMA TABLE_SCHEMA 253 192 4 N 1 0 33
def information_schema COLUMNS COLUMNS TABLE_NAME TABLE_NAME 253 192 2 N 1 0 33
def information_schema COLUMNS COLUMNS COLUMN_NAME COLUMN_NAME 253 192 1 N 1 0 33
-def information_schema COLUMNS COLUMNS COLUMN_DEFAULT COLUMN_DEFAULT 252 589815 0 Y 16 0 33
+def information_schema COLUMNS COLUMNS COLUMN_DEFAULT COLUMN_DEFAULT 252 589788 0 Y 16 0 33
def information_schema COLUMNS COLUMNS IS_NULLABLE IS_NULLABLE 253 9 2 N 1 0 33
def information_schema COLUMNS COLUMNS DATA_TYPE DATA_TYPE 253 192 3 N 1 0 33
def information_schema COLUMNS COLUMNS CHARACTER_SET_NAME CHARACTER_SET_NAME 253 96 0 Y 0 0 33
@@ -987,7 +987,7 @@ def information_schema COLUMNS COLUMNS COLUMN_NAME Field 253 192 1 N 1 0 33
def information_schema COLUMNS COLUMNS COLUMN_TYPE Type 252 589815 7 N 17 0 33
def information_schema COLUMNS COLUMNS IS_NULLABLE Null 253 9 2 N 1 0 33
def information_schema COLUMNS COLUMNS COLUMN_KEY Key 253 9 3 N 1 0 33
-def information_schema COLUMNS COLUMNS COLUMN_DEFAULT Default 252 589815 0 Y 16 0 33
+def information_schema COLUMNS COLUMNS COLUMN_DEFAULT Default 252 589788 0 Y 16 0 33
def information_schema COLUMNS COLUMNS EXTRA Extra 253 81 0 N 1 0 33
Field Type Null Key Default Extra
c int(11) NO PRI NULL
diff --git a/mysql-test/r/show_function_with_pad_char_to_full_length.result b/mysql-test/r/show_function_with_pad_char_to_full_length.result
new file mode 100644
index 00000000000..785cab7b3e6
--- /dev/null
+++ b/mysql-test/r/show_function_with_pad_char_to_full_length.result
@@ -0,0 +1,24 @@
+create function f() returns int return 1;
+show function status;
+Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
+T f T T T T T T T T T
+set sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';
+show function status;
+Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
+T f T T T T T T T T T
+drop function f;
+select @@sql_mode;
+@@sql_mode
+PAD_CHAR_TO_FULL_LENGTH
+create function f() returns int return 1;
+select ROUTINE_NAME from information_schema.ROUTINES where ROUTINE_NAME='f';
+ROUTINE_NAME
+f
+set sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';
+select ROUTINE_NAME from information_schema.ROUTINES where ROUTINE_NAME='f';
+ROUTINE_NAME
+f
+drop function f;
+select @@sql_mode;
+@@sql_mode
+PAD_CHAR_TO_FULL_LENGTH
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index d9b5dfd5a1f..57d704c36be 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -8079,4 +8079,167 @@ CALL sp1();
CALL sp1();
drop user 'foo'@'%';
drop procedure sp1;
+#
+# MDEV-10972: Insert from select / view / union --
+# repeatable crash in 10.1, 10.2 Linux/Mac/Windows
+#
+create table t (id int auto_increment primary key);
+insert into t values (9494),(9495),(9496),(9497),(9498),(9499),(9500),(9501),(9502),(9503);
+create VIEW v AS
+select id from t
+union
+select id from t
+;
+drop procedure if exists p;
+Warnings:
+Note 1305 PROCEDURE test.p does not exist
+create procedure p()
+insert into tmp_t select t.id from (
+select id from v
+union
+select id from v
+) sq
+inner join t on (sq.id = t.id);
+CALL p();
+ERROR 42S02: Table 'test.tmp_t' doesn't exist
+create table tmp_t (id int null);
+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
diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result
index 9dcd5975411..68efe3df8d0 100644
--- a/mysql-test/r/strict.result
+++ b/mysql-test/r/strict.result
@@ -1240,9 +1240,9 @@ Warning 1364 Field 'i' doesn't have a default value
DROP TABLE t1;
set @@sql_mode='traditional';
create table t1(a varchar(65537));
-ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead
+ERROR 42000: Column length too big for column 'a' (max = 65532); use BLOB or TEXT instead
create table t1(a varbinary(65537));
-ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead
+ERROR 42000: Column length too big for column 'a' (max = 65532); use BLOB or TEXT instead
set @@sql_mode='traditional';
create table t1(a int, b date not null);
alter table t1 modify a bigint unsigned not null;
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index cf542a5913e..40f936fb3b4 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -7210,6 +7210,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_exists2in.result b/mysql-test/r/subselect_exists2in.result
index 5deb2dfa9c5..d47e446fe8f 100644
--- a/mysql-test/r/subselect_exists2in.result
+++ b/mysql-test/r/subselect_exists2in.result
@@ -934,5 +934,42 @@ f2
foo
set optimizer_switch= @optimizer_switch_save;
DROP TABLE t1;
+#
+# MDEV-14164: Unknown column error when adding aggregate to function
+# in oracle style procedure FOR loop
+#
+CREATE TABLE t1(id INT, val INT);
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE cur1 CURSOR FOR SELECT * FROM (
+SELECT DISTINCT id FROM t1) a
+WHERE NOT EXISTS (SELECT * FROM ( SELECT id FROM t1) b
+WHERE a.id=b.id);
+OPEN cur1;
+CLOSE cur1;
+OPEN cur1;
+CLOSE cur1;
+END;
+//
+CALL p1();
+DROP PROCEDURE p1;
+DROP TABLE t1;
+CREATE TABLE t1(id INT, val INT);
+CREATE PROCEDURE p1()
+BEGIN
+SELECT * FROM (SELECT DISTINCT id FROM t1) a
+WHERE NOT a.id IN (SELECT b.id FROM t1 b);
+SELECT * FROM (SELECT DISTINCT id FROM t1) a
+WHERE NOT EXISTS (SELECT * FROM t1 b WHERE a.id=b.id);
+END;
+//
+CALL p1();
+id
+id
+CALL p1();
+id
+id
+DROP PROCEDURE p1;
+DROP TABLE t1;
# End of 10.0 tests
set optimizer_switch=default;
diff --git a/mysql-test/r/subselect_mat_cost_bugs.result b/mysql-test/r/subselect_mat_cost_bugs.result
index 57b0526c6a3..df6b543bab8 100644
--- a/mysql-test/r/subselect_mat_cost_bugs.result
+++ b/mysql-test/r/subselect_mat_cost_bugs.result
@@ -502,3 +502,20 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index idx idx 5 NULL 5 Using where; Using index
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
drop table t1;
+#
+# MDEV-13135: subquery with ON expression subject to
+# semi-join optimizations
+#
+CREATE TABLE t1 (a INT);
+CREATE ALGORITHM=MERGE VIEW v1 AS SELECT a AS v_a FROM t1;
+INSERT INTO t1 VALUES (1),(3);
+CREATE TABLE t2 (b INT, KEY(b));
+INSERT INTO t2 VALUES (3),(4);
+SELECT * FROM t1 WHERE a NOT IN (
+SELECT b FROM t2 INNER JOIN v1 ON (b IN ( SELECT a FROM t1 ))
+WHERE v_a = b
+);
+a
+1
+DROP VIEW v1;
+DROP TABLE t1,t2;
diff --git a/mysql-test/r/subselect_no_exists_to_in.result b/mysql-test/r/subselect_no_exists_to_in.result
index a3a6e2ab4c0..a23820820ef 100644
--- a/mysql-test/r/subselect_no_exists_to_in.result
+++ b/mysql-test/r/subselect_no_exists_to_in.result
@@ -7210,6 +7210,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 11457ccbb02..baa74307f89 100644
--- a/mysql-test/r/subselect_no_mat.result
+++ b/mysql-test/r/subselect_no_mat.result
@@ -7203,6 +7203,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 076953c210f..039f2fe1a9e 100644
--- a/mysql-test/r/subselect_no_opts.result
+++ b/mysql-test/r/subselect_no_opts.result
@@ -7201,6 +7201,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 b5c7e9bfdbd..0ce77bbb376 100644
--- a/mysql-test/r/subselect_no_scache.result
+++ b/mysql-test/r/subselect_no_scache.result
@@ -7216,6 +7216,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 52da5f1cec3..574e78122f1 100644
--- a/mysql-test/r/subselect_no_semijoin.result
+++ b/mysql-test/r/subselect_no_semijoin.result
@@ -7201,6 +7201,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/symlink.result b/mysql-test/r/symlink.result
index 803b43dec87..63fc37300b2 100644
--- a/mysql-test/r/symlink.result
+++ b/mysql-test/r/symlink.result
@@ -227,3 +227,15 @@ DROP DATABASE x;
CREATE TABLE test.t1(id INT(11)) ENGINE MYISAM
DATA DIRECTORY "MYSQLTEST_VARDIR/tmp";
DROP TABLE test.t1;
+use test;
+create table t1(c1 int, c2 int, c3 varchar(100)) engine=MyISAM data directory='MYSQL_TMP_DIR' index directory = 'MYSQL_TMP_DIR';
+insert t1 values (1,2,3), (2,3,4), (3,4,5), (4,5,6), (5,6,7), (6,7,8), (7,8,9);
+alter online table t1 delay_key_write=1;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) DEFAULT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `c3` varchar(100) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 DATA DIRECTORY='MYSQL_TMP_DIR/' INDEX DIRECTORY='MYSQL_TMP_DIR/'
+drop table t1;
diff --git a/mysql-test/r/tc_heuristic_recover.result b/mysql-test/r/tc_heuristic_recover.result
new file mode 100644
index 00000000000..f5a295cbd9f
--- /dev/null
+++ b/mysql-test/r/tc_heuristic_recover.result
@@ -0,0 +1,37 @@
+call mtr.add_suppression("Can't init tc log");
+call mtr.add_suppression("Found 1 prepared transactions!");
+call mtr.add_suppression("Aborting");
+set debug_sync='RESET';
+CREATE TABLE t1 (i INT) ENGINE=InnoDB;
+SET GLOBAL innodb_flush_log_at_trx_commit=1;
+FLUSH TABLES;
+set debug_sync='ha_commit_trans_after_prepare WAIT_FOR go';
+INSERT INTO t1 VALUES (1);;
+# Prove that no COMMIT or ROLLBACK occurred yet.
+SELECT * FROM t1;
+i
+SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+SELECT * FROM t1;
+i
+1
+# Kill the server
+FOUND 1 /was in the XA prepared state/ in mysqld.1.err
+FOUND 1 /Found 1 prepared transactions!/ in mysqld.1.err
+NOT FOUND /\[ERROR\] Can\'t init tc log/ in mysqld.1.err
+FOUND 2 /was in the XA prepared state/ in mysqld.1.err
+FOUND 1 /Found 1 prepared transactions!/ in mysqld.1.err
+FOUND 1 /\[ERROR\] Can\'t init tc log/ in mysqld.1.err
+FOUND 1 /Please restart mysqld without --tc-heuristic-recover/ in mysqld.1.err
+FOUND 3 /was in the XA prepared state/ in mysqld.1.err
+FOUND 1 /Found 1 prepared transactions!/ in mysqld.1.err
+FOUND 2 /\[ERROR\] Can\'t init tc log/ in mysqld.1.err
+FOUND 2 /Please restart mysqld without --tc-heuristic-recover/ in mysqld.1.err
+FOUND 3 /was in the XA prepared state/ in mysqld.1.err
+FOUND 1 /Found 1 prepared transactions!/ in mysqld.1.err
+SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
+SELECT * FROM t1;
+i
+SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+SELECT * FROM t1;
+i
+DROP TABLE t1;
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index 86219875bed..8455450e294 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -2290,3 +2290,20 @@ INSERT INTO t1 VALUES ('a');
ERROR 22001: Data too long for column 'c' at row 1
DROP TRIGGER t1_bi;
DROP TABLE t1;
+#
+# 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.
diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result
index 639a97be27b..4136eb4dff7 100644
--- a/mysql-test/r/type_bit.result
+++ b/mysql-test/r/type_bit.result
@@ -806,3 +806,27 @@ SUM(a)
NULL
DROP TABLE t1;
End of 5.1 tests
+#
+# Start of 10.1 tests
+#
+#
+# MDEV-8867 Wrong field type or metadata for COALESCE(bit_column, 1)
+#
+CREATE TABLE t1 (val bit(1));
+INSERT INTO t1 VALUES (0);
+CREATE TABLE t2 AS SELECT COALESCE(val, 1) AS c FROM t1;
+SELECT * FROM t2;
+c
+0
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `c` decimal(1,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t2;
+SELECT COALESCE(val, 1) FROM t1;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def COALESCE(val, 1) 246 2 1 Y 32896 0 63
+COALESCE(val, 1)
+0
+DROP TABLE t1;
diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result
index 132de86e27b..223d26ad6d8 100644
--- a/mysql-test/r/type_blob.result
+++ b/mysql-test/r/type_blob.result
@@ -37,7 +37,7 @@ ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT
CREATE TABLE t2 (a char(256));
ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT instead
CREATE TABLE t1 (a varchar(70000) default "hello");
-ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead
+ERROR 42000: Column length too big for column 'a' (max = 65532); use BLOB or TEXT instead
CREATE TABLE t2 (a blob default "hello");
ERROR 42000: BLOB/TEXT column 'a' can't have a default value
drop table if exists t1,t2;
diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result
index d2587d7199e..661dcabbcfe 100644
--- a/mysql-test/r/type_date.result
+++ b/mysql-test/r/type_date.result
@@ -843,5 +843,16 @@ Warning 1292 Incorrect datetime value: '1'
Warning 1292 Incorrect datetime value: '1'
DROP TABLE t1;
#
+# MDEV-14221 Assertion `0' failed in Item::field_type_for_temporal_comparison
+#
+CREATE TABLE t1 (d DATE);
+INSERT INTO t1 VALUES ('1985-05-13'),('1989-12-24');
+SELECT d, COUNT(*) FROM t1 GROUP BY d WITH ROLLUP HAVING CASE d WHEN '2017-05-25' THEN 0 ELSE 1 END;
+d COUNT(*)
+1985-05-13 1
+1989-12-24 1
+NULL 2
+DROP TABLE t1;
+#
# End of 10.1 tests
#
diff --git a/mysql-test/r/type_time_6065.result b/mysql-test/r/type_time_6065.result
index a61c658d50e..067fe9b89fc 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/type_varchar.result b/mysql-test/r/type_varchar.result
index e15b029e9c6..882b7f55102 100644
--- a/mysql-test/r/type_varchar.result
+++ b/mysql-test/r/type_varchar.result
@@ -513,7 +513,76 @@ Warning 1292 Truncated incorrect DOUBLE value: 's '
Warning 1292 Truncated incorrect DOUBLE value: ' '
DROP TABLE t1;
#
-# Start of 10.0 tests
+# MDEV-13530 VARBINARY doesn't convert to to BLOB for sizes 65533, 65534 and 65535
+#
+CREATE TABLE t1 (c1 VARBINARY(65532));
+DESCRIBE t1;
+Field Type Null Key Default Extra
+c1 varbinary(65532) YES NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 VARBINARY(65533));
+Warnings:
+Note 1246 Converting column 'c1' from VARBINARY to BLOB
+DESCRIBE t1;
+Field Type Null Key Default Extra
+c1 blob YES NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 VARBINARY(65534));
+Warnings:
+Note 1246 Converting column 'c1' from VARBINARY to BLOB
+DESCRIBE t1;
+Field Type Null Key Default Extra
+c1 blob YES NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 VARBINARY(65535));
+Warnings:
+Note 1246 Converting column 'c1' from VARBINARY to BLOB
+DESCRIBE t1;
+Field Type Null Key Default Extra
+c1 blob YES NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 VARBINARY(65536));
+Warnings:
+Note 1246 Converting column 'c1' from VARBINARY to BLOB
+DESCRIBE t1;
+Field Type Null Key Default Extra
+c1 mediumblob YES NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 VARCHAR(65532));
+DESCRIBE t1;
+Field Type Null Key Default Extra
+c1 varchar(65532) YES NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 VARCHAR(65533));
+Warnings:
+Note 1246 Converting column 'c1' from VARCHAR to TEXT
+DESCRIBE t1;
+Field Type Null Key Default Extra
+c1 text YES NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 VARCHAR(65534));
+Warnings:
+Note 1246 Converting column 'c1' from VARCHAR to TEXT
+DESCRIBE t1;
+Field Type Null Key Default Extra
+c1 text YES NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 VARCHAR(65535));
+Warnings:
+Note 1246 Converting column 'c1' from VARCHAR to TEXT
+DESCRIBE t1;
+Field Type Null Key Default Extra
+c1 text YES NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 VARCHAR(65536));
+Warnings:
+Note 1246 Converting column 'c1' from VARCHAR to TEXT
+DESCRIBE t1;
+Field Type Null Key Default Extra
+c1 mediumtext YES NULL
+DROP TABLE t1;
+#
+# End of 5.5 tests
#
#
# MDEV-6950 Bad results with joins comparing DATE and INT/ENUM/VARCHAR columns
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
index 233e7399cd2..62b5e2841fb 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -2068,6 +2068,43 @@ 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);
+ERROR HY000: Invalid use of group function
+(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
+1 0
+3 0
+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/user_var.result b/mysql-test/r/user_var.result
index 178f9fb7db4..ec19f922b05 100644
--- a/mysql-test/r/user_var.result
+++ b/mysql-test/r/user_var.result
@@ -1,4 +1,3 @@
-drop table if exists t1,t2;
set @a := foo;
ERROR 42S22: Unknown column 'foo' in 'field list'
set @a := connection_id() + 3;
@@ -126,14 +125,14 @@ select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i;
set @a=0;
select @a,@a:="hello",@a,@a:=3,@a,@a:="hello again" from t1 group by i;
@a @a:="hello" @a @a:=3 @a @a:="hello again"
-0 hello 0 3 3 hello again
-0 hello 0 3 3 hello again
-0 hello 0 3 3 hello again
+0 hello 0 3 0 hello again
+0 hello 0 3 0 hello again
+0 hello 0 3 0 hello again
select @a,@a:="hello",@a,@a:=3,@a,@a:="hello again" from t1 group by i;
@a @a:="hello" @a @a:=3 @a @a:="hello again"
-hello again hello hello 3 3 hello again
-hello again hello hello 3 3 hello again
-hello again hello hello 3 3 hello again
+hello again hello hello again 3 hello again hello again
+hello again hello hello again 3 hello again hello again
+hello again hello hello again 3 hello again hello again
drop table t1;
set @a=_latin2'test';
select charset(@a),collation(@a),coercibility(@a);
@@ -570,3 +569,6 @@ End of 5.5 tests
#
set @var= repeat('a',20000);
1
+explain select @a:=max(seq) from seq_1_to_1000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index fef3e4a3e9e..b621fc13ee4 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -1544,7 +1544,7 @@ one
1
explain SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0);
one
@@ -1555,7 +1555,7 @@ one
set sql_buffer_result=1;
explain SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using temporary
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0);
one
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 39513acf9b6..88f40b2cc9d 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -5659,12 +5659,23 @@ CREATE TABLE t3 (a INT);
CREATE ALGORITHM = MERGE VIEW v1 AS SELECT t2.a FROM t3 AS t1, t3 AS t2;
CREATE ALGORITHM = MERGE VIEW v2 AS SELECT * FROM v1;
PREPARE stmt FROM 'REPLACE INTO v2 SELECT a FROM t3';
-EXECUTE stmt;
-ERROR HY000: Can not insert into join view 'test.v2' without fields list
-EXECUTE stmt;
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/xa.result b/mysql-test/r/xa.result
index 6c242d950ab..0bf9b07bb2f 100644
--- a/mysql-test/r/xa.result
+++ b/mysql-test/r/xa.result
@@ -200,6 +200,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 41dbc744228..375b2c62827 100644
--- a/mysql-test/r/xml.result
+++ b/mysql-test/r/xml.result
@@ -1274,5 +1274,17 @@ 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/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/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/encryption/disabled.def b/mysql-test/suite/encryption/disabled.def
index d92d3495cb8..abbb82d51f6 100644
--- a/mysql-test/suite/encryption/disabled.def
+++ b/mysql-test/suite/encryption/disabled.def
@@ -12,3 +12,4 @@
innodb_scrub : MDEV-8139 scrubbing does not work reliably
innodb_scrub_background : MDEV-8139 scrubbing does not work reliably
+
diff --git a/mysql-test/suite/encryption/r/encryption_force.result b/mysql-test/suite/encryption/r/encryption_force.result
index de5f7da60a8..9d42b360e7c 100644
--- a/mysql-test/suite/encryption/r/encryption_force.result
+++ b/mysql-test/suite/encryption/r/encryption_force.result
@@ -34,11 +34,11 @@ t4 CREATE TABLE `t4` (
/*!50100 PARTITION BY HASH (a)
PARTITIONS 2 */
alter table t1 encrypted=no;
-ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options")
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTED'
alter table t2 encrypted=yes;
alter table t3 encrypted=default;
alter table t4 encrypted=no;
-ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options")
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTED'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
diff --git a/mysql-test/suite/encryption/r/filekeys_encfile.result b/mysql-test/suite/encryption/r/filekeys_encfile.result
index add6f312fda..6d5baa1b7ff 100644
--- a/mysql-test/suite/encryption/r/filekeys_encfile.result
+++ b/mysql-test/suite/encryption/r/filekeys_encfile.result
@@ -14,7 +14,7 @@ t1 CREATE TABLE `t1` (
`b` char(200) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes `encryption_key_id`=2
alter table t1 encryption_key_id=3;
-ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options")
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTION_KEY_ID'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
diff --git a/mysql-test/suite/encryption/r/filekeys_encfile_file.result b/mysql-test/suite/encryption/r/filekeys_encfile_file.result
index add6f312fda..6d5baa1b7ff 100644
--- a/mysql-test/suite/encryption/r/filekeys_encfile_file.result
+++ b/mysql-test/suite/encryption/r/filekeys_encfile_file.result
@@ -14,7 +14,7 @@ t1 CREATE TABLE `t1` (
`b` char(200) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes `encryption_key_id`=2
alter table t1 encryption_key_id=3;
-ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options")
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTION_KEY_ID'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
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 4e4fd89d1ae..d581b98513d 100644
--- a/mysql-test/suite/encryption/r/innodb-bad-key-change.result
+++ b/mysql-test/suite/encryption/r/innodb-bad-key-change.result
@@ -28,14 +28,7 @@ foobar 2
# Restart server with keysbad3.txt
SELECT * FROM t1;
ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
-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.
-Warning 192 Table "test"."t1" in file ./test/t1.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table.
-Error 1296 Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
DROP TABLE t1;
-SHOW WARNINGS;
-Level Code Message
# 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;
@@ -44,73 +37,32 @@ INSERT INTO t2 VALUES ('foobar',1,2);
# Restart server with keys2.txt
SELECT * FROM t2;
ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
-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.
-Warning 192 Table "test"."t2" in file ./test/t2.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table.
-Error 1296 Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
SELECT * FROM t2 where id = 1;
ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
-SHOW WARNINGS;
-Level Code Message
-Warning 192 Table "test"."t2" in file ./test/t2.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table.
-Error 1296 Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
SELECT * FROM t2 where b = 1;
ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
-SHOW WARNINGS;
-Level Code Message
-Warning 192 Table "test"."t2" in file ./test/t2.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table.
-Error 1296 Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
INSERT INTO t2 VALUES ('tmp',3,3);
ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
-SHOW WARNINGS;
-Level Code Message
-Warning 192 Table "test"."t2" in file ./test/t2.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table.
-Error 1296 Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
DELETE FROM t2 where b = 3;
ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
-SHOW WARNINGS;
-Level Code Message
-Warning 192 Table "test"."t2" in file ./test/t2.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table.
-Error 1296 Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
DELETE FROM t2 where id = 3;
ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
-SHOW WARNINGS;
-Level Code Message
-Warning 192 Table "test"."t2" in file ./test/t2.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table.
-Error 1296 Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
UPDATE t2 set b = b +1;
ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
-SHOW WARNINGS;
-Level Code Message
-Warning 192 Table "test"."t2" in file ./test/t2.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table.
-Error 1296 Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
OPTIMIZE TABLE t2;
Table Op Msg_type Msg_text
test.t2 optimize Warning Table "test"."t2" in file ./test/t2.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table.
test.t2 optimize Error Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
test.t2 optimize error Corrupt
-SHOW WARNINGS;
-Level Code Message
ALTER TABLE t2 ADD COLUMN d INT;
ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
-SHOW WARNINGS;
-Level Code Message
-Warning 192 Table "test"."t2" in file ./test/t2.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table.
-Error 1296 Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
ANALYZE TABLE t2;
Table Op Msg_type Msg_text
test.t2 analyze Warning Table "test"."t2" in file ./test/t2.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table.
test.t2 analyze Error Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
test.t2 analyze error Corrupt
-SHOW WARNINGS;
-Level Code Message
TRUNCATE TABLE t2;
ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
-SHOW WARNINGS;
-Level Code Message
-Warning 192 Table "test"."t2" in file ./test/t2.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table.
-Error 1296 Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB
DROP TABLE t2;
# Start server with keys2.txt
diff --git a/mysql-test/suite/encryption/r/innodb-encryption-alter.result b/mysql-test/suite/encryption/r/innodb-encryption-alter.result
index 5869c5d7000..9ff0f492034 100644
--- a/mysql-test/suite/encryption/r/innodb-encryption-alter.result
+++ b/mysql-test/suite/encryption/r/innodb-encryption-alter.result
@@ -43,11 +43,10 @@ CREATE TABLE t2 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNOD
Warnings:
Warning 140 InnoDB: Ignored ENCRYPTION_KEY_ID 1 when encryption is disabled
ALTER TABLE t1 ENCRYPTION_KEY_ID=99;
-ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options")
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTION_KEY_ID'
SHOW WARNINGS;
Level Code Message
Warning 140 InnoDB: ENCRYPTION_KEY_ID 99 not available
-Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options")
-Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB
+Error 1478 Table storage engine 'InnoDB' does not support the create option 'ENCRYPTION_KEY_ID'
set innodb_default_encryption_key_id = 1;
drop table t1,t2;
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 ec92825ac8e..88437408c32 100644
--- a/mysql-test/suite/encryption/r/innodb_encryption-page-compression.result
+++ b/mysql-test/suite/encryption/r/innodb_encryption-page-compression.result
@@ -1,5 +1,4 @@
SET GLOBAL innodb_file_format = `Barracuda`;
-SET GLOBAL innodb_file_per_table = ON;
SET GLOBAL innodb_encryption_threads = 4;
SET GLOBAL innodb_encrypt_tables = on;
set global innodb_compression_algorithm = 1;
@@ -139,15 +138,9 @@ count(*)
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;
@@ -159,8 +152,8 @@ 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
+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
@@ -168,8 +161,8 @@ variable_value > 0
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 9194412133d..5909674c21c 100644
--- a/mysql-test/suite/encryption/r/innodb_encryption.result
+++ b/mysql-test/suite/encryption/r/innodb_encryption.result
@@ -1,5 +1,3 @@
-call mtr.add_suppression("InnoDB: New log files created");
-call mtr.add_suppression("InnoDB: Creating foreign key constraint system tables.");
SET @start_global_value = @@global.innodb_encryption_threads;
SHOW VARIABLES LIKE 'innodb_encrypt%';
Variable_name Value
@@ -14,6 +12,8 @@ SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_
NAME
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
NAME
+mysql/innodb_table_stats
+mysql/innodb_index_stats
./ibdata1
# Success!
# Now turn off encryption and wait for threads to decrypt everything
@@ -21,6 +21,8 @@ SET GLOBAL innodb_encrypt_tables = off;
# Wait max 10 min for key encryption threads to encrypt all spaces
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
NAME
+mysql/innodb_table_stats
+mysql/innodb_index_stats
./ibdata1
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
NAME
@@ -33,6 +35,8 @@ SET GLOBAL innodb_encrypt_tables = on;
# Wait 15s to check that nothing gets encrypted
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
NAME
+mysql/innodb_table_stats
+mysql/innodb_index_stats
./ibdata1
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
NAME
@@ -44,6 +48,8 @@ SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_
NAME
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
NAME
+mysql/innodb_table_stats
+mysql/innodb_index_stats
./ibdata1
# Success!
# Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0
@@ -56,6 +62,8 @@ innodb_encryption_rotation_iops 100
innodb_encryption_threads 0
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
NAME
+mysql/innodb_table_stats
+mysql/innodb_index_stats
./ibdata1
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 ab958004eab..1c8341137b4 100644
--- a/mysql-test/suite/encryption/r/innodb_encryption_filekeys.result
+++ b/mysql-test/suite/encryption/r/innodb_encryption_filekeys.result
@@ -1,6 +1,4 @@
-call mtr.add_suppression("trying to do an operation on a dropped tablespace .*");
SET GLOBAL innodb_file_format = `Barracuda`;
-SET GLOBAL innodb_file_per_table = ON;
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;
@@ -14,24 +12,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!
@@ -50,18 +45,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/tempfiles.result b/mysql-test/suite/encryption/r/tempfiles.result
index a0b7596dd5a..658b7dc291b 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;
create table t1 (a text) engine=innodb;
start transaction;
@@ -33,14 +37,67 @@ commit;
start transaction;
insert t1 select repeat(seq, 1000) from seq_1_to_8;
commit;
-drop table t1;
-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;
+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 175c830982c..9395f467539 100644
--- a/mysql-test/suite/encryption/t/encrypt_and_grep.test
+++ b/mysql-test/suite/encryption/t/encrypt_and_grep.test
@@ -63,7 +63,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/encryption_force.test b/mysql-test/suite/encryption/t/encryption_force.test
index 3e09dd91839..3c6f039184b 100644
--- a/mysql-test/suite/encryption/t/encryption_force.test
+++ b/mysql-test/suite/encryption/t/encryption_force.test
@@ -22,13 +22,11 @@ show create table t2;
show create table t3;
show create table t4;
---replace_regex /#sql-[0-9a-f_]*/#sql-temporary/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
alter table t1 encrypted=no;
alter table t2 encrypted=yes;
alter table t3 encrypted=default;
---replace_regex /#sql-[0-9a-f_]*/#sql-temporary/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
alter table t4 encrypted=no;
show create table t1;
diff --git a/mysql-test/suite/encryption/t/filekeys_goodtest.inc b/mysql-test/suite/encryption/t/filekeys_goodtest.inc
index 146a570412c..5317eeb3d12 100644
--- a/mysql-test/suite/encryption/t/filekeys_goodtest.inc
+++ b/mysql-test/suite/encryption/t/filekeys_goodtest.inc
@@ -7,8 +7,7 @@ insert t1 values (12345, repeat('1234567890', 20));
alter table t1 encryption_key_id=2;
show create table t1;
---replace_regex /#sql-[0-9a-f_]*/#sql-temporary/
---error ER_CANT_CREATE_TABLE
+--error ER_ILLEGAL_HA_CREATE_OPTION
alter table t1 encryption_key_id=3;
show create table t1;
alter table t1 encryption_key_id=33;
@@ -17,4 +16,3 @@ alter table t1 encryption_key_id=4;
show create table t1;
drop table t1;
-
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 66546872c25..6fa5fc9847f 100644
--- a/mysql-test/suite/encryption/t/innodb-bad-key-change.test
+++ b/mysql-test/suite/encryption/t/innodb-bad-key-change.test
@@ -40,18 +40,18 @@ 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_GET_ERRMSG
SELECT * FROM t1;
---replace_regex /tablespace [0-9]*/tablespace / /key_id [0-9]*/key_id /
-SHOW WARNINGS;
+--enable_warnings
-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keysbad3.txt
-- source include/restart_mysqld.inc
+--disable_warnings
--replace_regex /tablespace [0-9]*/tablespace /
DROP TABLE t1;
---replace_regex /tablespace [0-9]*/tablespace / /key_id [0-9]*/key_id /
-SHOW WARNINGS;
+--enable_warnings
#
# MDEV-8591: Database page corruption on disk or a failed space, Assertion failure in file buf0buf.cc
@@ -71,51 +71,41 @@ 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_GET_ERRMSG
SELECT * FROM t2;
---replace_regex /tablespace [0-9]*/tablespace / /key_id [0-9]*/key_id /
-SHOW WARNINGS;
+
--error ER_GET_ERRMSG
SELECT * FROM t2 where id = 1;
---replace_regex /tablespace [0-9]*/tablespace / /key_id [0-9]*/key_id /
-SHOW WARNINGS;
+
--error ER_GET_ERRMSG
SELECT * FROM t2 where b = 1;
---replace_regex /tablespace [0-9]*/tablespace / /key_id [0-9]*/key_id /
-SHOW WARNINGS;
+
--replace_regex /tablespace [0-9]*/tablespace /
--error ER_GET_ERRMSG
INSERT INTO t2 VALUES ('tmp',3,3);
---replace_regex /tablespace [0-9]*/tablespace / /key_id [0-9]*/key_id /
-SHOW WARNINGS;
+
--error ER_GET_ERRMSG
DELETE FROM t2 where b = 3;
---replace_regex /tablespace [0-9]*/tablespace / /key_id [0-9]*/key_id /
-SHOW WARNINGS;
+
--error ER_GET_ERRMSG
DELETE FROM t2 where id = 3;
---replace_regex /tablespace [0-9]*/tablespace / /key_id [0-9]*/key_id /
-SHOW WARNINGS;
+
--error ER_GET_ERRMSG
UPDATE t2 set b = b +1;
---replace_regex /tablespace [0-9]*/tablespace / /key_id [0-9]*/key_id /
-SHOW WARNINGS;
+
OPTIMIZE TABLE t2;
---replace_regex /tablespace [0-9]*/tablespace / /key_id [0-9]*/key_id /
-SHOW WARNINGS;
+
--error ER_GET_ERRMSG
ALTER TABLE t2 ADD COLUMN d INT;
---replace_regex /tablespace [0-9]*/tablespace / /key_id [0-9]*/key_id /
-SHOW WARNINGS;
+
ANALYZE TABLE t2;
---replace_regex /tablespace [0-9]*/tablespace / /key_id [0-9]*/key_id /
-SHOW WARNINGS;
+
--error ER_GET_ERRMSG
TRUNCATE TABLE t2;
---replace_regex /tablespace [0-9]*/tablespace / /key_id [0-9]*/key_id /
-SHOW WARNINGS;
DROP TABLE t2;
+--enable_warnings
--echo
--echo # Start server with keys2.txt
diff --git a/mysql-test/suite/encryption/t/innodb-encryption-alter.test b/mysql-test/suite/encryption/t/innodb-encryption-alter.test
index 316ece1c16b..9420fb74a4c 100644
--- a/mysql-test/suite/encryption/t/innodb-encryption-alter.test
+++ b/mysql-test/suite/encryption/t/innodb-encryption-alter.test
@@ -33,10 +33,8 @@ DROP TABLE t1;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB;
SHOW CREATE TABLE t1;
CREATE TABLE t2 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=NO ENCRYPTION_KEY_ID=1;
---replace_regex /#sql-[0-9a-f_]*/#sql-temporary/
---error 1005
+--error ER_ILLEGAL_HA_CREATE_OPTION
ALTER TABLE t1 ENCRYPTION_KEY_ID=99;
---replace_regex /#sql-[0-9a-f_]*/#sql-temporary/
SHOW WARNINGS;
set innodb_default_encryption_key_id = 1;
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 ea6bd65d605..0c18b97bfd6 100644
--- a/mysql-test/suite/encryption/t/innodb_encryption-page-compression.test
+++ b/mysql-test/suite/encryption/t/innodb_encryption-page-compression.test
@@ -1,17 +1,14 @@
-- source include/have_innodb.inc
-- source include/have_example_key_management_plugin.inc
+-- source include/not_embedded.inc
--disable_query_log
-let $innodb_compression_algorithm_orig=`SELECT @@innodb_compression_algorithm`;
-let $innodb_file_format_orig = `SELECT @@innodb_file_format`;
-let $innodb_file_per_table_orig = `SELECT @@innodb_file_per_table`;
let $innodb_encrypt_tables_orig = `SELECT @@innodb_encrypt_tables`;
let $innodb_encryption_threads_orig = `SELECT @@innodb_encryption_threads`;
--enable_query_log
--disable_warnings
SET GLOBAL innodb_file_format = `Barracuda`;
-SET GLOBAL innodb_file_per_table = ON;
SET GLOBAL innodb_encryption_threads = 4;
SET GLOBAL innodb_encrypt_tables = on;
--enable_warnings
@@ -86,11 +83,13 @@ select count(*) from innodb_page_compressed9 where c1 < 500000;
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;
@@ -105,13 +104,15 @@ update innodb_page_compressed7 set c1 = c1 + 1;
update innodb_page_compressed8 set c1 = c1 + 1;
update innodb_page_compressed9 set c1 = c1 + 1;
-let $wait_condition= select variable_value > 0 from information_schema.global_status where variable_name = 'INNODB_NUM_PAGES_DECRYPTED';
+let $wait_condition= select variable_value > 0 from information_schema.global_status where variable_name = 'INNODB_NUM_PAGES_ENCRYPTED';
+--source include/wait_condition.inc
+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
-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_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;
@@ -127,9 +128,6 @@ drop table innodb_page_compressed9;
# reset system
--disable_query_log
-EVAL SET GLOBAL innodb_compression_algorithm = $innodb_compression_algorithm_orig;
-EVAL SET GLOBAL innodb_file_per_table = $innodb_file_per_table_orig;
-EVAL SET GLOBAL innodb_file_format = $innodb_file_format_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 aab8c56f072..d183a2914bd 100644
--- a/mysql-test/suite/encryption/t/innodb_encryption.test
+++ b/mysql-test/suite/encryption/t/innodb_encryption.test
@@ -8,18 +8,17 @@
# embedded does not support restart
-- source include/not_embedded.inc
-call mtr.add_suppression("InnoDB: New log files created");
-call mtr.add_suppression("InnoDB: Creating foreign key constraint system tables.");
-
SET @start_global_value = @@global.innodb_encryption_threads;
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(*) >= 1 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;
@@ -62,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(*) >=1 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 8f0986071f1..f73e78aa5bf 100644
--- a/mysql-test/suite/encryption/t/innodb_encryption_filekeys.test
+++ b/mysql-test/suite/encryption/t/innodb_encryption_filekeys.test
@@ -1,21 +1,18 @@
-- 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 $innodb_file_format_orig = `SELECT @@innodb_file_format`;
-let $innodb_file_per_table_orig = `SELECT @@innodb_file_per_table`;
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
+--disable_warnings
SET GLOBAL innodb_file_format = `Barracuda`;
-SET GLOBAL innodb_file_per_table = ON;
SET GLOBAL innodb_encrypt_tables = OFF;
SET GLOBAL innodb_encryption_threads = 4;
+--enable_warnings
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB;
SHOW CREATE TABLE t1;
@@ -25,21 +22,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;
@@ -60,7 +56,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
}
@@ -90,7 +86,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
}
@@ -119,7 +115,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
}
@@ -131,15 +127,16 @@ 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_file_per_table = $innodb_file_per_table_orig;
+--disable_warnings
EVAL SET GLOBAL innodb_file_format = $innodb_file_format_orig;
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_warnings
--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 34dcbdf5963..5232bcb5d12 100644
--- a/mysql-test/suite/encryption/t/tempfiles.test
+++ b/mysql-test/suite/encryption/t/tempfiles.test
@@ -11,6 +11,8 @@ source include/have_binlog_format_row.inc;
# engine. But there's no need to run it twice for InnoDB and XtraDB.
source include/have_xtradb.inc;
+select @@encrypt_tmp_files;
+
#
# MyISAM messing around with IO_CACHE::file
#
@@ -31,6 +33,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;
@@ -48,7 +51,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;
@@ -58,17 +60,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/engines/funcs/t/rpl_insert.test b/mysql-test/suite/engines/funcs/t/rpl_insert.test
index 763a484ea5d..f57a6e226d1 100644
--- a/mysql-test/suite/engines/funcs/t/rpl_insert.test
+++ b/mysql-test/suite/engines/funcs/t/rpl_insert.test
@@ -2,9 +2,9 @@
--echo # Bug#20821: INSERT DELAYED fails to write some rows to binlog
--echo #
---source include/master-slave.inc
--source include/not_embedded.inc
--source include/not_windows.inc
+--source include/master-slave.inc
--disable_warnings
CREATE SCHEMA IF NOT EXISTS mysqlslap;
diff --git a/mysql-test/suite/federated/net_thd_crash-12951.result b/mysql-test/suite/federated/net_thd_crash-12951.result
new file mode 100644
index 00000000000..573ac96efff
--- /dev/null
+++ b/mysql-test/suite/federated/net_thd_crash-12951.result
@@ -0,0 +1,11 @@
+set global query_cache_size= 16*1024*1024;
+set global query_cache_type= 1;
+create table t1 (i int) engine=innodb;
+create table t2 (i int) engine=federated
+CONNECTION="mysql://root@localhost:MASTER_MYPORT/test/t1";
+select * from t2;
+i
+drop table t2;
+drop table t1;
+set global query_cache_type= default;
+set global query_cache_size= default;
diff --git a/mysql-test/suite/federated/net_thd_crash-12951.test b/mysql-test/suite/federated/net_thd_crash-12951.test
new file mode 100644
index 00000000000..81cd826686e
--- /dev/null
+++ b/mysql-test/suite/federated/net_thd_crash-12951.test
@@ -0,0 +1,23 @@
+#
+# MDEV-12951 Server crash [mysqld got exception 0xc0000005]
+#
+
+--source include/have_innodb.inc
+
+set global query_cache_size= 16*1024*1024;
+set global query_cache_type= 1;
+
+create table t1 (i int) engine=innodb;
+--replace_result $MASTER_MYPORT MASTER_MYPORT
+eval create table t2 (i int) engine=federated
+ CONNECTION="mysql://root@localhost:$MASTER_MYPORT/test/t1";
+
+select * from t2;
+
+source include/restart_mysqld.inc;
+
+drop table t2;
+drop table t1;
+
+set global query_cache_type= default;
+set global query_cache_size= default;
diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def
index cd19fccd483..b67dea0f2f4 100644
--- a/mysql-test/suite/galera/disabled.def
+++ b/mysql-test/suite/galera/disabled.def
@@ -54,3 +54,8 @@ 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
+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 \ No newline at end of file
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..59d4d4a2bf3
--- /dev/null
+++ b/mysql-test/suite/galera/r/MW-388.result
@@ -0,0 +1,46 @@
+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 = "d,sync.wsrep_apply_cb";
+Warnings:
+Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
+INSERT INTO t1 VALUES (1, 'node 2');;
+SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached";
+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 ();;
+SET SESSION DEBUG_SYNC = "now WAIT_FOR wsrep_after_replication_reached";
+SET GLOBAL DEBUG = "";
+Warnings:
+Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
+SET DEBUG_SYNC = "now SIGNAL wsrep_after_replication_continue";
+SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb";
+SELECT @errno = 1213;
+@errno = 1213
+0
+SELECT * FROM t1;
+f1 f2
+1 node 2
+3 node 1
+SELECT * FROM t1;
+f1 f2
+1 node 2
+3 node 1
+SET GLOBAL wsrep_slave_threads = DEFAULT;
+DROP TABLE t1;
+DROP PROCEDURE insert_proc;
+SET GLOBAL debug = NULL;
+Warnings:
+Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead
+SET debug_sync='RESET';
+SELECT @@debug_sync;
+@@debug_sync
+ON - current signal: ''
diff --git a/mysql-test/suite/galera/r/MW-402.result b/mysql-test/suite/galera/r/MW-402.result
new file mode 100644
index 00000000000..fdcf6e324b5
--- /dev/null
+++ b/mysql-test/suite/galera/r/MW-402.result
@@ -0,0 +1,192 @@
+CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
+CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER,
+CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) ON DELETE CASCADE);
+INSERT INTO p VALUES (1, 0);
+INSERT INTO p VALUES (2, 0);
+INSERT INTO c VALUES (1, 1, 0);
+SET AUTOCOMMIT=ON;
+START TRANSACTION;
+UPDATE c SET f2=1 where f1=1;
+SET SESSION wsrep_sync_wait = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
+DELETE FROM p WHERE f1 = 1;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync';
+COMMIT;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
+SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync';
+SET GLOBAL wsrep_provider_options = 'dbug=';
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+SELECT * FROM p;
+f1 f2
+2 0
+SELECT * FROM c;
+f1 p_id f2
+DROP TABLE c;
+DROP TABLE p;
+CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
+CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER,
+CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) ON UPDATE CASCADE);
+INSERT INTO p VALUES (1, 0);
+INSERT INTO p VALUES (2, 0);
+INSERT INTO c VALUES (1, 1, 0);
+SET AUTOCOMMIT=ON;
+START TRANSACTION;
+UPDATE c SET f2=2 where f1=1;
+SET SESSION wsrep_sync_wait = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
+UPDATE p set f1=11 WHERE f1 = 1;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync';
+COMMIT;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
+SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync';
+SET GLOBAL wsrep_provider_options = 'dbug=';
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+SELECT * FROM p;
+f1 f2
+2 0
+11 0
+SELECT * FROM c;
+f1 p_id f2
+1 11 0
+DROP TABLE c;
+DROP TABLE p;
+CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
+CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER,
+CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) ON UPDATE CASCADE);
+INSERT INTO p VALUES (1, 0);
+INSERT INTO p VALUES (2, 0);
+INSERT INTO c VALUES (1, 1, 0);
+SET AUTOCOMMIT=ON;
+START TRANSACTION;
+UPDATE c SET p_id=2 where f1=1;
+SET SESSION wsrep_sync_wait = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
+UPDATE p set f1=11 WHERE f1 = 1;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync';
+COMMIT;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
+SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync';
+SET GLOBAL wsrep_provider_options = 'dbug=';
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+SELECT * FROM p;
+f1 f2
+2 0
+11 0
+SELECT * FROM c;
+f1 p_id f2
+1 11 0
+SET AUTOCOMMIT=ON;
+START TRANSACTION;
+UPDATE p set f1=21 WHERE f1 = 11;
+SET SESSION wsrep_sync_wait = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
+UPDATE c SET p_id=2 where f1=1;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync';
+COMMIT;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
+SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync';
+SET GLOBAL wsrep_provider_options = 'dbug=';
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+SELECT * FROM p;
+f1 f2
+2 0
+11 0
+SELECT * FROM c;
+f1 p_id f2
+1 2 0
+DROP TABLE c;
+DROP TABLE p;
+CREATE TABLE p1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
+CREATE TABLE p2 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
+CREATE TABLE c (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER,
+f2 INTEGER,
+CONSTRAINT fk_1 FOREIGN KEY (p1_id) REFERENCES p1 (f1)
+ON DELETE CASCADE,
+CONSTRAINT fk_2 FOREIGN KEY (p2_id) REFERENCES p2 (f1));
+INSERT INTO p1 VALUES (1, 0);
+INSERT INTO p2 VALUES (1, 0);
+INSERT INTO c VALUES (1, 1, 1, 0);
+SET AUTOCOMMIT=ON;
+START TRANSACTION;
+UPDATE p2 SET f2=2 where f1=1;
+SET SESSION wsrep_sync_wait = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
+DELETE FROM p1 WHERE f1 = 1;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync';
+COMMIT;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
+SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync';
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SELECT * FROM p1;
+f1 f2
+SELECT * FROM p2;
+f1 f2
+1 2
+SELECT * FROM c;
+f1 p1_id p2_id f2
+DROP TABLE c;
+DROP TABLE p1;
+DROP TABLE p2;
+CREATE TABLE p1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
+CREATE TABLE p2 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
+CREATE TABLE c (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER,
+f2 INTEGER,
+CONSTRAINT fk_1 FOREIGN KEY (p1_id) REFERENCES p1 (f1)
+ON DELETE CASCADE,
+CONSTRAINT fk_2 FOREIGN KEY (p2_id) REFERENCES p2 (f1)
+ON DELETE CASCADE);
+INSERT INTO p1 VALUES (1, 0);
+INSERT INTO p2 VALUES (1, 0);
+INSERT INTO c VALUES (1, 1, 1, 0);
+SET AUTOCOMMIT=ON;
+START TRANSACTION;
+DELETE FROM p2 WHERE f1=1;
+SET SESSION wsrep_sync_wait = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
+DELETE FROM p1 WHERE f1=1;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync';
+COMMIT;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
+SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync';
+SET GLOBAL wsrep_provider_options = 'dbug=';
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+SELECT * FROM p1;
+f1 f2
+SELECT * FROM p2;
+f1 f2
+1 0
+SELECT * FROM c;
+f1 p1_id p2_id f2
+DROP TABLE c;
+DROP TABLE p1;
+DROP TABLE p2;
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..4e6019ec8ad
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_bf_lock_wait.result
@@ -0,0 +1,18 @@
+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|
+call p1;
+call p1;
+call p1;
+call p1;
+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_gtid_slave.result b/mysql-test/suite/galera/r/galera_gtid_slave.result
new file mode 100644
index 00000000000..40f3f1c0d53
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_gtid_slave.result
@@ -0,0 +1,26 @@
+START SLAVE;
+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
+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
+INSERT INTO t1 VALUES(4);
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-4,2-2-2,2-3-3
+DROP TABLE t1,t2;
+reset master;
+STOP SLAVE;
+RESET SLAVE ALL;
+reset master;
+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..81fae57d731
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result
@@ -0,0 +1,130 @@
+#Connection 2
+START SLAVE;
+#Connection 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
+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
+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
+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
+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
+Shutting down server ...
+#Connection 2
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_during');
+INSERT INTO t1 VALUES ('node1_committed_during');
+COMMIT;
+#Connection 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
+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
+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
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-6,2-2-7,2-3-8
+#Connection 3
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-6,2-2-7,2-3-8
+#Connection 1
+SET AUTOCOMMIT=ON;
+#Connection 2
+SET AUTOCOMMIT=ON;
+#Connection 3
+SET AUTOCOMMIT=ON;
+#Connection 2
+STOP slave;
+INSERT INTO t1 VALUES ('node2_slave_stoped');
+#Connection 1
+INSERT INTO t1 VALUES ('node1_normal_entry');
+include/save_master_gtid.inc
+#Connection 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
+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
+DROP TABLE t2,t1;
+#Connection 2
+#Connection 3
+#Connection 2
+STOP SLAVE;
+RESET SLAVE ALL;
+reset master;
+#Connection 3
+reset master;
+#Connection 1
+reset master;
diff --git a/mysql-test/suite/galera/r/galera_mdev_13787.result b/mysql-test/suite/galera/r/galera_mdev_13787.result
new file mode 100644
index 00000000000..e3133f60b0c
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_mdev_13787.result
@@ -0,0 +1,3 @@
+create table t(a int);
+insert into t select 1;
+DROP TABLE t;
diff --git a/mysql-test/suite/galera/r/sql_log_bin.result b/mysql-test/suite/galera/r/sql_log_bin.result
index 237725ec9a7..a2ebafe5231 100644
--- a/mysql-test/suite/galera/r/sql_log_bin.result
+++ b/mysql-test/suite/galera/r/sql_log_bin.result
@@ -6,6 +6,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/t/MW-388.test b/mysql-test/suite/galera/t/MW-388.test
new file mode 100644
index 00000000000..209695dca80
--- /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 = "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 = "";
+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 = 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/MW-402.test b/mysql-test/suite/galera/t/MW-402.test
new file mode 100644
index 00000000000..80f368b50c8
--- /dev/null
+++ b/mysql-test/suite/galera/t/MW-402.test
@@ -0,0 +1,228 @@
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+--source include/have_debug_sync.inc
+--source suite/galera/include/galera_have_debug_sync.inc
+
+#
+# we must open connection node_1a here, MW-369.inc will use it later
+#
+--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
+
+#
+# cascading delete operation is replicated from node2
+# and this conflicts with an update for child table in node1
+#
+# As a result, the update should fail for certification error
+#
+--connection node_1
+
+CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
+CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER,
+ CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) ON DELETE CASCADE);
+
+
+INSERT INTO p VALUES (1, 0);
+INSERT INTO p VALUES (2, 0);
+
+INSERT INTO c VALUES (1, 1, 0);
+
+--let $mw_369_parent_query = UPDATE c SET f2=1 where f1=1
+--let $mw_369_child_query = DELETE FROM p WHERE f1 = 1
+
+--connection node_1a
+--source MW-369.inc
+
+# Commit fails
+--connection node_1
+--error ER_LOCK_DEADLOCK
+--reap
+
+--connection node_2
+SELECT * FROM p;
+SELECT * FROM c;
+
+DROP TABLE c;
+DROP TABLE p;
+
+#
+# cascading update operation is replicated from node2
+# and this conflicts with an update for child table in node1
+#
+# As a result, the update should fail for certification error
+#
+--connection node_1
+
+CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
+CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER,
+ CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) ON UPDATE CASCADE);
+
+
+INSERT INTO p VALUES (1, 0);
+INSERT INTO p VALUES (2, 0);
+
+INSERT INTO c VALUES (1, 1, 0);
+
+--let $mw_369_parent_query = UPDATE c SET f2=2 where f1=1
+--let $mw_369_child_query = UPDATE p set f1=11 WHERE f1 = 1
+
+--connection node_1a
+--source MW-369.inc
+
+# Commit fails
+--connection node_1
+--error ER_LOCK_DEADLOCK
+--reap
+
+--connection node_2
+SELECT * FROM p;
+SELECT * FROM c;
+
+DROP TABLE c;
+DROP TABLE p;
+
+#
+# ON UPDATE CASCADE tests
+# Here we update primary key of parent table to cause cascaded update
+# on child table
+#
+# cascading update operation is replicated from node2
+# and this conflicts with an update for child table in node1
+#
+# As a result, the update should fail for certification error
+#
+--connection node_1
+
+CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
+CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER,
+ CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) ON UPDATE CASCADE);
+
+
+INSERT INTO p VALUES (1, 0);
+INSERT INTO p VALUES (2, 0);
+
+INSERT INTO c VALUES (1, 1, 0);
+
+--let $mw_369_parent_query = UPDATE c SET p_id=2 where f1=1
+--let $mw_369_child_query = UPDATE p set f1=11 WHERE f1 = 1
+
+--connection node_1a
+--source MW-369.inc
+
+# Commit fails
+--connection node_1
+--error ER_LOCK_DEADLOCK
+--reap
+
+# same as previous, but statements in different order
+--connection node_2
+SELECT * FROM p;
+SELECT * FROM c;
+
+--let $mw_369_parent_query = UPDATE p set f1=21 WHERE f1 = 11
+--let $mw_369_child_query = UPDATE c SET p_id=2 where f1=1
+
+--connection node_1a
+--source MW-369.inc
+
+# Commit fails
+--connection node_1
+--error ER_LOCK_DEADLOCK
+--reap
+
+
+--connection node_2
+SELECT * FROM p;
+SELECT * FROM c;
+
+DROP TABLE c;
+DROP TABLE p;
+
+#
+# CASCADE DELETE tests with two parent tables
+# Here we cause cascaded operation on child table through
+# one parent table and have other operation on the other
+# parent table
+#
+# cascading update operation is replicated from node2
+# but this does not conflict with an update for the other parent table in node1
+#
+# As a result, the update on p2 should succeed
+#
+--connection node_1
+
+CREATE TABLE p1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
+CREATE TABLE p2 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
+CREATE TABLE c (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER,
+ f2 INTEGER,
+ CONSTRAINT fk_1 FOREIGN KEY (p1_id) REFERENCES p1 (f1)
+ ON DELETE CASCADE,
+ CONSTRAINT fk_2 FOREIGN KEY (p2_id) REFERENCES p2 (f1));
+
+INSERT INTO p1 VALUES (1, 0);
+INSERT INTO p2 VALUES (1, 0);
+
+INSERT INTO c VALUES (1, 1, 1, 0);
+
+--let $mw_369_parent_query = UPDATE p2 SET f2=2 where f1=1
+--let $mw_369_child_query = DELETE FROM p1 WHERE f1 = 1
+
+--connection node_1a
+--source MW-369.inc
+
+# Commit succeeds
+--connection node_1
+--reap
+
+--connection node_2
+SELECT * FROM p1;
+SELECT * FROM p2;
+SELECT * FROM c;
+
+DROP TABLE c;
+DROP TABLE p1;
+DROP TABLE p2;
+
+#
+# CASCADE DELETE tests with two parent tables
+# Here we cause cascaded operation on child table through
+# one parent table and issue other delete operation through the
+# other parent table. The cascade progresses to same child table row where
+# we should see the conflict to happen
+#
+# As a result, the update on p2 should fail
+#
+--connection node_1
+
+CREATE TABLE p1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
+CREATE TABLE p2 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
+CREATE TABLE c (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER,
+ f2 INTEGER,
+ CONSTRAINT fk_1 FOREIGN KEY (p1_id) REFERENCES p1 (f1)
+ ON DELETE CASCADE,
+ CONSTRAINT fk_2 FOREIGN KEY (p2_id) REFERENCES p2 (f1)
+ ON DELETE CASCADE);
+
+INSERT INTO p1 VALUES (1, 0);
+INSERT INTO p2 VALUES (1, 0);
+
+INSERT INTO c VALUES (1, 1, 1, 0);
+
+--let $mw_369_parent_query = DELETE FROM p2 WHERE f1=1
+--let $mw_369_child_query = DELETE FROM p1 WHERE f1=1
+
+--connection node_1a
+--source MW-369.inc
+
+# Commit succeeds
+--connection node_1
+--error ER_LOCK_DEADLOCK
+--reap
+
+--connection node_2
+SELECT * FROM p1;
+SELECT * FROM p2;
+SELECT * FROM c;
+
+DROP TABLE c;
+DROP TABLE p1;
+DROP TABLE p2; \ No newline at end of file
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_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_mdev_13787.opt b/mysql-test/suite/galera/t/galera_mdev_13787.opt
new file mode 100644
index 00000000000..27ec1e3f00e
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_mdev_13787.opt
@@ -0,0 +1 @@
+--innodb-stats-persistent=1
diff --git a/mysql-test/suite/galera/t/galera_mdev_13787.test b/mysql-test/suite/galera/t/galera_mdev_13787.test
new file mode 100644
index 00000000000..940cffb8b65
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_mdev_13787.test
@@ -0,0 +1,6 @@
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+--connection node_1
+create table t(a int);
+insert into t select 1;
+DROP TABLE t;
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/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/galera_3nodes.cnf b/mysql-test/suite/galera_3nodes/galera_3nodes.cnf
index fe3bcb1e8ff..91aa53ad7b1 100644
--- a/mysql-test/suite/galera_3nodes/galera_3nodes.cnf
+++ b/mysql-test/suite/galera_3nodes/galera_3nodes.cnf
@@ -14,6 +14,9 @@ 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=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S'
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/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/innodb/include/import.inc b/mysql-test/suite/innodb/include/import.inc
new file mode 100644
index 00000000000..e8265cb3db6
--- /dev/null
+++ b/mysql-test/suite/innodb/include/import.inc
@@ -0,0 +1,40 @@
+# Export Table and Import from saved files .cfg and .ibd
+# Caller should create t1 table definition and populate table
+
+let $MYSQLD_DATADIR = `SELECT @@datadir`;
+
+if(!$source_db) {
+ let $source_db = test;
+}
+
+if(!$dest_db) {
+ let $dest_db = test;
+}
+
+eval FLUSH TABLES $source_db.t1 FOR EXPORT;
+
+--copy_file $MYSQLD_DATADIR/$source_db/t1.cfg $MYSQLD_DATADIR/t1.cfg_back
+--copy_file $MYSQLD_DATADIR/$source_db/t1.ibd $MYSQLD_DATADIR/t1.ibd_back
+
+UNLOCK TABLES;
+
+if($source_db != $dest_db) {
+ eval USE $dest_db;
+ let $create1 = query_get_value(SHOW CREATE TABLE $source_db.t1, Create Table, 1);
+ eval $create1;
+}
+
+eval ALTER TABLE $dest_db.t1 DISCARD TABLESPACE;
+
+--move_file $MYSQLD_DATADIR/t1.cfg_back $MYSQLD_DATADIR/$dest_db/t1.cfg
+--move_file $MYSQLD_DATADIR/t1.ibd_back $MYSQLD_DATADIR/$dest_db/t1.ibd
+
+eval ALTER TABLE $dest_db.t1 IMPORT TABLESPACE;
+
+eval CHECK TABLE $dest_db.t1;
+eval SHOW CREATE TABLE $dest_db.t1;
+eval SELECT * FROM $dest_db.t1;
+
+if($source_db != $dest_db) {
+ eval DROP TABLE $dest_db.t1;
+}
diff --git a/mysql-test/suite/innodb/include/innodb_dict.inc b/mysql-test/suite/innodb/include/innodb_dict.inc
new file mode 100644
index 00000000000..1e05181272d
--- /dev/null
+++ b/mysql-test/suite/innodb/include/innodb_dict.inc
@@ -0,0 +1,9 @@
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
diff --git a/mysql-test/suite/innodb/r/alter_rename_existing.result b/mysql-test/suite/innodb/r/alter_rename_existing.result
new file mode 100644
index 00000000000..b0b5083b635
--- /dev/null
+++ b/mysql-test/suite/innodb/r/alter_rename_existing.result
@@ -0,0 +1,96 @@
+#
+# Show what happens during ALTER TABLE when an existing file
+# exists in the target location.
+#
+# Bug #19218794: IF TABLESPACE EXISTS, CAN'T CREATE TABLE,
+# BUT CAN ALTER ENGINE=INNODB
+#
+CREATE TABLE t1 (a SERIAL, b CHAR(10)) ENGINE=Memory;
+INSERT INTO t1(b) VALUES('one'), ('two'), ('three');
+#
+# Create a file called MYSQLD_DATADIR/test/t1.ibd
+# Directory listing of test/*.ibd
+#
+t1.ibd
+ALTER TABLE t1 ENGINE = InnoDB;
+ERROR HY000: Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME' (errno: 184 "Tablespace already exists")
+#
+# Move the file to InnoDB as t2
+#
+ALTER TABLE t1 RENAME TO t2, ENGINE = INNODB;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ `b` char(10) DEFAULT NULL,
+ UNIQUE KEY `a` (`a`)
+) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
+SELECT * from t2;
+a b
+1 one
+2 two
+3 three
+ALTER TABLE t2 RENAME TO t1;
+ERROR HY000: Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME' (errno: 184 "Tablespace already exists")
+#
+# Create another t1, but in the system tablespace.
+#
+SET GLOBAL innodb_file_per_table=OFF;
+CREATE TABLE t1 (a SERIAL, b CHAR(20)) ENGINE=InnoDB;
+INSERT INTO t1(b) VALUES('one'), ('two'), ('three');
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ `b` char(20) DEFAULT NULL,
+ UNIQUE KEY `a` (`a`)
+) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
+SELECT name, space=0 FROM information_schema.innodb_sys_tables WHERE name = 'test/t1';
+name space=0
+test/t1 1
+#
+# ALTER TABLE from system tablespace to system tablespace
+#
+ALTER TABLE t1 ADD COLUMN c INT, ALGORITHM=INPLACE;
+ALTER TABLE t1 ADD COLUMN d INT, ALGORITHM=COPY;
+#
+# Try to move t1 from the system tablespace to a file-per-table
+# while a blocking t1.ibd file exists.
+#
+SET GLOBAL innodb_file_per_table=ON;
+ALTER TABLE t1 ADD COLUMN e1 INT, ALGORITHM=INPLACE;
+ERROR HY000: Tablespace for table 'test/t1' exists. Please DISCARD the tablespace before IMPORT.
+ALTER TABLE t1 ADD COLUMN e2 INT, ALGORITHM=COPY;
+ERROR HY000: Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME' (errno: 184 "Tablespace already exists")
+#
+# Delete the blocking file called MYSQLD_DATADIR/test/t1.ibd
+# Move t1 to file-per-table using ALGORITHM=INPLACE with no blocking t1.ibd.
+#
+ALTER TABLE t1 ADD COLUMN e INT, ALGORITHM=INPLACE;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ `b` char(20) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL,
+ `d` int(11) DEFAULT NULL,
+ `e` int(11) DEFAULT NULL,
+ UNIQUE KEY `a` (`a`)
+) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
+SELECT name, space=0 FROM information_schema.innodb_sys_tables WHERE name = 'test/t1';
+name space=0
+test/t1 0
+DROP TABLE t1;
+#
+# Rename t2.ibd to t1.ibd.
+#
+ALTER TABLE t2 RENAME TO t1;
+SELECT name, space=0 FROM information_schema.innodb_sys_tables WHERE name = 'test/t1';
+name space=0
+test/t1 0
+SELECT * from t1;
+a b
+1 one
+2 two
+3 three
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/create-index-debug.result b/mysql-test/suite/innodb/r/create-index-debug.result
new file mode 100644
index 00000000000..99f6efe9bfe
--- /dev/null
+++ b/mysql-test/suite/innodb/r/create-index-debug.result
@@ -0,0 +1,26 @@
+SET @saved_debug_dbug = @@SESSION.debug_dbug;
+#
+#BUG#21326304 INNODB ONLINE ALTER TABLE ENDS IN CRASH ON DISK FULL
+#
+CREATE TABLE t1(f1 CHAR(255) NOT NULL, f2 CHAR(255) NOT NULL, f3
+CHAR(255) NOT NULL, f4 CHAR(255) NOT NULL, f5 CHAR(255) NOT NULL,f6
+CHAR(255) NOT NULL, f7 CHAR(255) NOT NULL, f8 CHAR(255) NOT NULL,f9
+CHAR(255) NOT NULL, f10 CHAR(255) NOT NULL, f11 CHAR(255) NOT NULL,f12
+CHAR(255) NOT NULL, f13 CHAR(255) NOT NULL, f14 CHAR(255) NOT NULL,f15
+CHAR(255) NOT NULL, f16 CHAR(255) NOT NULL, f17 CHAR(255) NOT NULL,f18
+CHAR(255) NOT NULL)
+ENGINE=INNODB ROW_FORMAT=DYNAMIC;
+Warnings:
+Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT.
+INSERT INTO t1
+VALUES('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r');
+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 debug_dbug = '+d,disk_is_full';
+ALTER TABLE t1 FORCE, ALGORITHM=INPLACE;
+ERROR HY000: The table 't1' is full
+SET debug_dbug= @saved_debug_dbug;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/index_tree_operation.result b/mysql-test/suite/innodb/r/index_tree_operation.result
new file mode 100644
index 00000000000..29660962e0c
--- /dev/null
+++ b/mysql-test/suite/innodb/r/index_tree_operation.result
@@ -0,0 +1,55 @@
+#
+# Bug#15923864 (Bug#67718):
+# INNODB DRASTICALLY UNDER-FILLS PAGES IN CERTAIN CONDITIONS
+#
+SET GLOBAL innodb_file_per_table=ON;
+CREATE TABLE t1 (a BIGINT PRIMARY KEY, b VARCHAR(4096)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (0, REPEAT('a', 4096));
+INSERT INTO t1 VALUES (1000, REPEAT('a', 4096));
+INSERT INTO t1 VALUES (1001, REPEAT('a', 4096));
+INSERT INTO t1 VALUES (1002, REPEAT('a', 4096));
+INSERT INTO t1 VALUES (1, REPEAT('a', 4096));
+INSERT INTO t1 VALUES (2, REPEAT('a', 4096));
+SELECT page_number, number_records
+FROM information_schema.innodb_sys_tablespaces s1,
+information_schema.innodb_buffer_page s2
+WHERE s1.space = s2.space AND name = 'test/t1'
+AND page_type = "INDEX" ORDER BY page_number;
+page_number number_records
+3 2
+4 3
+5 3
+INSERT INTO t1 VALUES (999, REPEAT('a', 4096));
+SELECT page_number, number_records
+FROM information_schema.innodb_sys_tablespaces s1,
+information_schema.innodb_buffer_page s2
+WHERE s1.space = s2.space AND name = 'test/t1'
+AND page_type = "INDEX" ORDER BY page_number;
+page_number number_records
+3 3
+4 3
+5 3
+6 1
+INSERT INTO t1 VALUES (998, REPEAT('a', 4096));
+SELECT page_number, number_records
+FROM information_schema.innodb_sys_tablespaces s1,
+information_schema.innodb_buffer_page s2
+WHERE s1.space = s2.space AND name = 'test/t1'
+AND page_type = "INDEX" ORDER BY page_number;
+page_number number_records
+3 3
+4 3
+5 3
+6 2
+INSERT INTO t1 VALUES (997, REPEAT('a', 4096));
+SELECT page_number, number_records
+FROM information_schema.innodb_sys_tablespaces s1,
+information_schema.innodb_buffer_page s2
+WHERE s1.space = s2.space AND name = 'test/t1'
+AND page_type = "INDEX" ORDER BY page_number;
+page_number number_records
+3 3
+4 3
+5 3
+6 3
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/innodb-16k.result b/mysql-test/suite/innodb/r/innodb-16k.result
index 9e6e5145fa0..77ff688f130 100644
--- a/mysql-test/suite/innodb/r/innodb-16k.result
+++ b/mysql-test/suite/innodb/r/innodb-16k.result
@@ -331,9 +331,10 @@ CREATE INDEX t1e ON t1 (e(767));
UPDATE t1 SET a=@c,b=@c,c=@c,d=@c,e=@c,f=@c,g=@c,h=@c,i=@c,j=@c,
k=@c,l=@c,m=@c,n=@c,o=@c,p=@c,q=@c,r=@c,s=@c,t=@c,u=@c;
CREATE INDEX t1f ON t1 (f(767));
+BEGIN;
UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d,f=@d,g=@d,h=@d,i=@d,j=@d,
k=@d,l=@d,m=@d,n=@d,o=@d,p=@d,q=@d,r=@d,s=@d,t=@d,u=@d;
-ERROR HY000: Undo log record is too big.
+ROLLBACK;
BEGIN;
UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d;
UPDATE t1 SET f=@d,g=@d,h=@d,i=@d,j=@d,k=@d,l=@d,m=@d,
@@ -366,8 +367,9 @@ UPDATE t1 SET r=@e;
CREATE INDEX t1s ON t1 (s(767));
UPDATE t1 SET s=@e;
CREATE INDEX t1t ON t1 (t(767));
+BEGIN;
UPDATE t1 SET t=@e;
-ERROR HY000: Undo log record is too big.
+ROLLBACK;
CREATE INDEX t1u ON t1 (u(767));
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
CREATE INDEX t1ut ON t1 (u(767), t(767));
@@ -546,11 +548,11 @@ PRIMARY KEY (b(10), a), INDEX (c(767)), INDEX(b(767))
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
INSERT INTO bug12547647 VALUES (5,REPEAT('khdfo5AlOq',1900),REPEAT('g',7751));
COMMIT;
+BEGIN;
UPDATE bug12547647 SET c = REPEAT('b',16928);
-ERROR HY000: Undo log record is too big.
SHOW WARNINGS;
Level Code Message
-Error 1713 Undo log record is too big.
+ROLLBACK;
DROP TABLE bug12547647;
SET SESSION innodb_strict_mode = off;
CREATE TABLE t1(
diff --git a/mysql-test/suite/innodb/r/innodb-32k.result b/mysql-test/suite/innodb/r/innodb-32k.result
index 2253ba5588f..f9635fefccb 100644
--- a/mysql-test/suite/innodb/r/innodb-32k.result
+++ b/mysql-test/suite/innodb/r/innodb-32k.result
@@ -228,13 +228,14 @@ aa=@c,ba=@c,ca=@c,da=@c,ea=@c,fa=@c,ga=@c,ha=@c,ia=@c,ja=@c,
ka=@c,la=@c,ma=@c,na=@c,oa=@c,pa=@c,qa=@c,ra=@c,sa=@c,ta=@c,ua=@c,
va=@c,wa=@c,xa=@c,ya=@c,za=@c;
CREATE INDEX t1f17 ON t1 (v(767));
+BEGIN;
UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d,f=@d,g=@d,h=@d,i=@d,j=@d,
k=@d,l=@d,m=@d,n=@d,o=@d,p=@d,q=@d,r=@d,s=@d,t=@d,u=@d,
v=@d,w=@d,x=@d,y=@d,z=@d,
aa=@d,ba=@d,ca=@d,da=@d,ea=@d,fa=@d,ga=@d,ha=@d,ia=@d,ja=@d,
ka=@d,la=@d,ma=@d,na=@d,oa=@d,pa=@d,qa=@d,ra=@d,sa=@d,ta=@d,ua=@d,
va=@d,wa=@d,xa=@d,ya=@d,za=@d;
-ERROR HY000: Undo log record is too big.
+ROLLBACK;
BEGIN;
UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d;
UPDATE t1 SET f=@d,g=@d,h=@d,i=@d,j=@d;
diff --git a/mysql-test/suite/innodb/r/innodb-64k.result b/mysql-test/suite/innodb/r/innodb-64k.result
index 0ce744e9e60..dc938f236cd 100644
--- a/mysql-test/suite/innodb/r/innodb-64k.result
+++ b/mysql-test/suite/innodb/r/innodb-64k.result
@@ -263,6 +263,7 @@ kc=@c,lc=@c,mc=@c,nc=@c,oc=@c,pc=@c,qc=@c,rc=@c,sc=@c,tc=@c,uc=@c,
vc=@c,wc=@c,xc=@c,yc=@c,zc=@c;
COMMIT;
CREATE INDEX tg1f2 ON t1 (ia(767),ja(767));
+BEGIN;
UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d,f=@d,g=@d,h=@d,i=@d,j=@d,
k=@d,l=@d,m=@d,n=@d,o=@d,p=@d,q=@d,r=@d,s=@d,t=@d,u=@d,
v=@d,w=@d,x=@d,y=@d,z=@d,
@@ -275,7 +276,7 @@ vb=@d,wb=@d,xb=@d,yb=@d,zb=@d,
ac=@d,bc=@d,cc=@d,dc=@d,ec=@d,fc=@d,gc=@d,hc=@d,ic=@d,jc=@d,
kc=@d,lc=@d,mc=@d,nc=@d,oc=@d,pc=@d,qc=@d,rc=@d,sc=@d,tc=@d,uc=@d,
vc=@d,wc=@d,xc=@d,yc=@d,zc=@d;
-ERROR HY000: Undo log record is too big.
+ROLLBACK;
BEGIN;
UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d;
UPDATE t1 SET f=@d,g=@d,h=@d,i=@d,j=@d;
diff --git a/mysql-test/suite/innodb/r/innodb-alter-autoinc.result b/mysql-test/suite/innodb/r/innodb-alter-autoinc.result
new file mode 100644
index 00000000000..82eb448fe45
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-alter-autoinc.result
@@ -0,0 +1,174 @@
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(347),(33101),(123),(45),(6);
+SET @old_sql_mode = @@sql_mode;
+SET @@sql_mode = 'STRICT_TRANS_TABLES';
+ALTER TABLE t1 ADD PRIMARY KEY(a);
+SET @@sql_mode = @old_sql_mode;
+ALTER TABLE t1 DROP PRIMARY KEY, ADD id INT AUTO_INCREMENT PRIMARY KEY,
+LOCK=NONE;
+ERROR 0A000: LOCK=NONE is not supported. Reason: Adding an auto-increment column requires a lock. Try LOCK=SHARED.
+ALTER TABLE t1 ADD id INT AUTO_INCREMENT;
+ERROR 42000: Incorrect table definition; there can be only one auto column and it must be defined as a key
+ALTER TABLE t1 ADD id INT AUTO_INCREMENT, ADD INDEX(a, id);
+ERROR 42000: Incorrect table definition; there can be only one auto column and it must be defined as a key
+ALTER TABLE t1 ADD id INT NOT NULL, ADD INDEX(id, a);
+SELECT * FROM t1;
+a id
+6 0
+45 0
+123 0
+347 0
+33101 0
+SET AUTO_INCREMENT_INCREMENT = 5, AUTO_INCREMENT_OFFSET = 30;
+ALTER TABLE t1 DROP PRIMARY KEY, ADD id INT AUTO_INCREMENT PRIMARY KEY,
+DROP COLUMN id, AUTO_INCREMENT = 42, ALGORITHM=COPY;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`id`),
+ KEY `id` (`id`,`a`)
+) ENGINE=InnoDB AUTO_INCREMENT=70 DEFAULT CHARSET=latin1
+BEGIN;
+INSERT INTO t1 VALUES(7,0);
+SELECT * FROM t1;
+a id
+6 45
+45 50
+123 55
+347 60
+33101 65
+7 70
+ROLLBACK;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`id`),
+ KEY `id` (`id`,`a`)
+) ENGINE=InnoDB AUTO_INCREMENT=75 DEFAULT CHARSET=latin1
+ALTER TABLE t1 DROP PRIMARY KEY, ADD id INT AUTO_INCREMENT PRIMARY KEY,
+DROP COLUMN id, AUTO_INCREMENT = 42, LOCK=NONE;
+ERROR 0A000: LOCK=NONE is not supported. Reason: Adding an auto-increment column requires a lock. Try LOCK=SHARED.
+ALTER TABLE t1 DROP PRIMARY KEY, ADD id INT AUTO_INCREMENT PRIMARY KEY,
+DROP COLUMN id, AUTO_INCREMENT = 42, ALGORITHM=INPLACE;
+SELECT * FROM t1;
+a id
+6 45
+45 50
+123 55
+347 60
+33101 65
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`id`),
+ KEY `id` (`id`,`a`)
+) ENGINE=InnoDB AUTO_INCREMENT=70 DEFAULT CHARSET=latin1
+INSERT INTO t1 SET a=123;
+INSERT INTO t1 VALUES(-123,-45);
+ALTER TABLE t1 AUTO_INCREMENT = 75;
+INSERT INTO t1 SET a=123;
+SELECT * FROM t1;
+a id
+-123 -45
+6 45
+45 50
+123 55
+347 60
+33101 65
+123 70
+123 75
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`id`),
+ KEY `id` (`id`,`a`)
+) ENGINE=InnoDB AUTO_INCREMENT=80 DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(347),(33101),(123),(45),(6);
+ALTER TABLE t1 ADD PRIMARY KEY(a);
+ALTER TABLE t1 ADD id INT NOT NULL, ADD INDEX(id, a);
+SELECT * FROM t1;
+a id
+6 0
+45 0
+123 0
+347 0
+33101 0
+ALTER TABLE t1 DROP PRIMARY KEY, ADD id INT AUTO_INCREMENT PRIMARY KEY,
+DROP COLUMN id, AUTO_INCREMENT = 42, ALGORITHM=INPLACE;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`id`),
+ KEY `id` (`id`,`a`)
+) ENGINE=InnoDB AUTO_INCREMENT=70 DEFAULT CHARSET=latin1
+BEGIN;
+INSERT INTO t1 VALUES(7,0);
+SELECT * FROM t1;
+a id
+6 45
+45 50
+123 55
+347 60
+33101 65
+7 70
+ROLLBACK;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`id`),
+ KEY `id` (`id`,`a`)
+) ENGINE=InnoDB AUTO_INCREMENT=75 DEFAULT CHARSET=latin1
+ALTER TABLE t1 DROP PRIMARY KEY, ADD id INT AUTO_INCREMENT PRIMARY KEY,
+DROP COLUMN id, AUTO_INCREMENT = 42, ALGORITHM=COPY;
+SELECT * FROM t1;
+a id
+6 45
+45 50
+123 55
+347 60
+33101 65
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`id`),
+ KEY `id` (`id`,`a`)
+) ENGINE=InnoDB AUTO_INCREMENT=75 DEFAULT CHARSET=latin1
+INSERT INTO t1 SET a=123;
+INSERT INTO t1 VALUES(-123,-45);
+ALTER TABLE t1 AUTO_INCREMENT = 75;
+INSERT INTO t1 SET a=123;
+SELECT * FROM t1;
+a id
+-123 -45
+6 45
+45 50
+123 55
+347 60
+33101 65
+123 75
+123 80
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL,
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`id`),
+ KEY `id` (`id`,`a`)
+) ENGINE=InnoDB AUTO_INCREMENT=85 DEFAULT CHARSET=latin1
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/innodb-alter-table.result b/mysql-test/suite/innodb/r/innodb-alter-table.result
index c4460a7226b..34a05d39882 100644
--- a/mysql-test/suite/innodb/r/innodb-alter-table.result
+++ b/mysql-test/suite/innodb/r/innodb-alter-table.result
@@ -185,3 +185,44 @@ ticket CREATE TABLE `ticket` (
KEY `org_id` (`org_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE ticket;
+CREATE TABLE t (
+id bigint(20) unsigned NOT NULL auto_increment,
+d date NOT NULL,
+a bigint(20) unsigned NOT NULL,
+b smallint(5) unsigned DEFAULT NULL,
+PRIMARY KEY (id,d)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs STATS_SAMPLE_PAGES=2
+PARTITION BY RANGE COLUMNS(d)
+(
+PARTITION p20170914 VALUES LESS THAN ('2017-09-15') ENGINE = InnoDB,
+PARTITION p99991231 VALUES LESS THAN (MAXVALUE) ENGINE = InnoDB);
+insert into t(d,a,b) values ('2017-09-15',rand()*10000,rand()*10);
+insert into t(d,a,b) values ('2017-09-15',rand()*10000,rand()*10);
+replace into t(d,a,b) select '2017-09-15',rand()*10000,rand()*10 from t t1, t t2, t t3, t t4;
+select count(*) from t where d ='2017-09-15';
+count(*)
+18
+ALTER TABLE t CHANGE b c smallint(5) unsigned , ADD KEY idx_d_a (d, a);
+SHOW CREATE TABLE t;
+Table Create Table
+t CREATE TABLE `t` (
+ `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ `d` date NOT NULL,
+ `a` bigint(20) unsigned NOT NULL,
+ `c` smallint(5) unsigned DEFAULT NULL,
+ PRIMARY KEY (`id`,`d`),
+ KEY `idx_d_a` (`d`,`a`)
+) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs STATS_SAMPLE_PAGES=2
+/*!50500 PARTITION BY RANGE COLUMNS(d)
+(PARTITION p20170914 VALUES LESS THAN ('2017-09-15') ENGINE = InnoDB,
+ PARTITION p99991231 VALUES LESS THAN (MAXVALUE) ENGINE = InnoDB) */
+analyze table t;
+Table Op Msg_type Msg_text
+test.t analyze status OK
+select count(*) from t where d ='2017-09-15';
+count(*)
+18
+select count(*) from t force index(primary) where d ='2017-09-15';
+count(*)
+18
+DROP TABLE t;
diff --git a/mysql-test/suite/innodb/r/innodb-alter.result b/mysql-test/suite/innodb/r/innodb-alter.result
new file mode 100644
index 00000000000..fadbcce332a
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-alter.result
@@ -0,0 +1,861 @@
+SET NAMES utf8;
+CREATE TABLE t1 (
+c1 INT PRIMARY KEY, c2 INT DEFAULT 1, ct TEXT,
+INDEX(c2))
+ENGINE=InnoDB;
+INSERT INTO t1 SET c1=1;
+CREATE TABLE sys_tables SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
+WHERE NAME LIKE 'test/t%';
+CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+CREATE TABLE t1p LIKE t1;
+CREATE TABLE t1c (c1 INT PRIMARY KEY, c2 INT, c3 INT, INDEX(c2), INDEX(c3),
+CONSTRAINT t1c2 FOREIGN KEY (c2) REFERENCES t1(c2),
+CONSTRAINT t1c3 FOREIGN KEY (c3) REFERENCES t1p(c2))
+ENGINE=InnoDB;
+CREATE TABLE sys_foreign SELECT i.*
+FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN i
+WHERE FOR_NAME LIKE 'test/t%';
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 c2 0
+test/t1c3 c3 c2 0
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c2 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 c2
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 c2 0
+test/t1c3 c3 c2 0
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT '1',
+ `ct` text,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 ALTER c2 DROP DEFAULT;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11),
+ `ct` text,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c2 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 c2
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 c2 0
+test/t1c3 c3 c2 0
+ALTER TABLE t1 CHANGE c2 c2 INT AFTER c1;
+ALTER TABLE t1 CHANGE c1 c1 INT FIRST;
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c2 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 c2
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 c2 0
+test/t1c3 c3 c2 0
+ALTER TABLE t1 CHANGE C2 c3 INT;
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c3 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 c3
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 c3 0
+test/t1c3 c3 c2 0
+ALTER TABLE t1 CHANGE c3 C INT;
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+C 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 C
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 C 0
+test/t1c3 c3 c2 0
+ALTER TABLE t1 CHANGE C Cöŀumň_TWO INT;
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 Cöŀumň_TWO 0
+test/t1c3 c3 c2 0
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+Cöŀumň_TWO 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 Cöŀumň_TWO
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 Cöŀumň_TWO 0
+test/t1c3 c3 c2 0
+ALTER TABLE t1 CHANGE cöĿǖmň_two c3 INT;
+ERROR 42S22: Unknown column 'cöĿǖmň_two' in 't1'
+ALTER TABLE t1 CHANGE cÖĿUMŇ_two c3 INT, RENAME TO t3;
+SELECT st.NAME, i.NAME
+FROM sys_tables st INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES i
+ON i.TABLE_ID=st.TABLE_ID;
+NAME NAME
+test/t1 test/t3
+SHOW CREATE TABLE t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `c1` int(11) NOT NULL,
+ `c3` int(11) DEFAULT NULL,
+ `ct` text,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`c3`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SHOW CREATE TABLE t1c;
+Table Create Table
+t1c CREATE TABLE `t1c` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `c3` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`c2`),
+ KEY `c3` (`c3`),
+ CONSTRAINT `t1c2` FOREIGN KEY (`c2`) REFERENCES `t3` (`c3`),
+ CONSTRAINT `t1c3` FOREIGN KEY (`c3`) REFERENCES `t1p` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t3 CHANGE c3
+`12345678901234567890123456789012345678901234567890123456789012345` INT;
+ERROR 42000: Identifier name '12345678901234567890123456789012345678901234567890123456789012345' is too long
+ALTER TABLE t3 CHANGE c3
+`1234567890123456789012345678901234567890123456789012345678901234` INT;
+SHOW CREATE TABLE t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `c1` int(11) NOT NULL,
+ `1234567890123456789012345678901234567890123456789012345678901234` int(11) DEFAULT NULL,
+ `ct` text,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`1234567890123456789012345678901234567890123456789012345678901234`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t3 CHANGE
+`1234567890123456789012345678901234567890123456789012345678901234`
+`倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ å€¡å€¢å€£å€¤å€¥å€¦å€§å€¨å€©å€ªå€«å€¬å€­å€®å€¯å€°å€±å€²å€³å€´å€µå€¶å€·å€¸å€¹å€ºå€»å€¼å€½å€¾å€¿å€` INT;
+ERROR 42000: Identifier name '倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ ' is too long
+ALTER TABLE t3 CHANGE
+`1234567890123456789012345678901234567890123456789012345678901234`
+`倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ å€¡å€¢å€£å€¤å€¥å€¦å€§å€¨å€©å€ªå€«å€¬å€­å€®å€¯å€°å€±å€²å€³å€´å€µå€¶å€·å€¸å€¹å€ºå€»å€¼å€½å€¾å€¿Ã¤` INT;
+ERROR 42000: Identifier name '倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ ' is too long
+ALTER TABLE t3 CHANGE
+`1234567890123456789012345678901234567890123456789012345678901234`
+`倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ å€¡å€¢å€£å€¤å€¥å€¦å€§å€¨å€©å€ªå€«å€¬å€­å€®å€¯å€°å€±å€²å€³å€´å€µå€¶å€·å€¸å€¹å€ºå€»å€¼å€½å€¾Ã¤` INT;
+ALTER TABLE t3 CHANGE
+`倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ å€¡å€¢å€£å€¤å€¥å€¦å€§å€¨å€©å€ªå€«å€¬å€­å€®å€¯å€°å€±å€²å€³å€´å€µå€¶å€·å€¸å€¹å€ºå€»å€¼å€½å€¾Ã„`
+c3 INT;
+ALTER TABLE t3 CHANGE c3 ðŒ€ðŒðŒ‚ðŒƒðŒ„ðŒ…ðŒ†ðŒ‡ðŒˆðŒ‰ðŒŠðŒ‹ðŒŒðŒðŒŽðŒðŒðŒ‘ðŒ’ðŒ“ðŒ”ðŒ•ðŒ–ðŒ—ðŒ˜ðŒ™ðŒšðŒ›ðŒœ INT;
+ERROR HY000: Invalid utf8 character string: '\xF0\x90\x8C\x80\xF0\x90\x8C\x81\xF0\x90\x8C\x82\xF0\x90\x8C\x83'
+ALTER TABLE t3 CHANGE c3 😲 INT;
+ERROR HY000: Invalid utf8 character string: '\xF0\x9F\x98\xB2'
+ALTER TABLE t3 RENAME TO t2;
+SELECT st.NAME, i.NAME
+FROM sys_tables st INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES i
+ON i.TABLE_ID=st.TABLE_ID;
+NAME NAME
+test/t1 test/t2
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `c1` int(11) NOT NULL,
+ `c3` int(11) DEFAULT NULL,
+ `ct` text,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`c3`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+RENAME TABLE t2 TO t1;
+SELECT st.NAME, i.NAME
+FROM sys_tables st INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES i
+ON i.TABLE_ID=st.TABLE_ID;
+NAME NAME
+test/t1 test/t1
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c3 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 c3
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 c3 0
+test/t1c3 c3 c2 0
+ALTER TABLE t1 DROP INDEX c2;
+ERROR HY000: Cannot drop index 'c2': needed in a foreign key constraint
+ALTER TABLE t1 DROP INDEX c4;
+ERROR 42000: Can't DROP 'c4'; check that column/key exists
+ALTER TABLE t1c DROP FOREIGN KEY c2;
+ERROR 42000: Can't DROP 'c2'; check that column/key exists
+ALTER TABLE t1c DROP FOREIGN KEY t1c2, DROP FOREIGN KEY c2;
+ERROR 42000: Can't DROP 'c2'; check that column/key exists
+ALTER TABLE t1c DROP FOREIGN KEY t1c2, DROP FOREIGN KEY c2, DROP INDEX c2;
+ERROR 42000: Can't DROP 'c2'; check that column/key exists
+ALTER TABLE t1c DROP INDEX c2;
+ERROR HY000: Cannot drop index 'c2': needed in a foreign key constraint
+ALTER TABLE t1c DROP FOREIGN KEY ẗ1C2;
+ERROR 42000: Can't DROP 'ẗ1C2'; check that column/key exists
+SHOW CREATE TABLE t1c;
+Table Create Table
+t1c CREATE TABLE `t1c` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `c3` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`c2`),
+ KEY `c3` (`c3`),
+ CONSTRAINT `t1c2` FOREIGN KEY (`c2`) REFERENCES `t1` (`c3`),
+ CONSTRAINT `t1c3` FOREIGN KEY (`c3`) REFERENCES `t1p` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SET foreign_key_checks=0;
+DROP TABLE t1p;
+SET foreign_key_checks=1;
+SHOW CREATE TABLE t1c;
+Table Create Table
+t1c CREATE TABLE `t1c` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `c3` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`c2`),
+ KEY `c3` (`c3`),
+ CONSTRAINT `t1c2` FOREIGN KEY (`c2`) REFERENCES `t1` (`c3`),
+ CONSTRAINT `t1c3` FOREIGN KEY (`c3`) REFERENCES `t1p` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c3 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 c3
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 c3 0
+test/t1c3 c3 c2 0
+CREATE TABLE t1p (c1 INT PRIMARY KEY, c2 INT, INDEX(c2)) ENGINE=InnoDB;
+ALTER TABLE t1c DROP INDEX C2, DROP INDEX C3;
+ERROR HY000: Cannot drop index 'c2': needed in a foreign key constraint
+ALTER TABLE t1c DROP INDEX C3;
+ERROR HY000: Cannot drop index 'c3': needed in a foreign key constraint
+SET foreign_key_checks=0;
+ALTER TABLE t1c DROP INDEX C3;
+SET foreign_key_checks=1;
+SHOW CREATE TABLE t1c;
+Table Create Table
+t1c CREATE TABLE `t1c` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `c3` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`c2`),
+ CONSTRAINT `t1c2` FOREIGN KEY (`c2`) REFERENCES `t1` (`c3`),
+ CONSTRAINT `t1c3` FOREIGN KEY (`c3`) REFERENCES `t1p` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c3 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 c3
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 c3 0
+test/t1c3 c3 c2 0
+ALTER TABLE t1c DROP FOREIGN KEY t1C3;
+SHOW CREATE TABLE t1c;
+Table Create Table
+t1c CREATE TABLE `t1c` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `c3` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`c2`),
+ CONSTRAINT `t1c2` FOREIGN KEY (`c2`) REFERENCES `t1` (`c3`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c3 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 c3
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 c3 0
+ALTER TABLE t1c DROP INDEX c2, DROP FOREIGN KEY t1C2;
+SHOW CREATE TABLE t1c;
+Table Create Table
+t1c CREATE TABLE `t1c` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `c3` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c3 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 c3
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+ALTER TABLE t1 DROP INDEX c2, CHANGE c3 c2 INT;
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c2 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+CREATE TABLE t1o LIKE t1;
+ALTER TABLE t1 ADD FULLTEXT INDEX (ct),
+CHANGE c1 pk INT, ALTER c2 SET DEFAULT 42, RENAME TO tt,
+ALGORITHM=INPLACE, LOCK=NONE;
+ERROR 0A000: LOCK=NONE is not supported. Reason: Fulltext index creation requires a lock. Try LOCK=SHARED.
+ALTER TABLE t1 ADD FULLTEXT INDEX (ct),
+CHANGE c1 pk INT, ALTER c2 SET DEFAULT 42, RENAME TO tt,
+ALGORITHM=INPLACE, LOCK=SHARED;
+Warnings:
+Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+SHOW CREATE TABLE tt;
+Table Create Table
+tt CREATE TABLE `tt` (
+ `pk` int(11) NOT NULL,
+ `c2` int(11) DEFAULT '42',
+ `ct` text,
+ PRIMARY KEY (`pk`),
+ FULLTEXT KEY `ct` (`ct`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t1o CHANGE c1 dB_row_Id INT, ALGORITHM=COPY;
+ERROR 42000: Incorrect column name 'dB_row_Id'
+ALTER TABLE t1o CHANGE c1 dB_row_Id INT, ALGORITHM=INPLACE;
+ERROR 42000: Incorrect column name 'DB_ROW_ID'
+ALTER TABLE t1o CHANGE c1 DB_TRX_ID INT;
+ERROR 42000: Incorrect column name 'DB_TRX_ID'
+ALTER TABLE t1o CHANGE c1 db_roll_ptr INT;
+ERROR 42000: Incorrect column name 'DB_ROLL_PTR'
+ALTER TABLE t1o ADD COLUMN DB_TRX_ID INT;
+ERROR 42000: Incorrect column name 'DB_TRX_ID'
+ALTER TABLE t1o ADD COLUMN db_roll_ptr INT;
+ERROR 42000: Incorrect column name 'db_roll_ptr'
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ADD COLUMN FTS_DOC_ID BIGINT;
+ERROR HY000: Column 'FTS_DOC_ID' is of wrong type for an InnoDB FULLTEXT index
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED;
+ERROR HY000: Column 'FTS_DOC_ID' is of wrong type for an InnoDB FULLTEXT index
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct),
+ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ADD COLUMN FTS_DOC_ID INT;
+ERROR 42S21: Duplicate column name 'FTS_DOC_ID'
+ALTER TABLE t1o DROP COLUMN FTS_DOC_ID, ALGORITHM=INPLACE;
+ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot drop or rename FTS_DOC_ID. Try ALGORITHM=COPY.
+ALTER TABLE t1o DROP COLUMN FTS_DOC_ID, DROP INDEX ct, ALGORITHM=INPLACE;
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ADD COLUMN cu TEXT;
+Warnings:
+Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID
+ALTER TABLE t1o ADD FULLTEXT INDEX(cu), ADD COLUMN FTS_DOC_ID BIGINT,
+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 t1o ADD FULLTEXT INDEX(cu), ADD COLUMN FTS_DOC_ID BIGINT;
+ERROR 42000: Incorrect column name 'FTS_DOC_ID'
+ALTER TABLE t1o ADD FULLTEXT INDEX(cu), ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED,
+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 t1o ADD FULLTEXT INDEX(cu), ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED;
+ERROR 42000: Incorrect column name 'FTS_DOC_ID'
+ALTER TABLE t1o ADD FULLTEXT INDEX(cu),
+ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL, 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 t1o ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
+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 t1o ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
+ALTER TABLE t1o DROP COLUMN FTS_DOC_ID, ALGORITHM=INPLACE;
+ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot drop or rename FTS_DOC_ID. Try ALGORITHM=COPY.
+ALTER TABLE t1o DROP COLUMN FTS_DOC_ID;
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_DOC_ID INT,
+ALGORITHM=COPY;
+ERROR 42000: Incorrect column name 'FTS_DOC_ID'
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_DOC_ID INT,
+ALGORITHM=INPLACE;
+ERROR 42000: Incorrect column name 'FTS_DOC_ID'
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_Doc_ID INT,
+ALGORITHM=INPLACE;
+ERROR 42000: Incorrect column name 'FTS_DOC_ID'
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct),
+CHANGE c1 FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE;
+ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.
+CREATE TABLE t1n LIKE t1o;
+ALTER TABLE t1n ADD FULLTEXT INDEX(ct);
+ALTER TABLE t1n CHANGE c1 Fts_DOC_ID INT, ALGORITHM=INPLACE;
+ERROR 42000: Incorrect column name 'FTS_DOC_ID'
+ALTER TABLE t1n CHANGE c1 Fts_DOC_ID INT, ALGORITHM=COPY;
+ERROR 42000: Incorrect column name 'Fts_DOC_ID'
+ALTER TABLE t1n CHANGE FTS_DOC_ID c11 INT, ALGORITHM=INPLACE;
+ERROR 42S22: Unknown column 'FTS_DOC_ID' in 't1n'
+ALTER TABLE t1n CHANGE c1 FTS_DOC_ïD INT, ALGORITHM=INPLACE;
+ALTER TABLE t1n CHANGE FTS_DOC_ÃD c1 INT, ALGORITHM=INPLACE;
+ALTER TABLE t1n CHANGE c1 c2 INT, CHANGE c2 ct INT, CHANGE ct c1 TEXT,
+ALGORITHM=INPLACE;
+SHOW CREATE TABLE t1n;
+Table Create Table
+t1n CREATE TABLE `t1n` (
+ `c2` int(11) NOT NULL,
+ `ct` int(11) DEFAULT NULL,
+ `c1` text,
+ `cu` text,
+ PRIMARY KEY (`c2`),
+ FULLTEXT KEY `ct` (`c1`),
+ FULLTEXT KEY `ct_2` (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t1n CHANGE c2 c1 INT, CHANGE ct c2 INT, CHANGE c1 ct TEXT,
+ALGORITHM=COPY;
+SHOW CREATE TABLE t1n;
+Table Create Table
+t1n CREATE TABLE `t1n` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `ct` text,
+ `cu` text,
+ PRIMARY KEY (`c1`),
+ FULLTEXT KEY `ct` (`ct`),
+ FULLTEXT KEY `ct_2` (`ct`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t1n ADD INDEX(c2), CHANGE c2 c4 INT, ALGORITHM=INPLACE;
+ERROR 42000: Key column 'c2' doesn't exist in table
+ALTER TABLE t1n ADD INDEX(c2), CHANGE c2 c4 INT, ALGORITHM=COPY;
+ERROR 42000: Key column 'c2' doesn't exist in table
+ALTER TABLE t1n ADD INDEX(c4), CHANGE c2 c4 INT, ALGORITHM=INPLACE;
+SHOW CREATE TABLE t1n;
+Table Create Table
+t1n CREATE TABLE `t1n` (
+ `c1` int(11) NOT NULL,
+ `c4` int(11) DEFAULT NULL,
+ `ct` text,
+ `cu` text,
+ PRIMARY KEY (`c1`),
+ KEY `c4` (`c4`),
+ FULLTEXT KEY `ct` (`ct`),
+ FULLTEXT KEY `ct_2` (`ct`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t1n DROP INDEX c4;
+ALTER TABLE t1n CHANGE c4 c1 INT, ADD INDEX(c1), ALGORITHM=INPLACE;
+ERROR 42S21: Duplicate column name 'c1'
+ALTER TABLE t1n CHANGE c4 c11 INT, ADD INDEX(c11), ALGORITHM=INPLACE;
+SHOW CREATE TABLE t1n;
+Table Create Table
+t1n CREATE TABLE `t1n` (
+ `c1` int(11) NOT NULL,
+ `c11` int(11) DEFAULT NULL,
+ `ct` text,
+ `cu` text,
+ PRIMARY KEY (`c1`),
+ KEY `c11` (`c11`),
+ FULLTEXT KEY `ct` (`ct`),
+ FULLTEXT KEY `ct_2` (`ct`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t1n;
+ALTER TABLE t1o MODIFY c1 BIGINT UNSIGNED NOT NULL, DROP INDEX ct,
+ALGORITHM=INPLACE;
+ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.
+ALTER TABLE t1o MODIFY c1 BIGINT UNSIGNED NOT NULL, DROP INDEX ct;
+ALTER TABLE t1o CHANGE c1 FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE;
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ALGORITHM=INPLACE;
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE;
+ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot drop or rename FTS_DOC_ID. Try ALGORITHM=COPY.
+SELECT sc.pos FROM information_schema.innodb_sys_columns sc
+INNER JOIN information_schema.innodb_sys_tables st
+ON sc.TABLE_ID=st.TABLE_ID
+WHERE st.NAME='test/t1o' AND sc.NAME='FTS_DOC_ID';
+pos
+0
+SHOW CREATE TABLE t1o;
+Table Create Table
+t1o CREATE TABLE `t1o` (
+ `FTS_DOC_ID` bigint(20) unsigned NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `ct` text,
+ `cu` text,
+ PRIMARY KEY (`FTS_DOC_ID`),
+ FULLTEXT KEY `ct` (`ct`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
+DROP INDEX ct, ALGORITHM=INPLACE;
+SHOW CREATE TABLE t1o;
+Table Create Table
+t1o CREATE TABLE `t1o` (
+ `foo_id` bigint(20) unsigned NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `ct` text,
+ `cu` text,
+ PRIMARY KEY (`foo_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t1c, t1p, sys_tables, sys_indexes, sys_foreign;
+CREATE TABLE sys_tables SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
+WHERE NAME='test/t1o';
+CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+CREATE TABLE sys_foreign SELECT i.*
+FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN i WHERE FOR_NAME='test/t1o';
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+foo_id 0 6 1800 8
+c2 1 6 1027 4
+ct 2 5 524540 10
+cu 3 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 foo_id
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+ALTER TABLE t1o ADD UNIQUE INDEX FTS_DOC_ID_INDEX(FTS_DOC_ID),
+ADD FULLTEXT INDEX(ct),
+CHANGE foo_id FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
+ALTER TABLE t1o DROP INDEX ct, DROP INDEX FTS_DOC_ID_INDEX,
+CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL;
+ALTER TABLE t1o ADD UNIQUE INDEX FTS_DOC_ID_INDEX(foo_id);
+ALTER TABLE t1o CHANGE foo_id FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
+ADD FULLTEXT INDEX(ct);
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE;
+ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot drop or rename FTS_DOC_ID. Try ALGORITHM=COPY.
+DROP TABLE sys_indexes;
+CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+FTS_DOC_ID 0 6 1800 8
+c2 1 6 1027 4
+ct 2 5 524540 10
+cu 3 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 FTS_DOC_ID
+FTS_DOC_ID_INDEX 0 FTS_DOC_ID
+ct 0 ct
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+DROP TABLE tt, t1o, sys_tables, sys_indexes, sys_foreign;
+CREATE TABLE t (t TEXT, FULLTEXT(t)) ENGINE=InnoDB;
+DROP INDEX t ON t;
+SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name
+FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
+WHERE name LIKE '%FTS_%' ORDER BY 1, 2;
+prefix name
+FTS_0 test/FTS_AUX_BEING_DELETED
+FTS_0 test/FTS_AUX_BEING_DELETED_CACHE
+FTS_0 test/FTS_AUX_CONFIG
+FTS_0 test/FTS_AUX_DELETED
+FTS_0 test/FTS_AUX_DELETED_CACHE
+SELECT sc.pos, sc.NAME FROM information_schema.innodb_sys_columns sc
+INNER JOIN information_schema.innodb_sys_tables st
+ON sc.TABLE_ID=st.TABLE_ID
+WHERE st.NAME='test/t';
+pos NAME
+0 t
+1 FTS_DOC_ID
+ALTER TABLE t ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE;
+SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name
+FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
+WHERE name LIKE '%FTS_%' ORDER BY 1, 2;
+prefix name
+ALTER TABLE t ADD FULLTEXT INDEX(t);
+Warnings:
+Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID
+SELECT sc.pos, sc.NAME FROM information_schema.innodb_sys_columns sc
+INNER JOIN information_schema.innodb_sys_tables st
+ON sc.TABLE_ID=st.TABLE_ID
+WHERE st.NAME='test/t';
+pos NAME
+0 t
+1 FTS_DOC_ID
+DROP TABLE t;
+#
+# Bug #19465984 INNODB DATA DICTIONARY IS NOT UPDATED WHILE
+# RENAMING THE COLUMN
+#
+CREATE TABLE t1(c1 INT NOT NULL, PRIMARY KEY(c1))ENGINE=INNODB;
+CREATE TABLE t2(c2 INT NOT NULL, FOREIGN KEY(c2) REFERENCES t1(c1))ENGINE=INNODB;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `c2` int(11) NOT NULL,
+ KEY `c2` (`c2`),
+ CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`c2`) REFERENCES `t1` (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 CHANGE COLUMN c1 C1 INT;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `C1` int(11) NOT NULL,
+ PRIMARY KEY (`C1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `c2` int(11) NOT NULL,
+ KEY `c2` (`c2`),
+ CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`c2`) REFERENCES `t1` (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `C1` int(11) NOT NULL,
+ PRIMARY KEY (`C1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `c2` int(11) NOT NULL,
+ KEY `c2` (`c2`),
+ CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`c2`) REFERENCES `t1` (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t2, t1;
+#
+# BUG 20029625 - HANDLE_FATAL_SIGNAL (SIG=11) IN
+# DICT_MEM_TABLE_COL_RENAME_LOW
+#
+CREATE TABLE parent(a INT, b INT, KEY(a, b)) ENGINE = InnoDB;
+CREATE TABLE t1(a1 INT, a2 INT) ENGINE = InnoDB;
+set foreign_key_checks=0;
+ALTER TABLE t1 ADD CONSTRAINT fk_a FOREIGN KEY(a1, a2) REFERENCES parent(a, b) ON DELETE SET NULL ON UPDATE CASCADE;
+ALTER TABLE t1 CHANGE a2 a3 INT,ADD CONSTRAINT fk_1 FOREIGN KEY(a1, a3) REFERENCES parent(a, b) ON DELETE SET NULL ON UPDATE CASCADE;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a1` int(11) DEFAULT NULL,
+ `a3` int(11) DEFAULT NULL,
+ KEY `fk_1` (`a1`,`a3`),
+ CONSTRAINT `fk_1` FOREIGN KEY (`a1`, `a3`) REFERENCES `parent` (`a`, `b`) ON DELETE SET NULL ON UPDATE CASCADE,
+ CONSTRAINT `fk_a` FOREIGN KEY (`a1`, `a3`) REFERENCES `parent` (`a`, `b`) ON DELETE SET NULL ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+ALTER TABLE t1 CHANGE a3 a4 INT;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a1` int(11) DEFAULT NULL,
+ `a4` int(11) DEFAULT NULL,
+ KEY `fk_1` (`a1`,`a4`),
+ CONSTRAINT `fk_1` FOREIGN KEY (`a1`, `a4`) REFERENCES `parent` (`a`, `b`) ON DELETE SET NULL ON UPDATE CASCADE,
+ CONSTRAINT `fk_a` FOREIGN KEY (`a1`, `a4`) REFERENCES `parent` (`a`, `b`) ON DELETE SET NULL ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+ALTER TABLE parent CHANGE b c INT;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a1` int(11) DEFAULT NULL,
+ `a4` int(11) DEFAULT NULL,
+ KEY `fk_1` (`a1`,`a4`),
+ CONSTRAINT `fk_1` FOREIGN KEY (`a1`, `a4`) REFERENCES `parent` (`a`, `c`) ON DELETE SET NULL ON UPDATE CASCADE,
+ CONSTRAINT `fk_a` FOREIGN KEY (`a1`, `a4`) REFERENCES `parent` (`a`, `c`) ON DELETE SET NULL ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+DROP TABLE t1, parent;
+#
+#BUG#21514135 SCHEMA MISMATCH ERROR WHEN IMPORTING TABLESPACE AFTER
+#DROPPING AN INDEX
+#
+CREATE DATABASE source_db;
+CREATE DATABASE dest_db;
+CREATE TABLE source_db.t1 (
+id int(11) NOT NULL,
+age int(11) DEFAULT NULL,
+name varchar(20),
+PRIMARY KEY (id),
+KEY index1 (age)
+) ENGINE=InnoDB;
+ALTER TABLE source_db.t1 DROP INDEX index1, ADD INDEX index2(name, age), algorithm=inplace;
+FLUSH TABLES source_db.t1 FOR EXPORT;
+UNLOCK TABLES;
+USE dest_db;
+CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ `age` int(11) DEFAULT NULL,
+ `name` varchar(20) DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `index2` (`name`,`age`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+ALTER TABLE dest_db.t1 DISCARD TABLESPACE;
+ALTER TABLE dest_db.t1 IMPORT TABLESPACE;
+CHECK TABLE dest_db.t1;
+Table Op Msg_type Msg_text
+dest_db.t1 check status OK
+SHOW CREATE TABLE dest_db.t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ `age` int(11) DEFAULT NULL,
+ `name` varchar(20) DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `index2` (`name`,`age`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SELECT * FROM dest_db.t1;
+id age name
+DROP TABLE dest_db.t1;
+ALTER TABLE source_db.t1 DROP INDEX index2, algorithm=inplace;
+FLUSH TABLES source_db.t1 FOR EXPORT;
+UNLOCK TABLES;
+USE dest_db;
+CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ `age` int(11) DEFAULT NULL,
+ `name` varchar(20) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+ALTER TABLE dest_db.t1 DISCARD TABLESPACE;
+ALTER TABLE dest_db.t1 IMPORT TABLESPACE;
+CHECK TABLE dest_db.t1;
+Table Op Msg_type Msg_text
+dest_db.t1 check status OK
+SHOW CREATE TABLE dest_db.t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ `age` int(11) DEFAULT NULL,
+ `name` varchar(20) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SELECT * FROM dest_db.t1;
+id age name
+DROP TABLE dest_db.t1;
+DROP TABLE source_db.t1;
+DROP DATABASE source_db;
+DROP DATABASE dest_db;
diff --git a/mysql-test/suite/innodb/r/innodb-autoinc.result b/mysql-test/suite/innodb/r/innodb-autoinc.result
index ddca4685e05..7d50ed00a92 100644
--- a/mysql-test/suite/innodb/r/innodb-autoinc.result
+++ b/mysql-test/suite/innodb/r/innodb-autoinc.result
@@ -1348,3 +1348,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-enlarge-blob.result b/mysql-test/suite/innodb/r/innodb-enlarge-blob.result
index e74e954e360..8c8e9cf5007 100644
--- a/mysql-test/suite/innodb/r/innodb-enlarge-blob.result
+++ b/mysql-test/suite/innodb/r/innodb-enlarge-blob.result
@@ -1,37 +1,17 @@
-CREATE TABLE t1 (a LONGTEXT) ENGINE=INNODB DEFAULT CHARSET=UTF8 ROW_FORMAT=DYNAMIC;
+CREATE TABLE t1 (a LONGTEXT) ENGINE=INNODB ROW_FORMAT=REDUNDANT;
SHOW WARNINGS;
Level Code Message
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B');
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-UPDATE t1 SET a=CONCAT(a, RAND(), a);
+INSERT INTO t1 SET a=CONCAT('A', SPACE(8000), 'B');
+INSERT INTO t1 SELECT a FROM t1;
UPDATE t1 SET a=CONCAT(a, RAND(), a);
UPDATE t1 SET a=CONCAT(a, RAND(), a);
SELECT * from t1;
DROP TABLE t1;
-CREATE TABLE t1 (a LONGTEXT) ENGINE=INNODB DEFAULT CHARSET=UTF8 ROW_FORMAT=REDUNDANT;
+CREATE TABLE t1 (a LONGTEXT) ENGINE=INNODB ROW_FORMAT=DYNAMIC;
SHOW WARNINGS;
Level Code Message
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B');
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-UPDATE t1 SET a=CONCAT(a, RAND(), a);
+INSERT INTO t1 SET a=CONCAT('A', SPACE(8000), 'B');
+INSERT INTO t1 SELECT a FROM t1;
UPDATE t1 SET a=CONCAT(a, RAND(), a);
UPDATE t1 SET a=CONCAT(a, RAND(), a);
SELECT * from t1;
diff --git a/mysql-test/suite/innodb/r/innodb-get-fk.result b/mysql-test/suite/innodb/r/innodb-get-fk.result
index ee17f262854..aa1bff8f134 100644
--- a/mysql-test/suite/innodb/r/innodb-get-fk.result
+++ b/mysql-test/suite/innodb/r/innodb-get-fk.result
@@ -40,6 +40,9 @@ crew_role_assigned CREATE TABLE `crew_role_assigned` (
CONSTRAINT `fk_crewRoleAssigned_crewId` FOREIGN KEY (`crew_id`) REFERENCES `crew` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `fk_crewRoleAssigned_pilotId` FOREIGN KEY (`crew_id`) REFERENCES `pilot` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='This is a comment about tables'
+SET GLOBAL innodb_buffer_pool_load_now = ON;
+SET GLOBAL innodb_buffer_pool_dump_now = ON;
+SET GLOBAL innodb_buffer_pool_load_abort = ON;
ALTER TABLE `repro`.`crew_role_assigned` COMMENT = "This is a new comment about tables";
SHOW CREATE TABLE `repro`.`crew_role_assigned`;
Table Create Table
diff --git a/mysql-test/suite/innodb/r/innodb-index-debug.result b/mysql-test/suite/innodb/r/innodb-index-debug.result
new file mode 100644
index 00000000000..69dd8742b5b
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-index-debug.result
@@ -0,0 +1,91 @@
+set global innodb_file_per_table=on;
+set global innodb_file_format='Barracuda';
+CREATE TABLE t1(c1 INT NOT NULL, c2 INT, PRIMARY KEY(c1)) Engine=InnoDB;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5);
+SET @saved_debug_dbug = @@SESSION.debug_dbug;
+SET DEBUG_DBUG='+d,ib_build_indexes_too_many_concurrent_trxs, ib_rename_indexes_too_many_concurrent_trxs, ib_drop_index_too_many_concurrent_trxs';
+ALTER TABLE t1 ADD UNIQUE INDEX(c2);
+ERROR HY000: Too many active concurrent transactions
+SET DEBUG_DBUG = @saved_debug_dbug;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE bug13861218 (c1 INT NOT NULL, c2 INT NOT NULL, INDEX(c2))
+ENGINE=InnoDB;
+INSERT INTO bug13861218 VALUES (8, 0), (4, 0), (0, 0);
+SET DEBUG_DBUG = '+d,ib_row_merge_buf_add_two';
+CREATE UNIQUE INDEX ui ON bug13861218(c1);
+SET DEBUG_DBUG = @saved_debug_dbug;
+DROP TABLE bug13861218;
+CREATE TABLE bug13861218 (c1 INT NOT NULL, c2 INT UNIQUE) ENGINE=InnoDB;
+INSERT INTO bug13861218 VALUES (8, NULL), (4, NULL), (0, NULL);
+SET DEBUG_DBUG = '+d,ib_row_merge_buf_add_two';
+CREATE UNIQUE INDEX ui ON bug13861218(c1);
+SET DEBUG_DBUG = @saved_debug_dbug;
+DROP TABLE bug13861218;
+set global innodb_file_per_table=1;
+set global innodb_file_format=Antelope;
+set global innodb_file_format_max=Antelope;
+#
+# Bug #21762319 ADDING INDEXES ON EMPTY TABLE IS SLOW
+# WITH LARGE INNODB_SORT_BUFFER_SIZE.
+call mtr.add_suppression("InnoDB: Cannot create temporary merge file");
+create table t480(a serial)engine=innodb;
+insert into t480
+values(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),
+(),(),(),(),(),(),(),();
+insert into t480 select 0 from t480;
+insert into t480 select 0 from t480;
+insert into t480 select 0 from t480;
+insert into t480 select 0 from t480;
+create table t1(f1 int auto_increment not null,
+f2 char(200) not null, f3 char(200) not null,
+f4 char(200) not null,primary key(f1))engine=innodb;
+insert into t1 select NULL,'aaa','bbb','ccc' from t480;
+insert into t1 select NULL,'aaaa','bbbb','cccc' from t480;
+insert into t1 select NULL,'aaaaa','bbbbb','ccccc' from t480;
+insert into t1 select NULL,'aaaaaa','bbbbbb','cccccc' from t480;
+insert into t1 select NULL,'aaaaaaa','bbbbbbb','ccccccc' from t480;
+insert into t1 select NULL,'aaaaaaaa','bbbbbbbb','cccccccc' from t480;
+select count(*) from t1;
+count(*)
+2880
+SET DEBUG_DBUG = '+d,innobase_tmpfile_creation_failure';
+alter table t1 force, algorithm=inplace;
+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
+SET DEBUG_DBUG = @saved_debug_dbug;
+drop table t1, 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;
+SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL built WAIT_FOR log';
+ALTER TABLE t1 DROP j, FORCE;
+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';
+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;
+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';
+ERROR 23000: Duplicate entry '0' for key 'i'
+SET DEBUG_SYNC='RESET';
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/innodb-index-online,crypt.rdiff b/mysql-test/suite/innodb/r/innodb-index-online,crypt.rdiff
new file mode 100644
index 00000000000..767e36f3bfb
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-index-online,crypt.rdiff
@@ -0,0 +1,20 @@
+--- innodb-index-online.result
++++ innodb-index-online,crypt.reject
+@@ -260,7 +260,7 @@
+ @merge_encrypt_1>@merge_encrypt_0, @merge_decrypt_1>@merge_decrypt_0,
+ @rowlog_encrypt_1>@rowlog_encrypt_0;
+ sort_balance @merge_encrypt_1>@merge_encrypt_0 @merge_decrypt_1>@merge_decrypt_0 @rowlog_encrypt_1>@rowlog_encrypt_0
+-0 0 0 0
++0 1 1 1
+ SET DEBUG_SYNC = 'now SIGNAL dml2_done';
+ ERROR HY000: Creating index 'c2e' required more than 'innodb_online_alter_log_max_size' bytes of modification log. Please try again.
+ SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+@@ -364,7 +364,7 @@
+ @rowlog_encrypt_2-@rowlog_encrypt_1>0 as log_encrypted,
+ @rowlog_decrypt_2-@rowlog_decrypt_1>0 as log_decrypted;
+ sort_encrypted sort_decrypted log_encrypted log_decrypted
+-0 0 0 0
++1 1 1 1
+ SELECT COUNT(c22f) FROM t1;
+ COUNT(c22f)
+ 320
diff --git a/mysql-test/suite/innodb/r/innodb-index-online-delete.result b/mysql-test/suite/innodb/r/innodb-index-online-delete.result
new file mode 100644
index 00000000000..d02d78acb32
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-index-online-delete.result
@@ -0,0 +1,13 @@
+CREATE TABLE t (a INT PRIMARY KEY, b INT NOT NULL) ENGINE=InnoDB;
+INSERT INTO t VALUES(1,2),(2,3);
+SET DEBUG_SYNC='alter_table_inplace_after_lock_downgrade SIGNAL do WAIT_FOR m';
+SET DEBUG_SYNC='innodb_after_inplace_alter_table SIGNAL scanned WAIT_FOR done';
+CREATE INDEX tb ON t(b);
+SET DEBUG_SYNC='now WAIT_FOR do';
+SET DEBUG_SYNC='row_update_for_mysql_error SIGNAL m WAIT_FOR scanned';
+UPDATE t SET a=2 WHERE a=1;
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+call mtr.add_suppression('InnoDB: record in index .*tb was not found on rollback, trying to insert');
+SET DEBUG_SYNC='now SIGNAL done';
+SET DEBUG_SYNC='RESET';
+DROP TABLE t;
diff --git a/mysql-test/suite/innodb/r/innodb-index-online-fk.result b/mysql-test/suite/innodb/r/innodb-index-online-fk.result
new file mode 100644
index 00000000000..f37cd844adb
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-index-online-fk.result
@@ -0,0 +1,604 @@
+CREATE TABLE parent (a INT PRIMARY KEY, b INT NOT NULL) ENGINE = InnoDB;
+INSERT INTO parent VALUES(1,2),(2,3);
+CREATE INDEX tb ON parent(b);
+INSERT INTO parent VALUES(10,20),(20,30);
+CREATE TABLE child (a1 INT PRIMARY KEY, a2 INT) ENGINE = InnoDB;
+CREATE INDEX tb ON child(a2);
+INSERT INTO child VALUES(10,20);
+ALTER TABLE child ADD FOREIGN KEY(a2) REFERENCES parent(b),
+ALGORITHM = INPLACE;
+ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Adding foreign keys needs foreign_key_checks=OFF. Try ALGORITHM=COPY.
+SET foreign_key_checks = 0;
+ALTER TABLE child ADD CONSTRAINT fk_1 FOREIGN KEY (a2)
+REFERENCES parent(b) ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN;
+ID FOR_NAME REF_NAME N_COLS TYPE
+test/fk_1 test/child test/parent 1 6
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/fk_1 a2 b 0
+ALTER TABLE child ADD CONSTRAINT fk_1 FOREIGN KEY (a2)
+REFERENCES parent(b) ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+ERROR HY000: Duplicate foreign key constraint name 'test/fk_1'
+SET foreign_key_checks = 1;
+INSERT INTO child VALUES(1,2),(2,3);
+INSERT INTO child VALUES(4,4);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `fk_1` FOREIGN KEY (`a2`) REFERENCES `parent` (`b`) ON DELETE SET NULL ON UPDATE CASCADE)
+SELECT * FROM parent;
+a b
+1 2
+2 3
+10 20
+20 30
+SET foreign_key_checks = 0;
+ALTER TABLE child ADD CONSTRAINT fk_20 FOREIGN KEY (a1, a2)
+REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+ERROR HY000: Failed to add the foreign key constaint. Missing index for constraint 'fk_20' in the referenced table 'parent'
+SHOW WARNINGS;
+Level Code Message
+Error 1822 Failed to add the foreign key constaint. Missing index for constraint 'fk_20' in the referenced table 'parent'
+SHOW ERRORS;
+Level Code Message
+Error 1822 Failed to add the foreign key constaint. Missing index for constraint 'fk_20' in the referenced table 'parent'
+CREATE INDEX idx1 on parent(a, b);
+ALTER TABLE child ADD CONSTRAINT fk_10 FOREIGN KEY (a1, a2)
+REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+ALTER TABLE child ADD CONSTRAINT fk_2 FOREIGN KEY (a1, a2)
+REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE, ADD INDEX idx1(a1,a2),
+ALGORITHM = INPLACE;
+ALTER TABLE child ADD CONSTRAINT fk_3 FOREIGN KEY (a1, a2)
+REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE;
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN;
+ID FOR_NAME REF_NAME N_COLS TYPE
+test/fk_1 test/child test/parent 1 6
+test/fk_10 test/child test/parent 2 5
+test/fk_2 test/child test/parent 2 5
+test/fk_3 test/child test/parent 2 5
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/fk_1 a2 b 0
+test/fk_10 a1 a 0
+test/fk_10 a2 b 1
+test/fk_2 a1 a 0
+test/fk_2 a2 b 1
+test/fk_3 a1 a 0
+test/fk_3 a2 b 1
+SET foreign_key_checks = 1;
+INSERT INTO child VALUES(5,4);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `fk_1` FOREIGN KEY (`a2`) REFERENCES `parent` (`b`) ON DELETE SET NULL ON UPDATE CASCADE)
+SHOW CREATE TABLE child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a1` int(11) NOT NULL,
+ `a2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`a1`),
+ KEY `tb` (`a2`),
+ KEY `idx1` (`a1`,`a2`),
+ CONSTRAINT `fk_1` FOREIGN KEY (`a2`) REFERENCES `parent` (`b`) ON DELETE SET NULL ON UPDATE CASCADE,
+ CONSTRAINT `fk_10` FOREIGN KEY (`a1`, `a2`) REFERENCES `parent` (`a`, `b`) ON DELETE CASCADE ON UPDATE CASCADE,
+ CONSTRAINT `fk_2` FOREIGN KEY (`a1`, `a2`) REFERENCES `parent` (`a`, `b`) ON DELETE CASCADE ON UPDATE CASCADE,
+ CONSTRAINT `fk_3` FOREIGN KEY (`a1`, `a2`) REFERENCES `parent` (`a`, `b`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DELETE FROM parent where a = 1;
+SELECT * FROM child;
+a1 a2
+1 NULL
+2 3
+10 20
+SET foreign_key_checks = 0;
+SET @saved_debug_dbug = @@SESSION.debug_dbug;
+SET DEBUG_DBUG = '+d,innodb_test_open_ref_fail';
+ALTER TABLE child ADD CONSTRAINT fk_4 FOREIGN KEY (a1, a2)
+REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+SET DEBUG_DBUG = @saved_debug_dbug;
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN;
+ID FOR_NAME REF_NAME N_COLS TYPE
+test/fk_1 test/child test/parent 1 6
+test/fk_10 test/child test/parent 2 5
+test/fk_2 test/child test/parent 2 5
+test/fk_3 test/child test/parent 2 5
+test/fk_4 test/child test/parent 2 5
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/fk_1 a2 b 0
+test/fk_10 a1 a 0
+test/fk_10 a2 b 1
+test/fk_2 a1 a 0
+test/fk_2 a2 b 1
+test/fk_3 a1 a 0
+test/fk_3 a2 b 1
+test/fk_4 a1 a 0
+test/fk_4 a2 b 1
+SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name;
+name name
+test/child a1
+test/child a2
+SELECT NAME FROM information_schema.INNODB_SYS_TABLES;
+NAME
+SYS_DATAFILES
+SYS_FOREIGN
+SYS_FOREIGN_COLS
+SYS_TABLESPACES
+mysql/innodb_index_stats
+mysql/innodb_table_stats
+test/child
+test/parent
+INSERT INTO child VALUES(5,4);
+SET foreign_key_checks = 1;
+INSERT INTO child VALUES(6,5);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `fk_1` FOREIGN KEY (`a2`) REFERENCES `parent` (`b`) ON DELETE SET NULL ON UPDATE CASCADE)
+SET foreign_key_checks = 0;
+CREATE TABLE `#parent` (a INT PRIMARY KEY, b INT NOT NULL) ENGINE = InnoDB;
+CREATE INDEX tb ON `#parent`(a, b);
+CREATE TABLE `#child` (a1 INT PRIMARY KEY, a2 INT) ENGINE = InnoDB;
+CREATE INDEX tb ON `#child`(a1, a2);
+SET DEBUG_DBUG = '+d,innodb_test_no_foreign_idx';
+ALTER TABLE `#child` ADD CONSTRAINT fk_40 FOREIGN KEY (a1, a2)
+REFERENCES `#parent`(a, b) ON DELETE CASCADE ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+ERROR HY000: Failed to add the foreign key constaint. Missing index for constraint 'fk_40' in the foreign table '#child'
+SET DEBUG_DBUG = @saved_debug_dbug;
+SHOW ERRORS;
+Level Code Message
+Error 1821 Failed to add the foreign key constaint. Missing index for constraint 'fk_40' in the foreign table '#child'
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN;
+ID FOR_NAME REF_NAME N_COLS TYPE
+test/fk_1 test/child test/parent 1 6
+test/fk_10 test/child test/parent 2 5
+test/fk_2 test/child test/parent 2 5
+test/fk_3 test/child test/parent 2 5
+test/fk_4 test/child test/parent 2 5
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/fk_1 a2 b 0
+test/fk_10 a1 a 0
+test/fk_10 a2 b 1
+test/fk_2 a1 a 0
+test/fk_2 a2 b 1
+test/fk_3 a1 a 0
+test/fk_3 a2 b 1
+test/fk_4 a1 a 0
+test/fk_4 a2 b 1
+SET DEBUG_DBUG = '+d,innodb_test_no_reference_idx';
+ALTER TABLE child ADD CONSTRAINT fk_42 FOREIGN KEY (a1, a2)
+REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+ERROR HY000: Failed to add the foreign key constaint. Missing index for constraint 'fk_42' in the referenced table 'parent'
+SET DEBUG_DBUG = @saved_debug_dbug;
+SHOW ERRORS;
+Level Code Message
+Error 1822 Failed to add the foreign key constaint. Missing index for constraint 'fk_42' in the referenced table 'parent'
+SET DEBUG_DBUG = '+d,innodb_test_wrong_fk_option';
+ALTER TABLE child ADD CONSTRAINT fk_42 FOREIGN KEY (a1, a2)
+REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+ERROR HY000: Failed to add the foreign key constraint on table 'child'. Incorrect options in FOREIGN KEY constraint 'test/fk_42'
+SET DEBUG_DBUG = @saved_debug_dbug;
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN;
+ID FOR_NAME REF_NAME N_COLS TYPE
+test/fk_1 test/child test/parent 1 6
+test/fk_10 test/child test/parent 2 5
+test/fk_2 test/child test/parent 2 5
+test/fk_3 test/child test/parent 2 5
+test/fk_4 test/child test/parent 2 5
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/fk_1 a2 b 0
+test/fk_10 a1 a 0
+test/fk_10 a2 b 1
+test/fk_2 a1 a 0
+test/fk_2 a2 b 1
+test/fk_3 a1 a 0
+test/fk_3 a2 b 1
+test/fk_4 a1 a 0
+test/fk_4 a2 b 1
+SET DEBUG_DBUG = '+d,innodb_test_cannot_add_fk_system';
+ALTER TABLE `#child` ADD CONSTRAINT fk_43 FOREIGN KEY (a1, a2)
+REFERENCES `#parent`(a, b) ON DELETE CASCADE ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+ERROR HY000: Failed to add the foreign key constraint 'test/fk_43' to system tables
+SET DEBUG_DBUG = @saved_debug_dbug;
+SHOW ERRORS;
+Level Code Message
+Error 1823 Failed to add the foreign key constraint 'test/fk_43' to system tables
+DROP TABLE `#child`;
+DROP TABLE `#parent`;
+SET foreign_key_checks = 0;
+ALTER TABLE child ADD CONSTRAINT fk_5 FOREIGN KEY (a2) REFERENCES parent(b)
+ON DELETE SET NULL ON UPDATE CASCADE,
+ADD CONSTRAINT fk_6 FOREIGN KEY (a1, a2)
+REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN;
+ID FOR_NAME REF_NAME N_COLS TYPE
+test/fk_1 test/child test/parent 1 6
+test/fk_10 test/child test/parent 2 5
+test/fk_2 test/child test/parent 2 5
+test/fk_3 test/child test/parent 2 5
+test/fk_4 test/child test/parent 2 5
+test/fk_5 test/child test/parent 1 6
+test/fk_6 test/child test/parent 2 5
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/fk_1 a2 b 0
+test/fk_10 a1 a 0
+test/fk_10 a2 b 1
+test/fk_2 a1 a 0
+test/fk_2 a2 b 1
+test/fk_3 a1 a 0
+test/fk_3 a2 b 1
+test/fk_4 a1 a 0
+test/fk_4 a2 b 1
+test/fk_5 a2 b 0
+test/fk_6 a1 a 0
+test/fk_6 a2 b 1
+DROP TABLE child;
+DROP TABLE parent;
+CREATE TABLE parent (a INT PRIMARY KEY, b INT NOT NULL) ENGINE = InnoDB;
+INSERT INTO parent VALUES(1,2),(2,3);
+CREATE INDEX tb ON parent(b);
+INSERT INTO parent VALUES(10,20),(20,30);
+CREATE TABLE child (a1 INT PRIMARY KEY, a2 INT) ENGINE = InnoDB;
+CREATE INDEX tb ON child(a2);
+INSERT INTO child VALUES(10,20);
+SET foreign_key_checks = 0;
+ALTER TABLE child DROP INDEX tb, ADD CONSTRAINT fk_4 FOREIGN KEY (a2)
+REFERENCES parent(b) ON DELETE CASCADE ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+SHOW CREATE TABLE child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a1` int(11) NOT NULL,
+ `a2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`a1`),
+ KEY `fk_4` (`a2`),
+ CONSTRAINT `fk_4` FOREIGN KEY (`a2`) REFERENCES `parent` (`b`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN;
+ID FOR_NAME REF_NAME N_COLS TYPE
+test/fk_4 test/child test/parent 1 5
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/fk_4 a2 b 0
+SET foreign_key_checks = 1;
+DROP TABLE child;
+DROP TABLE parent;
+CREATE TABLE parent (a INT PRIMARY KEY, b INT NOT NULL) ENGINE = InnoDB;
+INSERT INTO parent VALUES(1,2),(2,3);
+CREATE INDEX tb ON parent(b);
+INSERT INTO parent VALUES(10,20),(20,30);
+CREATE TABLE child (a1 INT PRIMARY KEY, a2 INT) ENGINE = InnoDB;
+CREATE INDEX tb ON child(a2);
+SET foreign_key_checks = 0;
+ALTER TABLE child CHANGE a2 a3 INT,
+ADD CONSTRAINT fk_1 FOREIGN KEY (a2) REFERENCES parent(b)
+ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+ERROR 42000: Key column 'a2' doesn't exist in table
+ALTER TABLE child CHANGE a2 a3 INT,
+ADD CONSTRAINT fk_1 FOREIGN KEY (a3) REFERENCES parent(b)
+ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+DROP TABLE child;
+DROP TABLE parent;
+CREATE TABLE parent (a INT PRIMARY KEY, b INT NOT NULL) ENGINE = InnoDB;
+INSERT INTO parent VALUES(1,2),(2,3);
+CREATE INDEX tb ON parent(b);
+INSERT INTO parent VALUES(10,20),(20,30);
+CREATE TABLE child (a1 INT NOT NULL, a2 INT) ENGINE = InnoDB;
+CREATE INDEX tb ON child(a2);
+SET foreign_key_checks = 0;
+SET DEBUG_DBUG = '+d,innodb_test_cannot_add_fk_system';
+ALTER TABLE child ADD PRIMARY KEY idx (a3), CHANGE a1 a3 INT,
+ADD CONSTRAINT fk_1 FOREIGN KEY (a2) REFERENCES parent(b)
+ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+ERROR HY000: Failed to add the foreign key constraint 'test/fk_1' to system tables
+SET DEBUG_DBUG = @saved_debug_dbug;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN;
+ID FOR_NAME REF_NAME N_COLS TYPE
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS;
+ID FOR_COL_NAME REF_COL_NAME POS
+SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name;
+name name
+test/child a1
+test/child a2
+SELECT NAME FROM information_schema.INNODB_SYS_TABLES;
+NAME
+SYS_DATAFILES
+SYS_FOREIGN
+SYS_FOREIGN_COLS
+SYS_TABLESPACES
+mysql/innodb_index_stats
+mysql/innodb_table_stats
+test/child
+test/parent
+ALTER TABLE child ADD PRIMARY KEY idx (a3), CHANGE a1 a3 INT,
+ADD CONSTRAINT fk_1 FOREIGN KEY (a2) REFERENCES parent(b)
+ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN;
+ID FOR_NAME REF_NAME N_COLS TYPE
+test/fk_1 test/child test/parent 1 6
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/fk_1 a2 b 0
+SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name;
+name name
+test/child a2
+test/child a3
+SELECT NAME FROM information_schema.INNODB_SYS_TABLES;
+NAME
+SYS_DATAFILES
+SYS_FOREIGN
+SYS_FOREIGN_COLS
+SYS_TABLESPACES
+mysql/innodb_index_stats
+mysql/innodb_table_stats
+test/child
+test/parent
+SHOW CREATE TABLE child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a3` int(11) NOT NULL,
+ `a2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`a3`),
+ KEY `tb` (`a2`),
+ CONSTRAINT `fk_1` FOREIGN KEY (`a2`) REFERENCES `parent` (`b`) ON DELETE SET NULL ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE child;
+CREATE TABLE child (a1 INT NOT NULL, a2 INT) ENGINE = InnoDB;
+ALTER TABLE child ADD PRIMARY KEY idx (a1),
+ADD CONSTRAINT fk_1 FOREIGN KEY (a2) REFERENCES parent(b)
+ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+SELECT * from information_schema.INNODB_SYS_FOREIGN;
+ID FOR_NAME REF_NAME N_COLS TYPE
+test/fk_1 test/child test/parent 1 6
+SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/fk_1 a2 b 0
+SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name;
+name name
+test/child a1
+test/child a2
+SELECT NAME FROM information_schema.INNODB_SYS_TABLES;
+NAME
+SYS_DATAFILES
+SYS_FOREIGN
+SYS_FOREIGN_COLS
+SYS_TABLESPACES
+mysql/innodb_index_stats
+mysql/innodb_table_stats
+test/child
+test/parent
+SHOW CREATE TABLE child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a1` int(11) NOT NULL,
+ `a2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`a1`),
+ KEY `fk_1` (`a2`),
+ CONSTRAINT `fk_1` FOREIGN KEY (`a2`) REFERENCES `parent` (`b`) ON DELETE SET NULL ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE child;
+CREATE TABLE child (a1 INT NOT NULL, a2 INT) ENGINE = InnoDB;
+ALTER TABLE child CHANGE a1 a3 INT,
+ADD CONSTRAINT fk_1 FOREIGN KEY (a3) REFERENCES parent(b)
+ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+SELECT * from information_schema.INNODB_SYS_FOREIGN;
+ID FOR_NAME REF_NAME N_COLS TYPE
+test/fk_1 test/child test/parent 1 6
+SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/fk_1 a3 b 0
+SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name;
+name name
+test/child a2
+test/child a3
+SELECT NAME FROM information_schema.INNODB_SYS_TABLES;
+NAME
+SYS_DATAFILES
+SYS_FOREIGN
+SYS_FOREIGN_COLS
+SYS_TABLESPACES
+mysql/innodb_index_stats
+mysql/innodb_table_stats
+test/child
+test/parent
+SHOW CREATE TABLE child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a3` int(11) DEFAULT NULL,
+ `a2` int(11) DEFAULT NULL,
+ KEY `fk_1` (`a3`),
+ CONSTRAINT `fk_1` FOREIGN KEY (`a3`) REFERENCES `parent` (`b`) ON DELETE SET NULL ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE child;
+CREATE TABLE child (a1 INT NOT NULL, a2 INT) ENGINE = InnoDB;
+ALTER TABLE child ADD PRIMARY KEY idx (a3), CHANGE a1 a3 INT,
+ADD CONSTRAINT fk_1 FOREIGN KEY (a3) REFERENCES parent(b)
+ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+ERROR HY000: Failed to add the foreign key constraint on table 'child'. Incorrect options in FOREIGN KEY constraint 'test/fk_1'
+DROP TABLE parent;
+DROP TABLE child;
+CREATE TABLE parent (a INT PRIMARY KEY, b INT NOT NULL, c INT) ENGINE = InnoDB;
+INSERT INTO parent VALUES(1,2,3),(2,3,4);
+CREATE INDEX tb ON parent(b);
+CREATE TABLE child (a1 INT NOT NULL, a2 INT, a3 INT) ENGINE = InnoDB;
+CREATE INDEX tb ON child(a2);
+ALTER TABLE child
+ADD CONSTRAINT fk_a FOREIGN KEY (a2) REFERENCES parent(b)
+ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+ALTER TABLE child
+ADD CONSTRAINT fk_b FOREIGN KEY (a1) REFERENCES parent(a),
+ALGORITHM = INPLACE;
+ALTER TABLE child CHANGE a2 a2_new INT, CHANGE a1 a1_new INT;
+SHOW CREATE TABLE child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a1_new` int(11) DEFAULT NULL,
+ `a2_new` int(11) DEFAULT NULL,
+ `a3` int(11) DEFAULT NULL,
+ KEY `tb` (`a2_new`),
+ KEY `fk_b` (`a1_new`),
+ CONSTRAINT `fk_a` FOREIGN KEY (`a2_new`) REFERENCES `parent` (`b`) ON DELETE SET NULL ON UPDATE CASCADE,
+ CONSTRAINT `fk_b` FOREIGN KEY (`a1_new`) REFERENCES `parent` (`a`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SELECT * from information_schema.INNODB_SYS_FOREIGN;
+ID FOR_NAME REF_NAME N_COLS TYPE
+test/fk_a test/child test/parent 1 6
+test/fk_b test/child test/parent 1 0
+SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/fk_a a2_new b 0
+test/fk_b a1_new a 0
+ALTER TABLE child
+ADD CONSTRAINT fk_new_1 FOREIGN KEY (a1_new) REFERENCES parent(b),
+ADD CONSTRAINT fk_new_2 FOREIGN KEY (a2_new) REFERENCES parent(a),
+ADD CONSTRAINT fk_new_3 FOREIGN KEY (a3) REFERENCES parent(c),
+ALGORITHM = INPLACE;
+ERROR HY000: Failed to add the foreign key constaint. Missing index for constraint 'fk_new_3' in the referenced table 'parent'
+SHOW CREATE TABLE child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a1_new` int(11) DEFAULT NULL,
+ `a2_new` int(11) DEFAULT NULL,
+ `a3` int(11) DEFAULT NULL,
+ KEY `tb` (`a2_new`),
+ KEY `fk_b` (`a1_new`),
+ CONSTRAINT `fk_a` FOREIGN KEY (`a2_new`) REFERENCES `parent` (`b`) ON DELETE SET NULL ON UPDATE CASCADE,
+ CONSTRAINT `fk_b` FOREIGN KEY (`a1_new`) REFERENCES `parent` (`a`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SELECT * from information_schema.INNODB_SYS_FOREIGN;
+ID FOR_NAME REF_NAME N_COLS TYPE
+test/fk_a test/child test/parent 1 6
+test/fk_b test/child test/parent 1 0
+SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/fk_a a2_new b 0
+test/fk_b a1_new a 0
+ALTER TABLE child
+ADD CONSTRAINT fk_new_1 FOREIGN KEY (a1_new) REFERENCES parent(b),
+ADD CONSTRAINT fk_new_2 FOREIGN KEY (a2_new) REFERENCES parent(a),
+ADD CONSTRAINT fk_new_3 FOREIGN KEY (a3) REFERENCES parent(a),
+ALGORITHM = INPLACE;
+SHOW CREATE TABLE child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a1_new` int(11) DEFAULT NULL,
+ `a2_new` int(11) DEFAULT NULL,
+ `a3` int(11) DEFAULT NULL,
+ KEY `tb` (`a2_new`),
+ KEY `fk_new_1` (`a1_new`),
+ KEY `fk_new_3` (`a3`),
+ CONSTRAINT `fk_a` FOREIGN KEY (`a2_new`) REFERENCES `parent` (`b`) ON DELETE SET NULL ON UPDATE CASCADE,
+ CONSTRAINT `fk_b` FOREIGN KEY (`a1_new`) REFERENCES `parent` (`a`),
+ CONSTRAINT `fk_new_1` FOREIGN KEY (`a1_new`) REFERENCES `parent` (`b`),
+ CONSTRAINT `fk_new_2` FOREIGN KEY (`a2_new`) REFERENCES `parent` (`a`),
+ CONSTRAINT `fk_new_3` FOREIGN KEY (`a3`) REFERENCES `parent` (`a`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SELECT * from information_schema.INNODB_SYS_FOREIGN;
+ID FOR_NAME REF_NAME N_COLS TYPE
+test/fk_a test/child test/parent 1 6
+test/fk_b test/child test/parent 1 0
+test/fk_new_1 test/child test/parent 1 0
+test/fk_new_2 test/child test/parent 1 0
+test/fk_new_3 test/child test/parent 1 0
+SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/fk_a a2_new b 0
+test/fk_b a1_new a 0
+test/fk_new_1 a1_new b 0
+test/fk_new_2 a2_new a 0
+test/fk_new_3 a3 a 0
+DROP TABLE child;
+CREATE TABLE child (a1 INT NOT NULL, a2 INT, a3 INT) ENGINE = InnoDB;
+CREATE INDEX tb ON child(a2);
+ALTER TABLE child ADD PRIMARY KEY idx (a1),
+ADD CONSTRAINT fk_new_1 FOREIGN KEY (a1) REFERENCES parent(b),
+ADD CONSTRAINT fk_new_2 FOREIGN KEY (a2) REFERENCES parent(a),
+ADD CONSTRAINT fk_new_3 FOREIGN KEY (a3) REFERENCES parent(c),
+ALGORITHM = INPLACE;
+ERROR HY000: Failed to add the foreign key constaint. Missing index for constraint 'fk_new_3' in the referenced table 'parent'
+SHOW CREATE TABLE child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a1` int(11) NOT NULL,
+ `a2` int(11) DEFAULT NULL,
+ `a3` int(11) DEFAULT NULL,
+ KEY `tb` (`a2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SELECT * from information_schema.INNODB_SYS_FOREIGN;
+ID FOR_NAME REF_NAME N_COLS TYPE
+SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS;
+ID FOR_COL_NAME REF_COL_NAME POS
+ALTER TABLE child ADD PRIMARY KEY idx (a1),
+ADD CONSTRAINT fk_new_1 FOREIGN KEY (a1) REFERENCES parent(b),
+ADD CONSTRAINT fk_new_2 FOREIGN KEY (a2) REFERENCES parent(a),
+ADD CONSTRAINT fk_new_3 FOREIGN KEY (a3) REFERENCES parent(a),
+ALGORITHM = INPLACE;
+SHOW CREATE TABLE child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a1` int(11) NOT NULL,
+ `a2` int(11) DEFAULT NULL,
+ `a3` int(11) DEFAULT NULL,
+ PRIMARY KEY (`a1`),
+ KEY `tb` (`a2`),
+ KEY `fk_new_3` (`a3`),
+ CONSTRAINT `fk_new_1` FOREIGN KEY (`a1`) REFERENCES `parent` (`b`),
+ CONSTRAINT `fk_new_2` FOREIGN KEY (`a2`) REFERENCES `parent` (`a`),
+ CONSTRAINT `fk_new_3` FOREIGN KEY (`a3`) REFERENCES `parent` (`a`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SELECT * from information_schema.INNODB_SYS_FOREIGN;
+ID FOR_NAME REF_NAME N_COLS TYPE
+test/fk_new_1 test/child test/parent 1 0
+test/fk_new_2 test/child test/parent 1 0
+test/fk_new_3 test/child test/parent 1 0
+SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/fk_new_1 a1 b 0
+test/fk_new_2 a2 a 0
+test/fk_new_3 a3 a 0
+SET foreign_key_checks = 1;
+DROP TABLE child;
+DROP TABLE parent;
+CREATE TABLE Parent (a INT PRIMARY KEY, b INT NOT NULL) ENGINE = InnoDB;
+INSERT INTO Parent VALUES(1,2),(2,3);
+CREATE INDEX tb ON Parent(b);
+INSERT INTO Parent VALUES(10,20),(20,30);
+CREATE TABLE Child (a1 INT PRIMARY KEY, a2 INT) ENGINE = InnoDB;
+CREATE INDEX tb ON Child(a2);
+INSERT INTO Child VALUES(10,20);
+SET foreign_key_checks = 0;
+ALTER TABLE Child ADD CONSTRAINT fk_1 FOREIGN KEY (a2)
+REFERENCES Parent(b) ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+DROP TABLE Child;
+DROP TABLE Parent;
+CREATE TABLE `t2`(a int,c int,d int) ENGINE=INNODB;
+CREATE TABLE `t3`(a int,c int,d int) ENGINE=INNODB;
+CREATE INDEX idx ON t3(a);
+ALTER TABLE `t2` ADD CONSTRAINT `fw` FOREIGN KEY (`c`) REFERENCES t3 (a);
+ALTER TABLE `t2` ADD CONSTRAINT `e` foreign key (`d`) REFERENCES t3(a);
+ALTER TABLE `t3` ADD CONSTRAINT `e` foreign key (`c`) REFERENCES `t2`(`c`) ON UPDATE SET NULL;
+ERROR HY000: Failed to add the foreign key constraint 'test/e' to system tables
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN;
+ID FOR_NAME REF_NAME N_COLS TYPE
+test/e test/t2 test/t3 1 0
+test/fw test/t2 test/t3 1 0
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/e d a 0
+test/fw c a 0
+DROP TABLE t2;
+DROP TABLE t3;
diff --git a/mysql-test/suite/innodb/r/innodb-index-online-purge.result b/mysql-test/suite/innodb/r/innodb-index-online-purge.result
new file mode 100644
index 00000000000..9ea7c331218
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-index-online-purge.result
@@ -0,0 +1,36 @@
+CREATE TABLE t (a INT PRIMARY KEY, c TEXT) ENGINE=InnoDB;
+CREATE TABLE u (a INT PRIMARY KEY, b INT, c INT NOT NULL) ENGINE=InnoDB;
+INSERT INTO t VALUES (1,'aa');
+BEGIN;
+INSERT INTO u SET a=1, c=1;
+INSERT INTO u SELECT a+1,NULL,a+1 FROM u;
+INSERT INTO u SELECT a+2,NULL,a+2 FROM u;
+INSERT INTO u SELECT a+4,NULL,a+4 FROM u;
+INSERT INTO u SELECT a+8,NULL,a+8 FROM u;
+INSERT INTO u SELECT a+16,NULL,a+16 FROM u;
+INSERT INTO u SELECT a+32,NULL,a+32 FROM u;
+INSERT INTO u SELECT a+64,NULL,a+64 FROM u;
+INSERT INTO u SELECT a+128,NULL,a+64 FROM u;
+INSERT INTO u SELECT a+256,NULL,a+64 FROM u;
+COMMIT;
+BEGIN;
+DELETE FROM u;
+SET DEBUG_SYNC='row_log_apply_before SIGNAL created_u WAIT_FOR dml_done_u';
+ALTER TABLE u ADD INDEX (c);
+COMMIT;
+SET DEBUG_SYNC='now WAIT_FOR created_u';
+SELECT state FROM information_schema.processlist
+WHERE info='ALTER TABLE u ADD INDEX (c)';
+state
+debug sync point: row_log_apply_before
+SET DEBUG_SYNC='row_log_apply_before SIGNAL created_t WAIT_FOR dml_done_t';
+CREATE INDEX c1 ON t (c(1));
+SET DEBUG_SYNC='now WAIT_FOR created_t';
+UPDATE t SET c='ab';
+SELECT SLEEP(10);
+SLEEP(10)
+0
+SET DEBUG_SYNC='now SIGNAL dml_done_u';
+SET DEBUG_SYNC='now SIGNAL dml_done_t';
+SET DEBUG_SYNC='RESET';
+DROP TABLE t,u;
diff --git a/mysql-test/suite/innodb/r/innodb-index-online.result b/mysql-test/suite/innodb/r/innodb-index-online.result
new file mode 100644
index 00000000000..efbc5c14e61
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-index-online.result
@@ -0,0 +1,447 @@
+call mtr.add_suppression("InnoDB: Warning: Small buffer pool size");
+SET @global_innodb_file_per_table_orig = @@global.innodb_file_per_table;
+SET GLOBAL innodb_file_per_table = on;
+CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT, c3 TEXT)
+ENGINE=InnoDB STATS_PERSISTENT=0;
+INSERT INTO t1 VALUES (1,1,''), (2,2,''), (3,3,''), (4,4,''), (5,5,'');
+SET GLOBAL innodb_monitor_enable = module_ddl;
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 0
+SET DEBUG_SYNC = 'RESET';
+SET DEBUG_SYNC = 'write_row_noreplace SIGNAL have_handle WAIT_FOR go_ahead';
+INSERT INTO t1 VALUES(1,2,3);
+SET DEBUG_SYNC = 'now WAIT_FOR have_handle';
+SET lock_wait_timeout = 1;
+ALTER TABLE t1 ADD UNIQUE INDEX(c2);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+SET DEBUG_SYNC = 'now SIGNAL go_ahead';
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 0
+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
+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
+SET DEBUG_DBUG = @saved_debug_dbug;
+CREATE UNIQUE INDEX c2 ON t1(c2);
+DROP INDEX c2 ON t1;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `c3` text,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=0
+BEGIN;
+INSERT INTO t1 VALUES(7,4,2);
+SET DEBUG_SYNC = 'row_log_apply_before SIGNAL scanned WAIT_FOR rollback_done';
+ALTER TABLE t1 ADD UNIQUE INDEX(c2);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+COMMIT;
+ALTER TABLE t1 ADD UNIQUE INDEX(c2);
+ERROR 23000: Duplicate entry '4' for key 'c2'
+DELETE FROM t1 WHERE c1 = 7;
+ALTER TABLE t1 ADD FOREIGN KEY(c2) REFERENCES t1(c2), ALGORITHM = INPLACE;
+ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Adding foreign keys needs foreign_key_checks=OFF. Try ALGORITHM=COPY.
+ALTER TABLE t1 ADD UNIQUE INDEX(c2), LOCK = EXCLUSIVE, ALGORITHM = INPLACE;
+DROP INDEX c2 ON t1;
+ALTER TABLE t1 ADD UNIQUE INDEX(c2);
+SET DEBUG_SYNC = 'now WAIT_FOR scanned';
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 1
+ddl_pending_alter_table 1
+BEGIN;
+INSERT INTO t1 VALUES(7,4,2);
+ROLLBACK;
+SET DEBUG_SYNC = 'now SIGNAL rollback_done';
+ERROR 23000: Duplicate entry '4' for key 'c2'
+SET DEBUG_SYNC = 'row_log_apply_after SIGNAL created WAIT_FOR dml_done';
+ALTER TABLE t1 ADD UNIQUE INDEX(c2);
+SET DEBUG_SYNC = 'now WAIT_FOR created';
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 1
+INSERT INTO t1 VALUES(6,3,1);
+SET DEBUG_SYNC = 'now SIGNAL dml_done';
+ERROR 23000: Duplicate entry for key 'c2'
+DELETE FROM t1 WHERE c1=6;
+ALTER TABLE t1 ADD UNIQUE INDEX(c2);
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 0
+INSERT INTO t1 VALUES(6,3,1);
+ERROR 23000: Duplicate entry '3' for key 'c2'
+INSERT INTO t1 VALUES(7,4,2);
+ERROR 23000: Duplicate entry '4' for key 'c2'
+ALTER TABLE t1 STATS_PERSISTENT=1;
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+UPDATE mysql.innodb_index_stats SET stat_value = 5
+WHERE database_name = 'test' AND table_name= 't1' AND index_name = 'PRIMARY'
+AND stat_value = 6;
+SELECT * FROM mysql.innodb_index_stats WHERE table_name IN ('t1');
+database_name table_name index_name last_update stat_name stat_value sample_size stat_description
+test t1 PRIMARY LAST_UPDATE n_diff_pfx01 5 1 c1
+test t1 PRIMARY LAST_UPDATE n_leaf_pages 1 NULL Number of leaf pages in the index
+test t1 PRIMARY LAST_UPDATE size 1 NULL Number of pages in the index
+test t1 c2 LAST_UPDATE n_diff_pfx01 5 1 c2
+test t1 c2 LAST_UPDATE n_leaf_pages 1 NULL Number of leaf pages in the index
+test t1 c2 LAST_UPDATE size 1 NULL Number of pages in the index
+CREATE TABLE t1_c2_stats SELECT * FROM mysql.innodb_index_stats
+WHERE database_name = 'test' AND table_name = 't1' and index_name = 'c2';
+ALTER TABLE t1_c2_stats ENGINE=INNODB;
+DROP INDEX c2 ON t1;
+ANALYZE TABLE t1_c2_stats;
+Table Op Msg_type Msg_text
+test.t1_c2_stats analyze status OK
+SELECT * FROM mysql.innodb_index_stats WHERE table_name IN ('t1', 't1_c2_stats');
+database_name table_name index_name last_update stat_name stat_value sample_size stat_description
+test t1 PRIMARY LAST_UPDATE n_diff_pfx01 5 1 c1
+test t1 PRIMARY LAST_UPDATE n_leaf_pages 1 NULL Number of leaf pages in the index
+test t1 PRIMARY LAST_UPDATE size 1 NULL Number of pages in the index
+KILL QUERY @id;
+ERROR 70100: Query execution was interrupted
+SET DEBUG_SYNC = 'row_log_apply_before SIGNAL c2d_created WAIT_FOR kill_done';
+CREATE INDEX c2d ON t1(c2);
+SET DEBUG_SYNC = 'now WAIT_FOR c2d_created';
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 1
+ddl_pending_alter_table 1
+KILL QUERY @id;
+SET DEBUG_SYNC = 'now SIGNAL kill_done';
+ERROR 70100: Query execution was interrupted
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 0
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+INSERT INTO t1 SELECT 5 + c1, c2, c3 FROM t1;
+INSERT INTO t1 SELECT 10 + c1, c2, c3 FROM t1;
+INSERT INTO t1 SELECT 20 + c1, c2, c3 FROM t1;
+INSERT INTO t1 SELECT 40 + c1, c2, c3 FROM t1;
+EXPLAIN SELECT COUNT(*) FROM t1 WHERE c2 > 3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 80 Using where
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+UPDATE t1_c2_stats SET index_name = 'c2d';
+UPDATE t1_c2_stats SET stat_value = 2 WHERE stat_name = 'n_diff_pfx01';
+INSERT INTO t1_c2_stats
+SELECT database_name, table_name, index_name, last_update, 'n_diff_pfx02', 80,
+sample_size, 'c2,c1' FROM t1_c2_stats
+WHERE stat_name = 'n_diff_pfx01' AND stat_description = 'c2';
+INSERT INTO mysql.innodb_index_stats SELECT * FROM t1_c2_stats;
+DROP TABLE t1_c2_stats;
+CREATE INDEX c2d ON t1(c2);
+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 0 PRIMARY 1 c1 A 80 NULL NULL BTREE
+t1 1 c2d 1 c2 A 10 NULL NULL YES BTREE
+EXPLAIN SELECT COUNT(*) FROM t1 WHERE c2 > 3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c2d c2d 5 NULL 32 Using where; Using index
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `c3` text,
+ PRIMARY KEY (`c1`),
+ KEY `c2d` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=1
+SET @merge_encrypt_0=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
+SET @merge_decrypt_0=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
+SET @rowlog_encrypt_0=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
+SET DEBUG_SYNC = 'row_log_apply_before SIGNAL c2e_created WAIT_FOR dml2_done';
+SET lock_wait_timeout = 10;
+ALTER TABLE t1 DROP INDEX c2d, ADD INDEX c2e(c2),
+ALGORITHM = INPLACE;
+INSERT INTO t1 SELECT 80 + c1, c2, c3 FROM t1;
+INSERT INTO t1 SELECT 160 + c1, c2, c3 FROM t1;
+SET DEBUG_SYNC = 'now WAIT_FOR c2e_created';
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 1
+ddl_pending_alter_table 1
+BEGIN;
+DELETE FROM t1;
+ROLLBACK;
+UPDATE t1 SET c2 = c2 + 1;
+BEGIN;
+UPDATE t1 SET c2 = c2 + 1;
+DELETE FROM t1;
+ROLLBACK;
+BEGIN;
+DELETE FROM t1;
+ROLLBACK;
+UPDATE t1 SET c2 = c2 + 1;
+BEGIN;
+UPDATE t1 SET c2 = c2 + 1;
+DELETE FROM t1;
+ROLLBACK;
+BEGIN;
+DELETE FROM t1;
+ROLLBACK;
+UPDATE t1 SET c2 = c2 + 1;
+BEGIN;
+UPDATE t1 SET c2 = c2 + 1;
+DELETE FROM t1;
+ROLLBACK;
+BEGIN;
+DELETE FROM t1;
+ROLLBACK;
+UPDATE t1 SET c2 = c2 + 1;
+BEGIN;
+UPDATE t1 SET c2 = c2 + 1;
+DELETE FROM t1;
+ROLLBACK;
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 1
+ddl_pending_alter_table 1
+SELECT sf.name, sf.pos FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES si
+INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_FIELDS sf
+ON si.index_id = sf.index_id WHERE si.name = '?c2e';
+name pos
+c2 0
+SET @merge_encrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
+SET @merge_decrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
+SET @rowlog_encrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
+SELECT
+(@merge_encrypt_1-@merge_encrypt_0)-
+(@merge_decrypt_1-@merge_decrypt_0) as sort_balance,
+@merge_encrypt_1>@merge_encrypt_0, @merge_decrypt_1>@merge_decrypt_0,
+@rowlog_encrypt_1>@rowlog_encrypt_0;
+sort_balance @merge_encrypt_1>@merge_encrypt_0 @merge_decrypt_1>@merge_decrypt_0 @rowlog_encrypt_1>@rowlog_encrypt_0
+0 0 0 0
+SET DEBUG_SYNC = 'now SIGNAL dml2_done';
+ERROR HY000: Creating index 'c2e' required more than 'innodb_online_alter_log_max_size' bytes of modification log. Please try again.
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 1
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 0
+SELECT sf.name, sf.pos FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES si
+INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_FIELDS sf
+ON si.index_id = sf.index_id WHERE si.name = 'c2e';
+name pos
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 1
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 0
+ALTER TABLE t1 COMMENT 'testing if c2e will be dropped';
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 0
+SET @merge_encrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
+SET @merge_decrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
+SET @rowlog_encrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
+SET @rowlog_decrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted');
+SET DEBUG_SYNC = 'row_log_apply_before SIGNAL c2f_created WAIT_FOR dml3_done';
+ALTER TABLE t1 ADD INDEX c2f(c2);
+SET DEBUG_SYNC = 'now WAIT_FOR c2f_created';
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 1
+ddl_pending_alter_table 1
+BEGIN;
+INSERT INTO t1 SELECT 320 + c1, c2, c3 FROM t1 WHERE c1 > 160;
+DELETE FROM t1 WHERE c1 > 320;
+ROLLBACK;
+BEGIN;
+UPDATE t1 SET c2 = c2 + 1;
+DELETE FROM t1;
+ROLLBACK;
+BEGIN;
+INSERT INTO t1 SELECT 320 + c1, c2, c3 FROM t1 WHERE c1 > 160;
+DELETE FROM t1 WHERE c1 > 320;
+ROLLBACK;
+BEGIN;
+UPDATE t1 SET c2 = c2 + 1;
+DELETE FROM t1;
+ROLLBACK;
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 1
+ddl_pending_alter_table 1
+SET DEBUG_SYNC = 'now SIGNAL dml3_done';
+Warnings:
+Note 1831 Duplicate index `c2f`. This is deprecated and will be disallowed in a future release.
+ALTER TABLE t1 CHANGE c2 c22f INT;
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 0
+SET @merge_encrypt_2=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
+SET @merge_decrypt_2=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
+SET @rowlog_encrypt_2=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
+SET @rowlog_decrypt_2=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted');
+SELECT
+(@merge_encrypt_2-@merge_encrypt_1)-
+(@merge_decrypt_2-@merge_decrypt_1) as sort_balance,
+(@rowlog_encrypt_2-@rowlog_encrypt_1)-
+(@rowlog_decrypt_2-@rowlog_decrypt_1) as log_balance;
+sort_balance log_balance
+0 0
+SELECT
+@merge_encrypt_2-@merge_encrypt_1>0 as sort_encrypted,
+@merge_decrypt_2-@merge_decrypt_1>0 as sort_decrypted,
+@rowlog_encrypt_2-@rowlog_encrypt_1>0 as log_encrypted,
+@rowlog_decrypt_2-@rowlog_decrypt_1>0 as log_decrypted;
+sort_encrypted sort_decrypted log_encrypted log_decrypted
+0 0 0 0
+SELECT COUNT(c22f) FROM t1;
+COUNT(c22f)
+320
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+ALTER TABLE t1 ADD UNIQUE INDEX c3p5(c3(5));
+ERROR 23000: Duplicate entry 'NULL' for key 'c3p5'
+UPDATE t1 SET c3 = NULL WHERE c3 = '';
+SET lock_wait_timeout = 1;
+SET DEBUG_SYNC = 'row_log_apply_before SIGNAL c3p5_created WAIT_FOR ins_done';
+ALTER TABLE t1 ADD UNIQUE INDEX c3p5(c3(5));
+SET DEBUG_SYNC = 'now WAIT_FOR c3p5_created';
+SELECT sf.name, sf.pos FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES si
+INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_FIELDS sf
+ON si.index_id = sf.index_id WHERE si.name = '?c3p5';
+name pos
+c3 0
+SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL ins_done WAIT_FOR ddl_timed_out';
+INSERT INTO t1 VALUES(347,33101,NULL);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+SET DEBUG_SYNC = 'now SIGNAL ddl_timed_out';
+SELECT sf.name, sf.pos FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES si
+INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_FIELDS sf
+ON si.index_id = sf.index_id WHERE si.name = 'c3p5';
+name pos
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 1
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 0
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 1
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 0
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c22f` int(11) DEFAULT NULL,
+ `c3` text,
+ PRIMARY KEY (`c1`),
+ KEY `c2d` (`c22f`),
+ KEY `c2f` (`c22f`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=1 COMMENT='testing if c2e will be dropped'
+ALTER TABLE t1 DROP INDEX c2d, DROP INDEX c2f;
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 0
+ALTER TABLE t1 ADD INDEX c2h(c22f), ALGORITHM = INPLACE;
+ALTER TABLE t1 ADD INDEX c2h(c22f), ALGORITHM = COPY;
+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);
+SET DEBUG_SYNC = 'now WAIT_FOR t1u_created';
+BEGIN;
+INSERT INTO t1 VALUES('bar'),('bar');
+SET DEBUG_SYNC = 'now SIGNAL dup_done';
+ERROR 23000: Duplicate entry 'bar' for key 'c'
+SET DEBUG_SYNC = 'RESET';
+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..dba01945de3
--- /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 /InnoDB: Difficult to find free blocks / in mysqld.1.err
diff --git a/mysql-test/suite/innodb/r/innodb-page_compression_tables.result b/mysql-test/suite/innodb/r/innodb-page_compression_tables.result
index 98de5db3c12..072f1d1e440 100644
--- a/mysql-test/suite/innodb/r/innodb-page_compression_tables.result
+++ b/mysql-test/suite/innodb/r/innodb-page_compression_tables.result
@@ -38,12 +38,11 @@ innodb_redundant CREATE TABLE `innodb_redundant` (
`b` char(200) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT
alter table innodb_redundant page_compressed=1;
-ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options")
+ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'PAGE_COMPRESSED'
show warnings;
Level Code Message
Warning 140 InnoDB: PAGE_COMPRESSED table can't have ROW_TYPE=REDUNDANT
-Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options")
-Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB
+Error 1478 Table storage engine 'InnoDB' does not support the create option 'PAGE_COMPRESSED'
show create table innodb_redundant;
Table Create Table
innodb_redundant CREATE TABLE `innodb_redundant` (
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,crypt.rdiff b/mysql-test/suite/innodb/r/innodb-table-online,crypt.rdiff
new file mode 100644
index 00000000000..443ec528cd8
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-table-online,crypt.rdiff
@@ -0,0 +1,20 @@
+--- innodb-table-online.result
++++ innodb-table-online,crypt.reject
+@@ -254,7 +254,7 @@
+ @merge_encrypt_1>@merge_encrypt_0, @merge_decrypt_1>@merge_decrypt_0,
+ @rowlog_encrypt_1>@rowlog_encrypt_0;
+ sort_balance @merge_encrypt_1>@merge_encrypt_0 @merge_decrypt_1>@merge_decrypt_0 @rowlog_encrypt_1>@rowlog_encrypt_0
+-0 0 0 0
++0 0 0 1
+ SET DEBUG_SYNC = 'now SIGNAL dml2_done';
+ # session con1
+ ERROR HY000: Creating index 'PRIMARY' required more than 'innodb_online_alter_log_max_size' bytes of modification log. Please try again.
+@@ -345,7 +345,7 @@
+ @rowlog_encrypt_2-@rowlog_encrypt_1>0 as log_encrypted,
+ @rowlog_decrypt_2-@rowlog_decrypt_1>0 as log_decrypted;
+ sort_encrypted sort_decrypted log_encrypted log_decrypted
+-0 0 0 0
++1 1 1 1
+ ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY c3p5(c3(5));
+ ERROR 23000: Duplicate entry '' for key 'PRIMARY'
+ UPDATE t1 SET c3 = NULL WHERE c3 = '';
diff --git a/mysql-test/suite/innodb/r/innodb-table-online.result b/mysql-test/suite/innodb/r/innodb-table-online.result
new file mode 100644
index 00000000000..9b1097b3afa
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-table-online.result
@@ -0,0 +1,446 @@
+call mtr.add_suppression("InnoDB: Warning: Small buffer pool size");
+call mtr.add_suppression("InnoDB: Error: table 'test/t1'");
+call mtr.add_suppression("MySQL is trying to open a table handle but the .ibd file for");
+SET @global_innodb_file_per_table_orig = @@global.innodb_file_per_table;
+SET GLOBAL innodb_file_per_table = on;
+SET @file_format = @@GLOBAL.innodb_file_format;
+SET GLOBAL innodb_file_format = Barracuda;
+CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT NOT NULL, c3 CHAR(255) NOT NULL)
+ENGINE = InnoDB;
+INSERT INTO t1 VALUES (1,1,''), (2,2,''), (3,3,''), (4,4,''), (5,5,'');
+SET GLOBAL innodb_monitor_enable = module_ddl;
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 0
+SET DEBUG_SYNC = 'RESET';
+SET DEBUG_SYNC = 'write_row_noreplace SIGNAL have_handle WAIT_FOR go_ahead';
+INSERT INTO t1 VALUES(1,2,3);
+# Establish session con1 (user=root)
+SET DEBUG_SYNC = 'now WAIT_FOR have_handle';
+SET lock_wait_timeout = 1;
+ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+SET DEBUG_SYNC = 'now SIGNAL go_ahead';
+# session default
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 0
+# session 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
+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
+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
+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
+ALTER TABLE t1 ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE, LOCK=NONE;
+# session default
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) NOT NULL,
+ `c3` char(255) NOT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT
+BEGIN;
+INSERT INTO t1 VALUES(7,4,2);
+# session con1
+SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL scanned WAIT_FOR insert_done';
+ALTER TABLE t1 DROP PRIMARY KEY, ADD UNIQUE INDEX(c2);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+# session default
+COMMIT;
+# session con1
+ALTER TABLE t1 DROP PRIMARY KEY, ADD UNIQUE INDEX(c2);
+ERROR 23000: Duplicate entry '4' for key 'c2'
+# session default
+DELETE FROM t1 WHERE c1 = 7;
+# session con1
+ALTER TABLE t1 DROP PRIMARY KEY, ADD UNIQUE INDEX(c2), ROW_FORMAT=COMPACT,
+LOCK = SHARED, ALGORITHM = INPLACE;
+ALTER TABLE t1 ADD UNIQUE INDEX(c2),
+LOCK = EXCLUSIVE, ALGORITHM = INPLACE;
+Warnings:
+Note 1831 Duplicate index `c2_2`. This is deprecated and will be disallowed in a future release.
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) NOT NULL,
+ `c3` char(255) NOT NULL,
+ UNIQUE KEY `c2` (`c2`),
+ UNIQUE KEY `c2_2` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
+ALTER TABLE t1 DROP INDEX c2, ALGORITHM = INPLACE;
+ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Dropping a primary key is not allowed without also adding a new primary key. Try ALGORITHM=COPY.
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) NOT NULL,
+ `c3` char(255) NOT NULL,
+ UNIQUE KEY `c2` (`c2`),
+ UNIQUE KEY `c2_2` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
+ALTER TABLE t1 DROP INDEX c2, ADD PRIMARY KEY(c1);
+# session default
+SET DEBUG_SYNC = 'now WAIT_FOR scanned';
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 1
+ddl_pending_alter_table 1
+BEGIN;
+INSERT INTO t1 VALUES(4,7,2);
+SET DEBUG_SYNC = 'now SIGNAL insert_done';
+# session con1
+ERROR 23000: Duplicate entry '4' for key 'PRIMARY'
+# session default
+ROLLBACK;
+# session con1
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) NOT NULL,
+ `c3` char(255) NOT NULL,
+ UNIQUE KEY `c2` (`c2`),
+ UNIQUE KEY `c2_2` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
+ALTER TABLE t1 DROP PRIMARY KEY, ADD UNIQUE INDEX(c2), ALGORITHM = INPLACE;
+ERROR 42000: Can't DROP 'PRIMARY'; check that column/key exists
+ALTER TABLE t1 DROP INDEX c2, ADD PRIMARY KEY(c1), ALGORITHM = INPLACE;
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 0
+# session default
+INSERT INTO t1 VALUES(6,3,1);
+ERROR 23000: Duplicate entry '3' for key 'c2_2'
+INSERT INTO t1 VALUES(7,4,2);
+ERROR 23000: Duplicate entry '4' for key 'c2_2'
+DROP INDEX c2_2 ON t1;
+BEGIN;
+INSERT INTO t1 VALUES(7,4,2);
+ROLLBACK;
+# session con1
+KILL QUERY @id;
+ERROR 70100: Query execution was interrupted
+SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL rebuilt WAIT_FOR dml_done';
+SET DEBUG_SYNC = 'row_log_table_apply2_before SIGNAL applied WAIT_FOR kill_done';
+ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
+# session default
+SET DEBUG_SYNC = 'now WAIT_FOR rebuilt';
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 1
+ddl_pending_alter_table 1
+BEGIN;
+INSERT INTO t1 VALUES(7,4,2);
+ROLLBACK;
+SET DEBUG_SYNC = 'now SIGNAL dml_done WAIT_FOR applied';
+KILL QUERY @id;
+SET DEBUG_SYNC = 'now SIGNAL kill_done';
+# session con1
+ERROR 70100: Query execution was interrupted
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 0
+# session default
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+INSERT INTO t1 SELECT 5 + c1, c2, c3 FROM t1;
+INSERT INTO t1 SELECT 10 + c1, c2, c3 FROM t1;
+INSERT INTO t1 SELECT 20 + c1, c2, c3 FROM t1;
+INSERT INTO t1 SELECT 40 + c1, c2, c3 FROM t1;
+EXPLAIN SELECT COUNT(*) FROM t1 WHERE c2 > 3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL ROWS Using where
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+SET @merge_encrypt_0=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
+SET @merge_decrypt_0=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
+SET @rowlog_encrypt_0=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
+# session con1
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) NOT NULL,
+ `c3` char(255) NOT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
+ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
+SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL rebuilt2 WAIT_FOR dml2_done';
+SET lock_wait_timeout = 10;
+ALTER TABLE t1 ROW_FORMAT=COMPACT
+PAGE_COMPRESSED = YES PAGE_COMPRESSION_LEVEL = 1, ALGORITHM = INPLACE;
+# session default
+INSERT INTO t1 SELECT 80 + c1, c2, c3 FROM t1;
+INSERT INTO t1 SELECT 160 + c1, c2, c3 FROM t1;
+UPDATE t1 SET c2 = c2 + 1;
+SET DEBUG_SYNC = 'now WAIT_FOR rebuilt2';
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 1
+ddl_pending_alter_table 1
+BEGIN;
+DELETE FROM t1;
+ROLLBACK;
+UPDATE t1 SET c2 = c2 + 1;
+BEGIN;
+UPDATE t1 SET c2 = c2 + 1;
+DELETE FROM t1;
+ROLLBACK;
+BEGIN;
+DELETE FROM t1;
+ROLLBACK;
+UPDATE t1 SET c2 = c2 + 1;
+BEGIN;
+UPDATE t1 SET c2 = c2 + 1;
+DELETE FROM t1;
+ROLLBACK;
+BEGIN;
+DELETE FROM t1;
+ROLLBACK;
+UPDATE t1 SET c2 = c2 + 1;
+BEGIN;
+UPDATE t1 SET c2 = c2 + 1;
+DELETE FROM t1;
+ROLLBACK;
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 1
+ddl_pending_alter_table 1
+SET @merge_encrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
+SET @merge_decrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
+SET @rowlog_encrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
+SELECT
+(@merge_encrypt_1-@merge_encrypt_0)-
+(@merge_decrypt_1-@merge_decrypt_0) as sort_balance,
+@merge_encrypt_1>@merge_encrypt_0, @merge_decrypt_1>@merge_decrypt_0,
+@rowlog_encrypt_1>@rowlog_encrypt_0;
+sort_balance @merge_encrypt_1>@merge_encrypt_0 @merge_decrypt_1>@merge_decrypt_0 @rowlog_encrypt_1>@rowlog_encrypt_0
+0 0 0 0
+SET DEBUG_SYNC = 'now SIGNAL dml2_done';
+# session con1
+ERROR HY000: Creating index 'PRIMARY' required more than 'innodb_online_alter_log_max_size' bytes of modification log. Please try again.
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 0
+SET @merge_encrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
+SET @merge_decrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
+SET @rowlog_encrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
+SET @rowlog_decrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted');
+SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL rebuilt3 WAIT_FOR dml3_done';
+ALTER TABLE t1 ADD PRIMARY KEY(c22f), CHANGE c2 c22f INT;
+ERROR 42000: Multiple primary key defined
+ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(c22f), CHANGE c2 c22f INT;
+ERROR 23000: Duplicate entry '5' for key 'PRIMARY'
+ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(c1,c22f,c4(5)),
+CHANGE c2 c22f INT, CHANGE c3 c3 CHAR(255) NULL, CHANGE c1 c1 INT AFTER c22f,
+ADD COLUMN c4 VARCHAR(6) DEFAULT 'Online', LOCK=NONE;
+# session default
+SET DEBUG_SYNC = 'now WAIT_FOR rebuilt3';
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 1
+ddl_pending_alter_table 1
+BEGIN;
+INSERT INTO t1 SELECT 320 + c1, c2, c3 FROM t1 WHERE c1 > 240;
+DELETE FROM t1 WHERE c1 > 320;
+ROLLBACK;
+BEGIN;
+UPDATE t1 SET c2 = c2 + 1;
+DELETE FROM t1;
+ROLLBACK;
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 1
+ddl_pending_alter_table 1
+SET DEBUG_SYNC = 'now SIGNAL dml3_done';
+# session con1
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 0
+SELECT COUNT(c22f) FROM t1;
+COUNT(c22f)
+320
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SET @merge_encrypt_2=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
+SET @merge_decrypt_2=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
+SET @rowlog_encrypt_2=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
+SET @rowlog_decrypt_2=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted');
+SELECT
+(@merge_encrypt_2-@merge_encrypt_1)-
+(@merge_decrypt_2-@merge_decrypt_1) as sort_balance,
+(@rowlog_encrypt_2-@rowlog_encrypt_1)-
+(@rowlog_decrypt_2-@rowlog_decrypt_1) as log_balance;
+sort_balance log_balance
+0 0
+SELECT
+@merge_encrypt_2-@merge_encrypt_1>0 as sort_encrypted,
+@merge_decrypt_2-@merge_decrypt_1>0 as sort_decrypted,
+@rowlog_encrypt_2-@rowlog_encrypt_1>0 as log_encrypted,
+@rowlog_decrypt_2-@rowlog_decrypt_1>0 as log_decrypted;
+sort_encrypted sort_decrypted log_encrypted log_decrypted
+0 0 0 0
+ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY c3p5(c3(5));
+ERROR 23000: Duplicate entry '' for key 'PRIMARY'
+UPDATE t1 SET c3 = NULL WHERE c3 = '';
+SET lock_wait_timeout = 1;
+ALTER TABLE t1 DROP COLUMN c22f, ADD PRIMARY KEY c3p5(c3(5));
+ERROR 42000: Multiple primary key defined
+SET @old_sql_mode = @@sql_mode;
+SET @@sql_mode = 'STRICT_TRANS_TABLES';
+ALTER TABLE t1 DROP COLUMN c22f, DROP PRIMARY KEY, ADD PRIMARY KEY c3p5(c3(5)),
+ALGORITHM = INPLACE;
+ERROR 22004: Invalid use of NULL value
+ALTER TABLE t1 MODIFY c3 CHAR(255) NOT NULL;
+ERROR 22004: Invalid use of NULL value
+SET @@sql_mode = @old_sql_mode;
+UPDATE t1 SET c3=LEFT(CONCAT(c1,REPEAT('foo',c1)),255) WHERE c3 IS NULL;
+SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL c3p5_created0 WAIT_FOR ins_done0';
+SET @@sql_mode = 'STRICT_TRANS_TABLES';
+ALTER TABLE t1 MODIFY c3 CHAR(255) NOT NULL, DROP COLUMN c22f,
+ADD COLUMN c5 CHAR(5) DEFAULT 'tired' FIRST;
+# session default
+SET DEBUG_SYNC = 'now WAIT_FOR c3p5_created0';
+BEGIN;
+INSERT INTO t1 VALUES(347,33101,'Pikku kakkosen posti','YLETV2');
+INSERT INTO t1 VALUES(33101,347,NULL,'');
+SET DEBUG_SYNC = 'now SIGNAL ins_done0';
+# session con1
+ERROR 22004: Invalid use of NULL value
+SET @@sql_mode = @old_sql_mode;
+# session default
+ROLLBACK;
+# session con1
+ALTER TABLE t1 MODIFY c3 CHAR(255) NOT NULL;
+SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL c3p5_created WAIT_FOR ins_done';
+ALTER TABLE t1 DROP PRIMARY KEY, DROP COLUMN c22f,
+ADD COLUMN c6 VARCHAR(1000) DEFAULT
+'I love tracking down hard-to-reproduce bugs.',
+ADD PRIMARY KEY c3p5(c3(5), c6(2));
+# session default
+SET DEBUG_SYNC = 'now WAIT_FOR c3p5_created';
+SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL ins_done WAIT_FOR ddl_timed_out';
+INSERT INTO t1 VALUES(347,33101,NULL,'');
+ERROR 23000: Column 'c3' cannot be null
+INSERT INTO t1 VALUES(347,33101,'Pikku kakkosen posti','');
+# session con1
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+SET DEBUG_SYNC = 'now SIGNAL ddl_timed_out';
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+name count
+ddl_background_drop_indexes 0
+ddl_background_drop_tables 0
+ddl_online_create_index 0
+ddl_pending_alter_table 0
+# session default
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+321
+ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
+SELECT * FROM t1 LIMIT 10;
+c22f c1 c3 c4
+5 1 1foo Online
+6 2 2foofoo Online
+7 3 3foofoofoo Online
+8 4 4foofoofoofoo Online
+9 5 5foofoofoofoofoo Online
+5 6 6foofoofoofoofoofoo Online
+6 7 7foofoofoofoofoofoofoo Online
+7 8 8foofoofoofoofoofoofoofoo Online
+8 9 9foofoofoofoofoofoofoofoofoo Online
+9 10 10foofoofoofoofoofoofoofoofoofoo Online
+# session con1
+ALTER TABLE t1 DISCARD TABLESPACE;
+# Disconnect session con1
+# session default
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c22f` int(11) NOT NULL,
+ `c1` int(11) NOT NULL,
+ `c3` char(255) NOT NULL,
+ `c4` varchar(6) NOT NULL DEFAULT 'Online',
+ PRIMARY KEY (`c1`,`c22f`,`c4`(5))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT
+SET DEBUG_SYNC = 'RESET';
+SET GLOBAL innodb_monitor_disable = module_ddl;
+DROP TABLE t1;
+SET GLOBAL innodb_file_per_table = @global_innodb_file_per_table_orig;
+SET GLOBAL innodb_file_format = @file_format;
+SET GLOBAL innodb_monitor_enable = default;
+SET GLOBAL innodb_monitor_disable = default;
diff --git a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result
index 92ae1d52b6c..66b7d246e30 100644
--- a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result
+++ b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result
@@ -1,26 +1,15 @@
-call mtr.add_suppression("InnoDB: Page for tablespace .* ");
-call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=");
-call mtr.add_suppression("InnoDB: Corruption: Block in space_id .* in file .* corrupted");
-call mtr.add_suppression("InnoDB: Based on page type .*");
-FLUSH TABLES;
SET GLOBAL innodb_file_per_table = 1;
-DROP DATABASE IF EXISTS test_wl5522;
-Warnings:
-Note 1008 Can't drop database 'test_wl5522'; database doesn't exist
CREATE DATABASE test_wl5522;
-SET SESSION debug_dbug="+d,ib_discard_before_commit_crash";
CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = InnoDB;
INSERT INTO test_wl5522.t1 VALUES(1),(2),(3);
+SET SESSION debug_dbug="+d,ib_discard_before_commit_crash";
ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE;
ERROR HY000: Lost connection to MySQL server during query
DROP TABLE test_wl5522.t1;
SET GLOBAL innodb_file_per_table = 1;
-SELECT @@innodb_file_per_table;
-@@innodb_file_per_table
-1
-SET SESSION debug_dbug="+d,ib_discard_after_commit_crash";
CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = InnoDB;
INSERT INTO test_wl5522.t1 VALUES(1),(2),(3);
+SET SESSION debug_dbug="+d,ib_discard_after_commit_crash";
ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE;
ERROR HY000: Lost connection to MySQL server during query
DROP TABLE test_wl5522.t1;
@@ -37,19 +26,18 @@ ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE;
SELECT COUNT(*) FROM test_wl5522.t1;
ERROR HY000: Tablespace has been discarded for table 't1'
restore: t1 .ibd and .cfg files
-SET SESSION debug_dbug="+d,ib_import_before_commit_crash";
SELECT * FROM test_wl5522.t1;
ERROR HY000: Tablespace has been discarded for table 't1'
+SET SESSION debug_dbug="+d,ib_import_before_commit_crash";
ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
ERROR HY000: Lost connection to MySQL server during query
-SET SESSION debug_dbug="+d,ib_import_before_checkpoint_crash";
SELECT COUNT(*) FROM test_wl5522.t1;
ERROR HY000: Tablespace has been discarded for table 't1'
+SET SESSION debug_dbug="+d,ib_import_before_checkpoint_crash";
ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
ERROR HY000: Lost connection to MySQL server during query
unlink: t1.ibd
unlink: t1.cfg
-# Restart and reconnect to the server
DROP TABLE test_wl5522.t1;
SET GLOBAL innodb_file_per_table = 1;
SELECT @@innodb_file_per_table;
@@ -495,7 +483,7 @@ c4 VARCHAR(2048),
INDEX idx1(c2),
INDEX idx2(c3(512)),
INDEX idx3(c4(512))) Engine=InnoDB;
-SET GLOBAL INNODB_PURGE_STOP_NOW=ON;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
SET GLOBAL innodb_disable_background_merge=ON;
SET GLOBAL innodb_monitor_reset = ibuf_merges;
SET GLOBAL innodb_monitor_reset = ibuf_merges_insert;
@@ -660,7 +648,7 @@ FROM information_schema.innodb_metrics
WHERE name = 'ibuf_merges_inserts' AND count > 0;
name
SET GLOBAL innodb_disable_background_merge=OFF;
-SET GLOBAL INNODB_PURGE_RUN_NOW=ON;
+COMMIT;
DROP TABLE test_wl5522.t1;
CREATE TABLE test_wl5522.t1 (
c1 BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
@@ -796,8 +784,8 @@ t1 CREATE TABLE `t1` (
) ENGINE=InnoDB AUTO_INCREMENT=185 DEFAULT CHARSET=latin1
DROP TABLE test_wl5522.t1;
CREATE TABLE test_wl5522.t1 (c1 INT, c2 VARCHAR(1024), c3 BLOB) ENGINE = Innodb;
-INSERT INTO test_wl5522.t1 VALUES
-(100, REPEAT('Karanbir', 899), REPEAT('Ajeeth', 1200));
+INSERT IGNORE INTO test_wl5522.t1 VALUES
+(100, REPEAT('Karanbir', 899), REPEAT('Ajeeth', 2731));
Warnings:
Warning 1265 Data truncated for column 'c2' at row 1
INSERT INTO test_wl5522.t1 SELECT * FROM test_wl5522.t1;
@@ -832,7 +820,7 @@ ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE;
SELECT COUNT(*) FROM test_wl5522.t1;
ERROR HY000: Tablespace has been discarded for table 't1'
restore: t1 .ibd and .cfg files
-SET SESSION debug_dbug="+d,buf_page_is_corrupt_failure";
+SET SESSION debug_dbug="+d,buf_page_import_corrupt_failure";
ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
ERROR HY000: Internal error: Cannot reset LSNs in table '"test_wl5522"."t1"' : Data structure corruption
SET SESSION debug_dbug=@saved_debug_dbug;
diff --git a/mysql-test/suite/innodb/r/innodb-wl5980-alter.result b/mysql-test/suite/innodb/r/innodb-wl5980-alter.result
new file mode 100644
index 00000000000..6cf3ad4fc08
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-wl5980-alter.result
@@ -0,0 +1,1409 @@
+#
+# This is a copy of innodb-alter.test except using remote tablespaces
+# and showing those files.
+#
+SET default_storage_engine=InnoDB;
+SET GLOBAL innodb_file_per_table=ON;
+SET NAMES utf8;
+CREATE TABLE t1 (
+c1 INT PRIMARY KEY, c2 INT DEFAULT 1, ct TEXT,
+INDEX(c2))
+ENGINE=InnoDB DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir';
+INSERT INTO t1 SET c1=1;
+CREATE TABLE sys_tables SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
+WHERE NAME LIKE 'test/t%';
+CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+CREATE TABLE t1p LIKE t1;
+CREATE TABLE t1c (c1 INT PRIMARY KEY, c2 INT, c3 INT, INDEX(c2), INDEX(c3),
+CONSTRAINT t1c2 FOREIGN KEY (c2) REFERENCES t1(c2),
+CONSTRAINT t1c3 FOREIGN KEY (c3) REFERENCES t1p(c2))
+ENGINE=InnoDB DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir';
+CREATE TABLE sys_foreign SELECT i.*
+FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN i
+WHERE FOR_NAME LIKE 'test/t%';
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 c2 0
+test/t1c3 c3 c2 0
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c2 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 c2
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 c2 0
+test/t1c3 c3 c2 0
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT '1',
+ `ct` text,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir/'
+ALTER TABLE t1 ALTER c2 DROP DEFAULT;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11),
+ `ct` text,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir/'
+### files in MYSQL_DATA_DIR/test
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1.frm
+t1.isl
+t1c.frm
+t1c.isl
+t1p.frm
+t1p.ibd
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1.ibd
+t1c.ibd
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c2 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 c2
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 c2 0
+test/t1c3 c3 c2 0
+ALTER TABLE t1 CHANGE c2 c2 INT AFTER c1;
+ALTER TABLE t1 CHANGE c1 c1 INT FIRST;
+### files in MYSQL_DATA_DIR/test
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1.frm
+t1.isl
+t1c.frm
+t1c.isl
+t1p.frm
+t1p.ibd
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1.ibd
+t1c.ibd
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c2 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 c2
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 c2 0
+test/t1c3 c3 c2 0
+ALTER TABLE t1 CHANGE C2 c3 INT;
+### files in MYSQL_DATA_DIR/test
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1.frm
+t1.isl
+t1c.frm
+t1c.isl
+t1p.frm
+t1p.ibd
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1.ibd
+t1c.ibd
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c3 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 c3
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 c3 0
+test/t1c3 c3 c2 0
+ALTER TABLE t1 CHANGE c3 C INT;
+### files in MYSQL_DATA_DIR/test
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1.frm
+t1.isl
+t1c.frm
+t1c.isl
+t1p.frm
+t1p.ibd
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1.ibd
+t1c.ibd
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+C 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 C
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 C 0
+test/t1c3 c3 c2 0
+ALTER TABLE t1 CHANGE C Cöŀumň_TWO INT;
+### files in MYSQL_DATA_DIR/test
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1.frm
+t1.isl
+t1c.frm
+t1c.isl
+t1p.frm
+t1p.ibd
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1.ibd
+t1c.ibd
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 Cöŀumň_TWO 0
+test/t1c3 c3 c2 0
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+Cöŀumň_TWO 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 Cöŀumň_TWO
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 Cöŀumň_TWO 0
+test/t1c3 c3 c2 0
+ALTER TABLE t1 CHANGE cöĿǖmň_two c3 INT;
+ERROR 42S22: Unknown column 'cöĿǖmň_two' in 't1'
+ALTER TABLE t1 CHANGE cÖĿUMŇ_two c3 INT, RENAME TO t3;
+### files in MYSQL_DATA_DIR/test
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1c.frm
+t1c.isl
+t1p.frm
+t1p.ibd
+t3.frm
+t3.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1c.ibd
+t3.ibd
+SELECT st.NAME, i.NAME
+FROM sys_tables st INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES i
+ON i.TABLE_ID=st.TABLE_ID;
+NAME NAME
+test/t1 test/t3
+SHOW CREATE TABLE t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `c1` int(11) NOT NULL,
+ `c3` int(11) DEFAULT NULL,
+ `ct` text,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`c3`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir/'
+SHOW CREATE TABLE t1c;
+Table Create Table
+t1c CREATE TABLE `t1c` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `c3` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`c2`),
+ KEY `c3` (`c3`),
+ CONSTRAINT `t1c2` FOREIGN KEY (`c2`) REFERENCES `t3` (`c3`),
+ CONSTRAINT `t1c3` FOREIGN KEY (`c3`) REFERENCES `t1p` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir/'
+ALTER TABLE t3 CHANGE c3
+`12345678901234567890123456789012345678901234567890123456789012345` INT;
+ERROR 42000: Identifier name '12345678901234567890123456789012345678901234567890123456789012345' is too long
+ALTER TABLE t3 CHANGE c3
+`1234567890123456789012345678901234567890123456789012345678901234` INT;
+### files in MYSQL_DATA_DIR/test
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1c.frm
+t1c.isl
+t1p.frm
+t1p.ibd
+t3.frm
+t3.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1c.ibd
+t3.ibd
+SHOW CREATE TABLE t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `c1` int(11) NOT NULL,
+ `1234567890123456789012345678901234567890123456789012345678901234` int(11) DEFAULT NULL,
+ `ct` text,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`1234567890123456789012345678901234567890123456789012345678901234`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir/'
+ALTER TABLE t3 CHANGE
+`1234567890123456789012345678901234567890123456789012345678901234`
+`倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ å€¡å€¢å€£å€¤å€¥å€¦å€§å€¨å€©å€ªå€«å€¬å€­å€®å€¯å€°å€±å€²å€³å€´å€µå€¶å€·å€¸å€¹å€ºå€»å€¼å€½å€¾å€¿å€` INT;
+ERROR 42000: Identifier name '倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ ' is too long
+ALTER TABLE t3 CHANGE
+`1234567890123456789012345678901234567890123456789012345678901234`
+`倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ å€¡å€¢å€£å€¤å€¥å€¦å€§å€¨å€©å€ªå€«å€¬å€­å€®å€¯å€°å€±å€²å€³å€´å€µå€¶å€·å€¸å€¹å€ºå€»å€¼å€½å€¾å€¿Ã¤` INT;
+ERROR 42000: Identifier name '倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ ' is too long
+ALTER TABLE t3 CHANGE
+`1234567890123456789012345678901234567890123456789012345678901234`
+`倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ å€¡å€¢å€£å€¤å€¥å€¦å€§å€¨å€©å€ªå€«å€¬å€­å€®å€¯å€°å€±å€²å€³å€´å€µå€¶å€·å€¸å€¹å€ºå€»å€¼å€½å€¾Ã¤` INT;
+### files in MYSQL_DATA_DIR/test
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1c.frm
+t1c.isl
+t1p.frm
+t1p.ibd
+t3.frm
+t3.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1c.ibd
+t3.ibd
+ALTER TABLE t3 CHANGE
+`倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ å€¡å€¢å€£å€¤å€¥å€¦å€§å€¨å€©å€ªå€«å€¬å€­å€®å€¯å€°å€±å€²å€³å€´å€µå€¶å€·å€¸å€¹å€ºå€»å€¼å€½å€¾Ã„`
+c3 INT;
+### files in MYSQL_DATA_DIR/test
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1c.frm
+t1c.isl
+t1p.frm
+t1p.ibd
+t3.frm
+t3.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1c.ibd
+t3.ibd
+ALTER TABLE t3 CHANGE c3 ðŒ€ðŒðŒ‚ðŒƒðŒ„ðŒ…ðŒ†ðŒ‡ðŒˆðŒ‰ðŒŠðŒ‹ðŒŒðŒðŒŽðŒðŒðŒ‘ðŒ’ðŒ“ðŒ”ðŒ•ðŒ–ðŒ—ðŒ˜ðŒ™ðŒšðŒ›ðŒœ INT;
+ERROR HY000: Invalid utf8 character string: '\xF0\x90\x8C\x80\xF0\x90\x8C\x81\xF0\x90\x8C\x82\xF0\x90\x8C\x83'
+ALTER TABLE t3 CHANGE c3 😲 INT;
+ERROR HY000: Invalid utf8 character string: '\xF0\x9F\x98\xB2'
+ALTER TABLE t3 RENAME TO t2;
+### files in MYSQL_DATA_DIR/test
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1c.frm
+t1c.isl
+t1p.frm
+t1p.ibd
+t2.frm
+t2.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1c.ibd
+t2.ibd
+SELECT st.NAME, i.NAME
+FROM sys_tables st INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES i
+ON i.TABLE_ID=st.TABLE_ID;
+NAME NAME
+test/t1 test/t2
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `c1` int(11) NOT NULL,
+ `c3` int(11) DEFAULT NULL,
+ `ct` text,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`c3`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir/'
+RENAME TABLE t2 TO t1;
+SELECT st.NAME, i.NAME
+FROM sys_tables st INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES i
+ON i.TABLE_ID=st.TABLE_ID;
+NAME NAME
+test/t1 test/t1
+### files in MYSQL_DATA_DIR/test
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1.frm
+t1.isl
+t1c.frm
+t1c.isl
+t1p.frm
+t1p.ibd
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1.ibd
+t1c.ibd
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c3 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 c3
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 c3 0
+test/t1c3 c3 c2 0
+ALTER TABLE t1 DROP INDEX c2;
+ERROR HY000: Cannot drop index 'c2': needed in a foreign key constraint
+ALTER TABLE t1 DROP INDEX c4;
+ERROR 42000: Can't DROP 'c4'; check that column/key exists
+ALTER TABLE t1c DROP FOREIGN KEY c2;
+ERROR 42000: Can't DROP 'c2'; check that column/key exists
+ALTER TABLE t1c DROP FOREIGN KEY t1c2, DROP FOREIGN KEY c2;
+ERROR 42000: Can't DROP 'c2'; check that column/key exists
+ALTER TABLE t1c DROP FOREIGN KEY t1c2, DROP FOREIGN KEY c2, DROP INDEX c2;
+ERROR 42000: Can't DROP 'c2'; check that column/key exists
+ALTER TABLE t1c DROP INDEX c2;
+ERROR HY000: Cannot drop index 'c2': needed in a foreign key constraint
+ALTER TABLE t1c DROP FOREIGN KEY ẗ1C2;
+ERROR 42000: Can't DROP 'ẗ1C2'; check that column/key exists
+SHOW CREATE TABLE t1c;
+Table Create Table
+t1c CREATE TABLE `t1c` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `c3` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`c2`),
+ KEY `c3` (`c3`),
+ CONSTRAINT `t1c2` FOREIGN KEY (`c2`) REFERENCES `t1` (`c3`),
+ CONSTRAINT `t1c3` FOREIGN KEY (`c3`) REFERENCES `t1p` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir/'
+SET foreign_key_checks=0;
+DROP TABLE t1p;
+SET foreign_key_checks=1;
+SHOW CREATE TABLE t1c;
+Table Create Table
+t1c CREATE TABLE `t1c` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `c3` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`c2`),
+ KEY `c3` (`c3`),
+ CONSTRAINT `t1c2` FOREIGN KEY (`c2`) REFERENCES `t1` (`c3`),
+ CONSTRAINT `t1c3` FOREIGN KEY (`c3`) REFERENCES `t1p` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir/'
+### files in MYSQL_DATA_DIR/test
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1.frm
+t1.isl
+t1c.frm
+t1c.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1.ibd
+t1c.ibd
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c3 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 c3
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 c3 0
+test/t1c3 c3 c2 0
+CREATE TABLE t1p (c1 INT PRIMARY KEY, c2 INT, INDEX(c2))
+ENGINE=InnoDB DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir';
+ALTER TABLE t1c DROP INDEX C2, DROP INDEX C3;
+ERROR HY000: Cannot drop index 'c2': needed in a foreign key constraint
+ALTER TABLE t1c DROP INDEX C3;
+ERROR HY000: Cannot drop index 'c3': needed in a foreign key constraint
+SET foreign_key_checks=0;
+ALTER TABLE t1c DROP INDEX C3;
+### files in MYSQL_DATA_DIR/test
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1.frm
+t1.isl
+t1c.frm
+t1c.isl
+t1p.frm
+t1p.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1.ibd
+t1c.ibd
+t1p.ibd
+SET foreign_key_checks=1;
+SHOW CREATE TABLE t1c;
+Table Create Table
+t1c CREATE TABLE `t1c` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `c3` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`c2`),
+ CONSTRAINT `t1c2` FOREIGN KEY (`c2`) REFERENCES `t1` (`c3`),
+ CONSTRAINT `t1c3` FOREIGN KEY (`c3`) REFERENCES `t1p` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir/'
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c3 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 c3
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 c3 0
+test/t1c3 c3 c2 0
+ALTER TABLE t1c DROP FOREIGN KEY t1C3;
+### files in MYSQL_DATA_DIR/test
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1.frm
+t1.isl
+t1c.frm
+t1c.isl
+t1p.frm
+t1p.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1.ibd
+t1c.ibd
+t1p.ibd
+SHOW CREATE TABLE t1c;
+Table Create Table
+t1c CREATE TABLE `t1c` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `c3` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`),
+ KEY `c2` (`c2`),
+ CONSTRAINT `t1c2` FOREIGN KEY (`c2`) REFERENCES `t1` (`c3`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir/'
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c3 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 c3
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+test/t1c2 c2 c3 0
+ALTER TABLE t1c DROP INDEX c2, DROP FOREIGN KEY t1C2;
+### files in MYSQL_DATA_DIR/test
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1.frm
+t1.isl
+t1c.frm
+t1c.isl
+t1p.frm
+t1p.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1.ibd
+t1c.ibd
+t1p.ibd
+SHOW CREATE TABLE t1c;
+Table Create Table
+t1c CREATE TABLE `t1c` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `c3` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir/'
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c3 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+c2 0 c3
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+ALTER TABLE t1 DROP INDEX c2, CHANGE c3 c2 INT;
+### files in MYSQL_DATA_DIR/test
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1.frm
+t1.isl
+t1c.frm
+t1c.isl
+t1p.frm
+t1p.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1.ibd
+t1c.ibd
+t1p.ibd
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+c1 0 6 1283 4
+c2 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 c1
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+CREATE TABLE t1o LIKE t1;
+ALTER TABLE t1 ADD FULLTEXT INDEX (ct),
+CHANGE c1 pk INT, ALTER c2 SET DEFAULT 42, RENAME TO tt,
+ALGORITHM=INPLACE, LOCK=NONE;
+ERROR 0A000: LOCK=NONE is not supported. Reason: Fulltext index creation requires a lock. Try LOCK=SHARED.
+ALTER TABLE t1 ADD FULLTEXT INDEX (ct),
+CHANGE c1 pk INT, ALTER c2 SET DEFAULT 42, RENAME TO tt,
+ALGORITHM=INPLACE, LOCK=SHARED;
+Warnings:
+Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID
+### files in MYSQL_DATA_DIR/test
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1c.frm
+t1c.isl
+t1o.frm
+t1o.ibd
+t1p.frm
+t1p.isl
+tt.frm
+tt.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1c.ibd
+t1p.ibd
+tt.ibd
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+SHOW CREATE TABLE tt;
+Table Create Table
+tt CREATE TABLE `tt` (
+ `pk` int(11) NOT NULL,
+ `c2` int(11) DEFAULT '42',
+ `ct` text,
+ PRIMARY KEY (`pk`),
+ FULLTEXT KEY `ct` (`ct`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir/'
+ALTER TABLE t1o CHANGE c1 dB_row_Id INT, ALGORITHM=COPY;
+ERROR 42000: Incorrect column name 'dB_row_Id'
+ALTER TABLE t1o CHANGE c1 dB_row_Id INT, ALGORITHM=INPLACE;
+ERROR 42000: Incorrect column name 'DB_ROW_ID'
+ALTER TABLE t1o CHANGE c1 DB_TRX_ID INT;
+ERROR 42000: Incorrect column name 'DB_TRX_ID'
+ALTER TABLE t1o CHANGE c1 db_roll_ptr INT;
+ERROR 42000: Incorrect column name 'DB_ROLL_PTR'
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_DOC_ID INT,
+ALGORITHM=COPY;
+ERROR 42000: Incorrect column name 'FTS_DOC_ID'
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_DOC_ID INT,
+ALGORITHM=INPLACE;
+ERROR HY000: Column 'FTS_DOC_ID' is of wrong type for an InnoDB FULLTEXT index
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_Doc_ID INT,
+ALGORITHM=INPLACE;
+ERROR 42000: Incorrect column name 'FTS_Doc_ID'
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct),
+CHANGE c1 FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE;
+ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.
+CREATE TABLE t1n LIKE t1o;
+ALTER TABLE t1n ADD FULLTEXT INDEX(ct);
+Warnings:
+Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID
+### files in MYSQL_DATA_DIR/test
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1c.frm
+t1c.isl
+t1n.frm
+t1n.ibd
+t1o.frm
+t1o.ibd
+t1p.frm
+t1p.isl
+tt.frm
+tt.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1c.ibd
+t1p.ibd
+tt.ibd
+ALTER TABLE t1n CHANGE c1 Fts_DOC_ID INT, ALGORITHM=INPLACE;
+ERROR 42000: Incorrect column name 'FTS_DOC_ID'
+ALTER TABLE t1n CHANGE c1 Fts_DOC_ID INT, ALGORITHM=COPY;
+ERROR 42000: Incorrect column name 'Fts_DOC_ID'
+ALTER TABLE t1n CHANGE FTS_DOC_ID c11 INT, ALGORITHM=INPLACE;
+ERROR 42S22: Unknown column 'FTS_DOC_ID' in 't1n'
+ALTER TABLE t1n CHANGE c1 FTS_DOC_ïD INT, ALGORITHM=INPLACE;
+### files in MYSQL_DATA_DIR/test
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1c.frm
+t1c.isl
+t1n.frm
+t1n.ibd
+t1o.frm
+t1o.ibd
+t1p.frm
+t1p.isl
+tt.frm
+tt.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1c.ibd
+t1p.ibd
+tt.ibd
+ALTER TABLE t1n CHANGE FTS_DOC_ÃD c1 INT, ALGORITHM=INPLACE;
+### files in MYSQL_DATA_DIR/test
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1c.frm
+t1c.isl
+t1n.frm
+t1n.ibd
+t1o.frm
+t1o.ibd
+t1p.frm
+t1p.isl
+tt.frm
+tt.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1c.ibd
+t1p.ibd
+tt.ibd
+ALTER TABLE t1n CHANGE c1 c2 INT, CHANGE c2 ct INT, CHANGE ct c1 TEXT,
+ALGORITHM=INPLACE;
+### files in MYSQL_DATA_DIR/test
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1c.frm
+t1c.isl
+t1n.frm
+t1n.ibd
+t1o.frm
+t1o.ibd
+t1p.frm
+t1p.isl
+tt.frm
+tt.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1c.ibd
+t1p.ibd
+tt.ibd
+SHOW CREATE TABLE t1n;
+Table Create Table
+t1n CREATE TABLE `t1n` (
+ `c2` int(11) NOT NULL,
+ `ct` int(11) DEFAULT NULL,
+ `c1` text,
+ PRIMARY KEY (`c2`),
+ FULLTEXT KEY `ct` (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t1n CHANGE c2 c1 INT, CHANGE ct c2 INT, CHANGE c1 ct TEXT,
+ALGORITHM=COPY;
+### files in MYSQL_DATA_DIR/test
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1c.frm
+t1c.isl
+t1n.frm
+t1n.ibd
+t1o.frm
+t1o.ibd
+t1p.frm
+t1p.isl
+tt.frm
+tt.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1c.ibd
+t1p.ibd
+tt.ibd
+SHOW CREATE TABLE t1n;
+Table Create Table
+t1n CREATE TABLE `t1n` (
+ `c1` int(11) NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `ct` text,
+ PRIMARY KEY (`c1`),
+ FULLTEXT KEY `ct` (`ct`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t1n ADD INDEX(c2), CHANGE c2 c4 INT, ALGORITHM=INPLACE;
+ERROR 42000: Key column 'c2' doesn't exist in table
+ALTER TABLE t1n ADD INDEX(c2), CHANGE c2 c4 INT, ALGORITHM=COPY;
+ERROR 42000: Key column 'c2' doesn't exist in table
+ALTER TABLE t1n ADD INDEX(c4), CHANGE c2 c4 INT, ALGORITHM=INPLACE;
+### files in MYSQL_DATA_DIR/test
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1c.frm
+t1c.isl
+t1n.frm
+t1n.ibd
+t1o.frm
+t1o.ibd
+t1p.frm
+t1p.isl
+tt.frm
+tt.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1c.ibd
+t1p.ibd
+tt.ibd
+SHOW CREATE TABLE t1n;
+Table Create Table
+t1n CREATE TABLE `t1n` (
+ `c1` int(11) NOT NULL,
+ `c4` int(11) DEFAULT NULL,
+ `ct` text,
+ PRIMARY KEY (`c1`),
+ KEY `c4` (`c4`),
+ FULLTEXT KEY `ct` (`ct`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t1n DROP INDEX c4;
+### files in MYSQL_DATA_DIR/test
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1c.frm
+t1c.isl
+t1n.frm
+t1n.ibd
+t1o.frm
+t1o.ibd
+t1p.frm
+t1p.isl
+tt.frm
+tt.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1c.ibd
+t1p.ibd
+tt.ibd
+ALTER TABLE t1n CHANGE c4 c1 INT, ADD INDEX(c1), ALGORITHM=INPLACE;
+ERROR 42S21: Duplicate column name 'c1'
+ALTER TABLE t1n CHANGE c4 c11 INT, ADD INDEX(c11), ALGORITHM=INPLACE;
+### files in MYSQL_DATA_DIR/test
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1c.frm
+t1c.isl
+t1n.frm
+t1n.ibd
+t1o.frm
+t1o.ibd
+t1p.frm
+t1p.isl
+tt.frm
+tt.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1c.ibd
+t1p.ibd
+tt.ibd
+SHOW CREATE TABLE t1n;
+Table Create Table
+t1n CREATE TABLE `t1n` (
+ `c1` int(11) NOT NULL,
+ `c11` int(11) DEFAULT NULL,
+ `ct` text,
+ PRIMARY KEY (`c1`),
+ KEY `c11` (`c11`),
+ FULLTEXT KEY `ct` (`ct`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t1n;
+ALTER TABLE t1o MODIFY c1 BIGINT UNSIGNED NOT NULL;
+### files in MYSQL_DATA_DIR/test
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1c.frm
+t1c.isl
+t1o.frm
+t1o.ibd
+t1p.frm
+t1p.isl
+tt.frm
+tt.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1c.ibd
+t1p.ibd
+tt.ibd
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct),
+CHANGE c1 FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE;
+### files in MYSQL_DATA_DIR/test
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1c.frm
+t1c.isl
+t1o.frm
+t1o.ibd
+t1p.frm
+t1p.isl
+tt.frm
+tt.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1c.ibd
+t1p.ibd
+tt.ibd
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
+LOCK=NONE;
+ERROR 0A000: LOCK=NONE is not supported. Reason: Cannot drop or rename FTS_DOC_ID. Try LOCK=SHARED.
+SELECT sc.pos FROM information_schema.innodb_sys_columns sc
+INNER JOIN information_schema.innodb_sys_tables st
+ON sc.TABLE_ID=st.TABLE_ID
+WHERE st.NAME='test/t1o' AND sc.NAME='FTS_DOC_ID';
+pos
+0
+SHOW CREATE TABLE t1o;
+Table Create Table
+t1o CREATE TABLE `t1o` (
+ `FTS_DOC_ID` bigint(20) unsigned NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `ct` text,
+ PRIMARY KEY (`FTS_DOC_ID`),
+ FULLTEXT KEY `ct` (`ct`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
+DROP INDEX ct, LOCK=NONE;
+### files in MYSQL_DATA_DIR/test
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1c.frm
+t1c.isl
+t1o.frm
+t1o.ibd
+t1p.frm
+t1p.isl
+tt.frm
+tt.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+t1c.ibd
+t1p.ibd
+tt.ibd
+SHOW CREATE TABLE t1o;
+Table Create Table
+t1o CREATE TABLE `t1o` (
+ `foo_id` bigint(20) unsigned NOT NULL,
+ `c2` int(11) DEFAULT NULL,
+ `ct` text,
+ PRIMARY KEY (`foo_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t1c, t1p, sys_tables, sys_indexes, sys_foreign;
+CREATE TABLE sys_tables SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
+WHERE NAME='test/t1o';
+CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+CREATE TABLE sys_foreign SELECT i.*
+FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN i WHERE FOR_NAME='test/t1o';
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+foo_id 0 6 1800 8
+c2 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 foo_id
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+ALTER TABLE t1o ADD UNIQUE INDEX FTS_DOC_ID_INDEX(foo_id);
+### files in MYSQL_DATA_DIR/test
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1o.frm
+t1o.ibd
+tt.frm
+tt.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+tt.ibd
+ALTER TABLE t1o CHANGE foo_id FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
+ADD FULLTEXT INDEX(ct);
+### files in MYSQL_DATA_DIR/test
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+FTS_AUX_INDEX_1.ibd
+FTS_AUX_INDEX_2.ibd
+FTS_AUX_INDEX_3.ibd
+FTS_AUX_INDEX_4.ibd
+FTS_AUX_INDEX_5.ibd
+FTS_AUX_INDEX_6.ibd
+FTS_AUX_BEING_DELETED.ibd
+FTS_AUX_BEING_DELETED_CACHE.ibd
+FTS_AUX_CONFIG.ibd
+FTS_AUX_DELETED.ibd
+FTS_AUX_DELETED_CACHE.ibd
+sys_foreign.frm
+sys_foreign.ibd
+sys_indexes.frm
+sys_indexes.ibd
+sys_tables.frm
+sys_tables.ibd
+t1o.frm
+t1o.ibd
+tt.frm
+tt.isl
+### files in MYSQL_TMP_DIR/alt_dir/test
+tt.ibd
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL;
+ERROR HY000: Index 'FTS_DOC_ID_INDEX' is of wrong type for an InnoDB FULLTEXT index
+DROP TABLE sys_indexes;
+CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN
+FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+NAME POS MTYPE PRTYPE LEN
+FTS_DOC_ID 0 6 1800 8
+c2 1 6 1027 4
+ct 2 5 524540 10
+SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i
+INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID;
+NAME POS NAME
+PRIMARY 0 FTS_DOC_ID
+FTS_DOC_ID_INDEX 0 FTS_DOC_ID
+ct 0 ct
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+ID FOR_COL_NAME REF_COL_NAME POS
+#
+# Cleanup
+#
+DROP TABLE tt, t1o, sys_tables, sys_indexes, sys_foreign;
+### files in MYSQL_DATA_DIR/test
+### files in MYSQL_TMP_DIR/alt_dir/test
diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result
index d50b9b36a4f..3255b61d422 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;
@@ -3144,3 +3146,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_corrupt_bit.result b/mysql-test/suite/innodb/r/innodb_corrupt_bit.result
index 0ef6f65d0ff..b3392c1a3c4 100644
--- a/mysql-test/suite/innodb/r/innodb_corrupt_bit.result
+++ b/mysql-test/suite/innodb/r/innodb_corrupt_bit.result
@@ -1,26 +1,62 @@
+set names utf8;
+SET UNIQUE_CHECKS=0;
+CREATE TABLE corrupt_bit_test_Ä(
+a INT AUTO_INCREMENT PRIMARY KEY,
+b CHAR(100),
+c INT,
+z INT,
+INDEX idx(b))
+ENGINE=InnoDB;
+INSERT INTO corrupt_bit_test_Ä VALUES(0,'x',1, 1);
+CREATE UNIQUE INDEX idxÄ ON corrupt_bit_test_Ä(c, b);
+CREATE UNIQUE INDEX idxÄ“ ON corrupt_bit_test_Ä(z, b);
+SELECT * FROM corrupt_bit_test_Ä;
a b c z
1 x 1 1
+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 @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 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);
ERROR HY000: Index "idx" is corrupted
+select c from corrupt_bit_test_Ä;
ERROR HY000: Index corrupt_bit_test_Ä is corrupted
+select z from corrupt_bit_test_Ä;
ERROR HY000: Index corrupt_bit_test_Ä is corrupted
+show warnings;
Level Code Message
Warning 180 InnoDB: Index "idxÄ“" for table "test"."corrupt_bit_test_Ä" is marked as corrupted
Error 1712 Index corrupt_bit_test_Ä is corrupted
+insert into corrupt_bit_test_Ä values (10001, "a", 20001, 20001);
+select * from corrupt_bit_test_Ä use index(primary) where a = 10001;
a b c z
10001 a 20001 20001
+begin;
+insert into corrupt_bit_test_Ä values (10002, "a", 20002, 20002);
+delete from corrupt_bit_test_Ä where a = 10001;
+insert into corrupt_bit_test_Ä values (10001, "a", 20001, 20001);
+rollback;
+drop index idxÄ on corrupt_bit_test_Ä;
+check table corrupt_bit_test_Ä;
Table Op Msg_type Msg_text
test.corrupt_bit_test_Ä check Warning InnoDB: Index "idx" is marked as corrupted
test.corrupt_bit_test_Ä check Warning InnoDB: Index "idxÄ“" is marked as corrupted
test.corrupt_bit_test_Ä check error Corrupt
+set names utf8;
+select z from corrupt_bit_test_Ä;
ERROR HY000: Index corrupt_bit_test_Ä is corrupted
+show create table corrupt_bit_test_Ä;
Table Create Table
corrupt_bit_test_Ä CREATE TABLE `corrupt_bit_test_Ä` (
`a` int(11) NOT NULL AUTO_INCREMENT,
@@ -31,8 +67,12 @@ corrupt_bit_test_Ä CREATE TABLE `corrupt_bit_test_Ä` (
UNIQUE KEY `idxē` (`z`,`b`),
KEY `idx` (`b`)
) ENGINE=InnoDB AUTO_INCREMENT=10003 DEFAULT CHARSET=latin1
+drop index idxÄ“ on corrupt_bit_test_Ä;
+CREATE INDEX idx3 ON corrupt_bit_test_Ä(b, c);
ERROR HY000: Index "idx" is corrupted
+CREATE INDEX idx4 ON corrupt_bit_test_Ä(b, z);
ERROR HY000: Index "idx" is corrupted
+show create table corrupt_bit_test_Ä;
Table Create Table
corrupt_bit_test_Ä CREATE TABLE `corrupt_bit_test_Ä` (
`a` int(11) NOT NULL AUTO_INCREMENT,
@@ -42,7 +82,12 @@ corrupt_bit_test_Ä CREATE TABLE `corrupt_bit_test_Ä` (
PRIMARY KEY (`a`),
KEY `idx` (`b`)
) ENGINE=InnoDB AUTO_INCREMENT=10003 DEFAULT CHARSET=latin1
+drop index idx on corrupt_bit_test_Ä;
+CREATE INDEX idx3 ON corrupt_bit_test_Ä(b, c);
+CREATE INDEX idx4 ON corrupt_bit_test_Ä(b, z);
+select z from corrupt_bit_test_Ä limit 10;
z
20001
1
2
+drop table corrupt_bit_test_Ä;
diff --git a/mysql-test/suite/innodb/r/mvcc.result b/mysql-test/suite/innodb/r/mvcc.result
new file mode 100644
index 00000000000..6bbabc8d87a
--- /dev/null
+++ b/mysql-test/suite/innodb/r/mvcc.result
@@ -0,0 +1,26 @@
+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;
+ALTER TABLE t1 FORCE, ALGORITHM=COPY;
+SELECT * FROM t1;
+ERROR HY000: Table definition has changed, please retry transaction
+COMMIT;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+ALTER TABLE t1 DISCARD TABLESPACE;
+ALTER TABLE t1 IMPORT TABLESPACE;
+# FIXME: Block this with ER_TABLE_DEF_CHANGED
+SELECT * FROM t1;
+a
+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/read_only_recover_committed.result b/mysql-test/suite/innodb/r/read_only_recover_committed.result
new file mode 100644
index 00000000000..593bcae40ee
--- /dev/null
+++ b/mysql-test/suite/innodb/r/read_only_recover_committed.result
@@ -0,0 +1,43 @@
+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;
+# 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;
+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;
+SELECT * FROM t;
+a
+1
+SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+SELECT * FROM t;
+a
+1
+UPDATE t SET a=3 WHERE a=1;
+ERROR HY000: Table 't' is read only
+# 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
+1
+SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+SELECT * FROM t;
+a
+1
+SELECT * FROM t;
+a
+1
+DROP TABLE t;
+NOT FOUND /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..47398c1ca23
--- /dev/null
+++ b/mysql-test/suite/innodb/r/recovery_shutdown.result
@@ -0,0 +1,56 @@
+#
+# 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;
+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;
+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;
+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;
+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;
+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;
+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;
+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;
+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;
+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/table_definition_cache_debug.result b/mysql-test/suite/innodb/r/table_definition_cache_debug.result
new file mode 100644
index 00000000000..a72d4baad21
--- /dev/null
+++ b/mysql-test/suite/innodb/r/table_definition_cache_debug.result
@@ -0,0 +1,16 @@
+SET @save_tdc= @@GLOBAL.table_definition_cache;
+SET @save_toc= @@GLOBAL.table_open_cache;
+SET GLOBAL table_definition_cache= 400;
+SET GLOBAL table_open_cache= 1024;
+CREATE TABLE to_be_evicted(a INT PRIMARY KEY, b INT NOT NULL) ENGINE=InnoDB;
+INSERT INTO to_be_evicted VALUES(1,2),(2,1);
+SET DEBUG_SYNC = 'row_log_apply_before SIGNAL scanned WAIT_FOR got_duplicate';
+ALTER TABLE to_be_evicted ADD UNIQUE INDEX(b);
+SET DEBUG_SYNC = 'now WAIT_FOR scanned';
+BEGIN;
+INSERT INTO to_be_evicted VALUES(3, 2);
+SET DEBUG_SYNC = 'now SIGNAL got_duplicate';
+ERROR 23000: Duplicate entry '2' for key 'b'
+COMMIT;
+SET DEBUG_SYNC = RESET;
+FLUSH TABLES;
diff --git a/mysql-test/suite/innodb/r/undo_log.result b/mysql-test/suite/innodb/r/undo_log.result
new file mode 100644
index 00000000000..a40c6b5b3bf
--- /dev/null
+++ b/mysql-test/suite/innodb/r/undo_log.result
@@ -0,0 +1,142 @@
+CREATE TABLE test_tab (
+a_str_18 mediumtext,
+b_str_3 varchar(32) DEFAULT NULL,
+a_str_13 mediumtext,
+b_str_5 varchar(40) DEFAULT NULL,
+b_str_6 varchar(50) DEFAULT NULL,
+b_str_7 char(32) DEFAULT NULL,
+b_str_8 varchar(32) DEFAULT NULL,
+b_str_9 varchar(255) DEFAULT NULL,
+a_str_28 char(255) DEFAULT NULL,
+a_str_27 varchar(255) DEFAULT NULL,
+b_str_10 varchar(32) DEFAULT NULL,
+a_str_26 varchar(255) DEFAULT NULL,
+a_str_6 varchar(50) DEFAULT NULL,
+b_str_11 varchar(32) DEFAULT NULL,
+b_str_12 varchar(255) DEFAULT NULL,
+b_str_13 char(32) DEFAULT NULL,
+b_str_14 varchar(32) DEFAULT NULL,
+b_str_15 char(32) DEFAULT NULL,
+b_str_16 char(32) DEFAULT NULL,
+b_str_17 varchar(32) DEFAULT NULL,
+b_str_18 varchar(32) DEFAULT NULL,
+a_str_25 varchar(40) DEFAULT NULL,
+b_str_19 varchar(255) DEFAULT NULL,
+a_str_23 varchar(40) DEFAULT NULL,
+b_str_20 varchar(32) DEFAULT NULL,
+a_str_21 varchar(255) DEFAULT NULL,
+a_str_20 varchar(255) DEFAULT NULL,
+a_str_39 varchar(255) DEFAULT NULL,
+a_str_38 varchar(255) DEFAULT NULL,
+a_str_37 varchar(255) DEFAULT NULL,
+b_str_21 char(32) DEFAULT NULL,
+b_str_23 varchar(80) DEFAULT NULL,
+b_str_24 varchar(32) DEFAULT NULL,
+b_str_25 varchar(32) DEFAULT NULL,
+b_str_26 char(32) NOT NULL DEFAULT '',
+b_str_27 varchar(255) DEFAULT NULL,
+a_str_36 varchar(255) DEFAULT NULL,
+a_str_33 varchar(100) DEFAULT NULL,
+a_ref_10 char(32) DEFAULT NULL,
+b_str_28 char(32) DEFAULT NULL,
+b_str_29 char(32) DEFAULT NULL,
+a_ref_6 char(32) DEFAULT NULL,
+a_ref_12 varchar(32) DEFAULT NULL,
+a_ref_11 varchar(32) DEFAULT NULL,
+a_str_49 varchar(40) DEFAULT NULL,
+b_str_30 varchar(32) DEFAULT NULL,
+a_ref_3 varchar(32) DEFAULT NULL,
+a_str_48 varchar(40) DEFAULT NULL,
+a_ref_1 char(32) DEFAULT NULL,
+b_str_31 varchar(32) DEFAULT NULL,
+b_str_32 varchar(255) DEFAULT NULL,
+b_str_33 char(32) DEFAULT NULL,
+b_str_34 varchar(32) DEFAULT NULL,
+a_str_47 varchar(40) DEFAULT NULL,
+b_str_36 varchar(255) DEFAULT NULL,
+a_str_46 varchar(40) DEFAULT NULL,
+a_str_45 varchar(255) DEFAULT NULL,
+b_str_38 varchar(32) DEFAULT NULL,
+b_str_39 char(32) DEFAULT NULL,
+b_str_40 varchar(32) DEFAULT NULL,
+a_str_41 varchar(255) DEFAULT NULL,
+b_str_41 varchar(32) DEFAULT NULL,
+PRIMARY KEY (b_str_26),
+UNIQUE KEY a_str_47 (a_str_47),
+UNIQUE KEY a_str_49 (a_str_49),
+UNIQUE KEY a_str_33 (a_str_33),
+UNIQUE KEY a_str_46 (a_str_46),
+UNIQUE KEY a_str_48 (a_str_48),
+KEY b_str_18 (b_str_18),
+KEY a_str_26 (a_str_26),
+KEY b_str_27 (b_str_27,b_str_19),
+KEY b_str_41 (b_str_41),
+KEY b_str_15 (b_str_15),
+KEY a_str_20 (a_str_20),
+KEY b_str_17 (b_str_17),
+KEY b_str_40 (b_str_40),
+KEY b_str_24 (b_str_24),
+KEY b_str_10 (b_str_10),
+KEY b_str_16 (b_str_16),
+KEY b_str_29 (b_str_29),
+KEY a_str_41 (a_str_41),
+KEY b_str_7 (b_str_7),
+KEY a_str_45 (a_str_45),
+KEY a_str_28 (a_str_28),
+KEY a_str_37 (a_str_37),
+KEY b_str_6 (b_str_6),
+KEY a_ref_6 (a_ref_6),
+KEY b_str_34 (b_str_34),
+KEY b_str_38 (b_str_38),
+KEY a_ref_10 (a_ref_10),
+KEY b_str_21 (b_str_21),
+KEY b_str_23 (b_str_23,b_str_19),
+KEY b_str_33 (b_str_33),
+KEY a_ref_12 (a_ref_12),
+KEY a_str_18 (a_str_18(255)),
+KEY a_str_39 (a_str_39),
+KEY a_str_27 (a_str_27),
+KEY a_str_25 (a_str_25),
+KEY b_str_9 (b_str_9),
+KEY a_str_23 (a_str_23),
+KEY b_str_8 (b_str_8),
+KEY a_str_21 (a_str_21),
+KEY b_str_3 (b_str_3),
+KEY b_str_30 (b_str_30),
+KEY b_str_12 (b_str_12),
+KEY b_str_25 (b_str_25),
+KEY b_str_13 (b_str_13),
+KEY a_str_38 (a_str_38),
+KEY a_str_13 (a_str_13(255)),
+KEY a_str_36 (a_str_36),
+KEY b_str_28 (b_str_28),
+KEY b_str_19 (b_str_19),
+KEY b_str_11 (b_str_11),
+KEY a_ref_1 (a_ref_1),
+KEY b_str_20 (b_str_20),
+KEY b_str_14 (b_str_14),
+KEY a_ref_3 (a_ref_3),
+KEY b_str_39 (b_str_39),
+KEY b_str_32 (b_str_32),
+KEY a_str_6 (a_str_6),
+KEY b_str_5 (b_str_5),
+KEY b_str_31 (b_str_31),
+KEY a_ref_11 (a_ref_11)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
+BEGIN;
+INSERT INTO test_tab (b_str_26, a_str_13, a_str_18) VALUES
+('a', REPEAT('f',4031), REPEAT('g', 4031));
+UPDATE test_tab SET a_str_13=REPEAT('h',4032), a_str_18=REPEAT('i',4032);
+SELECT 'Reducing length to 4030';
+Reducing length to 4030
+Reducing length to 4030
+UPDATE test_tab SET a_str_13=REPEAT('j',4030), a_str_18=REPEAT('k',4030);
+UPDATE test_tab SET a_str_13=REPEAT('l',4031), a_str_18=REPEAT('m',4031);
+ROLLBACK;
+SELECT COUNT(*) FROM test_tab;
+COUNT(*)
+0
+CHECK TABLE test_tab;
+Table Op Msg_type Msg_text
+test.test_tab check status OK
+DROP TABLE test_tab;
diff --git a/mysql-test/suite/innodb/t/alter_rename_existing.test b/mysql-test/suite/innodb/t/alter_rename_existing.test
new file mode 100644
index 00000000000..0c8bf481969
--- /dev/null
+++ b/mysql-test/suite/innodb/t/alter_rename_existing.test
@@ -0,0 +1,93 @@
+--echo #
+--echo # Show what happens during ALTER TABLE when an existing file
+--echo # exists in the target location.
+--echo #
+--echo # Bug #19218794: IF TABLESPACE EXISTS, CAN'T CREATE TABLE,
+--echo # BUT CAN ALTER ENGINE=INNODB
+--echo #
+
+--source include/have_innodb.inc
+
+--disable_query_log
+LET $MYSQLD_DATADIR = `select @@datadir`;
+SET @old_innodb_file_per_table = @@innodb_file_per_table;
+--enable_query_log
+
+CREATE TABLE t1 (a SERIAL, b CHAR(10)) ENGINE=Memory;
+INSERT INTO t1(b) VALUES('one'), ('two'), ('three');
+
+--echo #
+--echo # Create a file called MYSQLD_DATADIR/test/t1.ibd
+--exec echo "This is not t1.ibd" > $MYSQLD_DATADIR/test/t1.ibd
+
+--echo # Directory listing of test/*.ibd
+--echo #
+--list_files $MYSQLD_DATADIR/test/ *.ibd
+
+--replace_regex /Error on rename of '.*' to '.*'/Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME'/
+--error ER_ERROR_ON_RENAME
+ALTER TABLE t1 ENGINE = InnoDB;
+
+--echo #
+--echo # Move the file to InnoDB as t2
+--echo #
+ALTER TABLE t1 RENAME TO t2, ENGINE = INNODB;
+SHOW CREATE TABLE t2;
+SELECT * from t2;
+
+--replace_regex /Error on rename of '.*' to '.*'/Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME'/
+--error ER_ERROR_ON_RENAME
+ALTER TABLE t2 RENAME TO t1;
+
+--echo #
+--echo # Create another t1, but in the system tablespace.
+--echo #
+SET GLOBAL innodb_file_per_table=OFF;
+CREATE TABLE t1 (a SERIAL, b CHAR(20)) ENGINE=InnoDB;
+INSERT INTO t1(b) VALUES('one'), ('two'), ('three');
+SHOW CREATE TABLE t1;
+SELECT name, space=0 FROM information_schema.innodb_sys_tables WHERE name = 'test/t1';
+
+--echo #
+--echo # ALTER TABLE from system tablespace to system tablespace
+--echo #
+ALTER TABLE t1 ADD COLUMN c INT, ALGORITHM=INPLACE;
+ALTER TABLE t1 ADD COLUMN d INT, ALGORITHM=COPY;
+
+--echo #
+--echo # Try to move t1 from the system tablespace to a file-per-table
+--echo # while a blocking t1.ibd file exists.
+--echo #
+SET GLOBAL innodb_file_per_table=ON;
+--replace_regex /$MYSQLD_DATADIR/MYSQLD_DATADIR/
+--error ER_TABLESPACE_EXISTS
+ALTER TABLE t1 ADD COLUMN e1 INT, ALGORITHM=INPLACE;
+--replace_regex /Error on rename of '.*' to '.*'/Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME'/
+--error ER_ERROR_ON_RENAME
+ALTER TABLE t1 ADD COLUMN e2 INT, ALGORITHM=COPY;
+
+--echo #
+--echo # Delete the blocking file called MYSQLD_DATADIR/test/t1.ibd
+--remove_file $MYSQLD_DATADIR/test/t1.ibd
+
+--echo # Move t1 to file-per-table using ALGORITHM=INPLACE with no blocking t1.ibd.
+--echo #
+ALTER TABLE t1 ADD COLUMN e INT, ALGORITHM=INPLACE;
+SHOW CREATE TABLE t1;
+SELECT name, space=0 FROM information_schema.innodb_sys_tables WHERE name = 'test/t1';
+
+DROP TABLE t1;
+
+--echo #
+--echo # Rename t2.ibd to t1.ibd.
+--echo #
+ALTER TABLE t2 RENAME TO t1;
+SELECT name, space=0 FROM information_schema.innodb_sys_tables WHERE name = 'test/t1';
+SELECT * from t1;
+
+DROP TABLE t1;
+
+--disable_query_log
+call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot rename '.*' to '.*' for space ID .* because the target file exists. Remove the target file and try again");
+SET GLOBAL innodb_file_per_table = @old_innodb_file_per_table;
+--enable_query_log
diff --git a/mysql-test/suite/innodb/t/create-index-debug.test b/mysql-test/suite/innodb/t/create-index-debug.test
new file mode 100644
index 00000000000..9ea416fbe1e
--- /dev/null
+++ b/mysql-test/suite/innodb/t/create-index-debug.test
@@ -0,0 +1,34 @@
+--source include/have_innodb.inc
+--source include/have_innodb_16k.inc
+--source include/have_debug.inc
+
+SET @saved_debug_dbug = @@SESSION.debug_dbug;
+
+--echo #
+--echo #BUG#21326304 INNODB ONLINE ALTER TABLE ENDS IN CRASH ON DISK FULL
+--echo #
+CREATE TABLE t1(f1 CHAR(255) NOT NULL, f2 CHAR(255) NOT NULL, f3
+CHAR(255) NOT NULL, f4 CHAR(255) NOT NULL, f5 CHAR(255) NOT NULL,f6
+CHAR(255) NOT NULL, f7 CHAR(255) NOT NULL, f8 CHAR(255) NOT NULL,f9
+CHAR(255) NOT NULL, f10 CHAR(255) NOT NULL, f11 CHAR(255) NOT NULL,f12
+CHAR(255) NOT NULL, f13 CHAR(255) NOT NULL, f14 CHAR(255) NOT NULL,f15
+CHAR(255) NOT NULL, f16 CHAR(255) NOT NULL, f17 CHAR(255) NOT NULL,f18
+CHAR(255) NOT NULL)
+ENGINE=INNODB ROW_FORMAT=DYNAMIC;
+
+INSERT INTO t1
+VALUES('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r');
+
+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 debug_dbug = '+d,disk_is_full';
+
+--error ER_RECORD_FILE_FULL
+ALTER TABLE t1 FORCE, ALGORITHM=INPLACE;
+
+SET debug_dbug= @saved_debug_dbug;
+
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/index_tree_operation.opt b/mysql-test/suite/innodb/t/index_tree_operation.opt
new file mode 100644
index 00000000000..66bceccc683
--- /dev/null
+++ b/mysql-test/suite/innodb/t/index_tree_operation.opt
@@ -0,0 +1 @@
+--innodb-sys-tablespaces
diff --git a/mysql-test/suite/innodb/t/index_tree_operation.test b/mysql-test/suite/innodb/t/index_tree_operation.test
new file mode 100644
index 00000000000..b9695db9346
--- /dev/null
+++ b/mysql-test/suite/innodb/t/index_tree_operation.test
@@ -0,0 +1,74 @@
+-- source include/have_innodb.inc
+-- source include/have_innodb_16k.inc
+--echo #
+--echo # Bug#15923864 (Bug#67718):
+--echo # INNODB DRASTICALLY UNDER-FILLS PAGES IN CERTAIN CONDITIONS
+--echo #
+# InnoDB should try to insert to the next page before split,
+# if the insert record for split_and_insert is last of the page.
+# Otherwise, the follwing records 999,998,997 cause each page per record.
+#
+
+--disable_query_log
+SET @old_innodb_file_per_table = @@innodb_file_per_table;
+--enable_query_log
+
+SET GLOBAL innodb_file_per_table=ON;
+
+CREATE TABLE t1 (a BIGINT PRIMARY KEY, b VARCHAR(4096)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (0, REPEAT('a', 4096));
+INSERT INTO t1 VALUES (1000, REPEAT('a', 4096));
+INSERT INTO t1 VALUES (1001, REPEAT('a', 4096));
+INSERT INTO t1 VALUES (1002, REPEAT('a', 4096));
+INSERT INTO t1 VALUES (1, REPEAT('a', 4096));
+INSERT INTO t1 VALUES (2, REPEAT('a', 4096));
+
+# | 0, 1, 2 | 1000, 1001, 1002|
+
+SELECT page_number, number_records
+FROM information_schema.innodb_sys_tablespaces s1,
+information_schema.innodb_buffer_page s2
+WHERE s1.space = s2.space AND name = 'test/t1'
+AND page_type = "INDEX" ORDER BY page_number;
+
+INSERT INTO t1 VALUES (999, REPEAT('a', 4096));
+
+# try to insert '999' to the end of '0,1,2' page, but no space
+# the next '1000,1001,1002' page has also no space.
+# | 0, 1, 2 | 999 | 1000, 1001, 1002|
+
+SELECT page_number, number_records
+FROM information_schema.innodb_sys_tablespaces s1,
+information_schema.innodb_buffer_page s2
+WHERE s1.space = s2.space AND name = 'test/t1'
+AND page_type = "INDEX" ORDER BY page_number;
+
+
+INSERT INTO t1 VALUES (998, REPEAT('a', 4096));
+
+# try to insert to the end of '0,1,2' page, but no space
+# the next '998' page has space.
+# | 0, 1, 2 | 998, 999 | 1000, 1001, 1002|
+
+SELECT page_number, number_records
+FROM information_schema.innodb_sys_tablespaces s1,
+information_schema.innodb_buffer_page s2
+WHERE s1.space = s2.space AND name = 'test/t1'
+AND page_type = "INDEX" ORDER BY page_number;
+
+INSERT INTO t1 VALUES (997, REPEAT('a', 4096));
+
+# same
+# | 0, 1, 2 | 997, 998, 999 | 1000, 1001, 1002|
+
+SELECT page_number, number_records
+FROM information_schema.innodb_sys_tablespaces s1,
+information_schema.innodb_buffer_page s2
+WHERE s1.space = s2.space AND name = 'test/t1'
+AND page_type = "INDEX" ORDER BY page_number;
+
+DROP TABLE t1;
+
+--disable_query_log
+SET GLOBAL innodb_file_per_table = @old_innodb_file_per_table;
+--enable_query_log
diff --git a/mysql-test/suite/innodb/t/innodb-16k.test b/mysql-test/suite/innodb/t/innodb-16k.test
index 3cd90a00d55..d7922429f26 100644
--- a/mysql-test/suite/innodb/t/innodb-16k.test
+++ b/mysql-test/suite/innodb/t/innodb-16k.test
@@ -328,10 +328,10 @@ UPDATE t1 SET a=@c,b=@c,c=@c,d=@c,e=@c,f=@c,g=@c,h=@c,i=@c,j=@c,
# because the UNDO records will be smaller.
CREATE INDEX t1f ON t1 (f(767));
---error 1713
+BEGIN;
UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d,f=@d,g=@d,h=@d,i=@d,j=@d,
k=@d,l=@d,m=@d,n=@d,o=@d,p=@d,q=@d,r=@d,s=@d,t=@d,u=@d;
-
+ROLLBACK;
BEGIN;
UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d;
UPDATE t1 SET f=@d,g=@d,h=@d,i=@d,j=@d,k=@d,l=@d,m=@d,
@@ -371,8 +371,9 @@ UPDATE t1 SET s=@e;
# that CANNOT be updated.
CREATE INDEX t1t ON t1 (t(767));
---error 1713
+BEGIN;
UPDATE t1 SET t=@e;
+ROLLBACK;
# The function dict_index_too_big_for_undo() prevents us from adding
# one more index. But it is too late. The record is already too big.
@@ -515,9 +516,10 @@ INSERT INTO bug12547647 VALUES (5,REPEAT('khdfo5AlOq',1900),REPEAT('g',7751));
COMMIT;
# The following used to cause a hang while doing infinite undo log allocation.
---error 1713
+BEGIN;
UPDATE bug12547647 SET c = REPEAT('b',16928);
SHOW WARNINGS;
+ROLLBACK;
DROP TABLE bug12547647;
diff --git a/mysql-test/suite/innodb/t/innodb-32k.test b/mysql-test/suite/innodb/t/innodb-32k.test
index 65c1d4bbc76..356746e8ec4 100644
--- a/mysql-test/suite/innodb/t/innodb-32k.test
+++ b/mysql-test/suite/innodb/t/innodb-32k.test
@@ -294,13 +294,14 @@ UPDATE t1 SET a=@c,b=@c,c=@c,d=@c,e=@c,f=@c,g=@c,h=@c,i=@c,j=@c,
CREATE INDEX t1f17 ON t1 (v(767));
---error 1713
+BEGIN;
UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d,f=@d,g=@d,h=@d,i=@d,j=@d,
k=@d,l=@d,m=@d,n=@d,o=@d,p=@d,q=@d,r=@d,s=@d,t=@d,u=@d,
v=@d,w=@d,x=@d,y=@d,z=@d,
aa=@d,ba=@d,ca=@d,da=@d,ea=@d,fa=@d,ga=@d,ha=@d,ia=@d,ja=@d,
ka=@d,la=@d,ma=@d,na=@d,oa=@d,pa=@d,qa=@d,ra=@d,sa=@d,ta=@d,ua=@d,
va=@d,wa=@d,xa=@d,ya=@d,za=@d;
+ROLLBACK;
BEGIN;
UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d;
diff --git a/mysql-test/suite/innodb/t/innodb-64k.test b/mysql-test/suite/innodb/t/innodb-64k.test
index a947de25d79..0498544279b 100644
--- a/mysql-test/suite/innodb/t/innodb-64k.test
+++ b/mysql-test/suite/innodb/t/innodb-64k.test
@@ -304,7 +304,7 @@ COMMIT;
CREATE INDEX tg1f2 ON t1 (ia(767),ja(767));
---error 1713
+BEGIN;
UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d,f=@d,g=@d,h=@d,i=@d,j=@d,
k=@d,l=@d,m=@d,n=@d,o=@d,p=@d,q=@d,r=@d,s=@d,t=@d,u=@d,
v=@d,w=@d,x=@d,y=@d,z=@d,
@@ -317,6 +317,7 @@ UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d,f=@d,g=@d,h=@d,i=@d,j=@d,
ac=@d,bc=@d,cc=@d,dc=@d,ec=@d,fc=@d,gc=@d,hc=@d,ic=@d,jc=@d,
kc=@d,lc=@d,mc=@d,nc=@d,oc=@d,pc=@d,qc=@d,rc=@d,sc=@d,tc=@d,uc=@d,
vc=@d,wc=@d,xc=@d,yc=@d,zc=@d;
+ROLLBACK;
BEGIN;
UPDATE t1 SET a=@d,b=@d,c=@d,d=@d,e=@d;
diff --git a/mysql-test/suite/innodb/t/innodb-alter-autoinc.test b/mysql-test/suite/innodb/t/innodb-alter-autoinc.test
new file mode 100644
index 00000000000..e01c44aa26e
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-alter-autoinc.test
@@ -0,0 +1,104 @@
+--source include/have_innodb.inc
+
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(347),(33101),(123),(45),(6);
+# NULL -> NOT NULL only allowed INPLACE if strict sql_mode is on.
+SET @old_sql_mode = @@sql_mode;
+SET @@sql_mode = 'STRICT_TRANS_TABLES';
+ALTER TABLE t1 ADD PRIMARY KEY(a);
+SET @@sql_mode = @old_sql_mode;
+
+# We cannot assign AUTO_INCREMENT values during online index creation.
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE t1 DROP PRIMARY KEY, ADD id INT AUTO_INCREMENT PRIMARY KEY,
+ LOCK=NONE;
+
+--error ER_WRONG_AUTO_KEY
+ALTER TABLE t1 ADD id INT AUTO_INCREMENT;
+
+--error ER_WRONG_AUTO_KEY
+ALTER TABLE t1 ADD id INT AUTO_INCREMENT, ADD INDEX(a, id);
+
+ALTER TABLE t1 ADD id INT NOT NULL, ADD INDEX(id, a);
+
+SELECT * FROM t1;
+
+# Test with a non-default increment and offset
+SET AUTO_INCREMENT_INCREMENT = 5, AUTO_INCREMENT_OFFSET = 30;
+
+ALTER TABLE t1 DROP PRIMARY KEY, ADD id INT AUTO_INCREMENT PRIMARY KEY,
+ DROP COLUMN id, AUTO_INCREMENT = 42, ALGORITHM=COPY;
+
+SHOW CREATE TABLE t1;
+
+# The autoinc next value should increase. It is not rolled back.
+BEGIN;
+INSERT INTO t1 VALUES(7,0);
+SELECT * FROM t1;
+ROLLBACK;
+
+SHOW CREATE TABLE t1;
+
+# We cannot assign AUTO_INCREMENT values during online index creation.
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE t1 DROP PRIMARY KEY, ADD id INT AUTO_INCREMENT PRIMARY KEY,
+ DROP COLUMN id, AUTO_INCREMENT = 42, LOCK=NONE;
+
+ALTER TABLE t1 DROP PRIMARY KEY, ADD id INT AUTO_INCREMENT PRIMARY KEY,
+ DROP COLUMN id, AUTO_INCREMENT = 42, ALGORITHM=INPLACE;
+
+SELECT * FROM t1;
+SHOW CREATE TABLE t1;
+
+INSERT INTO t1 SET a=123;
+INSERT INTO t1 VALUES(-123,-45);
+
+ALTER TABLE t1 AUTO_INCREMENT = 75;
+
+INSERT INTO t1 SET a=123;
+SELECT * FROM t1;
+
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
+# ALGORITHM=INPLACE should deliver identical results to ALGORITHM=COPY.
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(347),(33101),(123),(45),(6);
+ALTER TABLE t1 ADD PRIMARY KEY(a);
+
+ALTER TABLE t1 ADD id INT NOT NULL, ADD INDEX(id, a);
+
+SELECT * FROM t1;
+
+ALTER TABLE t1 DROP PRIMARY KEY, ADD id INT AUTO_INCREMENT PRIMARY KEY,
+ DROP COLUMN id, AUTO_INCREMENT = 42, ALGORITHM=INPLACE;
+
+SHOW CREATE TABLE t1;
+
+# The autoinc next value should increase. It is not rolled back.
+BEGIN;
+INSERT INTO t1 VALUES(7,0);
+SELECT * FROM t1;
+ROLLBACK;
+
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 DROP PRIMARY KEY, ADD id INT AUTO_INCREMENT PRIMARY KEY,
+ DROP COLUMN id, AUTO_INCREMENT = 42, ALGORITHM=COPY;
+
+SELECT * FROM t1;
+
+SHOW CREATE TABLE t1;
+
+INSERT INTO t1 SET a=123;
+INSERT INTO t1 VALUES(-123,-45);
+
+ALTER TABLE t1 AUTO_INCREMENT = 75;
+
+INSERT INTO t1 SET a=123;
+SELECT * FROM t1;
+
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/innodb-alter-table.test b/mysql-test/suite/innodb/t/innodb-alter-table.test
index 97f0075f344..0cf456ad146 100644
--- a/mysql-test/suite/innodb/t/innodb-alter-table.test
+++ b/mysql-test/suite/innodb/t/innodb-alter-table.test
@@ -1,4 +1,5 @@
--source include/innodb_page_size.inc
+--source include/have_partition.inc
#
# MMDEV-8386: MariaDB creates very big tmp file and hangs on xtradb
@@ -171,3 +172,35 @@ ALTER TABLE ticket
SHOW CREATE TABLE ticket;
DROP TABLE ticket;
+
+#
+# MDEV-13838: Wrong result after altering a partitioned table
+#
+
+CREATE TABLE t (
+id bigint(20) unsigned NOT NULL auto_increment,
+d date NOT NULL,
+a bigint(20) unsigned NOT NULL,
+b smallint(5) unsigned DEFAULT NULL,
+PRIMARY KEY (id,d)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs STATS_SAMPLE_PAGES=2
+PARTITION BY RANGE COLUMNS(d)
+(
+PARTITION p20170914 VALUES LESS THAN ('2017-09-15') ENGINE = InnoDB,
+PARTITION p99991231 VALUES LESS THAN (MAXVALUE) ENGINE = InnoDB);
+
+insert into t(d,a,b) values ('2017-09-15',rand()*10000,rand()*10);
+insert into t(d,a,b) values ('2017-09-15',rand()*10000,rand()*10);
+
+replace into t(d,a,b) select '2017-09-15',rand()*10000,rand()*10 from t t1, t t2, t t3, t t4;
+
+select count(*) from t where d ='2017-09-15';
+
+ALTER TABLE t CHANGE b c smallint(5) unsigned , ADD KEY idx_d_a (d, a);
+SHOW CREATE TABLE t;
+analyze table t;
+
+select count(*) from t where d ='2017-09-15';
+select count(*) from t force index(primary) where d ='2017-09-15';
+
+DROP TABLE t;
diff --git a/mysql-test/suite/innodb/t/innodb-alter.opt b/mysql-test/suite/innodb/t/innodb-alter.opt
new file mode 100644
index 00000000000..aa400236153
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-alter.opt
@@ -0,0 +1,3 @@
+--loose-innodb-sys-indexes
+--loose-innodb-sys-columns
+--loose-innodb-sys-fields
diff --git a/mysql-test/suite/innodb/t/innodb-alter.test b/mysql-test/suite/innodb/t/innodb-alter.test
new file mode 100644
index 00000000000..af75482703c
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-alter.test
@@ -0,0 +1,483 @@
+--source include/have_innodb.inc
+
+SET NAMES utf8;
+
+CREATE TABLE t1 (
+ c1 INT PRIMARY KEY, c2 INT DEFAULT 1, ct TEXT,
+ INDEX(c2))
+ENGINE=InnoDB;
+
+INSERT INTO t1 SET c1=1;
+
+CREATE TABLE sys_tables SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
+WHERE NAME LIKE 'test/t%';
+CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+
+CREATE TABLE t1p LIKE t1;
+
+CREATE TABLE t1c (c1 INT PRIMARY KEY, c2 INT, c3 INT, INDEX(c2), INDEX(c3),
+ CONSTRAINT t1c2 FOREIGN KEY (c2) REFERENCES t1(c2),
+ CONSTRAINT t1c3 FOREIGN KEY (c3) REFERENCES t1p(c2))
+ENGINE=InnoDB;
+
+CREATE TABLE sys_foreign SELECT i.*
+FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN i
+WHERE FOR_NAME LIKE 'test/t%';
+
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+
+-- source suite/innodb/include/innodb_dict.inc
+
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 ALTER c2 DROP DEFAULT;
+SHOW CREATE TABLE t1;
+
+-- source suite/innodb/include/innodb_dict.inc
+
+# These should be no-op.
+ALTER TABLE t1 CHANGE c2 c2 INT AFTER c1;
+ALTER TABLE t1 CHANGE c1 c1 INT FIRST;
+
+-- source suite/innodb/include/innodb_dict.inc
+
+ALTER TABLE t1 CHANGE C2 c3 INT;
+
+-- source suite/innodb/include/innodb_dict.inc
+
+ALTER TABLE t1 CHANGE c3 C INT;
+
+-- source suite/innodb/include/innodb_dict.inc
+
+ALTER TABLE t1 CHANGE C Cöŀumň_TWO INT;
+
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+
+-- source suite/innodb/include/innodb_dict.inc
+
+-- error ER_BAD_FIELD_ERROR
+ALTER TABLE t1 CHANGE cöĿǖmň_two c3 INT;
+
+ALTER TABLE t1 CHANGE cÖĿUMŇ_two c3 INT, RENAME TO t3;
+
+SELECT st.NAME, i.NAME
+FROM sys_tables st INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES i
+ON i.TABLE_ID=st.TABLE_ID;
+
+SHOW CREATE TABLE t3;
+SHOW CREATE TABLE t1c;
+
+# The maximum column name length should be 64 characters.
+--error ER_TOO_LONG_IDENT
+ALTER TABLE t3 CHANGE c3
+`12345678901234567890123456789012345678901234567890123456789012345` INT;
+ALTER TABLE t3 CHANGE c3
+`1234567890123456789012345678901234567890123456789012345678901234` INT;
+SHOW CREATE TABLE t3;
+
+# Test the length limit with non-ASCII utf-8 characters.
+--error ER_TOO_LONG_IDENT
+ALTER TABLE t3 CHANGE
+`1234567890123456789012345678901234567890123456789012345678901234`
+`倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ å€¡å€¢å€£å€¤å€¥å€¦å€§å€¨å€©å€ªå€«å€¬å€­å€®å€¯å€°å€±å€²å€³å€´å€µå€¶å€·å€¸å€¹å€ºå€»å€¼å€½å€¾å€¿å€` INT;
+--error ER_TOO_LONG_IDENT
+ALTER TABLE t3 CHANGE
+`1234567890123456789012345678901234567890123456789012345678901234`
+`倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ å€¡å€¢å€£å€¤å€¥å€¦å€§å€¨å€©å€ªå€«å€¬å€­å€®å€¯å€°å€±å€²å€³å€´å€µå€¶å€·å€¸å€¹å€ºå€»å€¼å€½å€¾å€¿Ã¤` INT;
+ALTER TABLE t3 CHANGE
+`1234567890123456789012345678901234567890123456789012345678901234`
+`倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ å€¡å€¢å€£å€¤å€¥å€¦å€§å€¨å€©å€ªå€«å€¬å€­å€®å€¯å€°å€±å€²å€³å€´å€µå€¶å€·å€¸å€¹å€ºå€»å€¼å€½å€¾Ã¤` INT;
+
+# check that the rename is case-insensitive (note the upper-case ä at end)
+ALTER TABLE t3 CHANGE
+`倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ å€¡å€¢å€£å€¤å€¥å€¦å€§å€¨å€©å€ªå€«å€¬å€­å€®å€¯å€°å€±å€²å€³å€´å€µå€¶å€·å€¸å€¹å€ºå€»å€¼å€½å€¾Ã„`
+c3 INT;
+
+# test with 4-byte UTF-8 (should be disallowed)
+--error ER_INVALID_CHARACTER_STRING
+ALTER TABLE t3 CHANGE c3 ðŒ€ðŒðŒ‚ðŒƒðŒ„ðŒ…ðŒ†ðŒ‡ðŒˆðŒ‰ðŒŠðŒ‹ðŒŒðŒðŒŽðŒðŒðŒ‘ðŒ’ðŒ“ðŒ”ðŒ•ðŒ–ðŒ—ðŒ˜ðŒ™ðŒšðŒ›ðŒœ INT;
+--error ER_INVALID_CHARACTER_STRING
+ALTER TABLE t3 CHANGE c3 😲 INT;
+
+ALTER TABLE t3 RENAME TO t2;
+
+SELECT st.NAME, i.NAME
+FROM sys_tables st INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES i
+ON i.TABLE_ID=st.TABLE_ID;
+
+SHOW CREATE TABLE t2;
+
+RENAME TABLE t2 TO t1;
+
+SELECT st.NAME, i.NAME
+FROM sys_tables st INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES i
+ON i.TABLE_ID=st.TABLE_ID;
+
+-- source suite/innodb/include/innodb_dict.inc
+
+--error ER_DROP_INDEX_FK
+ALTER TABLE t1 DROP INDEX c2;
+
+--error ER_CANT_DROP_FIELD_OR_KEY
+ALTER TABLE t1 DROP INDEX c4;
+
+--error ER_CANT_DROP_FIELD_OR_KEY
+ALTER TABLE t1c DROP FOREIGN KEY c2;
+
+--error ER_CANT_DROP_FIELD_OR_KEY
+ALTER TABLE t1c DROP FOREIGN KEY t1c2, DROP FOREIGN KEY c2;
+
+--error ER_CANT_DROP_FIELD_OR_KEY
+ALTER TABLE t1c DROP FOREIGN KEY t1c2, DROP FOREIGN KEY c2, DROP INDEX c2;
+
+--error ER_DROP_INDEX_FK
+ALTER TABLE t1c DROP INDEX c2;
+
+--error ER_CANT_DROP_FIELD_OR_KEY
+ALTER TABLE t1c DROP FOREIGN KEY ẗ1C2;
+
+SHOW CREATE TABLE t1c;
+
+SET foreign_key_checks=0;
+DROP TABLE t1p;
+SET foreign_key_checks=1;
+
+SHOW CREATE TABLE t1c;
+
+-- source suite/innodb/include/innodb_dict.inc
+
+CREATE TABLE t1p (c1 INT PRIMARY KEY, c2 INT, INDEX(c2)) ENGINE=InnoDB;
+
+--error ER_DROP_INDEX_FK
+ALTER TABLE t1c DROP INDEX C2, DROP INDEX C3;
+--error ER_DROP_INDEX_FK
+ALTER TABLE t1c DROP INDEX C3;
+
+SET foreign_key_checks=0;
+ALTER TABLE t1c DROP INDEX C3;
+SET foreign_key_checks=1;
+
+SHOW CREATE TABLE t1c;
+-- source suite/innodb/include/innodb_dict.inc
+
+ALTER TABLE t1c DROP FOREIGN KEY t1C3;
+
+SHOW CREATE TABLE t1c;
+-- source suite/innodb/include/innodb_dict.inc
+
+ALTER TABLE t1c DROP INDEX c2, DROP FOREIGN KEY t1C2;
+
+SHOW CREATE TABLE t1c;
+
+-- source suite/innodb/include/innodb_dict.inc
+
+ALTER TABLE t1 DROP INDEX c2, CHANGE c3 c2 INT;
+
+-- source suite/innodb/include/innodb_dict.inc
+
+CREATE TABLE t1o LIKE t1;
+
+# This will implicitly add a FTS_DOC_ID column, which cannot be done online.
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE t1 ADD FULLTEXT INDEX (ct),
+CHANGE c1 pk INT, ALTER c2 SET DEFAULT 42, RENAME TO tt,
+ALGORITHM=INPLACE, LOCK=NONE;
+
+ALTER TABLE t1 ADD FULLTEXT INDEX (ct),
+CHANGE c1 pk INT, ALTER c2 SET DEFAULT 42, RENAME TO tt,
+ALGORITHM=INPLACE, LOCK=SHARED;
+
+# The output should be empty, because index->id was reassigned.
+-- source suite/innodb/include/innodb_dict.inc
+
+SHOW CREATE TABLE tt;
+
+# DB_ROW_ID, DB_TRX_ID, DB_ROLL_PTR are reserved InnoDB system column names.
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o CHANGE c1 dB_row_Id INT, ALGORITHM=COPY;
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o CHANGE c1 dB_row_Id INT, ALGORITHM=INPLACE;
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o CHANGE c1 DB_TRX_ID INT;
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o CHANGE c1 db_roll_ptr INT;
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o ADD COLUMN DB_TRX_ID INT;
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o ADD COLUMN db_roll_ptr INT;
+
+--error ER_INNODB_FT_WRONG_DOCID_COLUMN
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ADD COLUMN FTS_DOC_ID BIGINT;
+--error ER_INNODB_FT_WRONG_DOCID_COLUMN
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED;
+
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct),
+ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
+
+--error ER_DUP_FIELDNAME
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ADD COLUMN FTS_DOC_ID INT;
+
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE t1o DROP COLUMN FTS_DOC_ID, ALGORITHM=INPLACE;
+
+ALTER TABLE t1o DROP COLUMN FTS_DOC_ID, DROP INDEX ct, ALGORITHM=INPLACE;
+
+# This creates a hidden FTS_DOC_ID column.
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ADD COLUMN cu TEXT;
+
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE t1o ADD FULLTEXT INDEX(cu), ADD COLUMN FTS_DOC_ID BIGINT,
+ALGORITHM=INPLACE;
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o ADD FULLTEXT INDEX(cu), ADD COLUMN FTS_DOC_ID BIGINT;
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE t1o ADD FULLTEXT INDEX(cu), ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED,
+ALGORITHM=INPLACE;
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o ADD FULLTEXT INDEX(cu), ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED;
+
+# This would drop the hidden FTS_DOC_ID column and create
+# a fulltext index on ct and another fulltext index on cu.
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE t1o ADD FULLTEXT INDEX(cu),
+ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL, ALGORITHM=INPLACE;
+
+# Replace the hidden FTS_DOC_ID column with a user-visible one.
+# This used to work if there is at most one fulltext index.
+# Currently, we disallow native ALTER TABLE if the table
+# contains any FULLTEXT indexes.
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE t1o ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE;
+ALTER TABLE t1o ADD COLUMN FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
+# Replace the user-visible FTS_DOC_ID column with a hidden one.
+# We do not support this in-place.
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE t1o DROP COLUMN FTS_DOC_ID, ALGORITHM=INPLACE;
+ALTER TABLE t1o DROP COLUMN FTS_DOC_ID;
+
+# FTS_DOC_ID is the internal row identifier for full-text search.
+# It should be of type BIGINT UNSIGNED NOT NULL.
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_DOC_ID INT,
+ALGORITHM=COPY;
+
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_DOC_ID INT,
+ALGORITHM=INPLACE;
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_Doc_ID INT,
+ALGORITHM=INPLACE;
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct),
+CHANGE c1 FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE;
+
+CREATE TABLE t1n LIKE t1o;
+
+ALTER TABLE t1n ADD FULLTEXT INDEX(ct);
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1n CHANGE c1 Fts_DOC_ID INT, ALGORITHM=INPLACE;
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1n CHANGE c1 Fts_DOC_ID INT, ALGORITHM=COPY;
+--error ER_BAD_FIELD_ERROR
+ALTER TABLE t1n CHANGE FTS_DOC_ID c11 INT, ALGORITHM=INPLACE;
+ALTER TABLE t1n CHANGE c1 FTS_DOC_ïD INT, ALGORITHM=INPLACE;
+
+ALTER TABLE t1n CHANGE FTS_DOC_ÃD c1 INT, ALGORITHM=INPLACE;
+ALTER TABLE t1n CHANGE c1 c2 INT, CHANGE c2 ct INT, CHANGE ct c1 TEXT,
+ALGORITHM=INPLACE;
+SHOW CREATE TABLE t1n;
+ALTER TABLE t1n CHANGE c2 c1 INT, CHANGE ct c2 INT, CHANGE c1 ct TEXT,
+ALGORITHM=COPY;
+SHOW CREATE TABLE t1n;
+
+--error ER_KEY_COLUMN_DOES_NOT_EXITS
+ALTER TABLE t1n ADD INDEX(c2), CHANGE c2 c4 INT, ALGORITHM=INPLACE;
+--error ER_KEY_COLUMN_DOES_NOT_EXITS
+ALTER TABLE t1n ADD INDEX(c2), CHANGE c2 c4 INT, ALGORITHM=COPY;
+ALTER TABLE t1n ADD INDEX(c4), CHANGE c2 c4 INT, ALGORITHM=INPLACE;
+SHOW CREATE TABLE t1n;
+ALTER TABLE t1n DROP INDEX c4;
+--error ER_DUP_FIELDNAME
+ALTER TABLE t1n CHANGE c4 c1 INT, ADD INDEX(c1), ALGORITHM=INPLACE;
+ALTER TABLE t1n CHANGE c4 c11 INT, ADD INDEX(c11), ALGORITHM=INPLACE;
+
+SHOW CREATE TABLE t1n;
+DROP TABLE t1n;
+
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE t1o MODIFY c1 BIGINT UNSIGNED NOT NULL, DROP INDEX ct,
+ALGORITHM=INPLACE;
+
+# This will copy the table, removing the hidden FTS_DOC_ID column.
+ALTER TABLE t1o MODIFY c1 BIGINT UNSIGNED NOT NULL, DROP INDEX ct;
+
+ALTER TABLE t1o CHANGE c1 FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE;
+
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), ALGORITHM=INPLACE;
+
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE;
+
+# This should not show duplicates.
+SELECT sc.pos FROM information_schema.innodb_sys_columns sc
+INNER JOIN information_schema.innodb_sys_tables st
+ON sc.TABLE_ID=st.TABLE_ID
+WHERE st.NAME='test/t1o' AND sc.NAME='FTS_DOC_ID';
+
+SHOW CREATE TABLE t1o;
+
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
+DROP INDEX ct, ALGORITHM=INPLACE;
+
+SHOW CREATE TABLE t1o;
+
+DROP TABLE t1c, t1p, sys_tables, sys_indexes, sys_foreign;
+
+# Check the internal schemata of tt, t1o.
+
+CREATE TABLE sys_tables SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
+WHERE NAME='test/t1o';
+CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+CREATE TABLE sys_foreign SELECT i.*
+FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN i WHERE FOR_NAME='test/t1o';
+
+-- source suite/innodb/include/innodb_dict.inc
+
+# Ensure that there exists no hidden FTS_DOC_ID_INDEX on foo_id.
+
+ALTER TABLE t1o ADD UNIQUE INDEX FTS_DOC_ID_INDEX(FTS_DOC_ID),
+ADD FULLTEXT INDEX(ct),
+CHANGE foo_id FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
+
+ALTER TABLE t1o DROP INDEX ct, DROP INDEX FTS_DOC_ID_INDEX,
+CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL;
+
+ALTER TABLE t1o ADD UNIQUE INDEX FTS_DOC_ID_INDEX(foo_id);
+
+ALTER TABLE t1o CHANGE foo_id FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
+ADD FULLTEXT INDEX(ct);
+
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE;
+
+DROP TABLE sys_indexes;
+CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+
+-- source suite/innodb/include/innodb_dict.inc
+
+DROP TABLE tt, t1o, sys_tables, sys_indexes, sys_foreign;
+
+CREATE TABLE t (t TEXT, FULLTEXT(t)) ENGINE=InnoDB;
+DROP INDEX t ON t;
+
+LET $regexp=/FTS_([0-9a-f_]+)([A-Z_]+)/FTS_AUX_\2/;
+--replace_regex $regexp
+SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name
+FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
+WHERE name LIKE '%FTS_%' ORDER BY 1, 2;
+
+SELECT sc.pos, sc.NAME FROM information_schema.innodb_sys_columns sc
+INNER JOIN information_schema.innodb_sys_tables st
+ON sc.TABLE_ID=st.TABLE_ID
+WHERE st.NAME='test/t';
+
+ALTER TABLE t ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE;
+
+--replace_regex $regexp
+SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name
+FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
+WHERE name LIKE '%FTS_%' ORDER BY 1, 2;
+
+ALTER TABLE t ADD FULLTEXT INDEX(t);
+
+SELECT sc.pos, sc.NAME FROM information_schema.innodb_sys_columns sc
+INNER JOIN information_schema.innodb_sys_tables st
+ON sc.TABLE_ID=st.TABLE_ID
+WHERE st.NAME='test/t';
+
+DROP TABLE t;
+
+--disable_query_log
+call mtr.add_suppression("deleting orphaned .ibd file");
+--enable_query_log
+
+--echo #
+--echo # Bug #19465984 INNODB DATA DICTIONARY IS NOT UPDATED WHILE
+--echo # RENAMING THE COLUMN
+--echo #
+CREATE TABLE t1(c1 INT NOT NULL, PRIMARY KEY(c1))ENGINE=INNODB;
+CREATE TABLE t2(c2 INT NOT NULL, FOREIGN KEY(c2) REFERENCES t1(c1))ENGINE=INNODB;
+SHOW CREATE TABLE t1;
+SHOW CREATE TABLE t2;
+ALTER TABLE t1 CHANGE COLUMN c1 C1 INT;
+SHOW CREATE TABLE t1;
+SHOW CREATE TABLE t2;
+# FIXME: MDEV-13671 InnoDB should use case-insensitive column name comparisons
+# like the rest of the server
+#ALTER TABLE t1 CHANGE COLUMN C1 c5 INT;
+SHOW CREATE TABLE t1;
+SHOW CREATE TABLE t2;
+DROP TABLE t2, t1;
+
+--echo #
+--echo # BUG 20029625 - HANDLE_FATAL_SIGNAL (SIG=11) IN
+--echo # DICT_MEM_TABLE_COL_RENAME_LOW
+--echo #
+CREATE TABLE parent(a INT, b INT, KEY(a, b)) ENGINE = InnoDB;
+CREATE TABLE t1(a1 INT, a2 INT) ENGINE = InnoDB;
+
+set foreign_key_checks=0;
+ALTER TABLE t1 ADD CONSTRAINT fk_a FOREIGN KEY(a1, a2) REFERENCES parent(a, b) ON DELETE SET NULL ON UPDATE CASCADE;
+
+ALTER TABLE t1 CHANGE a2 a3 INT,ADD CONSTRAINT fk_1 FOREIGN KEY(a1, a3) REFERENCES parent(a, b) ON DELETE SET NULL ON UPDATE CASCADE;
+SHOW CREATE TABLE t1;
+CHECK TABLE t1;
+
+ALTER TABLE t1 CHANGE a3 a4 INT;
+SHOW CREATE TABLE t1;
+CHECK TABLE t1;
+
+ALTER TABLE parent CHANGE b c INT;
+SHOW CREATE TABLE t1;
+CHECK TABLE t1;
+
+DROP TABLE t1, parent;
+
+--echo #
+--echo #BUG#21514135 SCHEMA MISMATCH ERROR WHEN IMPORTING TABLESPACE AFTER
+--echo #DROPPING AN INDEX
+--echo #
+let $source_db = source_db;
+let $dest_db = dest_db;
+
+eval CREATE DATABASE $source_db;
+eval CREATE DATABASE $dest_db;
+
+eval CREATE TABLE $source_db.t1 (
+ id int(11) NOT NULL,
+ age int(11) DEFAULT NULL,
+ name varchar(20),
+ PRIMARY KEY (id),
+ KEY index1 (age)
+ ) ENGINE=InnoDB;
+
+eval ALTER TABLE $source_db.t1 DROP INDEX index1, ADD INDEX index2(name, age), algorithm=inplace;
+
+--source suite/innodb/include/import.inc
+
+eval ALTER TABLE $source_db.t1 DROP INDEX index2, algorithm=inplace;
+
+--source suite/innodb/include/import.inc
+
+eval DROP TABLE $source_db.t1;
+eval DROP DATABASE $source_db;
+eval DROP DATABASE $dest_db;
diff --git a/mysql-test/suite/innodb/t/innodb-autoinc.test b/mysql-test/suite/innodb/t/innodb-autoinc.test
index dd4c4ae8603..75b2e8984d9 100644
--- a/mysql-test/suite/innodb/t/innodb-autoinc.test
+++ b/mysql-test/suite/innodb/t/innodb-autoinc.test
@@ -680,3 +680,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-enlarge-blob.opt b/mysql-test/suite/innodb/t/innodb-enlarge-blob.opt
index 4c2cd9b3e3c..7cc886cb9e5 100644
--- a/mysql-test/suite/innodb/t/innodb-enlarge-blob.opt
+++ b/mysql-test/suite/innodb/t/innodb-enlarge-blob.opt
@@ -1,6 +1,5 @@
--innodb-file-per-table
--innodb-file-format='Barracuda'
--innodb-buffer-pool-size=32M
---innodb-log-file-size=32M
+--innodb-page-size=64k
--innodb-strict-mode=OFF
-
diff --git a/mysql-test/suite/innodb/t/innodb-enlarge-blob.test b/mysql-test/suite/innodb/t/innodb-enlarge-blob.test
index 84c23465a5c..65a64d299be 100644
--- a/mysql-test/suite/innodb/t/innodb-enlarge-blob.test
+++ b/mysql-test/suite/innodb/t/innodb-enlarge-blob.test
@@ -1,24 +1,13 @@
--source include/have_innodb.inc
---source include/innodb_page_size.inc
#
# MDEV-13227: Assertion failure len < 16384 in file rem0rec.cc line 1285
# Crashes with innodb_page_size=64K. Does not crash at <= 32K.
#
-CREATE TABLE t1 (a LONGTEXT) ENGINE=INNODB DEFAULT CHARSET=UTF8 ROW_FORMAT=DYNAMIC;
+CREATE TABLE t1 (a LONGTEXT) ENGINE=INNODB ROW_FORMAT=REDUNDANT;
SHOW WARNINGS;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B');
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-UPDATE t1 SET a=CONCAT(a, RAND(), a);
+INSERT INTO t1 SET a=CONCAT('A', SPACE(8000), 'B');
+INSERT INTO t1 SELECT a FROM t1;
UPDATE t1 SET a=CONCAT(a, RAND(), a);
UPDATE t1 SET a=CONCAT(a, RAND(), a);
# random data no output we are only interested if fails
@@ -27,20 +16,10 @@ SELECT * from t1;
--enable_result_log
DROP TABLE t1;
-CREATE TABLE t1 (a LONGTEXT) ENGINE=INNODB DEFAULT CHARSET=UTF8 ROW_FORMAT=REDUNDANT;
+CREATE TABLE t1 (a LONGTEXT) ENGINE=INNODB ROW_FORMAT=DYNAMIC;
SHOW WARNINGS;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B');
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
-UPDATE t1 SET a=CONCAT(a, RAND(), a);
+INSERT INTO t1 SET a=CONCAT('A', SPACE(8000), 'B');
+INSERT INTO t1 SELECT a FROM t1;
UPDATE t1 SET a=CONCAT(a, RAND(), a);
UPDATE t1 SET a=CONCAT(a, RAND(), a);
# random data no output we are only interested if fails
diff --git a/mysql-test/suite/innodb/t/innodb-get-fk.test b/mysql-test/suite/innodb/t/innodb-get-fk.test
index 339a7968623..46eb7dd0273 100644
--- a/mysql-test/suite/innodb/t/innodb-get-fk.test
+++ b/mysql-test/suite/innodb/t/innodb-get-fk.test
@@ -40,6 +40,11 @@ CONSTRAINT `fk_crewRoleAssigned_pilotId` FOREIGN KEY (`crew_id`) REFERENCES `rep
ALTER TABLE `repro`.`crew_role_assigned` COMMENT = 'innodb_read_only';
SHOW CREATE TABLE `repro`.`crew_role_assigned`;
+# These should be ignored in innodb_read_only mode.
+SET GLOBAL innodb_buffer_pool_load_now = ON;
+SET GLOBAL innodb_buffer_pool_dump_now = ON;
+SET GLOBAL innodb_buffer_pool_load_abort = ON;
+
-- let $restart_parameters=
-- source include/restart_mysqld.inc
diff --git a/mysql-test/suite/innodb/t/innodb-index-debug.opt b/mysql-test/suite/innodb/t/innodb-index-debug.opt
new file mode 100644
index 00000000000..778b4443d4f
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-index-debug.opt
@@ -0,0 +1 @@
+--innodb-sort-buffer-size=64k
diff --git a/mysql-test/suite/innodb/t/innodb-index-debug.test b/mysql-test/suite/innodb/t/innodb-index-debug.test
new file mode 100644
index 00000000000..e179b969a6a
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-index-debug.test
@@ -0,0 +1,122 @@
+-- source include/have_debug.inc
+-- source include/have_innodb.inc
+-- source include/have_debug_sync.inc
+
+let $per_table=`select @@innodb_file_per_table`;
+let $format=`select @@innodb_file_format`;
+set global innodb_file_per_table=on;
+set global innodb_file_format='Barracuda';
+
+#
+# Test for BUG# 12739098, check whether trx->error_status is reset on error.
+#
+CREATE TABLE t1(c1 INT NOT NULL, c2 INT, PRIMARY KEY(c1)) Engine=InnoDB;
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5);
+
+SET @saved_debug_dbug = @@SESSION.debug_dbug;
+SET DEBUG_DBUG='+d,ib_build_indexes_too_many_concurrent_trxs, ib_rename_indexes_too_many_concurrent_trxs, ib_drop_index_too_many_concurrent_trxs';
+--error ER_TOO_MANY_CONCURRENT_TRXS
+ALTER TABLE t1 ADD UNIQUE INDEX(c2);
+SET DEBUG_DBUG = @saved_debug_dbug;
+
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+#
+# Test for Bug#13861218 Records are not fully sorted during index creation
+#
+CREATE TABLE bug13861218 (c1 INT NOT NULL, c2 INT NOT NULL, INDEX(c2))
+ENGINE=InnoDB;
+INSERT INTO bug13861218 VALUES (8, 0), (4, 0), (0, 0);
+SET DEBUG_DBUG = '+d,ib_row_merge_buf_add_two';
+# Force creation of a PRIMARY KEY on c1 to see what happens on the index(c2).
+# No crash here, because n_uniq for c2 includes the clustered index fields
+CREATE UNIQUE INDEX ui ON bug13861218(c1);
+SET DEBUG_DBUG = @saved_debug_dbug;
+DROP TABLE bug13861218;
+
+CREATE TABLE bug13861218 (c1 INT NOT NULL, c2 INT UNIQUE) ENGINE=InnoDB;
+INSERT INTO bug13861218 VALUES (8, NULL), (4, NULL), (0, NULL);
+SET DEBUG_DBUG = '+d,ib_row_merge_buf_add_two';
+# Force creation of a PRIMARY KEY on c1 to see what happens on the index(c2).
+# assertion failure: ut_ad(cmp_dtuple_rec(dtuple, rec, rec_offsets) > 0)
+CREATE UNIQUE INDEX ui ON bug13861218(c1);
+SET DEBUG_DBUG = @saved_debug_dbug;
+DROP TABLE bug13861218;
+
+eval set global innodb_file_per_table=$per_table;
+eval set global innodb_file_format=$format;
+eval set global innodb_file_format_max=$format;
+
+--echo #
+--echo # Bug #21762319 ADDING INDEXES ON EMPTY TABLE IS SLOW
+--echo # WITH LARGE INNODB_SORT_BUFFER_SIZE.
+
+call mtr.add_suppression("InnoDB: Cannot create temporary merge file");
+
+# Table with large data which is greater than sort buffer
+
+create table t480(a serial)engine=innodb;
+insert into t480
+values(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),
+(),(),(),(),(),(),(),();
+insert into t480 select 0 from t480;
+insert into t480 select 0 from t480;
+insert into t480 select 0 from t480;
+insert into t480 select 0 from t480;
+create table t1(f1 int auto_increment not null,
+ f2 char(200) not null, f3 char(200) not null,
+ f4 char(200) not null,primary key(f1))engine=innodb;
+insert into t1 select NULL,'aaa','bbb','ccc' from t480;
+insert into t1 select NULL,'aaaa','bbbb','cccc' from t480;
+insert into t1 select NULL,'aaaaa','bbbbb','ccccc' from t480;
+insert into t1 select NULL,'aaaaaa','bbbbbb','cccccc' from t480;
+insert into t1 select NULL,'aaaaaaa','bbbbbbb','ccccccc' from t480;
+insert into t1 select NULL,'aaaaaaaa','bbbbbbbb','cccccccc' from t480;
+select count(*) from t1;
+
+SET DEBUG_DBUG = '+d,innobase_tmpfile_creation_failure';
+--error ER_OUT_OF_RESOURCES
+alter table t1 force, algorithm=inplace;
+SET DEBUG_DBUG = @saved_debug_dbug;
+drop table t1, 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;
diff --git a/mysql-test/suite/innodb/t/innodb-index-online-delete.test b/mysql-test/suite/innodb/t/innodb-index-online-delete.test
new file mode 100644
index 00000000000..ec5f93731ed
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-index-online-delete.test
@@ -0,0 +1,36 @@
+--source include/have_innodb.inc
+--source include/have_debug_sync.inc
+
+# Save the initial number of concurrent sessions.
+--source include/count_sessions.inc
+
+connect (con1,localhost,root,,);
+
+connection default;
+
+CREATE TABLE t (a INT PRIMARY KEY, b INT NOT NULL) ENGINE=InnoDB;
+INSERT INTO t VALUES(1,2),(2,3);
+
+SET DEBUG_SYNC='alter_table_inplace_after_lock_downgrade SIGNAL do WAIT_FOR m';
+SET DEBUG_SYNC='innodb_after_inplace_alter_table SIGNAL scanned WAIT_FOR done';
+--send
+CREATE INDEX tb ON t(b);
+
+connection con1;
+SET DEBUG_SYNC='now WAIT_FOR do';
+SET DEBUG_SYNC='row_update_for_mysql_error SIGNAL m WAIT_FOR scanned';
+--error ER_DUP_ENTRY
+UPDATE t SET a=2 WHERE a=1;
+call mtr.add_suppression('InnoDB: record in index .*tb was not found on rollback, trying to insert');
+SET DEBUG_SYNC='now SIGNAL done';
+
+disconnect con1;
+
+connection default;
+reap;
+SET DEBUG_SYNC='RESET';
+DROP TABLE t;
+
+# 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-index-online-fk.opt b/mysql-test/suite/innodb/t/innodb-index-online-fk.opt
new file mode 100644
index 00000000000..345d5529dce
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-index-online-fk.opt
@@ -0,0 +1,4 @@
+--loose-innodb-sys-tables
+--loose-innodb-sys-columns
+--loose-innodb-sys-foreign
+--loose-innodb-sys-foreign-cols
diff --git a/mysql-test/suite/innodb/t/innodb-index-online-fk.test b/mysql-test/suite/innodb/t/innodb-index-online-fk.test
new file mode 100644
index 00000000000..4480b88f0bf
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-index-online-fk.test
@@ -0,0 +1,484 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+
+CREATE TABLE parent (a INT PRIMARY KEY, b INT NOT NULL) ENGINE = InnoDB;
+INSERT INTO parent VALUES(1,2),(2,3);
+
+CREATE INDEX tb ON parent(b);
+
+INSERT INTO parent VALUES(10,20),(20,30);
+
+CREATE TABLE child (a1 INT PRIMARY KEY, a2 INT) ENGINE = InnoDB;
+
+CREATE INDEX tb ON child(a2);
+
+INSERT INTO child VALUES(10,20);
+
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE child ADD FOREIGN KEY(a2) REFERENCES parent(b),
+ALGORITHM = INPLACE;
+
+SET foreign_key_checks = 0;
+
+ALTER TABLE child ADD CONSTRAINT fk_1 FOREIGN KEY (a2)
+REFERENCES parent(b) ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN;
+
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS;
+
+# duplicated foreign key name
+--error ER_FK_DUP_NAME
+ALTER TABLE child ADD CONSTRAINT fk_1 FOREIGN KEY (a2)
+REFERENCES parent(b) ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+
+SET foreign_key_checks = 1;
+
+INSERT INTO child VALUES(1,2),(2,3);
+
+--error ER_NO_REFERENCED_ROW_2
+INSERT INTO child VALUES(4,4);
+
+SELECT * FROM parent;
+
+SET foreign_key_checks = 0;
+
+# This would fail. No corresponding index
+--error ER_FK_NO_INDEX_PARENT
+ALTER TABLE child ADD CONSTRAINT fk_20 FOREIGN KEY (a1, a2)
+REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+
+SHOW WARNINGS;
+
+SHOW ERRORS;
+
+CREATE INDEX idx1 on parent(a, b);
+
+ALTER TABLE child ADD CONSTRAINT fk_10 FOREIGN KEY (a1, a2)
+REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+
+# This should be successful, as we added the index
+ALTER TABLE child ADD CONSTRAINT fk_2 FOREIGN KEY (a1, a2)
+REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE, ADD INDEX idx1(a1,a2),
+ALGORITHM = INPLACE;
+
+ALTER TABLE child ADD CONSTRAINT fk_3 FOREIGN KEY (a1, a2)
+REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE;
+
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN;
+
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS;
+
+SET foreign_key_checks = 1;
+
+--error ER_NO_REFERENCED_ROW_2
+INSERT INTO child VALUES(5,4);
+
+SHOW CREATE TABLE child;
+
+DELETE FROM parent where a = 1;
+
+SELECT * FROM child;
+
+# Now test referenced table cannot be opened. This should work fine
+# when foreign_key_checks is set to 0
+
+SET foreign_key_checks = 0;
+
+# This is to test the scenario we cannot open the referenced table.
+# Since foreign_key_checks is set to 0, the foreign key should still
+# be added.
+SET @saved_debug_dbug = @@SESSION.debug_dbug;
+SET DEBUG_DBUG = '+d,innodb_test_open_ref_fail';
+ALTER TABLE child ADD CONSTRAINT fk_4 FOREIGN KEY (a1, a2)
+REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+SET DEBUG_DBUG = @saved_debug_dbug;
+
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN;
+
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS;
+
+SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name;
+
+SELECT NAME FROM information_schema.INNODB_SYS_TABLES;
+
+# this should succeed, since we disabled the foreign key check
+INSERT INTO child VALUES(5,4);
+
+SET foreign_key_checks = 1;
+
+--error ER_NO_REFERENCED_ROW_2
+INSERT INTO child VALUES(6,5);
+
+SET foreign_key_checks = 0;
+
+# Create some table with 'funny' characters, for testing the
+# error message
+CREATE TABLE `#parent` (a INT PRIMARY KEY, b INT NOT NULL) ENGINE = InnoDB;
+
+CREATE INDEX tb ON `#parent`(a, b);
+
+CREATE TABLE `#child` (a1 INT PRIMARY KEY, a2 INT) ENGINE = InnoDB;
+
+CREATE INDEX tb ON `#child`(a1, a2);
+
+# This is to test the scenario no foreign index, alter table should fail
+SET DEBUG_DBUG = '+d,innodb_test_no_foreign_idx';
+--error ER_FK_NO_INDEX_CHILD,
+ALTER TABLE `#child` ADD CONSTRAINT fk_40 FOREIGN KEY (a1, a2)
+REFERENCES `#parent`(a, b) ON DELETE CASCADE ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+SET DEBUG_DBUG = @saved_debug_dbug;
+
+SHOW ERRORS;
+
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN;
+
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS;
+
+# This is to test the scenario no index on referenced table,
+# alter table should fail
+SET DEBUG_DBUG = '+d,innodb_test_no_reference_idx';
+--error ER_FK_NO_INDEX_PARENT,
+ALTER TABLE child ADD CONSTRAINT fk_42 FOREIGN KEY (a1, a2)
+REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+SET DEBUG_DBUG = @saved_debug_dbug;
+
+SHOW ERRORS;
+
+# This is to test the scenario no index on referenced table,
+# alter table should fail
+SET DEBUG_DBUG = '+d,innodb_test_wrong_fk_option';
+--error ER_FK_INCORRECT_OPTION
+ALTER TABLE child ADD CONSTRAINT fk_42 FOREIGN KEY (a1, a2)
+REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+SET DEBUG_DBUG = @saved_debug_dbug;
+
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN;
+
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS;
+
+# This is to test the scenario cannot add fk to the system table,
+# alter table should fail
+SET DEBUG_DBUG = '+d,innodb_test_cannot_add_fk_system';
+--error ER_FK_FAIL_ADD_SYSTEM
+ALTER TABLE `#child` ADD CONSTRAINT fk_43 FOREIGN KEY (a1, a2)
+REFERENCES `#parent`(a, b) ON DELETE CASCADE ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+SET DEBUG_DBUG = @saved_debug_dbug;
+
+SHOW ERRORS;
+
+DROP TABLE `#child`;
+DROP TABLE `#parent`;
+
+# Now test add multiple foreign key constrain in a single clause
+SET foreign_key_checks = 0;
+
+ALTER TABLE child ADD CONSTRAINT fk_5 FOREIGN KEY (a2) REFERENCES parent(b)
+ON DELETE SET NULL ON UPDATE CASCADE,
+ADD CONSTRAINT fk_6 FOREIGN KEY (a1, a2)
+REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN;
+
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS;
+
+DROP TABLE child;
+DROP TABLE parent;
+
+# Test a case where child's foreign key index is being dropped in the
+# same clause of adding the foreign key. In theory, MySQL will
+# automatically create a new index to meet the index requirement
+CREATE TABLE parent (a INT PRIMARY KEY, b INT NOT NULL) ENGINE = InnoDB;
+
+INSERT INTO parent VALUES(1,2),(2,3);
+
+CREATE INDEX tb ON parent(b);
+
+INSERT INTO parent VALUES(10,20),(20,30);
+
+CREATE TABLE child (a1 INT PRIMARY KEY, a2 INT) ENGINE = InnoDB;
+
+CREATE INDEX tb ON child(a2);
+
+INSERT INTO child VALUES(10,20);
+
+SET foreign_key_checks = 0;
+
+ALTER TABLE child DROP INDEX tb, ADD CONSTRAINT fk_4 FOREIGN KEY (a2)
+REFERENCES parent(b) ON DELETE CASCADE ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+
+SHOW CREATE TABLE child;
+
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN;
+
+SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS;
+
+SET foreign_key_checks = 1;
+
+DROP TABLE child;
+
+DROP TABLE parent;
+
+# Test ADD FOREIGN KEY together with renaming columns.
+CREATE TABLE parent (a INT PRIMARY KEY, b INT NOT NULL) ENGINE = InnoDB;
+
+INSERT INTO parent VALUES(1,2),(2,3);
+
+CREATE INDEX tb ON parent(b);
+
+INSERT INTO parent VALUES(10,20),(20,30);
+
+CREATE TABLE child (a1 INT PRIMARY KEY, a2 INT) ENGINE = InnoDB;
+
+CREATE INDEX tb ON child(a2);
+
+SET foreign_key_checks = 0;
+
+--error ER_KEY_COLUMN_DOES_NOT_EXITS
+ALTER TABLE child CHANGE a2 a3 INT,
+ADD CONSTRAINT fk_1 FOREIGN KEY (a2) REFERENCES parent(b)
+ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+
+ALTER TABLE child CHANGE a2 a3 INT,
+ADD CONSTRAINT fk_1 FOREIGN KEY (a3) REFERENCES parent(b)
+ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+
+DROP TABLE child;
+
+DROP TABLE parent;
+
+# Add test for add Primary key and FK on changing columns
+CREATE TABLE parent (a INT PRIMARY KEY, b INT NOT NULL) ENGINE = InnoDB;
+INSERT INTO parent VALUES(1,2),(2,3);
+
+CREATE INDEX tb ON parent(b);
+
+INSERT INTO parent VALUES(10,20),(20,30);
+
+CREATE TABLE child (a1 INT NOT NULL, a2 INT) ENGINE = InnoDB;
+
+CREATE INDEX tb ON child(a2);
+
+SET foreign_key_checks = 0;
+
+# Let's rebuild the table and add the FK, make the add FK failed.
+
+SET DEBUG_DBUG = '+d,innodb_test_cannot_add_fk_system';
+--error ER_FK_FAIL_ADD_SYSTEM
+ALTER TABLE child ADD PRIMARY KEY idx (a3), CHANGE a1 a3 INT,
+ADD CONSTRAINT fk_1 FOREIGN KEY (a2) REFERENCES parent(b)
+ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+SET DEBUG_DBUG = @saved_debug_dbug;
+
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS;
+SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name;
+SELECT NAME FROM information_schema.INNODB_SYS_TABLES;
+
+# This should be successful. It will also check any left over
+# from previous failed operation (if dictionary entries not cleaned,
+# it will have dup key error.
+ALTER TABLE child ADD PRIMARY KEY idx (a3), CHANGE a1 a3 INT,
+ADD CONSTRAINT fk_1 FOREIGN KEY (a2) REFERENCES parent(b)
+ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS;
+SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name;
+SELECT NAME FROM information_schema.INNODB_SYS_TABLES;
+
+SHOW CREATE TABLE child;
+
+DROP TABLE child;
+
+CREATE TABLE child (a1 INT NOT NULL, a2 INT) ENGINE = InnoDB;
+
+# Now try primary index and FK
+ALTER TABLE child ADD PRIMARY KEY idx (a1),
+ADD CONSTRAINT fk_1 FOREIGN KEY (a2) REFERENCES parent(b)
+ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+
+SELECT * from information_schema.INNODB_SYS_FOREIGN;
+SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS;
+SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name;
+SELECT NAME FROM information_schema.INNODB_SYS_TABLES;
+
+SHOW CREATE TABLE child;
+
+DROP TABLE child;
+
+CREATE TABLE child (a1 INT NOT NULL, a2 INT) ENGINE = InnoDB;
+
+ALTER TABLE child CHANGE a1 a3 INT,
+ADD CONSTRAINT fk_1 FOREIGN KEY (a3) REFERENCES parent(b)
+ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+
+SELECT * from information_schema.INNODB_SYS_FOREIGN;
+SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS;
+SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name;
+SELECT NAME FROM information_schema.INNODB_SYS_TABLES;
+
+SHOW CREATE TABLE child;
+
+DROP TABLE child;
+
+CREATE TABLE child (a1 INT NOT NULL, a2 INT) ENGINE = InnoDB;
+# Now try all three
+--error ER_FK_INCORRECT_OPTION
+ALTER TABLE child ADD PRIMARY KEY idx (a3), CHANGE a1 a3 INT,
+ADD CONSTRAINT fk_1 FOREIGN KEY (a3) REFERENCES parent(b)
+ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+
+DROP TABLE parent;
+DROP TABLE child;
+
+CREATE TABLE parent (a INT PRIMARY KEY, b INT NOT NULL, c INT) ENGINE = InnoDB;
+INSERT INTO parent VALUES(1,2,3),(2,3,4);
+
+CREATE INDEX tb ON parent(b);
+
+CREATE TABLE child (a1 INT NOT NULL, a2 INT, a3 INT) ENGINE = InnoDB;
+CREATE INDEX tb ON child(a2);
+
+ALTER TABLE child
+ADD CONSTRAINT fk_a FOREIGN KEY (a2) REFERENCES parent(b)
+ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+
+ALTER TABLE child
+ADD CONSTRAINT fk_b FOREIGN KEY (a1) REFERENCES parent(a),
+ALGORITHM = INPLACE;
+
+ALTER TABLE child CHANGE a2 a2_new INT, CHANGE a1 a1_new INT;
+
+SHOW CREATE TABLE child;
+
+SELECT * from information_schema.INNODB_SYS_FOREIGN;
+SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS;
+
+# The third add FK will fail
+--error ER_FK_NO_INDEX_PARENT
+ALTER TABLE child
+ADD CONSTRAINT fk_new_1 FOREIGN KEY (a1_new) REFERENCES parent(b),
+ADD CONSTRAINT fk_new_2 FOREIGN KEY (a2_new) REFERENCES parent(a),
+ADD CONSTRAINT fk_new_3 FOREIGN KEY (a3) REFERENCES parent(c),
+ALGORITHM = INPLACE;
+
+# It should still have only 2 FKs
+SHOW CREATE TABLE child;
+
+SELECT * from information_schema.INNODB_SYS_FOREIGN;
+
+SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS;
+
+#Now let's make it successful
+ALTER TABLE child
+ADD CONSTRAINT fk_new_1 FOREIGN KEY (a1_new) REFERENCES parent(b),
+ADD CONSTRAINT fk_new_2 FOREIGN KEY (a2_new) REFERENCES parent(a),
+ADD CONSTRAINT fk_new_3 FOREIGN KEY (a3) REFERENCES parent(a),
+ALGORITHM = INPLACE;
+
+# It should still have 5 FKs
+SHOW CREATE TABLE child;
+
+SELECT * from information_schema.INNODB_SYS_FOREIGN;
+
+SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS;
+
+DROP TABLE child;
+CREATE TABLE child (a1 INT NOT NULL, a2 INT, a3 INT) ENGINE = InnoDB;
+CREATE INDEX tb ON child(a2);
+
+# Let's try this 3rd fk failure with add primary index
+--error ER_FK_NO_INDEX_PARENT
+ALTER TABLE child ADD PRIMARY KEY idx (a1),
+ADD CONSTRAINT fk_new_1 FOREIGN KEY (a1) REFERENCES parent(b),
+ADD CONSTRAINT fk_new_2 FOREIGN KEY (a2) REFERENCES parent(a),
+ADD CONSTRAINT fk_new_3 FOREIGN KEY (a3) REFERENCES parent(c),
+ALGORITHM = INPLACE;
+
+# It should still have no FKs, no PRIMARY
+SHOW CREATE TABLE child;
+
+SELECT * from information_schema.INNODB_SYS_FOREIGN;
+
+SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS;
+
+# make it successful
+ALTER TABLE child ADD PRIMARY KEY idx (a1),
+ADD CONSTRAINT fk_new_1 FOREIGN KEY (a1) REFERENCES parent(b),
+ADD CONSTRAINT fk_new_2 FOREIGN KEY (a2) REFERENCES parent(a),
+ADD CONSTRAINT fk_new_3 FOREIGN KEY (a3) REFERENCES parent(a),
+ALGORITHM = INPLACE;
+
+# It should have 3 FKs, a new PRIMARY
+SHOW CREATE TABLE child;
+
+SELECT * from information_schema.INNODB_SYS_FOREIGN;
+
+SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS;
+
+SET foreign_key_checks = 1;
+
+DROP TABLE child;
+DROP TABLE parent;
+
+CREATE TABLE Parent (a INT PRIMARY KEY, b INT NOT NULL) ENGINE = InnoDB;
+INSERT INTO Parent VALUES(1,2),(2,3);
+
+CREATE INDEX tb ON Parent(b);
+
+INSERT INTO Parent VALUES(10,20),(20,30);
+
+CREATE TABLE Child (a1 INT PRIMARY KEY, a2 INT) ENGINE = InnoDB;
+
+CREATE INDEX tb ON Child(a2);
+
+INSERT INTO Child VALUES(10,20);
+
+SET foreign_key_checks = 0;
+
+ALTER TABLE Child ADD CONSTRAINT fk_1 FOREIGN KEY (a2)
+REFERENCES Parent(b) ON DELETE SET NULL ON UPDATE CASCADE,
+ALGORITHM = INPLACE;
+
+DROP TABLE Child;
+DROP TABLE Parent;
+
+# This is the test for bug 14594526 - FK: ASSERTION IN
+# DICT_TABLE_CHECK_FOR_DUP_INDEXES
+CREATE TABLE `t2`(a int,c int,d int) ENGINE=INNODB;
+CREATE TABLE `t3`(a int,c int,d int) ENGINE=INNODB;
+CREATE INDEX idx ON t3(a);
+
+ALTER TABLE `t2` ADD CONSTRAINT `fw` FOREIGN KEY (`c`) REFERENCES t3 (a);
+
+ALTER TABLE `t2` ADD CONSTRAINT `e` foreign key (`d`) REFERENCES t3(a);
+
+--error ER_FK_FAIL_ADD_SYSTEM
+ALTER TABLE `t3` ADD CONSTRAINT `e` foreign key (`c`) REFERENCES `t2`(`c`) ON UPDATE SET NULL;
+
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS;
+
+DROP TABLE t2;
+
+DROP TABLE t3;
diff --git a/mysql-test/suite/innodb/t/innodb-index-online-purge.test b/mysql-test/suite/innodb/t/innodb-index-online-purge.test
new file mode 100644
index 00000000000..28ff9403c0c
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-index-online-purge.test
@@ -0,0 +1,73 @@
+--source include/have_innodb.inc
+--source include/have_debug_sync.inc
+
+# Save the initial number of concurrent sessions.
+--source include/count_sessions.inc
+
+connect (con1,localhost,root,,);
+
+connect (con2,localhost,root,,);
+connection default;
+
+CREATE TABLE t (a INT PRIMARY KEY, c TEXT) ENGINE=InnoDB;
+CREATE TABLE u (a INT PRIMARY KEY, b INT, c INT NOT NULL) ENGINE=InnoDB;
+
+INSERT INTO t VALUES (1,'aa');
+BEGIN;
+INSERT INTO u SET a=1, c=1;
+INSERT INTO u SELECT a+1,NULL,a+1 FROM u;
+INSERT INTO u SELECT a+2,NULL,a+2 FROM u;
+INSERT INTO u SELECT a+4,NULL,a+4 FROM u;
+INSERT INTO u SELECT a+8,NULL,a+8 FROM u;
+INSERT INTO u SELECT a+16,NULL,a+16 FROM u;
+INSERT INTO u SELECT a+32,NULL,a+32 FROM u;
+INSERT INTO u SELECT a+64,NULL,a+64 FROM u;
+INSERT INTO u SELECT a+128,NULL,a+64 FROM u;
+INSERT INTO u SELECT a+256,NULL,a+64 FROM u;
+COMMIT;
+
+BEGIN;
+DELETE FROM u;
+
+connection con2;
+SET DEBUG_SYNC='row_log_apply_before SIGNAL created_u WAIT_FOR dml_done_u';
+--send
+ALTER TABLE u ADD INDEX (c);
+
+connection default;
+# Check that the above SELECT is blocked
+let $wait_condition=
+ SELECT COUNT(*) = 1 from information_schema.processlist
+ WHERE state = 'Waiting for table metadata lock' AND
+ info = 'ALTER TABLE u ADD INDEX (c)';
+--source include/wait_condition.inc
+
+COMMIT;
+SET DEBUG_SYNC='now WAIT_FOR created_u';
+SELECT state FROM information_schema.processlist
+WHERE info='ALTER TABLE u ADD INDEX (c)';
+
+connection con1;
+SET DEBUG_SYNC='row_log_apply_before SIGNAL created_t WAIT_FOR dml_done_t';
+--send
+CREATE INDEX c1 ON t (c(1));
+connection default;
+SET DEBUG_SYNC='now WAIT_FOR created_t';
+UPDATE t SET c='ab';
+# Allow purge to kick in. TODO: Trigger this faster, somehow.
+SELECT SLEEP(10);
+SET DEBUG_SYNC='now SIGNAL dml_done_u';
+connection con2;
+reap;
+SET DEBUG_SYNC='now SIGNAL dml_done_t';
+disconnect con2;
+connection con1;
+reap;
+disconnect con1;
+connection default;
+SET DEBUG_SYNC='RESET';
+DROP TABLE t,u;
+
+# 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-index-online.opt b/mysql-test/suite/innodb/t/innodb-index-online.opt
new file mode 100644
index 00000000000..820778b0004
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-index-online.opt
@@ -0,0 +1,6 @@
+--innodb-sort-buffer-size=64k
+--innodb-online-alter-log-max-size=128k
+--innodb-buffer-pool-size=5M
+--innodb-log-buffer-size=256k
+--innodb-sys-indexes
+--innodb-sys-fields
diff --git a/mysql-test/suite/innodb/t/innodb-index-online.test b/mysql-test/suite/innodb/t/innodb-index-online.test
new file mode 100644
index 00000000000..efe1c796cf1
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-index-online.test
@@ -0,0 +1,508 @@
+--source include/innodb_page_size_small.inc
+--source include/innodb_encrypt_log.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+
+let $innodb_metrics_select=
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+
+call mtr.add_suppression("InnoDB: Warning: Small buffer pool size");
+
+# DISCARD TABLESPACE needs file-per-table
+SET @global_innodb_file_per_table_orig = @@global.innodb_file_per_table;
+SET GLOBAL innodb_file_per_table = on;
+
+# Save the initial number of concurrent sessions.
+--source include/count_sessions.inc
+
+CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT, c3 TEXT)
+ENGINE=InnoDB STATS_PERSISTENT=0;
+INSERT INTO t1 VALUES (1,1,''), (2,2,''), (3,3,''), (4,4,''), (5,5,'');
+
+SET GLOBAL innodb_monitor_enable = module_ddl;
+eval $innodb_metrics_select;
+
+SET DEBUG_SYNC = 'RESET';
+SET DEBUG_SYNC = 'write_row_noreplace SIGNAL have_handle WAIT_FOR go_ahead';
+--send
+INSERT INTO t1 VALUES(1,2,3);
+
+connect (con1,localhost,root,,);
+connection con1;
+
+# This should block at the end because of the INSERT in connection default
+# is holding a metadata lock.
+SET DEBUG_SYNC = 'now WAIT_FOR have_handle';
+SET lock_wait_timeout = 1;
+--error ER_LOCK_WAIT_TIMEOUT
+ALTER TABLE t1 ADD UNIQUE INDEX(c2);
+SET DEBUG_SYNC = 'now SIGNAL go_ahead';
+
+connection default;
+--error ER_DUP_ENTRY
+reap;
+eval $innodb_metrics_select;
+
+connection con1;
+SET @saved_debug_dbug = @@SESSION.debug_dbug;
+SET DEBUG_DBUG = '+d,innodb_OOM_prepare_inplace_alter';
+--error ER_OUT_OF_RESOURCES
+ALTER TABLE t1 ADD UNIQUE INDEX(c2);
+SET DEBUG_DBUG = @saved_debug_dbug;
+SET DEBUG_DBUG = '+d,innodb_OOM_inplace_alter';
+--error ER_OUT_OF_RESOURCES
+CREATE UNIQUE INDEX c2 ON t1(c2);
+SET DEBUG_DBUG = @saved_debug_dbug;
+CREATE UNIQUE INDEX c2 ON t1(c2);
+DROP INDEX c2 ON t1;
+
+connection default;
+SHOW CREATE TABLE t1;
+# Insert a duplicate entry (4) for the upcoming UNIQUE INDEX(c2).
+BEGIN;
+INSERT INTO t1 VALUES(7,4,2);
+
+connection con1;
+# This DEBUG_SYNC should not kick in yet, because the duplicate key will be
+# detected before we get a chance to apply the online log.
+SET DEBUG_SYNC = 'row_log_apply_before SIGNAL scanned WAIT_FOR rollback_done';
+# This will be a lock wait timeout on the meta-data lock,
+# because the transaction inserting (7,4,2) is still active.
+--error ER_LOCK_WAIT_TIMEOUT
+ALTER TABLE t1 ADD UNIQUE INDEX(c2);
+connection default;
+COMMIT;
+connection con1;
+--error ER_DUP_ENTRY
+ALTER TABLE t1 ADD UNIQUE INDEX(c2);
+connection default;
+DELETE FROM t1 WHERE c1 = 7;
+connection con1;
+# ADD FOREIGN KEY is not supported in-place
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE t1 ADD FOREIGN KEY(c2) REFERENCES t1(c2), ALGORITHM = INPLACE;
+# The previous DEBUG_SYNC should be ignored, because an exclusive lock
+# has been requested and the online log is not being allocated.
+ALTER TABLE t1 ADD UNIQUE INDEX(c2), LOCK = EXCLUSIVE, ALGORITHM = INPLACE;
+DROP INDEX c2 ON t1;
+# Now the previous DEBUG_SYNC should kick in.
+--send
+ALTER TABLE t1 ADD UNIQUE INDEX(c2);
+connection default;
+SET DEBUG_SYNC = 'now WAIT_FOR scanned';
+eval $innodb_metrics_select;
+
+# Insert a duplicate entry (4) for the already started UNIQUE INDEX(c2).
+BEGIN;
+INSERT INTO t1 VALUES(7,4,2);
+ROLLBACK;
+SET DEBUG_SYNC = 'now SIGNAL rollback_done';
+
+connection con1;
+# Because the modification log will be applied in order, there will be
+# a duplicate key error on the (7,4,2) even though we roll it back.
+--error ER_DUP_ENTRY
+reap;
+# Now, create the index without any concurrent DML, while no duplicate exists.
+SET DEBUG_SYNC = 'row_log_apply_after SIGNAL created WAIT_FOR dml_done';
+--send
+ALTER TABLE t1 ADD UNIQUE INDEX(c2);
+connection default;
+SET DEBUG_SYNC = 'now WAIT_FOR created';
+# At this point, the index has been created inside InnoDB but not yet
+# in the MySQL data dictionary.
+eval $innodb_metrics_select;
+# A duplicate key error should now be triggered by InnoDB, but reported
+# by the ALTER TABLE because the index does not 'officially' exist yet.
+INSERT INTO t1 VALUES(6,3,1);
+SET DEBUG_SYNC = 'now SIGNAL dml_done';
+connection con1;
+# This is due to the duplicate entry (6,3,1).
+--error ER_DUP_UNKNOWN_IN_INDEX
+reap;
+DELETE FROM t1 WHERE c1=6;
+ALTER TABLE t1 ADD UNIQUE INDEX(c2);
+eval $innodb_metrics_select;
+
+connection default;
+--error ER_DUP_ENTRY
+INSERT INTO t1 VALUES(6,3,1);
+--error ER_DUP_ENTRY
+INSERT INTO t1 VALUES(7,4,2);
+ALTER TABLE t1 STATS_PERSISTENT=1;
+ANALYZE TABLE t1;
+# Purge may or may not have cleaned up the DELETE FROM t1 WHERE c1 = 7;
+UPDATE mysql.innodb_index_stats SET stat_value = 5
+WHERE database_name = 'test' AND table_name= 't1' AND index_name = 'PRIMARY'
+AND stat_value = 6;
+--replace_column 4 LAST_UPDATE
+SELECT * FROM mysql.innodb_index_stats WHERE table_name IN ('t1');
+CREATE TABLE t1_c2_stats SELECT * FROM mysql.innodb_index_stats
+WHERE database_name = 'test' AND table_name = 't1' and index_name = 'c2';
+# in Embedded mode (./mtr --embedded-server) the t1_c2_stats table gets
+# created in MyISAM format by default even if we set
+# default_storage_engine='innodb'
+ALTER TABLE t1_c2_stats ENGINE=INNODB;
+DROP INDEX c2 ON t1;
+ANALYZE TABLE t1_c2_stats;
+--replace_column 4 LAST_UPDATE
+SELECT * FROM mysql.innodb_index_stats WHERE table_name IN ('t1', 't1_c2_stats');
+
+connection con1;
+let $ID= `SELECT @id := CONNECTION_ID()`;
+--error ER_QUERY_INTERRUPTED
+KILL QUERY @id;
+
+SET DEBUG_SYNC = 'row_log_apply_before SIGNAL c2d_created WAIT_FOR kill_done';
+--send
+CREATE INDEX c2d ON t1(c2);
+
+connection default;
+SET DEBUG_SYNC = 'now WAIT_FOR c2d_created';
+eval $innodb_metrics_select;
+let $ignore= `SELECT @id := $ID`;
+KILL QUERY @id;
+SET DEBUG_SYNC = 'now SIGNAL kill_done';
+
+connection con1;
+--error ER_QUERY_INTERRUPTED
+reap;
+eval $innodb_metrics_select;
+
+connection default;
+CHECK TABLE t1;
+INSERT INTO t1 SELECT 5 + c1, c2, c3 FROM t1;
+INSERT INTO t1 SELECT 10 + c1, c2, c3 FROM t1;
+INSERT INTO t1 SELECT 20 + c1, c2, c3 FROM t1;
+INSERT INTO t1 SELECT 40 + c1, c2, c3 FROM t1;
+# Purge may or may not have cleaned up the DELETE FROM t1 WHERE c1 = 7;
+--replace_result 81 80
+EXPLAIN SELECT COUNT(*) FROM t1 WHERE c2 > 3;
+ANALYZE TABLE t1;
+
+connection con1;
+# Forge some statistics for c2d, and see that they will be used
+UPDATE t1_c2_stats SET index_name = 'c2d';
+# Fake the statistics. The cardinality should be 5,80.
+UPDATE t1_c2_stats SET stat_value = 2 WHERE stat_name = 'n_diff_pfx01';
+INSERT INTO t1_c2_stats
+SELECT database_name, table_name, index_name, last_update, 'n_diff_pfx02', 80,
+sample_size, 'c2,c1' FROM t1_c2_stats
+WHERE stat_name = 'n_diff_pfx01' AND stat_description = 'c2';
+INSERT INTO mysql.innodb_index_stats SELECT * FROM t1_c2_stats;
+DROP TABLE t1_c2_stats;
+
+CREATE INDEX c2d ON t1(c2);
+# This should show the newly calculated stats by CREATE INDEX above,
+# not the faked cardinality=4 for c2d(c2).
+# Purge may or may not have cleaned up the DELETE FROM t1 WHERE c1 = 7;
+--replace_result 81 80
+SHOW INDEX FROM t1;
+EXPLAIN SELECT COUNT(*) FROM t1 WHERE c2 > 3;
+
+SHOW CREATE TABLE t1;
+
+connection default;
+SET @merge_encrypt_0=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
+SET @merge_decrypt_0=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
+SET @rowlog_encrypt_0=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
+connection con1;
+
+# Exceed the configured innodb_online_alter_log_max_size.
+# The actual limit is a multiple of innodb_sort_buf_size,
+# because that is the size of the in-memory log buffers.
+SET DEBUG_SYNC = 'row_log_apply_before SIGNAL c2e_created WAIT_FOR dml2_done';
+# Ensure that the ALTER TABLE will be executed even with some concurrent DML.
+SET lock_wait_timeout = 10;
+--send
+# FIXME: MDEV-13668
+#ALTER TABLE t1 CHANGE c2 c22 INT, DROP INDEX c2d, ADD INDEX c2e(c22),
+ALTER TABLE t1 DROP INDEX c2d, ADD INDEX c2e(c2),
+ALGORITHM = INPLACE;
+
+# Generate some log (delete-mark, delete-unmark, insert etc.)
+# while the index creation is blocked. Some of this may run
+# in parallel with the clustered index scan.
+connection default;
+INSERT INTO t1 SELECT 80 + c1, c2, c3 FROM t1;
+INSERT INTO t1 SELECT 160 + c1, c2, c3 FROM t1;
+#UPDATE t1 SET c2 = c2 + 1;
+SET DEBUG_SYNC = 'now WAIT_FOR c2e_created';
+# At this point, the clustered index scan must have completed,
+# but the modification log keeps accumulating due to the DEBUG_SYNC.
+eval $innodb_metrics_select;
+let $c= 4;
+while ($c)
+{
+ BEGIN;
+ DELETE FROM t1;
+ ROLLBACK;
+ UPDATE t1 SET c2 = c2 + 1;
+ BEGIN;
+ UPDATE t1 SET c2 = c2 + 1;
+ DELETE FROM t1;
+ ROLLBACK;
+ dec $c;
+}
+# Incomplete index c2e should exist until the DDL thread notices the overflow.
+# (The output below strips TEMP_INDEX_PREFIX from the name.)
+eval $innodb_metrics_select;
+SELECT sf.name, sf.pos FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES si
+INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_FIELDS sf
+ON si.index_id = sf.index_id WHERE si.name = '?c2e';
+
+SET @merge_encrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
+SET @merge_decrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
+SET @rowlog_encrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
+
+SELECT
+(@merge_encrypt_1-@merge_encrypt_0)-
+(@merge_decrypt_1-@merge_decrypt_0) as sort_balance,
+@merge_encrypt_1>@merge_encrypt_0, @merge_decrypt_1>@merge_decrypt_0,
+@rowlog_encrypt_1>@rowlog_encrypt_0;
+
+# Release con1.
+SET DEBUG_SYNC = 'now SIGNAL dml2_done';
+
+connection con1;
+# If the following fails with the wrong error, it probably means that
+# you should rerun with a larger mtr --debug-sync-timeout.
+--error ER_INNODB_ONLINE_LOG_TOO_BIG
+reap;
+# The index c2e should have been dropped from the data dictionary
+# when the above error was noticed. It should still exist in the
+# cache with index->online_status = ONLINE_INDEX_ABORTED_DROPPED.
+eval $innodb_metrics_select;
+SELECT sf.name, sf.pos FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES si
+INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_FIELDS sf
+ON si.index_id = sf.index_id WHERE si.name = 'c2e';
+
+# ddl_background_drop_indexes = 1 here, because the incomplete index c2e still
+# exists in the InnoDB data dictionary cache.
+eval $innodb_metrics_select;
+
+connection default;
+
+ALTER TABLE t1 COMMENT 'testing if c2e will be dropped';
+
+# Check that the 'zombie' index c2e was dropped.
+eval $innodb_metrics_select;
+
+SET @merge_encrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
+SET @merge_decrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
+SET @rowlog_encrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
+SET @rowlog_decrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted');
+
+connection con1;
+# Accumulate and apply some modification log.
+SET DEBUG_SYNC = 'row_log_apply_before SIGNAL c2f_created WAIT_FOR dml3_done';
+--send
+# FIXME: MDEV-13668
+#ALTER TABLE t1 ADD INDEX c2f(c22f), CHANGE c2 c22f INT;
+ALTER TABLE t1 ADD INDEX c2f(c2);
+
+connection default;
+SET DEBUG_SYNC = 'now WAIT_FOR c2f_created';
+# Generate some log (delete-mark, delete-unmark, insert etc.)
+eval $innodb_metrics_select;
+let $c= 2;
+while ($c)
+{
+BEGIN;
+INSERT INTO t1 SELECT 320 + c1, c2, c3 FROM t1 WHERE c1 > 160;
+DELETE FROM t1 WHERE c1 > 320;
+ROLLBACK;
+BEGIN;
+UPDATE t1 SET c2 = c2 + 1;
+DELETE FROM t1;
+ROLLBACK;
+dec $c;
+}
+eval $innodb_metrics_select;
+# Release con1.
+SET DEBUG_SYNC = 'now SIGNAL dml3_done';
+
+connection con1;
+reap;
+# FIXME: MDEV-13668
+ALTER TABLE t1 CHANGE c2 c22f INT;
+
+eval $innodb_metrics_select;
+
+connection default;
+
+SET @merge_encrypt_2=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
+SET @merge_decrypt_2=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
+SET @rowlog_encrypt_2=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
+SET @rowlog_decrypt_2=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted');
+
+SELECT
+(@merge_encrypt_2-@merge_encrypt_1)-
+(@merge_decrypt_2-@merge_decrypt_1) as sort_balance,
+(@rowlog_encrypt_2-@rowlog_encrypt_1)-
+(@rowlog_decrypt_2-@rowlog_decrypt_1) as log_balance;
+SELECT
+@merge_encrypt_2-@merge_encrypt_1>0 as sort_encrypted,
+@merge_decrypt_2-@merge_decrypt_1>0 as sort_decrypted,
+@rowlog_encrypt_2-@rowlog_encrypt_1>0 as log_encrypted,
+@rowlog_decrypt_2-@rowlog_decrypt_1>0 as log_decrypted;
+
+connection con1;
+SELECT COUNT(c22f) FROM t1;
+CHECK TABLE t1;
+
+# Create a column prefix index.
+--error ER_DUP_ENTRY
+ALTER TABLE t1 ADD UNIQUE INDEX c3p5(c3(5));
+UPDATE t1 SET c3 = NULL WHERE c3 = '';
+SET lock_wait_timeout = 1;
+SET DEBUG_SYNC = 'row_log_apply_before SIGNAL c3p5_created WAIT_FOR ins_done';
+--send
+ALTER TABLE t1 ADD UNIQUE INDEX c3p5(c3(5));
+
+connection default;
+SET DEBUG_SYNC = 'now WAIT_FOR c3p5_created';
+
+# Check that the index was created.
+SELECT sf.name, sf.pos FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES si
+INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_FIELDS sf
+ON si.index_id = sf.index_id WHERE si.name = '?c3p5';
+
+SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL ins_done WAIT_FOR ddl_timed_out';
+--send
+INSERT INTO t1 VALUES(347,33101,NULL);
+
+connection con1;
+--error ER_LOCK_WAIT_TIMEOUT
+reap;
+SET DEBUG_SYNC = 'now SIGNAL ddl_timed_out';
+
+# InnoDB should have cleaned up the index c3p5 from the data dictionary,
+# but not yet from the dictionary cache.
+SELECT sf.name, sf.pos FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES si
+INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_FIELDS sf
+ON si.index_id = sf.index_id WHERE si.name = 'c3p5';
+eval $innodb_metrics_select;
+
+connection default;
+reap;
+# Index c3p5 should still exist in the data dictionary cache.
+eval $innodb_metrics_select;
+
+--disable_parsing
+# Temporarily disabled by fix for bug#14213236. Should be either
+# removed or updated to take into account that locking for IMPORT/
+# DISCARD TABLESPACE happens on MDL layer. New test case is added
+# to validate this at MDL layer(i_main.alter_table.test)
+
+SET DEBUG_SYNC = 'row_log_apply_before SIGNAL c2g_created WAIT_FOR dml4_done';
+# The lock upgrade at the end of the ALTER will conflict with the DISCARD.
+SET lock_wait_timeout = 1;
+--send
+ALTER TABLE t1 DROP INDEX c2f, ADD INDEX c2g(c22f);
+
+connection con1;
+SET DEBUG_SYNC = 'now WAIT_FOR c2g_created';
+
+connect (con2,localhost,root,,);
+connection con2;
+
+# This will conflict with the ALTER in connection default, above.
+SET lock_wait_timeout = 10;
+--send
+ALTER TABLE t1 DISCARD TABLESPACE;
+
+connection con1;
+let $wait_condition=
+ SELECT COUNT(*) = 1 FROM information_schema.processlist
+ WHERE state = 'Waiting for table level lock' and
+ info = 'ALTER TABLE t1 DISCARD TABLESPACE';
+--source include/wait_condition.inc
+
+SET DEBUG_SYNC = 'now SIGNAL dml4_done';
+disconnect con1;
+connection con2;
+reap;
+disconnect con2;
+connection default;
+--error ER_LOCK_WAIT_TIMEOUT
+reap;
+--enable_parsing
+#remove below con1 disconnect if above test case is enabled
+connection default;
+
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 DROP INDEX c2d, DROP INDEX c2f;
+# The ALTER TABLE should have cleaned up c3p5 from the cache.
+eval $innodb_metrics_select;
+ALTER TABLE t1 ADD INDEX c2h(c22f), ALGORITHM = INPLACE;
+--error ER_DUP_KEYNAME
+ALTER TABLE t1 ADD INDEX c2h(c22f), ALGORITHM = COPY;
+
+SET DEBUG_SYNC = 'RESET';
+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
+
+SET GLOBAL innodb_file_per_table = @global_innodb_file_per_table_orig;
+--disable_warnings
+SET GLOBAL innodb_monitor_enable = default;
+SET GLOBAL innodb_monitor_disable = default;
+--enable_warnings
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..fe04f4b7705
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-lru-force-no-free-page.test
@@ -0,0 +1,25 @@
+--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_RANGE= -50000;
+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-page_compression_tables.test b/mysql-test/suite/innodb/t/innodb-page_compression_tables.test
index 41d844d26b4..d8a85d7f273 100644
--- a/mysql-test/suite/innodb/t/innodb-page_compression_tables.test
+++ b/mysql-test/suite/innodb/t/innodb-page_compression_tables.test
@@ -32,10 +32,8 @@ create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row
show warnings;
create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant;
show create table innodb_redundant;
---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
---error 1005
+--error ER_ILLEGAL_HA_CREATE_OPTION
alter table innodb_redundant page_compressed=1;
---replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
show warnings;
show create table innodb_redundant;
alter table innodb_redundant row_format=compact page_compressed=1;
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-table-online-master.opt b/mysql-test/suite/innodb/t/innodb-table-online-master.opt
new file mode 100644
index 00000000000..92eea2b0d2e
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-table-online-master.opt
@@ -0,0 +1 @@
+--innodb-sort-buffer-size=64k --innodb-online-alter-log-max-size=512k --innodb-buffer-pool-size=5M --innodb-log-buffer-size=256k
diff --git a/mysql-test/suite/innodb/t/innodb-table-online.test b/mysql-test/suite/innodb/t/innodb-table-online.test
new file mode 100644
index 00000000000..b9c9dc085d6
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-table-online.test
@@ -0,0 +1,454 @@
+--source include/innodb_page_size_small.inc
+--source include/innodb_encrypt_log.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+
+let $innodb_metrics_select=
+SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
+
+call mtr.add_suppression("InnoDB: Warning: Small buffer pool size");
+# these will be triggered by DISCARD TABLESPACE
+call mtr.add_suppression("InnoDB: Error: table 'test/t1'");
+call mtr.add_suppression("MySQL is trying to open a table handle but the .ibd file for");
+
+# DISCARD TABLESPACE needs file-per-table
+SET @global_innodb_file_per_table_orig = @@global.innodb_file_per_table;
+SET GLOBAL innodb_file_per_table = on;
+# PAGE_COMPRESSED needs innodb_file_format!=Antelope
+SET @file_format = @@GLOBAL.innodb_file_format;
+SET GLOBAL innodb_file_format = Barracuda;
+
+# Save the initial number of concurrent sessions.
+--source include/count_sessions.inc
+
+CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT NOT NULL, c3 CHAR(255) NOT NULL)
+ENGINE = InnoDB;
+INSERT INTO t1 VALUES (1,1,''), (2,2,''), (3,3,''), (4,4,''), (5,5,'');
+
+SET GLOBAL innodb_monitor_enable = module_ddl;
+eval $innodb_metrics_select;
+
+SET DEBUG_SYNC = 'RESET';
+SET DEBUG_SYNC = 'write_row_noreplace SIGNAL have_handle WAIT_FOR go_ahead';
+--send
+INSERT INTO t1 VALUES(1,2,3);
+
+--echo # Establish session con1 (user=root)
+connect (con1,localhost,root,,);
+connection con1;
+
+# This should block at the end because of the INSERT in connection default
+# is holding a metadata lock.
+SET DEBUG_SYNC = 'now WAIT_FOR have_handle';
+SET lock_wait_timeout = 1;
+--error ER_LOCK_WAIT_TIMEOUT
+ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
+SET DEBUG_SYNC = 'now SIGNAL go_ahead';
+
+--echo # session default
+connection default;
+--error ER_DUP_ENTRY
+reap;
+eval $innodb_metrics_select;
+
+--echo # session con1
+connection con1;
+SET @saved_debug_dbug = @@SESSION.debug_dbug;
+SET DEBUG_DBUG = '+d,innodb_OOM_prepare_inplace_alter';
+--error ER_OUT_OF_RESOURCES
+ALTER TABLE t1 ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE, LOCK=NONE;
+SET SESSION DEBUG = @saved_debug_dbug;
+SET SESSION DEBUG = '+d,innodb_OOM_inplace_alter';
+--error ER_OUT_OF_RESOURCES
+ALTER TABLE t1 ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE, LOCK=NONE;
+SET SESSION DEBUG = @saved_debug_dbug;
+ALTER TABLE t1 ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE, LOCK=NONE;
+
+--echo # session default
+connection default;
+SHOW CREATE TABLE t1;
+# Insert a duplicate entry (4) for the upcoming UNIQUE INDEX(c2).
+BEGIN;
+INSERT INTO t1 VALUES(7,4,2);
+
+--echo # session con1
+connection con1;
+# This DEBUG_SYNC should not kick in yet, because the duplicate key will be
+# detected before we get a chance to apply the online log.
+SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL scanned WAIT_FOR insert_done';
+# This will be a lock wait timeout on the meta-data lock,
+# because the transaction inserting (7,4,2) is still active.
+--error ER_LOCK_WAIT_TIMEOUT
+ALTER TABLE t1 DROP PRIMARY KEY, ADD UNIQUE INDEX(c2);
+
+--echo # session default
+connection default;
+COMMIT;
+
+--echo # session con1
+connection con1;
+--error ER_DUP_ENTRY
+ALTER TABLE t1 DROP PRIMARY KEY, ADD UNIQUE INDEX(c2);
+
+--echo # session default
+connection default;
+DELETE FROM t1 WHERE c1 = 7;
+
+--echo # session con1
+connection con1;
+ALTER TABLE t1 DROP PRIMARY KEY, ADD UNIQUE INDEX(c2), ROW_FORMAT=COMPACT,
+LOCK = SHARED, ALGORITHM = INPLACE;
+
+# The previous DEBUG_SYNC should be ignored, because an exclusive lock
+# has been requested and the online log is not being allocated.
+ALTER TABLE t1 ADD UNIQUE INDEX(c2),
+LOCK = EXCLUSIVE, ALGORITHM = INPLACE;
+
+SHOW CREATE TABLE t1;
+# We do not support plain DROP_PK_INDEX without ADD_PK_INDEX.
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE t1 DROP INDEX c2, ALGORITHM = INPLACE;
+SHOW CREATE TABLE t1;
+# Now the previous DEBUG_SYNC should kick in.
+--send
+ALTER TABLE t1 DROP INDEX c2, ADD PRIMARY KEY(c1);
+
+--echo # session default
+connection default;
+SET DEBUG_SYNC = 'now WAIT_FOR scanned';
+eval $innodb_metrics_select;
+
+# Insert a duplicate entry (4) for the already started UNIQUE INDEX(c1).
+BEGIN;
+INSERT INTO t1 VALUES(4,7,2);
+SET DEBUG_SYNC = 'now SIGNAL insert_done';
+
+--echo # session con1
+connection con1;
+# Because the modification log will be applied in order and we did
+# not roll back before the log apply, there will be a duplicate key
+# error on the (4,7,2).
+--error ER_DUP_ENTRY
+reap;
+
+--echo # session default
+connection default;
+ROLLBACK;
+
+--echo # session con1
+connection con1;
+SHOW CREATE TABLE t1;
+# Now, rebuild the table without any concurrent DML, while no duplicate exists.
+--error ER_CANT_DROP_FIELD_OR_KEY
+ALTER TABLE t1 DROP PRIMARY KEY, ADD UNIQUE INDEX(c2), ALGORITHM = INPLACE;
+ALTER TABLE t1 DROP INDEX c2, ADD PRIMARY KEY(c1), ALGORITHM = INPLACE;
+eval $innodb_metrics_select;
+
+--echo # session default
+connection default;
+--error ER_DUP_ENTRY
+INSERT INTO t1 VALUES(6,3,1);
+--error ER_DUP_ENTRY
+INSERT INTO t1 VALUES(7,4,2);
+DROP INDEX c2_2 ON t1;
+BEGIN;
+INSERT INTO t1 VALUES(7,4,2);
+ROLLBACK;
+
+--echo # session con1
+connection con1;
+let $ID= `SELECT @id := CONNECTION_ID()`;
+--error ER_QUERY_INTERRUPTED
+KILL QUERY @id;
+
+SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL rebuilt WAIT_FOR dml_done';
+SET DEBUG_SYNC = 'row_log_table_apply2_before SIGNAL applied WAIT_FOR kill_done';
+--send
+ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
+
+--echo # session default
+connection default;
+SET DEBUG_SYNC = 'now WAIT_FOR rebuilt';
+eval $innodb_metrics_select;
+BEGIN;
+INSERT INTO t1 VALUES(7,4,2);
+ROLLBACK;
+SET DEBUG_SYNC = 'now SIGNAL dml_done WAIT_FOR applied';
+let $ignore= `SELECT @id := $ID`;
+KILL QUERY @id;
+SET DEBUG_SYNC = 'now SIGNAL kill_done';
+
+--echo # session con1
+connection con1;
+--error ER_QUERY_INTERRUPTED
+reap;
+eval $innodb_metrics_select;
+
+--echo # session default
+connection default;
+CHECK TABLE t1;
+INSERT INTO t1 SELECT 5 + c1, c2, c3 FROM t1;
+INSERT INTO t1 SELECT 10 + c1, c2, c3 FROM t1;
+INSERT INTO t1 SELECT 20 + c1, c2, c3 FROM t1;
+INSERT INTO t1 SELECT 40 + c1, c2, c3 FROM t1;
+# Purge may or may not have cleaned up the DELETE FROM t1 WHERE c1 = 7;
+--replace_column 9 ROWS
+EXPLAIN SELECT COUNT(*) FROM t1 WHERE c2 > 3;
+ANALYZE TABLE t1;
+
+SET @merge_encrypt_0=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
+SET @merge_decrypt_0=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
+SET @rowlog_encrypt_0=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
+
+--echo # session con1
+connection con1;
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
+
+# Exceed the configured innodb_online_alter_log_max_size.
+# The actual limit is a multiple of innodb_sort_buf_size,
+# because that is the size of the in-memory log buffers.
+SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL rebuilt2 WAIT_FOR dml2_done';
+# Ensure that the ALTER TABLE will be executed even with some concurrent DML.
+SET lock_wait_timeout = 10;
+--send
+ALTER TABLE t1 ROW_FORMAT=COMPACT
+PAGE_COMPRESSED = YES PAGE_COMPRESSION_LEVEL = 1, ALGORITHM = INPLACE;
+
+# Generate some log (delete-mark, delete-unmark, insert etc.)
+# while the index creation is blocked. Some of this may run
+# in parallel with the clustered index scan.
+--echo # session default
+connection default;
+INSERT INTO t1 SELECT 80 + c1, c2, c3 FROM t1;
+INSERT INTO t1 SELECT 160 + c1, c2, c3 FROM t1;
+UPDATE t1 SET c2 = c2 + 1;
+SET DEBUG_SYNC = 'now WAIT_FOR rebuilt2';
+# At this point, the clustered index scan must have completed,
+# but the modification log keeps accumulating due to the DEBUG_SYNC.
+eval $innodb_metrics_select;
+let $c= 3;
+while ($c)
+{
+ BEGIN;
+ DELETE FROM t1;
+ ROLLBACK;
+ UPDATE t1 SET c2 = c2 + 1;
+ BEGIN;
+ UPDATE t1 SET c2 = c2 + 1;
+ DELETE FROM t1;
+ ROLLBACK;
+ dec $c;
+}
+# Temporary table should exist until the DDL thread notices the overflow.
+eval $innodb_metrics_select;
+
+SET @merge_encrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
+SET @merge_decrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
+SET @rowlog_encrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
+
+SELECT
+(@merge_encrypt_1-@merge_encrypt_0)-
+(@merge_decrypt_1-@merge_decrypt_0) as sort_balance,
+@merge_encrypt_1>@merge_encrypt_0, @merge_decrypt_1>@merge_decrypt_0,
+@rowlog_encrypt_1>@rowlog_encrypt_0;
+
+# Release con1.
+SET DEBUG_SYNC = 'now SIGNAL dml2_done';
+
+--echo # session con1
+connection con1;
+# If the following fails with the wrong error, it probably means that
+# you should rerun with a larger mtr --debug-sync-timeout.
+--error ER_INNODB_ONLINE_LOG_TOO_BIG
+reap;
+# The table should have been dropped from the data dictionary
+# when the above error was noticed.
+eval $innodb_metrics_select;
+
+SET @merge_encrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
+SET @merge_decrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
+SET @rowlog_encrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
+SET @rowlog_decrypt_1=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted');
+
+# Accumulate and apply some modification log.
+SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL rebuilt3 WAIT_FOR dml3_done';
+--error ER_MULTIPLE_PRI_KEY
+ALTER TABLE t1 ADD PRIMARY KEY(c22f), CHANGE c2 c22f INT;
+--error ER_DUP_ENTRY
+ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(c22f), CHANGE c2 c22f INT;
+--send
+ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(c1,c22f,c4(5)),
+CHANGE c2 c22f INT, CHANGE c3 c3 CHAR(255) NULL, CHANGE c1 c1 INT AFTER c22f,
+ADD COLUMN c4 VARCHAR(6) DEFAULT 'Online', LOCK=NONE;
+
+--echo # session default
+connection default;
+SET DEBUG_SYNC = 'now WAIT_FOR rebuilt3';
+# Generate some log (delete-mark, delete-unmark, insert etc.)
+eval $innodb_metrics_select;
+BEGIN;
+INSERT INTO t1 SELECT 320 + c1, c2, c3 FROM t1 WHERE c1 > 240;
+DELETE FROM t1 WHERE c1 > 320;
+ROLLBACK;
+BEGIN;
+UPDATE t1 SET c2 = c2 + 1;
+DELETE FROM t1;
+ROLLBACK;
+eval $innodb_metrics_select;
+# Release con1.
+SET DEBUG_SYNC = 'now SIGNAL dml3_done';
+
+--echo # session con1
+connection con1;
+reap;
+eval $innodb_metrics_select;
+SELECT COUNT(c22f) FROM t1;
+CHECK TABLE t1;
+
+SET @merge_encrypt_2=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_encrypted');
+SET @merge_decrypt_2=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_merge_blocks_decrypted');
+SET @rowlog_encrypt_2=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
+SET @rowlog_decrypt_2=
+(SELECT variable_value FROM information_schema.global_status
+WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted');
+
+SELECT
+(@merge_encrypt_2-@merge_encrypt_1)-
+(@merge_decrypt_2-@merge_decrypt_1) as sort_balance,
+(@rowlog_encrypt_2-@rowlog_encrypt_1)-
+(@rowlog_decrypt_2-@rowlog_decrypt_1) as log_balance;
+SELECT
+@merge_encrypt_2-@merge_encrypt_1>0 as sort_encrypted,
+@merge_decrypt_2-@merge_decrypt_1>0 as sort_decrypted,
+@rowlog_encrypt_2-@rowlog_encrypt_1>0 as log_encrypted,
+@rowlog_decrypt_2-@rowlog_decrypt_1>0 as log_decrypted;
+
+# Create a column prefix index.
+--error ER_DUP_ENTRY
+ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY c3p5(c3(5));
+UPDATE t1 SET c3 = NULL WHERE c3 = '';
+SET lock_wait_timeout = 1;
+--error ER_MULTIPLE_PRI_KEY
+ALTER TABLE t1 DROP COLUMN c22f, ADD PRIMARY KEY c3p5(c3(5));
+SET @old_sql_mode = @@sql_mode;
+# NULL -> NOT NULL only allowed INPLACE if strict sql_mode is on.
+# And adding a PRIMARY KEY will also add NOT NULL implicitly!
+SET @@sql_mode = 'STRICT_TRANS_TABLES';
+--error ER_INVALID_USE_OF_NULL
+ALTER TABLE t1 DROP COLUMN c22f, DROP PRIMARY KEY, ADD PRIMARY KEY c3p5(c3(5)),
+ALGORITHM = INPLACE;
+
+--error ER_INVALID_USE_OF_NULL
+ALTER TABLE t1 MODIFY c3 CHAR(255) NOT NULL;
+SET @@sql_mode = @old_sql_mode;
+UPDATE t1 SET c3=LEFT(CONCAT(c1,REPEAT('foo',c1)),255) WHERE c3 IS NULL;
+
+SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL c3p5_created0 WAIT_FOR ins_done0';
+# NULL -> NOT NULL only allowed INPLACE if strict sql_mode is on.
+SET @@sql_mode = 'STRICT_TRANS_TABLES';
+--send
+ALTER TABLE t1 MODIFY c3 CHAR(255) NOT NULL, DROP COLUMN c22f,
+ADD COLUMN c5 CHAR(5) DEFAULT 'tired' FIRST;
+
+--echo # session default
+connection default;
+
+SET DEBUG_SYNC = 'now WAIT_FOR c3p5_created0';
+BEGIN;
+INSERT INTO t1 VALUES(347,33101,'Pikku kakkosen posti','YLETV2');
+INSERT INTO t1 VALUES(33101,347,NULL,'');
+SET DEBUG_SYNC = 'now SIGNAL ins_done0';
+
+--echo # session con1
+connection con1;
+--error ER_INVALID_USE_OF_NULL
+reap;
+SET @@sql_mode = @old_sql_mode;
+
+--echo # session default
+connection default;
+ROLLBACK;
+
+--echo # session con1
+connection con1;
+ALTER TABLE t1 MODIFY c3 CHAR(255) NOT NULL;
+SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL c3p5_created WAIT_FOR ins_done';
+--send
+ALTER TABLE t1 DROP PRIMARY KEY, DROP COLUMN c22f,
+ADD COLUMN c6 VARCHAR(1000) DEFAULT
+'I love tracking down hard-to-reproduce bugs.',
+ADD PRIMARY KEY c3p5(c3(5), c6(2));
+
+--echo # session default
+connection default;
+SET DEBUG_SYNC = 'now WAIT_FOR c3p5_created';
+SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL ins_done WAIT_FOR ddl_timed_out';
+--error ER_BAD_NULL_ERROR
+INSERT INTO t1 VALUES(347,33101,NULL,'');
+--send
+INSERT INTO t1 VALUES(347,33101,'Pikku kakkosen posti','');
+
+--echo # session con1
+connection con1;
+--error ER_LOCK_WAIT_TIMEOUT
+reap;
+SET DEBUG_SYNC = 'now SIGNAL ddl_timed_out';
+eval $innodb_metrics_select;
+
+--echo # session default
+connection default;
+reap;
+SELECT COUNT(*) FROM t1;
+ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
+SELECT * FROM t1 LIMIT 10;
+
+--echo # session con1
+connection con1;
+ALTER TABLE t1 DISCARD TABLESPACE;
+--echo # Disconnect session con1
+disconnect con1;
+
+--echo # session default
+connection default;
+SHOW CREATE TABLE t1;
+SET DEBUG_SYNC = 'RESET';
+SET GLOBAL innodb_monitor_disable = module_ddl;
+DROP TABLE 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
+
+SET GLOBAL innodb_file_per_table = @global_innodb_file_per_table_orig;
+SET GLOBAL innodb_file_format = @file_format;
+--disable_warnings
+SET GLOBAL innodb_monitor_enable = default;
+SET GLOBAL innodb_monitor_disable = default;
+--enable_warnings
diff --git a/mysql-test/suite/innodb/t/innodb-wl5522-debug.test b/mysql-test/suite/innodb/t/innodb-wl5522-debug.test
index aa972238636..11bdd4305c2 100644
--- a/mysql-test/suite/innodb/t/innodb-wl5522-debug.test
+++ b/mysql-test/suite/innodb/t/innodb-wl5522-debug.test
@@ -1,4 +1,4 @@
-# Not supported in embedded
+# mysql-test-run.pl --embedded cannot restart the server.
--source include/not_embedded.inc
# Adding big test option for this test.
@@ -15,12 +15,6 @@
-- source include/have_innodb.inc
-call mtr.add_suppression("InnoDB: Page for tablespace .* ");
-call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=");
-call mtr.add_suppression("InnoDB: Corruption: Block in space_id .* in file .* corrupted");
-call mtr.add_suppression("InnoDB: Based on page type .*");
-FLUSH TABLES;
-
let MYSQLD_DATADIR =`SELECT @@datadir`;
let $innodb_file_per_table = `SELECT @@innodb_file_per_table`;
let $pathfix=/: '.*test_wl5522.*t1.ibd'/: 'test_wl5522\\t1.ibd'/;
@@ -28,51 +22,36 @@ let $strerrfix=/ (\(.+\))//;
SET GLOBAL innodb_file_per_table = 1;
-DROP DATABASE IF EXISTS test_wl5522;
CREATE DATABASE test_wl5522;
-##### Before DISCARD commit crash
-SET SESSION debug_dbug="+d,ib_discard_before_commit_crash";
-
CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = InnoDB;
INSERT INTO test_wl5522.t1 VALUES(1),(2),(3);
-# Write file to make mysql-test-run.pl start up the server again
---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--let $_server_id= `SELECT @@server_id`
+--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect
-# Execute the statement that causes the crash
+--exec echo wait > $_expect_file_name
+SET SESSION debug_dbug="+d,ib_discard_before_commit_crash";
--error 2013
ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE;
---enable_reconnect
---source include/wait_until_connected_again.inc
---disable_reconnect
+--source include/start_mysqld.inc
DROP TABLE test_wl5522.t1;
-#### Before DISCARD commit crash
-##### After DISCARD commit crash
SET GLOBAL innodb_file_per_table = 1;
-SELECT @@innodb_file_per_table;
-
-SET SESSION debug_dbug="+d,ib_discard_after_commit_crash";
CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = InnoDB;
INSERT INTO test_wl5522.t1 VALUES(1),(2),(3);
-# Write file to make mysql-test-run.pl start up the server again
---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-
-# Execute the statement that causes the crash
+--exec echo wait > $_expect_file_name
+SET SESSION debug_dbug="+d,ib_discard_after_commit_crash";
--error 2013
ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE;
---enable_reconnect
---source include/wait_until_connected_again.inc
---disable_reconnect
+--source include/start_mysqld.inc
DROP TABLE test_wl5522.t1;
-#### After DISCARD commit crash
SET GLOBAL innodb_file_per_table = 1;
@@ -106,59 +85,35 @@ do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
-##### Before commit crash
-SET SESSION debug_dbug="+d,ib_import_before_commit_crash";
-
--error ER_TABLESPACE_DISCARDED
SELECT * FROM test_wl5522.t1;
-# Write file to make mysql-test-run.pl start up the server again
---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-
-# Execute the statement that causes the crash
+--exec echo wait > $_expect_file_name
+SET SESSION debug_dbug="+d,ib_import_before_commit_crash";
--error 2013
ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
---enable_reconnect
---source include/wait_until_connected_again.inc
---disable_reconnect
-
-#### Before commit crash
+--source include/start_mysqld.inc
# Check that the DD is consistent after recovery
-##### Before checkpoint crash
-SET SESSION debug_dbug="+d,ib_import_before_checkpoint_crash";
-
--error ER_TABLESPACE_DISCARDED
SELECT COUNT(*) FROM test_wl5522.t1;
-# Don't start up the server right away.
---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-
-# Execute the statement that causes the crash
+--exec echo wait > $_expect_file_name
+SET SESSION debug_dbug="+d,ib_import_before_checkpoint_crash";
--error 2013
ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
# After the above test the results are non-deterministic,
# delete the old tablespace files and drop the table,
# recreate the table and do a proper import.
--- source include/wait_until_disconnected.inc
perl;
do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
ib_unlink_tablespace("test_wl5522", "t1");
EOF
---echo # Restart and reconnect to the server
---enable_reconnect
---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
---source include/wait_until_connected_again.inc
---disable_reconnect
-
-#### Before checkpoint crash
-
-# After the above test the results are non-deterministic, recreate the table
-# and do a proper import.
+--source include/start_mysqld.inc
DROP TABLE test_wl5522.t1;
@@ -198,6 +153,7 @@ SET SESSION debug_dbug="+d,ib_export_io_write_failure_1";
FLUSH TABLES test_wl5522.t1 FOR EXPORT;
UNLOCK TABLES;
+
SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
@@ -1087,7 +1043,9 @@ CREATE TABLE test_wl5522.t1 (
INDEX idx3(c4(512))) Engine=InnoDB;
# Stop purge so that it doesn't remove the delete marked entries.
-SET GLOBAL INNODB_PURGE_STOP_NOW=ON;
+connect (purge_control,localhost,root);
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+connection default;
# Disable change buffer merge from the master thread, additionally
# enable aggressive flushing so that more changes are buffered.
@@ -1157,7 +1115,10 @@ SELECT name
SET GLOBAL innodb_disable_background_merge=OFF;
# Enable normal operation
-SET GLOBAL INNODB_PURGE_RUN_NOW=ON;
+connection purge_control;
+COMMIT;
+disconnect purge_control;
+connection default;
DROP TABLE test_wl5522.t1;
@@ -1195,8 +1156,8 @@ DROP TABLE test_wl5522.t1;
# a Btree that has several levels
CREATE TABLE test_wl5522.t1 (c1 INT, c2 VARCHAR(1024), c3 BLOB) ENGINE = Innodb;
-INSERT INTO test_wl5522.t1 VALUES
- (100, REPEAT('Karanbir', 899), REPEAT('Ajeeth', 1200));
+INSERT IGNORE INTO test_wl5522.t1 VALUES
+ (100, REPEAT('Karanbir', 899), REPEAT('Ajeeth', 2731));
INSERT INTO test_wl5522.t1 SELECT * FROM test_wl5522.t1;
INSERT INTO test_wl5522.t1 SELECT * FROM test_wl5522.t1;
@@ -1262,7 +1223,7 @@ do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
-SET SESSION debug_dbug="+d,buf_page_is_corrupt_failure";
+SET SESSION debug_dbug="+d,buf_page_import_corrupt_failure";
--replace_regex /'.*t1.cfg'/'t1.cfg'/
@@ -1484,6 +1445,8 @@ call mtr.add_suppression("but tablespace with that id or name does not exist");
call mtr.add_suppression("Failed to find tablespace for table '\"test_wl5522\".\"t1\"' in the cache");
call mtr.add_suppression("Could not find a valid tablespace file for 'test_wl5522.*t1'");
call mtr.add_suppression("while reading index meta-data, expected to read 44 bytes but read only 0 bytes");
+call mtr.add_suppression("Page for tablespace.*that index is not found from configuration file");
+call mtr.add_suppression("Invalid FSP_SPACE_FLAGS=0x0");
--enable_query_log
#cleanup
diff --git a/mysql-test/suite/innodb/t/innodb-wl5980-alter.opt b/mysql-test/suite/innodb/t/innodb-wl5980-alter.opt
new file mode 100644
index 00000000000..aa400236153
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-wl5980-alter.opt
@@ -0,0 +1,3 @@
+--loose-innodb-sys-indexes
+--loose-innodb-sys-columns
+--loose-innodb-sys-fields
diff --git a/mysql-test/suite/innodb/t/innodb-wl5980-alter.test b/mysql-test/suite/innodb/t/innodb-wl5980-alter.test
new file mode 100644
index 00000000000..2815a6fc6d7
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-wl5980-alter.test
@@ -0,0 +1,593 @@
+--echo #
+--echo # This is a copy of innodb-alter.test except using remote tablespaces
+--echo # and showing those files.
+--echo #
+
+--source include/have_innodb.inc
+
+--disable_query_log
+# These values can change during the test
+LET $innodb_file_per_table_orig=`select @@innodb_file_per_table`;
+LET $regexp=/FTS_([0-9a-f_]+)([A-Z0-9_]+)\.ibd/FTS_AUX_\2.ibd/;
+
+# Set up some variables
+LET $MYSQL_DATA_DIR = `select @@datadir`;
+LET $data_directory_clause = DATA DIRECTORY='$MYSQL_TMP_DIR/alt_dir';
+--enable_query_log
+
+SET default_storage_engine=InnoDB;
+SET GLOBAL innodb_file_per_table=ON;
+
+SET NAMES utf8;
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+eval CREATE TABLE t1 (
+ c1 INT PRIMARY KEY, c2 INT DEFAULT 1, ct TEXT,
+ INDEX(c2))
+ENGINE=InnoDB $data_directory_clause;
+
+INSERT INTO t1 SET c1=1;
+
+CREATE TABLE sys_tables SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
+WHERE NAME LIKE 'test/t%';
+CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+
+CREATE TABLE t1p LIKE t1;
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+eval CREATE TABLE t1c (c1 INT PRIMARY KEY, c2 INT, c3 INT, INDEX(c2), INDEX(c3),
+ CONSTRAINT t1c2 FOREIGN KEY (c2) REFERENCES t1(c2),
+ CONSTRAINT t1c3 FOREIGN KEY (c3) REFERENCES t1p(c2))
+ENGINE=InnoDB $data_directory_clause;
+
+CREATE TABLE sys_foreign SELECT i.*
+FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN i
+WHERE FOR_NAME LIKE 'test/t%';
+
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+
+-- source suite/innodb/include/innodb_dict.inc
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 ALTER c2 DROP DEFAULT;
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+SHOW CREATE TABLE t1;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+-- source suite/innodb/include/innodb_dict.inc
+
+# These should be no-op.
+ALTER TABLE t1 CHANGE c2 c2 INT AFTER c1;
+ALTER TABLE t1 CHANGE c1 c1 INT FIRST;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+-- source suite/innodb/include/innodb_dict.inc
+
+ALTER TABLE t1 CHANGE C2 c3 INT;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+-- source suite/innodb/include/innodb_dict.inc
+
+ALTER TABLE t1 CHANGE c3 C INT;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+-- source suite/innodb/include/innodb_dict.inc
+
+ALTER TABLE t1 CHANGE C Cöŀumň_TWO INT;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i
+INNER JOIN sys_foreign sf ON i.ID = sf.ID;
+
+-- source suite/innodb/include/innodb_dict.inc
+
+-- error ER_BAD_FIELD_ERROR
+ALTER TABLE t1 CHANGE cöĿǖmň_two c3 INT;
+
+ALTER TABLE t1 CHANGE cÖĿUMŇ_two c3 INT, RENAME TO t3;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+SELECT st.NAME, i.NAME
+FROM sys_tables st INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES i
+ON i.TABLE_ID=st.TABLE_ID;
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+SHOW CREATE TABLE t3;
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+SHOW CREATE TABLE t1c;
+
+# The maximum column name length should be 64 characters.
+--error ER_TOO_LONG_IDENT
+ALTER TABLE t3 CHANGE c3
+`12345678901234567890123456789012345678901234567890123456789012345` INT;
+ALTER TABLE t3 CHANGE c3
+`1234567890123456789012345678901234567890123456789012345678901234` INT;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+SHOW CREATE TABLE t3;
+
+# Test the length limit with non-ASCII utf-8 characters.
+--error ER_TOO_LONG_IDENT
+ALTER TABLE t3 CHANGE
+`1234567890123456789012345678901234567890123456789012345678901234`
+`倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ å€¡å€¢å€£å€¤å€¥å€¦å€§å€¨å€©å€ªå€«å€¬å€­å€®å€¯å€°å€±å€²å€³å€´å€µå€¶å€·å€¸å€¹å€ºå€»å€¼å€½å€¾å€¿å€` INT;
+
+--error ER_TOO_LONG_IDENT
+ALTER TABLE t3 CHANGE
+`1234567890123456789012345678901234567890123456789012345678901234`
+`倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ å€¡å€¢å€£å€¤å€¥å€¦å€§å€¨å€©å€ªå€«å€¬å€­å€®å€¯å€°å€±å€²å€³å€´å€µå€¶å€·å€¸å€¹å€ºå€»å€¼å€½å€¾å€¿Ã¤` INT;
+
+ALTER TABLE t3 CHANGE
+`1234567890123456789012345678901234567890123456789012345678901234`
+`倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ å€¡å€¢å€£å€¤å€¥å€¦å€§å€¨å€©å€ªå€«å€¬å€­å€®å€¯å€°å€±å€²å€³å€´å€µå€¶å€·å€¸å€¹å€ºå€»å€¼å€½å€¾Ã¤` INT;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+# check that the rename is case-insensitive (note the upper-case ä at end)
+ALTER TABLE t3 CHANGE
+`倀å€å€‚倃倄倅倆倇倈倉倊個倌å€å€Žå€å€å€‘倒倓倔倕倖倗倘候倚倛倜å€å€žå€Ÿå€ å€¡å€¢å€£å€¤å€¥å€¦å€§å€¨å€©å€ªå€«å€¬å€­å€®å€¯å€°å€±å€²å€³å€´å€µå€¶å€·å€¸å€¹å€ºå€»å€¼å€½å€¾Ã„`
+c3 INT;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+# test with 4-byte UTF-8 (should be disallowed)
+--error ER_INVALID_CHARACTER_STRING
+ALTER TABLE t3 CHANGE c3 ðŒ€ðŒðŒ‚ðŒƒðŒ„ðŒ…ðŒ†ðŒ‡ðŒˆðŒ‰ðŒŠðŒ‹ðŒŒðŒðŒŽðŒðŒðŒ‘ðŒ’ðŒ“ðŒ”ðŒ•ðŒ–ðŒ—ðŒ˜ðŒ™ðŒšðŒ›ðŒœ INT;
+
+--error ER_INVALID_CHARACTER_STRING
+ALTER TABLE t3 CHANGE c3 😲 INT;
+
+ALTER TABLE t3 RENAME TO t2;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+SELECT st.NAME, i.NAME
+FROM sys_tables st INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES i
+ON i.TABLE_ID=st.TABLE_ID;
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+SHOW CREATE TABLE t2;
+
+RENAME TABLE t2 TO t1;
+
+SELECT st.NAME, i.NAME
+FROM sys_tables st INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES i
+ON i.TABLE_ID=st.TABLE_ID;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+-- source suite/innodb/include/innodb_dict.inc
+
+--error ER_DROP_INDEX_FK
+ALTER TABLE t1 DROP INDEX c2;
+
+--error ER_CANT_DROP_FIELD_OR_KEY
+ALTER TABLE t1 DROP INDEX c4;
+
+--error ER_CANT_DROP_FIELD_OR_KEY
+ALTER TABLE t1c DROP FOREIGN KEY c2;
+
+--error ER_CANT_DROP_FIELD_OR_KEY
+ALTER TABLE t1c DROP FOREIGN KEY t1c2, DROP FOREIGN KEY c2;
+
+--error ER_CANT_DROP_FIELD_OR_KEY
+ALTER TABLE t1c DROP FOREIGN KEY t1c2, DROP FOREIGN KEY c2, DROP INDEX c2;
+
+--error ER_DROP_INDEX_FK
+ALTER TABLE t1c DROP INDEX c2;
+
+--error ER_CANT_DROP_FIELD_OR_KEY
+ALTER TABLE t1c DROP FOREIGN KEY ẗ1C2;
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+SHOW CREATE TABLE t1c;
+
+SET foreign_key_checks=0;
+DROP TABLE t1p;
+SET foreign_key_checks=1;
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+SHOW CREATE TABLE t1c;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+-- source suite/innodb/include/innodb_dict.inc
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+eval CREATE TABLE t1p (c1 INT PRIMARY KEY, c2 INT, INDEX(c2))
+ ENGINE=InnoDB $data_directory_clause;
+
+--error ER_DROP_INDEX_FK
+ALTER TABLE t1c DROP INDEX C2, DROP INDEX C3;
+--error ER_DROP_INDEX_FK
+ALTER TABLE t1c DROP INDEX C3;
+
+SET foreign_key_checks=0;
+ALTER TABLE t1c DROP INDEX C3;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+SET foreign_key_checks=1;
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+SHOW CREATE TABLE t1c;
+
+-- source suite/innodb/include/innodb_dict.inc
+
+ALTER TABLE t1c DROP FOREIGN KEY t1C3;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--list_files $MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+SHOW CREATE TABLE t1c;
+-- source suite/innodb/include/innodb_dict.inc
+
+ALTER TABLE t1c DROP INDEX c2, DROP FOREIGN KEY t1C2;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+SHOW CREATE TABLE t1c;
+
+-- source suite/innodb/include/innodb_dict.inc
+
+ALTER TABLE t1 DROP INDEX c2, CHANGE c3 c2 INT;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+-- source suite/innodb/include/innodb_dict.inc
+
+CREATE TABLE t1o LIKE t1;
+
+# This will implicitly add a DOC_ID column.
+# The LOCK=NONE should thus fail.
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE t1 ADD FULLTEXT INDEX (ct),
+CHANGE c1 pk INT, ALTER c2 SET DEFAULT 42, RENAME TO tt,
+ALGORITHM=INPLACE, LOCK=NONE;
+
+# Retry with LOCK=EXCLUSIVE.
+ALTER TABLE t1 ADD FULLTEXT INDEX (ct),
+CHANGE c1 pk INT, ALTER c2 SET DEFAULT 42, RENAME TO tt,
+ALGORITHM=INPLACE, LOCK=SHARED;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+# The output should be empty, because index->id was reassigned.
+-- source suite/innodb/include/innodb_dict.inc
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+SHOW CREATE TABLE tt;
+
+# DB_ROW_ID, DB_TRX_ID, DB_ROLL_PTR are reserved InnoDB system column names.
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o CHANGE c1 dB_row_Id INT, ALGORITHM=COPY;
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o CHANGE c1 dB_row_Id INT, ALGORITHM=INPLACE;
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o CHANGE c1 DB_TRX_ID INT;
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o CHANGE c1 db_roll_ptr INT;
+
+# FTS_DOC_ID is the internal row identifier for full-text search.
+# It should be of type BIGINT UNSIGNED NOT NULL.
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_DOC_ID INT,
+ALGORITHM=COPY;
+
+--error ER_INNODB_FT_WRONG_DOCID_COLUMN
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_DOC_ID INT,
+ALGORITHM=INPLACE;
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct), CHANGE c1 FTS_Doc_ID INT,
+ALGORITHM=INPLACE;
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct),
+CHANGE c1 FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE;
+
+CREATE TABLE t1n LIKE t1o;
+
+ALTER TABLE t1n ADD FULLTEXT INDEX(ct);
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1n CHANGE c1 Fts_DOC_ID INT, ALGORITHM=INPLACE;
+--error ER_WRONG_COLUMN_NAME
+ALTER TABLE t1n CHANGE c1 Fts_DOC_ID INT, ALGORITHM=COPY;
+--error ER_BAD_FIELD_ERROR
+ALTER TABLE t1n CHANGE FTS_DOC_ID c11 INT, ALGORITHM=INPLACE;
+ALTER TABLE t1n CHANGE c1 FTS_DOC_ïD INT, ALGORITHM=INPLACE;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+ALTER TABLE t1n CHANGE FTS_DOC_ÃD c1 INT, ALGORITHM=INPLACE;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+ALTER TABLE t1n CHANGE c1 c2 INT, CHANGE c2 ct INT, CHANGE ct c1 TEXT,
+ALGORITHM=INPLACE;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+SHOW CREATE TABLE t1n;
+ALTER TABLE t1n CHANGE c2 c1 INT, CHANGE ct c2 INT, CHANGE c1 ct TEXT,
+ALGORITHM=COPY;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+SHOW CREATE TABLE t1n;
+
+--error ER_KEY_COLUMN_DOES_NOT_EXITS
+ALTER TABLE t1n ADD INDEX(c2), CHANGE c2 c4 INT, ALGORITHM=INPLACE;
+--error ER_KEY_COLUMN_DOES_NOT_EXITS
+ALTER TABLE t1n ADD INDEX(c2), CHANGE c2 c4 INT, ALGORITHM=COPY;
+
+ALTER TABLE t1n ADD INDEX(c4), CHANGE c2 c4 INT, ALGORITHM=INPLACE;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+SHOW CREATE TABLE t1n;
+ALTER TABLE t1n DROP INDEX c4;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+--error ER_DUP_FIELDNAME
+ALTER TABLE t1n CHANGE c4 c1 INT, ADD INDEX(c1), ALGORITHM=INPLACE;
+ALTER TABLE t1n CHANGE c4 c11 INT, ADD INDEX(c11), ALGORITHM=INPLACE;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+SHOW CREATE TABLE t1n;
+DROP TABLE t1n;
+
+ALTER TABLE t1o MODIFY c1 BIGINT UNSIGNED NOT NULL;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+ALTER TABLE t1o ADD FULLTEXT INDEX(ct),
+CHANGE c1 FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
+ALGORITHM=INPLACE;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+# This would create a hidden FTS_DOC_ID column, which cannot be done online.
+--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
+LOCK=NONE;
+
+# This should not show duplicates.
+SELECT sc.pos FROM information_schema.innodb_sys_columns sc
+INNER JOIN information_schema.innodb_sys_tables st
+ON sc.TABLE_ID=st.TABLE_ID
+WHERE st.NAME='test/t1o' AND sc.NAME='FTS_DOC_ID';
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+SHOW CREATE TABLE t1o;
+
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
+DROP INDEX ct, LOCK=NONE;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+SHOW CREATE TABLE t1o;
+
+DROP TABLE t1c, t1p, sys_tables, sys_indexes, sys_foreign;
+
+# Check the internal schemata of tt, t1o.
+
+CREATE TABLE sys_tables SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
+WHERE NAME='test/t1o';
+CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+CREATE TABLE sys_foreign SELECT i.*
+FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN i WHERE FOR_NAME='test/t1o';
+
+-- source suite/innodb/include/innodb_dict.inc
+
+# Ensure that there exists no hidden FTS_DOC_ID_INDEX on foo_id.
+
+ALTER TABLE t1o ADD UNIQUE INDEX FTS_DOC_ID_INDEX(foo_id);
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+ALTER TABLE t1o CHANGE foo_id FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
+ADD FULLTEXT INDEX(ct);
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+
+--error ER_INNODB_FT_WRONG_DOCID_INDEX
+ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL;
+
+DROP TABLE sys_indexes;
+CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i
+INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
+
+-- source suite/innodb/include/innodb_dict.inc
+
+--echo #
+--echo # Cleanup
+--echo #
+
+DROP TABLE tt, t1o, sys_tables, sys_indexes, sys_foreign;
+
+--echo ### files in MYSQL_DATA_DIR/test
+--replace_regex $regexp
+--list_files $MYSQL_DATA_DIR/test
+--echo ### files in MYSQL_TMP_DIR/alt_dir/test
+--replace_regex $regexp
+--list_files $MYSQL_TMP_DIR/alt_dir/test
+--rmdir $MYSQL_TMP_DIR/alt_dir/test
+--rmdir $MYSQL_TMP_DIR/alt_dir
+
+-- disable_query_log
+eval set global innodb_file_per_table=$innodb_file_per_table_orig;
+call mtr.add_suppression("deleting orphaned .ibd file");
+-- enable_query_log
diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test
index 2e7306c8e29..087d0c6a7dc 100644
--- a/mysql-test/suite/innodb/t/innodb.test
+++ b/mysql-test/suite/innodb/t/innodb.test
@@ -1,18 +1,3 @@
-#######################################################################
-# #
-# 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). #
-# #
-#######################################################################
-
-- source include/have_innodb.inc
-- source include/have_innodb_16k.inc
@@ -20,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
@@ -2530,17 +2519,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_corrupt_bit.test b/mysql-test/suite/innodb/t/innodb_corrupt_bit.test
index ee04e8d66fc..86b604b4a6a 100644
--- a/mysql-test/suite/innodb/t/innodb_corrupt_bit.test
+++ b/mysql-test/suite/innodb/t/innodb_corrupt_bit.test
@@ -8,7 +8,8 @@
-- source include/have_debug.inc
-- disable_query_log
-call mtr.add_suppression("Flagged corruption of idx.*in");
+call mtr.add_suppression("Flagged corruption of idx.*in ");
+-- enable_query_log
set names utf8;
@@ -37,9 +38,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_dbug="+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_dbug="";
+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/log_data_file_size.test b/mysql-test/suite/innodb/t/log_data_file_size.test
index 2f1c497595b..75e38673f69 100644
--- a/mysql-test/suite/innodb/t/log_data_file_size.test
+++ b/mysql-test/suite/innodb/t/log_data_file_size.test
@@ -24,13 +24,13 @@ use Fcntl 'SEEK_CUR', 'SEEK_END';
my $page_size = $ENV{'INNODB_PAGE_SIZE'};
my $restart;
+open(FILE, "+<", "$ENV{'MYSQLD_DATADIR'}ibdata1") or die;
if ($ENV{'MYSQLD_IS_DEBUG'})
{
# It is impractical to ensure that CREATE TABLE t will extend ibdata1.
# We rely on innodb_system_tablespace_extend_debug=1
# to recover from this fault injection if no size change was redo-logged.
my $root = $ENV{'INNODB_ROOT_PAGE'};
- open(FILE, "+<", "$ENV{'MYSQLD_DATADIR'}ibdata1") or die;
my $size = sysseek(FILE, 0, SEEK_END) / $page_size;
seek(FILE, $page_size * ($root + 1), SEEK_SET) or die;
my $empty_tail= 1;
@@ -40,8 +40,22 @@ if ($ENV{'MYSQLD_IS_DEBUG'})
$restart = "--innodb-data-file-size-debug=$size";
truncate(FILE, $page_size * $root);
}
- close FILE;
}
+# Clear the doublewrite buffer entries for our tables.
+sysseek(FILE, 6 * $page_size - 190, 0)||die "Unable to seek ibdata1\n";
+sysread(FILE, $_, 12) == 12||die "Unable to read TRX_SYS\n";
+my($magic,$d1,$d2)=unpack "NNN", $_;
+die "magic=$magic, $d1, $d2\n" unless $magic == 536853855 && $d2 >= $d1 + 64;
+sysseek(FILE, $d1 * $page_size, 0)||die "Unable to seek ibdata1\n";
+# Find the pages in the doublewrite buffer
+for (my $d = $d1; $d < $d2 + 64; $d++) {
+ sysread(FILE, $_, $page_size)==$page_size||die "Cannot read doublewrite\n";
+ my($space_id,$offset)=unpack "x[4]Nx[26]N",$_;
+ next unless $space_id && $offset > 3;
+ sysseek(FILE, $d * $page_size, 0)||die "Unable to seek ibdata1\n";
+ syswrite(FILE, chr(0) x $page_size)==$page_size||die;
+}
+close FILE;
open(FILE, ">$ENV{MYSQLTEST_VARDIR}/log/start_mysqld.txt") || die;
print FILE "--let \$restart_parameters=$restart\n" if $restart;
print FILE "--source include/start_mysqld.inc\n";
@@ -51,6 +65,9 @@ truncate(FILE, $page_size * 4);
close FILE;
open(FILE, "+<", "$ENV{'MYSQLD_DATADIR'}test/ibd4f.ibd") or die;
truncate(FILE, $page_size * 4 + 1234);
+# Work around MDEV-12699 and ensure that the truncated page is all-zero.
+sysseek(FILE, $page_size * 4, 0);
+syswrite(FILE, chr(0) x 1234);
close FILE;
open(FILE, "+<", "$ENV{'MYSQLD_DATADIR'}test/ibd5.ibd") or die;
truncate(FILE, $page_size * 5);
diff --git a/mysql-test/suite/innodb/t/log_file_size.test b/mysql-test/suite/innodb/t/log_file_size.test
index 9cc7742f6a8..061bf35ccef 100644
--- a/mysql-test/suite/innodb/t/log_file_size.test
+++ b/mysql-test/suite/innodb/t/log_file_size.test
@@ -26,7 +26,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/read_only_recover_committed.test b/mysql-test/suite/innodb/t/read_only_recover_committed.test
new file mode 100644
index 00000000000..402cbeba1b9
--- /dev/null
+++ b/mysql-test/suite/innodb/t/read_only_recover_committed.test
@@ -0,0 +1,68 @@
+--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+
+--error ER_OPEN_AS_READONLY
+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/recovery_shutdown.test b/mysql-test/suite/innodb/t/recovery_shutdown.test
new file mode 100644
index 00000000000..42d98ca34c7
--- /dev/null
+++ b/mysql-test/suite/innodb/t/recovery_shutdown.test
@@ -0,0 +1,61 @@
+--source include/have_innodb.inc
+--source include/not_embedded.inc
+
+--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/table_definition_cache_debug.opt b/mysql-test/suite/innodb/t/table_definition_cache_debug.opt
new file mode 100644
index 00000000000..c2db7e1df6e
--- /dev/null
+++ b/mysql-test/suite/innodb/t/table_definition_cache_debug.opt
@@ -0,0 +1 @@
+--innodb-open-files=30
diff --git a/mysql-test/suite/innodb/t/table_definition_cache_debug.test b/mysql-test/suite/innodb/t/table_definition_cache_debug.test
new file mode 100644
index 00000000000..57d64d6844e
--- /dev/null
+++ b/mysql-test/suite/innodb/t/table_definition_cache_debug.test
@@ -0,0 +1,66 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+
+SET @save_tdc= @@GLOBAL.table_definition_cache;
+SET @save_toc= @@GLOBAL.table_open_cache;
+
+# InnoDB plugin essentially ignores table_definition_cache size
+# and hard-wires it to 400, which also is the minimum allowed value.
+SET GLOBAL table_definition_cache= 400;
+SET GLOBAL table_open_cache= 1024;
+
+CREATE TABLE to_be_evicted(a INT PRIMARY KEY, b INT NOT NULL) ENGINE=InnoDB;
+INSERT INTO to_be_evicted VALUES(1,2),(2,1);
+
+connect(ddl,localhost,root,,);
+SET DEBUG_SYNC = 'row_log_apply_before SIGNAL scanned WAIT_FOR got_duplicate';
+--send
+ALTER TABLE to_be_evicted ADD UNIQUE INDEX(b);
+
+connection default;
+SET DEBUG_SYNC = 'now WAIT_FOR scanned';
+
+# During the ADD UNIQUE INDEX, start a transaction that inserts a duplicate
+# and then hogs the table lock, so that the unique index cannot be dropped.
+BEGIN;
+INSERT INTO to_be_evicted VALUES(3, 2);
+SET DEBUG_SYNC = 'now SIGNAL got_duplicate';
+
+connection ddl;
+--error ER_DUP_ENTRY
+reap;
+
+disconnect ddl;
+connection default;
+# Release the table lock.
+COMMIT;
+SET DEBUG_SYNC = RESET;
+
+# Allow cache eviction.
+FLUSH TABLES;
+--disable_query_log
+
+# Pollute the cache with many tables, so that our table will be evicted.
+let $N=1000;
+let $loop=$N;
+while ($loop)
+{
+ eval CREATE TABLE t_$loop(id INT)ENGINE=InnoDB;
+ dec $loop;
+}
+
+# Hopefully let InnoDB evict the tables.
+sleep 10;
+
+let $loop=$N;
+while ($loop)
+{
+ eval DROP TABLE t_$loop;
+ dec $loop;
+}
+
+SET GLOBAL table_definition_cache= @save_tdc;
+SET GLOBAL table_open_cache= @save_toc;
+
+DROP TABLE to_be_evicted;
diff --git a/mysql-test/suite/innodb/t/undo_log.test b/mysql-test/suite/innodb/t/undo_log.test
new file mode 100644
index 00000000000..c1a98793d91
--- /dev/null
+++ b/mysql-test/suite/innodb/t/undo_log.test
@@ -0,0 +1,139 @@
+--source include/have_innodb.inc
+CREATE TABLE test_tab (
+a_str_18 mediumtext,
+b_str_3 varchar(32) DEFAULT NULL,
+a_str_13 mediumtext,
+b_str_5 varchar(40) DEFAULT NULL,
+b_str_6 varchar(50) DEFAULT NULL,
+b_str_7 char(32) DEFAULT NULL,
+b_str_8 varchar(32) DEFAULT NULL,
+b_str_9 varchar(255) DEFAULT NULL,
+a_str_28 char(255) DEFAULT NULL,
+a_str_27 varchar(255) DEFAULT NULL,
+b_str_10 varchar(32) DEFAULT NULL,
+a_str_26 varchar(255) DEFAULT NULL,
+a_str_6 varchar(50) DEFAULT NULL,
+b_str_11 varchar(32) DEFAULT NULL,
+b_str_12 varchar(255) DEFAULT NULL,
+b_str_13 char(32) DEFAULT NULL,
+b_str_14 varchar(32) DEFAULT NULL,
+b_str_15 char(32) DEFAULT NULL,
+b_str_16 char(32) DEFAULT NULL,
+b_str_17 varchar(32) DEFAULT NULL,
+b_str_18 varchar(32) DEFAULT NULL,
+a_str_25 varchar(40) DEFAULT NULL,
+b_str_19 varchar(255) DEFAULT NULL,
+a_str_23 varchar(40) DEFAULT NULL,
+b_str_20 varchar(32) DEFAULT NULL,
+a_str_21 varchar(255) DEFAULT NULL,
+a_str_20 varchar(255) DEFAULT NULL,
+a_str_39 varchar(255) DEFAULT NULL,
+a_str_38 varchar(255) DEFAULT NULL,
+a_str_37 varchar(255) DEFAULT NULL,
+b_str_21 char(32) DEFAULT NULL,
+b_str_23 varchar(80) DEFAULT NULL,
+b_str_24 varchar(32) DEFAULT NULL,
+b_str_25 varchar(32) DEFAULT NULL,
+b_str_26 char(32) NOT NULL DEFAULT '',
+b_str_27 varchar(255) DEFAULT NULL,
+a_str_36 varchar(255) DEFAULT NULL,
+a_str_33 varchar(100) DEFAULT NULL,
+a_ref_10 char(32) DEFAULT NULL,
+b_str_28 char(32) DEFAULT NULL,
+b_str_29 char(32) DEFAULT NULL,
+a_ref_6 char(32) DEFAULT NULL,
+a_ref_12 varchar(32) DEFAULT NULL,
+a_ref_11 varchar(32) DEFAULT NULL,
+a_str_49 varchar(40) DEFAULT NULL,
+b_str_30 varchar(32) DEFAULT NULL,
+a_ref_3 varchar(32) DEFAULT NULL,
+a_str_48 varchar(40) DEFAULT NULL,
+a_ref_1 char(32) DEFAULT NULL,
+b_str_31 varchar(32) DEFAULT NULL,
+b_str_32 varchar(255) DEFAULT NULL,
+b_str_33 char(32) DEFAULT NULL,
+b_str_34 varchar(32) DEFAULT NULL,
+a_str_47 varchar(40) DEFAULT NULL,
+b_str_36 varchar(255) DEFAULT NULL,
+a_str_46 varchar(40) DEFAULT NULL,
+a_str_45 varchar(255) DEFAULT NULL,
+b_str_38 varchar(32) DEFAULT NULL,
+b_str_39 char(32) DEFAULT NULL,
+b_str_40 varchar(32) DEFAULT NULL,
+a_str_41 varchar(255) DEFAULT NULL,
+b_str_41 varchar(32) DEFAULT NULL,
+PRIMARY KEY (b_str_26),
+UNIQUE KEY a_str_47 (a_str_47),
+UNIQUE KEY a_str_49 (a_str_49),
+UNIQUE KEY a_str_33 (a_str_33),
+UNIQUE KEY a_str_46 (a_str_46),
+UNIQUE KEY a_str_48 (a_str_48),
+KEY b_str_18 (b_str_18),
+KEY a_str_26 (a_str_26),
+KEY b_str_27 (b_str_27,b_str_19),
+KEY b_str_41 (b_str_41),
+KEY b_str_15 (b_str_15),
+KEY a_str_20 (a_str_20),
+KEY b_str_17 (b_str_17),
+KEY b_str_40 (b_str_40),
+KEY b_str_24 (b_str_24),
+KEY b_str_10 (b_str_10),
+KEY b_str_16 (b_str_16),
+KEY b_str_29 (b_str_29),
+KEY a_str_41 (a_str_41),
+KEY b_str_7 (b_str_7),
+KEY a_str_45 (a_str_45),
+KEY a_str_28 (a_str_28),
+KEY a_str_37 (a_str_37),
+KEY b_str_6 (b_str_6),
+KEY a_ref_6 (a_ref_6),
+KEY b_str_34 (b_str_34),
+KEY b_str_38 (b_str_38),
+KEY a_ref_10 (a_ref_10),
+KEY b_str_21 (b_str_21),
+KEY b_str_23 (b_str_23,b_str_19),
+KEY b_str_33 (b_str_33),
+KEY a_ref_12 (a_ref_12),
+KEY a_str_18 (a_str_18(255)),
+KEY a_str_39 (a_str_39),
+KEY a_str_27 (a_str_27),
+KEY a_str_25 (a_str_25),
+KEY b_str_9 (b_str_9),
+KEY a_str_23 (a_str_23),
+KEY b_str_8 (b_str_8),
+KEY a_str_21 (a_str_21),
+KEY b_str_3 (b_str_3),
+KEY b_str_30 (b_str_30),
+KEY b_str_12 (b_str_12),
+KEY b_str_25 (b_str_25),
+KEY b_str_13 (b_str_13),
+KEY a_str_38 (a_str_38),
+KEY a_str_13 (a_str_13(255)),
+KEY a_str_36 (a_str_36),
+KEY b_str_28 (b_str_28),
+KEY b_str_19 (b_str_19),
+KEY b_str_11 (b_str_11),
+KEY a_ref_1 (a_ref_1),
+KEY b_str_20 (b_str_20),
+KEY b_str_14 (b_str_14),
+KEY a_ref_3 (a_ref_3),
+KEY b_str_39 (b_str_39),
+KEY b_str_32 (b_str_32),
+KEY a_str_6 (a_str_6),
+KEY b_str_5 (b_str_5),
+KEY b_str_31 (b_str_31),
+KEY a_ref_11 (a_ref_11)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
+
+BEGIN;
+INSERT INTO test_tab (b_str_26, a_str_13, a_str_18) VALUES
+('a', REPEAT('f',4031), REPEAT('g', 4031));
+
+UPDATE test_tab SET a_str_13=REPEAT('h',4032), a_str_18=REPEAT('i',4032);
+SELECT 'Reducing length to 4030';
+UPDATE test_tab SET a_str_13=REPEAT('j',4030), a_str_18=REPEAT('k',4030);
+UPDATE test_tab SET a_str_13=REPEAT('l',4031), a_str_18=REPEAT('m',4031);
+ROLLBACK;
+SELECT COUNT(*) FROM test_tab;
+CHECK TABLE test_tab;
+DROP TABLE test_tab;
diff --git a/mysql-test/suite/innodb_fts/r/concurrent_insert.result b/mysql-test/suite/innodb_fts/r/concurrent_insert.result
new file mode 100644
index 00000000000..b9798ca1a74
--- /dev/null
+++ b/mysql-test/suite/innodb_fts/r/concurrent_insert.result
@@ -0,0 +1,8 @@
+CREATE TABLE t1(a VARCHAR(5),FULLTEXT KEY(a)) ENGINE=InnoDB;
+SET DEBUG_SYNC = 'get_next_FTS_DOC_ID SIGNAL prepared WAIT_FOR race';
+REPLACE INTO t1(a) values('aaa');
+SET DEBUG_SYNC = 'now WAIT_FOR prepared';
+REPLACE INTO t1(a) VALUES('aaa');
+SET DEBUG_SYNC = 'now SIGNAL race';
+SET DEBUG_SYNC = 'RESET';
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb_fts/r/fulltext.result b/mysql-test/suite/innodb_fts/r/fulltext.result
index 1cdce29cdf9..6802894e44b 100644
--- a/mysql-test/suite/innodb_fts/r/fulltext.result
+++ b/mysql-test/suite/innodb_fts/r/fulltext.result
@@ -1,4 +1,3 @@
-drop table if exists t1,t2,t3;
CREATE TABLE t1 (a VARCHAR(200), b TEXT, FULLTEXT (a,b)) ENGINE = InnoDB;
INSERT INTO t1 VALUES('MySQL has now support', 'for full-text search'),
('Full-text indexes', 'are called collections'),
@@ -637,3 +636,58 @@ EXECUTE stmt;
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
End of 5.1 tests
+CREATE TABLE z(a INTEGER) engine=innodb;
+CREATE TABLE q(b TEXT CHARSET latin1, fulltext(b)) engine=innodb;
+EXPLAIN SELECT 1 FROM q WHERE (SELECT MATCH(b) AGAINST ('*') FROM z);
+ERROR 42000: syntax error, unexpected $end, expecting FTS_TERM or FTS_NUMB or '*'
+SELECT 1 FROM q WHERE (SELECT MATCH(b) AGAINST ('*') FROM z);
+ERROR 42000: syntax error, unexpected $end, expecting FTS_TERM or FTS_NUMB or '*'
+EXPLAIN SELECT MATCH(b) AGAINST ('*') FROM z;
+ERROR 42S22: Unknown column 'b' in 'field list'
+SELECT MATCH(b) AGAINST ('*') FROM z;
+ERROR 42S22: Unknown column 'b' in 'field list'
+EXPLAIN SELECT MATCH(a) AGAINST ('*') FROM z;
+ERROR HY000: Can't find FULLTEXT index matching the column list
+SELECT MATCH(a) AGAINST ('*') FROM z;
+ERROR HY000: Can't find FULLTEXT index matching the column list
+EXPLAIN SELECT MATCH(b) AGAINST ('*') FROM q;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE q ALL NULL NULL NULL NULL 1
+SELECT MATCH(b) AGAINST ('*') FROM q;
+ERROR 42000: syntax error, unexpected $end, expecting FTS_TERM or FTS_NUMB or '*'
+DROP TABLE z, q;
+create table t (
+FTS_DOC_ID BIGINT UNSIGNED PRIMARY KEY, t TEXT, FULLTEXT KEY (t)
+) ENGINE=InnoDB;
+INSERT INTO t values (1, 'foo bar'), (2, 'foo bar'), (3, 'foo');
+SELECT * FROM t WHERE MATCH(t) AGAINST ('foo bar' IN BOOLEAN MODE)
+LIMIT 0;
+FTS_DOC_ID t
+SELECT * FROM t WHERE MATCH(t) AGAINST ('foo bar' IN BOOLEAN MODE)
+LIMIT 1;
+FTS_DOC_ID t
+1 foo bar
+SELECT * FROM t WHERE MATCH(t) AGAINST ('foo bar' IN BOOLEAN MODE)
+LIMIT 2;
+FTS_DOC_ID t
+1 foo bar
+2 foo bar
+SELECT * FROM t WHERE MATCH(t) AGAINST ('foo bar' IN BOOLEAN MODE)
+LIMIT 3;
+FTS_DOC_ID t
+1 foo bar
+2 foo bar
+3 foo
+SELECT * FROM t WHERE MATCH(t) AGAINST ('foo bar' IN BOOLEAN MODE)
+LIMIT 4;
+FTS_DOC_ID t
+1 foo bar
+2 foo bar
+3 foo
+SELECT * FROM t WHERE MATCH(t) AGAINST ('foo bar' IN BOOLEAN MODE)
+LIMIT 5;
+FTS_DOC_ID t
+1 foo bar
+2 foo bar
+3 foo
+DROP TABLE t;
diff --git a/mysql-test/suite/innodb_fts/t/concurrent_insert.test b/mysql-test/suite/innodb_fts/t/concurrent_insert.test
new file mode 100644
index 00000000000..e5d61cd8b05
--- /dev/null
+++ b/mysql-test/suite/innodb_fts/t/concurrent_insert.test
@@ -0,0 +1,20 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+
+CREATE TABLE t1(a VARCHAR(5),FULLTEXT KEY(a)) ENGINE=InnoDB;
+SET DEBUG_SYNC = 'get_next_FTS_DOC_ID SIGNAL prepared WAIT_FOR race';
+--send
+REPLACE INTO t1(a) values('aaa');
+
+connect(dml, localhost, root, ,);
+SET DEBUG_SYNC = 'now WAIT_FOR prepared';
+REPLACE INTO t1(a) VALUES('aaa');
+SET DEBUG_SYNC = 'now SIGNAL race';
+disconnect dml;
+
+connection default;
+reap;
+SET DEBUG_SYNC = 'RESET';
+
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb_fts/t/fulltext.test b/mysql-test/suite/innodb_fts/t/fulltext.test
index 90d5d5c71e0..663b202265b 100644
--- a/mysql-test/suite/innodb_fts/t/fulltext.test
+++ b/mysql-test/suite/innodb_fts/t/fulltext.test
@@ -4,10 +4,6 @@
--source include/have_innodb.inc
---disable_warnings
-drop table if exists t1,t2,t3;
---enable_warnings
-
CREATE TABLE t1 (a VARCHAR(200), b TEXT, FULLTEXT (a,b)) ENGINE = InnoDB;
INSERT INTO t1 VALUES('MySQL has now support', 'for full-text search'),
('Full-text indexes', 'are called collections'),
@@ -679,3 +675,45 @@ DEALLOCATE PREPARE stmt;
DROP TABLE t1;
--echo End of 5.1 tests
+
+# This is an adapted and extended version of an Oracle test for
+# Bug#21140111: Explain ... match against: Assertion failed: ret ...
+# No bug was repeatable for MariaDB.
+
+CREATE TABLE z(a INTEGER) engine=innodb;
+CREATE TABLE q(b TEXT CHARSET latin1, fulltext(b)) engine=innodb;
+
+--error ER_PARSE_ERROR
+EXPLAIN SELECT 1 FROM q WHERE (SELECT MATCH(b) AGAINST ('*') FROM z);
+--error ER_PARSE_ERROR
+SELECT 1 FROM q WHERE (SELECT MATCH(b) AGAINST ('*') FROM z);
+--error ER_BAD_FIELD_ERROR
+EXPLAIN SELECT MATCH(b) AGAINST ('*') FROM z;
+--error ER_BAD_FIELD_ERROR
+SELECT MATCH(b) AGAINST ('*') FROM z;
+--error ER_FT_MATCHING_KEY_NOT_FOUND
+EXPLAIN SELECT MATCH(a) AGAINST ('*') FROM z;
+--error ER_FT_MATCHING_KEY_NOT_FOUND
+SELECT MATCH(a) AGAINST ('*') FROM z;
+EXPLAIN SELECT MATCH(b) AGAINST ('*') FROM q;
+--error ER_PARSE_ERROR
+SELECT MATCH(b) AGAINST ('*') FROM q;
+
+DROP TABLE z, q;
+
+create table t (
+ FTS_DOC_ID BIGINT UNSIGNED PRIMARY KEY, t TEXT, FULLTEXT KEY (t)
+) ENGINE=InnoDB;
+
+INSERT INTO t values (1, 'foo bar'), (2, 'foo bar'), (3, 'foo');
+let $limit=0;
+let $N=6;
+while ($N)
+{
+ eval SELECT * FROM t WHERE MATCH(t) AGAINST ('foo bar' IN BOOLEAN MODE)
+ LIMIT $limit;
+ inc $limit;
+ dec $N;
+}
+
+DROP TABLE t;
diff --git a/mysql-test/suite/innodb_zip/r/innodb_prefix_index_liftedlimit.result b/mysql-test/suite/innodb_zip/r/innodb_prefix_index_liftedlimit.result
index ccfd8a16710..474d36ea044 100644
--- a/mysql-test/suite/innodb_zip/r/innodb_prefix_index_liftedlimit.result
+++ b/mysql-test/suite/innodb_zip/r/innodb_prefix_index_liftedlimit.result
@@ -584,12 +584,12 @@ 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);
-ERROR HY000: Undo log record is too big.
SHOW WARNINGS;
Level Code Message
-Error 1713 Undo log record is too big.
+ROLLBACK;
DROP TABLE worklog5743;
CREATE TABLE worklog5743 (
col_1_varbinary VARBINARY (4000) , col_2_varchar VARCHAR (4000) ,
@@ -627,13 +627,13 @@ 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);
-ERROR HY000: Undo log record is too big.
SHOW WARNINGS;
Level Code Message
-Error 1713 Undo log record is too big.
+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)
diff --git a/mysql-test/suite/innodb/r/innodb-wl5522-debug-zip.result b/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result
index b7a2666bfe6..a751736aba6 100644
--- a/mysql-test/suite/innodb/r/innodb-wl5522-debug-zip.result
+++ b/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result
@@ -1,14 +1,12 @@
+call mtr.add_suppression("InnoDB: Tablespace for table .* is set as discarded.");
+call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* because the .ibd file is missing. Please refer to .* for how to resolve the issue.");
+call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file .*");
call mtr.add_suppression("InnoDB: Page for tablespace ");
call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=0x");
-call mtr.add_suppression("InnoDB: Corruption: Block in space_id .* in file .* corrupted");
-call mtr.add_suppression("InnoDB: Based on page type .*");
FLUSH TABLES;
-SET GLOBAL innodb_file_per_table = 1;
-SET GLOBAL innodb_file_format = `Barracuda`;
+SET GLOBAL innodb_file_per_table=1;
+SET GLOBAL innodb_file_format=Barracuda;
SET SESSION innodb_strict_mode=1;
-DROP DATABASE IF EXISTS test_wl5522;
-Warnings:
-Note 1008 Can't drop database 'test_wl5522'; database doesn't exist
CREATE DATABASE test_wl5522;
CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb
ROW_FORMAT=COMPRESSED;
@@ -38,9 +36,11 @@ unlink: t1.ibd
unlink: t1.cfg
# Restart and reconnect to the server
DROP TABLE test_wl5522.t1;
-SET GLOBAL innodb_file_per_table = 1;
-SET GLOBAL innodb_file_format = `Barracuda`;
SET SESSION innodb_strict_mode=1;
+SET @file_per_table = @@GLOBAL.innodb_file_per_table;
+SET @file_format = @@GLOBAL.innodb_file_format;
+SET GLOBAL innodb_file_per_table=1;
+SET GLOBAL innodb_file_format=Barracuda;
CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb
ROW_FORMAT=COMPRESSED;
ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE;
@@ -128,8 +128,8 @@ c4 VARCHAR(2048),
INDEX idx1(c2),
INDEX idx2(c3(512)),
INDEX idx3(c4(512))) Engine=InnoDB
-ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
-SET GLOBAL INNODB_PURGE_STOP_NOW=ON;
+ROW_FORMAT=COMPRESSED;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
SET GLOBAL innodb_disable_background_merge=ON;
SET GLOBAL innodb_monitor_reset = ibuf_merges;
SET GLOBAL innodb_monitor_reset = ibuf_merges_insert;
@@ -172,7 +172,7 @@ t1 CREATE TABLE `t1` (
KEY `idx1` (`c2`),
KEY `idx2` (`c3`(512)),
KEY `idx3` (`c4`(512))
-) ENGINE=InnoDB AUTO_INCREMENT=248 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8
+) ENGINE=InnoDB AUTO_INCREMENT=248 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED
SELECT c1, c2 FROM test_wl5522.t1;
c1 c2
2 32
@@ -294,7 +294,7 @@ FROM information_schema.innodb_metrics
WHERE name = 'ibuf_merges_inserts' AND count > 0;
name
SET GLOBAL innodb_disable_background_merge=OFF;
-SET GLOBAL INNODB_PURGE_RUN_NOW=ON;
+COMMIT;
DROP TABLE test_wl5522.t1;
CREATE TABLE test_wl5522.t1 (
c1 BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
@@ -304,7 +304,7 @@ c4 VARCHAR(2048),
INDEX idx1(c2),
INDEX idx2(c3(512)),
INDEX idx3(c4(512))) Engine=InnoDB
-ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
+ROW_FORMAT=COMPRESSED;
SELECT c1, c2 FROM test_wl5522.t1;
c1 c2
ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE;
@@ -428,11 +428,11 @@ t1 CREATE TABLE `t1` (
KEY `idx1` (`c2`),
KEY `idx2` (`c3`(512)),
KEY `idx3` (`c4`(512))
-) ENGINE=InnoDB AUTO_INCREMENT=185 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8
+) ENGINE=InnoDB AUTO_INCREMENT=185 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED
DROP TABLE test_wl5522.t1;
CREATE TABLE test_wl5522.t1 (c1 INT, c2 VARCHAR(1024), c3 BLOB) ENGINE = Innodb
ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
-INSERT INTO test_wl5522.t1 VALUES
+INSERT IGNORE INTO test_wl5522.t1 VALUES
(100, REPEAT('Karanbir', 899), REPEAT('Ajeeth', 1200));
Warnings:
Warning 1265 Data truncated for column 'c2' at row 1
@@ -470,8 +470,9 @@ ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE;
SELECT COUNT(*) FROM test_wl5522.t1;
ERROR HY000: Tablespace has been discarded for table 't1'
restore: t1 .ibd and .cfg files
-SET SESSION debug_dbug="+d,buf_page_is_corrupt_failure";
+SET SESSION debug_dbug="+d,buf_page_import_corrupt_failure";
ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
+ERROR HY000: Internal error: Cannot reset LSNs in table '"test_wl5522"."t1"' : Data structure corruption
SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
unlink: t1.ibd
@@ -561,5 +562,5 @@ set global innodb_monitor_enable = default;
set global innodb_monitor_disable = default;
set global innodb_monitor_reset = default;
set global innodb_monitor_reset_all = default;
-SET GLOBAL INNODB_FILE_PER_TABLE=1;
-SET GLOBAL INNODB_FILE_FORMAT=Antelope;
+SET GLOBAL innodb_file_per_table = @file_per_table;
+SET GLOBAL innodb_file_format = @file_format;
diff --git a/mysql-test/suite/innodb_zip/t/innodb_prefix_index_liftedlimit.test b/mysql-test/suite/innodb_zip/t/innodb_prefix_index_liftedlimit.test
index 541c0e119be..87f2fd3f467 100644
--- a/mysql-test/suite/innodb_zip/t/innodb_prefix_index_liftedlimit.test
+++ b/mysql-test/suite/innodb_zip/t/innodb_prefix_index_liftedlimit.test
@@ -536,10 +536,11 @@ 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));
---error ER_UNDO_RECORD_TOO_BIG
+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;
#------------------------------------------------------------------------------
@@ -585,13 +586,12 @@ REPEAT("a", 4000) , REPEAT("o", 4000), REPEAT("a", 4000),
REPEAT("a", 4000) , REPEAT("a", 255)
);
ROLLBACK;
-# Bug#12547647 - UPDATE LOGGING COULD EXCEED LOG PAGE SIZE
-# Instead of this error, it would hang before this fix.
---error ER_UNDO_RECORD_TOO_BIG
+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),
diff --git a/mysql-test/suite/innodb/t/innodb-wl5522-debug-zip.test b/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test
index c48b81a5a56..65b030c018f 100644
--- a/mysql-test/suite/innodb/t/innodb-wl5522-debug-zip.test
+++ b/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test
@@ -1,39 +1,32 @@
-# Not supported in embedded
+# mysql-test-run.pl --embedded cannot restart the server.
--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.
+# Valgrind can hang or return spurious messages on DBUG_SUICIDE
--source include/not_valgrind.inc
# Avoid CrashReporter popup on Mac
--source include/not_crashrep.inc
--- source include/have_innodb.inc
-
-# compressed table in tests are with sizes KEY_BLOCK_SIZE 1,2,4,8,16
-# Table creatation fails if KEY_BLOCK_SIZE > innodb-page-size,so
-# allow test to run only when innodb-page-size=16
---source include/have_innodb_16k.inc
+-- source include/innodb_page_size_small.inc
+call mtr.add_suppression("InnoDB: Tablespace for table .* is set as discarded.");
+call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* because the .ibd file is missing. Please refer to .* for how to resolve the issue.");
+call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file .*");
call mtr.add_suppression("InnoDB: Page for tablespace ");
call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=0x");
-call mtr.add_suppression("InnoDB: Corruption: Block in space_id .* in file .* corrupted");
-call mtr.add_suppression("InnoDB: Based on page type .*");
FLUSH TABLES;
+SET GLOBAL innodb_file_per_table=1;
+SET GLOBAL innodb_file_format=Barracuda;
+
let MYSQLD_DATADIR =`SELECT @@datadir`;
-let $innodb_file_per_table = `SELECT @@innodb_file_per_table`;
-let $innodb_file_format = `SELECT @@innodb_file_format`;
let $pathfix=/: '.*test_wl5522.*t1.ibd'/: 'test_wl5522_t1.ibd'/;
-SET GLOBAL innodb_file_per_table = 1;
-
-SET GLOBAL innodb_file_format = `Barracuda`;
SET SESSION innodb_strict_mode=1;
-DROP DATABASE IF EXISTS test_wl5522;
CREATE DATABASE test_wl5522;
# Create the table that we will use for crash recovery (during IMPORT)
@@ -46,7 +39,7 @@ INSERT INTO test_wl5522.t1 VALUES (1), (2), (3), (4);
FLUSH TABLES test_wl5522.t1 FOR EXPORT;
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_backup_tablespaces("test_wl5522", "t1");
EOF
UNLOCK TABLES;
@@ -60,7 +53,7 @@ INSERT INTO test_wl5522.t1 VALUES (1);
ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE;
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_discard_tablespaces("test_wl5522", "t1");
EOF
@@ -69,7 +62,7 @@ SELECT COUNT(*) FROM test_wl5522.t1;
# Restore files
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
@@ -112,7 +105,7 @@ ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
# recreate the table and do a proper import.
-- source include/wait_until_disconnected.inc
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_unlink_tablespace("test_wl5522", "t1");
EOF
@@ -129,10 +122,12 @@ EOF
DROP TABLE test_wl5522.t1;
-SET GLOBAL innodb_file_per_table = 1;
-SET GLOBAL innodb_file_format = `Barracuda`;
-
SET SESSION innodb_strict_mode=1;
+SET @file_per_table = @@GLOBAL.innodb_file_per_table;
+SET @file_format = @@GLOBAL.innodb_file_format;
+
+SET GLOBAL innodb_file_per_table=1;
+SET GLOBAL innodb_file_format=Barracuda;
CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb
ROW_FORMAT=COMPRESSED;
@@ -140,7 +135,7 @@ ROW_FORMAT=COMPRESSED;
ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE;
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
@@ -166,7 +161,7 @@ SELECT COUNT(*) FROM test_wl5522.t1;
# Restore files
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
@@ -183,7 +178,7 @@ SET SESSION debug_dbug=@saved_debug_dbug;
# Restore files
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
@@ -203,7 +198,7 @@ SELECT COUNT(*) FROM test_wl5522.t1;
# Restore files
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
@@ -217,7 +212,7 @@ ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
# Restore files
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
@@ -234,7 +229,7 @@ SET SESSION debug_dbug=@saved_debug_dbug;
# Restore files
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
@@ -249,7 +244,7 @@ SET SESSION debug_dbug=@saved_debug_dbug;
# Restore files
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
@@ -263,7 +258,7 @@ SET SESSION debug_dbug=@saved_debug_dbug;
# Restore files
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
@@ -277,7 +272,7 @@ SET SESSION debug_dbug=@saved_debug_dbug;
# Restore files
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
@@ -291,7 +286,7 @@ SET SESSION debug_dbug=@saved_debug_dbug;
# Restore files
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
@@ -305,7 +300,7 @@ SET SESSION debug_dbug=@saved_debug_dbug;
# Left over from the failed IMPORT
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_unlink_tablespace("test_wl5522", "t1");
EOF
@@ -331,10 +326,12 @@ CREATE TABLE test_wl5522.t1 (
INDEX idx1(c2),
INDEX idx2(c3(512)),
INDEX idx3(c4(512))) Engine=InnoDB
- ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
+ ROW_FORMAT=COMPRESSED;
# Stop purge so that it doesn't remove the delete marked entries.
-SET GLOBAL INNODB_PURGE_STOP_NOW=ON;
+connect (purge_control,localhost,root);
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+connection default;
# Disable change buffer merge from the master thread, additionally
# enable aggressive flushing so that more changes are buffered.
@@ -387,7 +384,7 @@ SELECT name
FLUSH TABLES test_wl5522.t1 FOR EXPORT;
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_backup_tablespaces("test_wl5522", "t1");
EOF
@@ -404,7 +401,10 @@ SELECT name
SET GLOBAL innodb_disable_background_merge=OFF;
# Enable normal operation
-SET GLOBAL INNODB_PURGE_RUN_NOW=ON;
+connection purge_control;
+COMMIT;
+disconnect purge_control;
+connection default;
DROP TABLE test_wl5522.t1;
@@ -416,14 +416,14 @@ CREATE TABLE test_wl5522.t1 (
INDEX idx1(c2),
INDEX idx2(c3(512)),
INDEX idx3(c4(512))) Engine=InnoDB
- ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
+ ROW_FORMAT=COMPRESSED;
SELECT c1, c2 FROM test_wl5522.t1;
ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE;
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
@@ -444,7 +444,7 @@ DROP TABLE test_wl5522.t1;
CREATE TABLE test_wl5522.t1 (c1 INT, c2 VARCHAR(1024), c3 BLOB) ENGINE = Innodb
ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
-INSERT INTO test_wl5522.t1 VALUES
+INSERT IGNORE INTO test_wl5522.t1 VALUES
(100, REPEAT('Karanbir', 899), REPEAT('Ajeeth', 1200));
INSERT INTO test_wl5522.t1 SELECT * FROM test_wl5522.t1;
@@ -459,7 +459,7 @@ SELECT COUNT(*) FROM test_wl5522.t1;
FLUSH TABLES test_wl5522.t1 FOR EXPORT;
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_backup_tablespaces("test_wl5522", "t1");
EOF
@@ -477,7 +477,7 @@ SELECT COUNT(*) FROM test_wl5522.t1;
# Restore files
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
@@ -493,7 +493,7 @@ SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_unlink_tablespace("test_wl5522", "t1");
EOF
@@ -509,16 +509,16 @@ SELECT COUNT(*) FROM test_wl5522.t1;
# Restore files
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
-SET SESSION debug_dbug="+d,buf_page_is_corrupt_failure";
+SET SESSION debug_dbug="+d,buf_page_import_corrupt_failure";
--replace_regex /'.*t1.cfg'/'t1.cfg'/
-# Following alter is not failing
-#--error ER_INTERNAL_ERROR
+# Following alter is failing
+--error ER_INTERNAL_ERROR
ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE;
SET SESSION debug_dbug=@saved_debug_dbug;
@@ -526,7 +526,7 @@ SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_unlink_tablespace("test_wl5522", "t1");
EOF
@@ -540,7 +540,7 @@ SELECT COUNT(*) FROM test_wl5522.t1;
# Restore files
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
@@ -556,7 +556,7 @@ SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_unlink_tablespace("test_wl5522", "t1");
EOF
@@ -570,7 +570,7 @@ SELECT COUNT(*) FROM test_wl5522.t1;
# Restore files
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
@@ -586,7 +586,7 @@ SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_unlink_tablespace("test_wl5522", "t1");
EOF
@@ -607,7 +607,7 @@ SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_unlink_tablespace("test_wl5522", "t1");
EOF
@@ -623,7 +623,7 @@ SELECT COUNT(*) FROM test_wl5522.t1;
# Restore files
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
@@ -638,7 +638,7 @@ SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_unlink_tablespace("test_wl5522", "t1");
EOF
@@ -654,7 +654,7 @@ SELECT COUNT(*) FROM test_wl5522.t1;
# Restore files
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
@@ -669,7 +669,7 @@ SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_unlink_tablespace("test_wl5522", "t1");
EOF
@@ -685,7 +685,7 @@ SELECT COUNT(*) FROM test_wl5522.t1;
# Restore files
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_restore_tablespaces("test_wl5522", "t1");
EOF
@@ -701,7 +701,7 @@ SET SESSION debug_dbug=@saved_debug_dbug;
DROP TABLE test_wl5522.t1;
perl;
-do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
ib_unlink_tablespace("test_wl5522", "t1");
EOF
@@ -736,11 +736,12 @@ call mtr.add_suppression("t1.ibd: Page .* at offset .* looks corrupted");
call mtr.add_suppression("but tablespace with that id or name does not exist");
call mtr.add_suppression("Failed to find tablespace for table '\"test_wl5522\".\"t1\"' in the cache");
call mtr.add_suppression("Could not find a valid tablespace file for 'test_wl5522.*t1'");
+call mtr.add_suppression("Index for table 't1' is corrupt; try to repair it");
--enable_query_log
#cleanup
--remove_file $MYSQLTEST_VARDIR/tmp/t1.cfg
--remove_file $MYSQLTEST_VARDIR/tmp/t1.ibd
-eval SET GLOBAL INNODB_FILE_PER_TABLE=$innodb_file_per_table;
-eval SET GLOBAL INNODB_FILE_FORMAT=$innodb_file_format;
+SET GLOBAL innodb_file_per_table = @file_per_table;
+SET GLOBAL innodb_file_format = @file_format;
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 d410944ddb2..8078687dad5 100644
--- a/mysql-test/suite/maria/maria.result
+++ b/mysql-test/suite/maria/maria.result
@@ -1595,7 +1595,14 @@ t1 CREATE TABLE `t1` (
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0
drop table t1;
create table t1 (v varchar(65535));
-ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
+Warnings:
+Note 1246 Converting column 'v' from VARCHAR to TEXT
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` text
+) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0
+drop table t1;
set @save_concurrent_insert=@@concurrent_insert;
set global concurrent_insert=1;
create table t1 (a int) ROW_FORMAT=FIXED;
@@ -2689,6 +2696,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 df73c8d8199..27e9a45fda7 100644
--- a/mysql-test/suite/maria/maria.test
+++ b/mysql-test/suite/maria/maria.test
@@ -927,8 +927,9 @@ show create table t1;
drop table t1;
# ARIA specific varchar tests
---error 1118
create table t1 (v varchar(65535));
+show create table t1;
+drop table t1;
#
# Test concurrent insert
@@ -1967,6 +1968,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/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
new file mode 100644
index 00000000000..f724d1d1fdc
--- /dev/null
+++ b/mysql-test/suite/mariabackup/apply-log-only-incr.result
@@ -0,0 +1,33 @@
+call mtr.add_suppression("InnoDB: New log files created");
+CREATE TABLE t(a INT UNSIGNED PRIMARY KEY) ENGINE INNODB;
+INSERT INTO t VALUES(0);
+COMMIT;
+start transaction;
+BEGIN;
+DELETE FROM t LIMIT 1;
+SET GLOBAL innodb_flush_log_at_trx_commit = 1;
+ROLLBACK;
+NOT FOUND /Rollback of trx with id/ in current_test
+# expect NOT FOUND
+NOT FOUND /Rollback of trx with id/ in current_test
+# expect NOT FOUND
+commit;
+SELECT count(*) FROM t;
+count(*)
+201
+# Restore and check results
+# shutdown server
+# remove datadir
+# xtrabackup move back
+# restart server
+SELECT COUNT(*) FROM t;
+COUNT(*)
+1
+SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+SELECT COUNT(*) FROM t;
+COUNT(*)
+201
+SELECT * FROM t;
+a
+0
+DROP TABLE t;
diff --git a/mysql-test/suite/mariabackup/apply-log-only-incr.test b/mysql-test/suite/mariabackup/apply-log-only-incr.test
new file mode 100644
index 00000000000..81c91d3c452
--- /dev/null
+++ b/mysql-test/suite/mariabackup/apply-log-only-incr.test
@@ -0,0 +1,70 @@
+--source include/have_innodb.inc
+
+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 INT UNSIGNED PRIMARY KEY) ENGINE INNODB;
+INSERT INTO t VALUES(0);
+COMMIT;
+
+start transaction;
+--disable_query_log
+let $n=100;
+while ($n) {
+eval INSERT t VALUES(101-$n);
+dec $n;
+}
+
+--disable_result_log
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir;
+--enable_result_log
+let $n=100;
+while ($n) {
+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 ;
+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
+--source include/search_pattern_in_file.inc
+--echo # expect NOT FOUND
+
+exec $XTRABACKUP --prepare --apply-log-only --target-dir=$basedir --incremental-dir=$incremental_dir ;
+
+--source include/search_pattern_in_file.inc
+--echo # expect NOT FOUND
+
+commit;
+SELECT count(*) FROM t;
+echo # Restore and check results;
+--let $targetdir=$basedir
+--let $restart_parameters= --innodb-force-recovery=3
+--source include/restart_and_restore.inc
+
+rmdir $basedir;
+rmdir $incremental_dir;
+
+SELECT COUNT(*) FROM t;
+SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+SELECT COUNT(*) FROM t;
+
+--let $restart_parameters=
+--source include/restart_mysqld.inc
+
+SELECT * FROM t;
+DROP TABLE t;
diff --git a/mysql-test/suite/mariabackup/apply-log-only.result b/mysql-test/suite/mariabackup/apply-log-only.result
new file mode 100644
index 00000000000..04b9c0d8ee2
--- /dev/null
+++ b/mysql-test/suite/mariabackup/apply-log-only.result
@@ -0,0 +1,10 @@
+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
+# expect NOT FOUND
+SELECT count(*) FROM t;
+count(*)
+1
+DROP TABLE t;
diff --git a/mysql-test/suite/mariabackup/apply-log-only.test b/mysql-test/suite/mariabackup/apply-log-only.test
new file mode 100644
index 00000000000..96a251fc03b
--- /dev/null
+++ b/mysql-test/suite/mariabackup/apply-log-only.test
@@ -0,0 +1,25 @@
+--source include/have_innodb.inc
+call mtr.add_suppression("InnoDB: New log files created");
+
+let $basedir=$MYSQLTEST_VARDIR/tmp/backup;
+
+CREATE TABLE t(a varchar(60)) ENGINE INNODB;
+start transaction;
+INSERT INTO t VALUES(1);
+
+--disable_result_log
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir;
+--enable_result_log
+
+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
+--source include/search_pattern_in_file.inc
+--echo # expect NOT FOUND
+
+SELECT count(*) FROM t;
+DROP TABLE t;
+
+# Cleanup
+rmdir $basedir;
diff --git a/mysql-test/suite/mariabackup/compress_qpress.result b/mysql-test/suite/mariabackup/compress_qpress.result
new file mode 100644
index 00000000000..f8dfb46e4db
--- /dev/null
+++ b/mysql-test/suite/mariabackup/compress_qpress.result
@@ -0,0 +1,15 @@
+CREATE TABLE t(i INT) ENGINE INNODB;
+INSERT INTO t VALUES(1);
+# xtrabackup backup
+INSERT INTO t VALUES(2);
+# xtrabackup prepare
+t.frm.qp
+t.ibd.qp
+# shutdown server
+# remove datadir
+# xtrabackup move back
+# restart server
+SELECT * FROM t;
+i
+1
+DROP TABLE t;
diff --git a/mysql-test/suite/mariabackup/compress_qpress.test b/mysql-test/suite/mariabackup/compress_qpress.test
new file mode 100644
index 00000000000..f86efe44e5d
--- /dev/null
+++ b/mysql-test/suite/mariabackup/compress_qpress.test
@@ -0,0 +1,24 @@
+CREATE TABLE t(i INT) ENGINE INNODB;
+INSERT INTO t VALUES(1);
+echo # xtrabackup backup;
+let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
+
+--disable_result_log
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --compress --target-dir=$targetdir;
+--enable_result_log
+
+INSERT INTO t VALUES(2);
+
+
+echo # xtrabackup prepare;
+--disable_result_log
+list_files $targetdir/test *.qp;
+exec $XTRABACKUP --decompress --remove-original --target-dir=$targetdir;
+list_files $targetdir/test *.qp;
+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/data_directory.result b/mysql-test/suite/mariabackup/data_directory.result
new file mode 100644
index 00000000000..e7201918cbd
--- /dev/null
+++ b/mysql-test/suite/mariabackup/data_directory.result
@@ -0,0 +1,13 @@
+CREATE TABLE t(a INT) ENGINE=InnoDB DATA DIRECTORY='table_data_dir';
+INSERT INTO t VALUES(1);
+# xtrabackup backup
+# xtrabackup prepare
+DROP TABLE t;
+# shutdown server
+# remove datadir
+# xtrabackup move back
+# restart server
+SELECT * FROM t;
+a
+1
+DROP TABLE t;
diff --git a/mysql-test/suite/mariabackup/data_directory.test b/mysql-test/suite/mariabackup/data_directory.test
new file mode 100644
index 00000000000..50789a34c78
--- /dev/null
+++ b/mysql-test/suite/mariabackup/data_directory.test
@@ -0,0 +1,23 @@
+let $table_data_dir=$MYSQLTEST_VARDIR/ddir;
+mkdir $table_data_dir;
+--replace_result $table_data_dir table_data_dir
+EVAL CREATE TABLE t(a INT) ENGINE=InnoDB DATA DIRECTORY='$table_data_dir';
+INSERT INTO t VALUES(1);
+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
+--source include/shutdown_mysqld.inc
+echo # xtrabackup prepare;
+--disable_result_log
+exec $XTRABACKUP --prepare --target-dir=$targetdir;
+--source include/start_mysqld.inc
+DROP TABLE t;
+rmdir $table_data_dir;
+-- source include/restart_and_restore.inc
+--enable_result_log
+SELECT * FROM t;
+DROP TABLE t;
+rmdir $targetdir;
+rmdir $table_data_dir;
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
new file mode 100644
index 00000000000..f2202c20968
--- /dev/null
+++ b/mysql-test/suite/mariabackup/huge_lsn.result
@@ -0,0 +1,19 @@
+#
+# MDEV-13416 mariabackup fails with EFAULT "Bad Address"
+#
+call mtr.add_suppression("InnoDB: New log files created");
+FOUND /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
+# remove datadir
+# xtrabackup move back
+# restart server
+SELECT * FROM t;
+i
+1
+DROP TABLE t;
diff --git a/mysql-test/suite/mariabackup/huge_lsn.test b/mysql-test/suite/mariabackup/huge_lsn.test
new file mode 100644
index 00000000000..baf577769c0
--- /dev/null
+++ b/mysql-test/suite/mariabackup/huge_lsn.test
@@ -0,0 +1,54 @@
+--source include/not_embedded.inc
+--source include/have_file_key_management.inc
+
+--echo #
+--echo # MDEV-13416 mariabackup fails with EFAULT "Bad Address"
+--echo #
+
+let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
+let MYSQLD_DATADIR=`select @@datadir`;
+call mtr.add_suppression("InnoDB: New log files created");
+
+--source include/shutdown_mysqld.inc
+
+perl;
+my $file= "$ENV{MYSQLD_DATADIR}/ibdata1";
+open(FILE, "+<", $file) or die "Unable to open $file\n";
+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, ~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";
+syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n";
+close(FILE) || die "Unable to close $file\n";
+EOF
+
+--remove_files_wildcard $MYSQLD_DATADIR ib_logfile*
+
+--source include/start_mysqld.inc
+let SEARCH_RANGE= -50000;
+let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
+--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;
+INSERT INTO t VALUES(1);
+
+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
+SET GLOBAL innodb_flush_log_at_trx_commit=1;
+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/incremental_backup.result b/mysql-test/suite/mariabackup/incremental_backup.result
index eeedc751d83..20d8cefbefb 100644
--- a/mysql-test/suite/mariabackup/incremental_backup.result
+++ b/mysql-test/suite/mariabackup/incremental_backup.result
@@ -1,8 +1,14 @@
call mtr.add_suppression("InnoDB: New log files created");
-CREATE TABLE t(i INT) ENGINE INNODB;
+CREATE TABLE t(i INT PRIMARY KEY) ENGINE INNODB;
+BEGIN;
+INSERT INTO t VALUES(2);
+SET GLOBAL innodb_flush_log_at_trx_commit = 1;
INSERT INTO t VALUES(1);
# Create full backup , modify table, then create incremental/differential backup
-INSERT INTO t VALUES(2);
+BEGIN;
+INSERT INTO t VALUES(0);
+DELETE FROM t WHERE i=0;
+COMMIT;
SELECT * FROM t;
i
1
diff --git a/mysql-test/suite/mariabackup/incremental_backup.test b/mysql-test/suite/mariabackup/incremental_backup.test
index b92d7b323ac..93582f047a7 100644
--- a/mysql-test/suite/mariabackup/incremental_backup.test
+++ b/mysql-test/suite/mariabackup/incremental_backup.test
@@ -4,23 +4,31 @@ 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(i INT) ENGINE INNODB;
+CREATE TABLE t(i INT PRIMARY KEY) ENGINE INNODB;
+BEGIN;
+INSERT INTO t VALUES(2);
+connect (con1,localhost,root,,);
+SET GLOBAL innodb_flush_log_at_trx_commit = 1;
INSERT INTO t VALUES(1);
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
-INSERT INTO t VALUES(2);
+BEGIN;
+INSERT INTO t VALUES(0);
+DELETE FROM t WHERE i=0;
+connection default;
+COMMIT;
SELECT * 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 --target-dir=$basedir --incremental-dir=$incremental_dir ;
+exec $XTRABACKUP --prepare --apply-log-only --target-dir=$basedir --incremental-dir=$incremental_dir ;
+disconnect con1;
echo # Restore and check results;
let $targetdir=$basedir;
-- source include/restart_and_restore.inc
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..53ce397fd5e
--- /dev/null
+++ b/mysql-test/suite/mariabackup/missing_ibd.test
@@ -0,0 +1,27 @@
+--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`;
+
+--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/partition_datadir.opt b/mysql-test/suite/mariabackup/partition_datadir.opt
new file mode 100644
index 00000000000..8a3240370eb
--- /dev/null
+++ b/mysql-test/suite/mariabackup/partition_datadir.opt
@@ -0,0 +1 @@
+--partition \ No newline at end of file
diff --git a/mysql-test/suite/mariabackup/partition_datadir.result b/mysql-test/suite/mariabackup/partition_datadir.result
new file mode 100644
index 00000000000..3fc5fe30907
--- /dev/null
+++ b/mysql-test/suite/mariabackup/partition_datadir.result
@@ -0,0 +1,22 @@
+CREATE TABLE t(i int)
+ENGINE=InnoDB
+PARTITION BY RANGE (i)
+(PARTITION p0 VALUES LESS THAN (100),
+PARTITION P1 VALUES LESS THAN (200),
+PARTITION p2 VALUES LESS THAN (300) DATA DIRECTORY = 'MYSQLTEST_VARDIR/partitdata',
+PARTITION p3 VALUES LESS THAN (400) DATA DIRECTORY = 'MYSQLTEST_VARDIR/partitdata',
+PARTITION p4 VALUES LESS THAN MAXVALUE);
+INSERT INTO t VALUES (1), (101), (201), (301), (401);
+DROP TABLE t;
+# shutdown server
+# remove datadir
+# xtrabackup move back
+# restart server
+SELECT * FROM t;
+i
+1
+101
+201
+301
+401
+DROP TABLE t;
diff --git a/mysql-test/suite/mariabackup/partition_datadir.test b/mysql-test/suite/mariabackup/partition_datadir.test
new file mode 100644
index 00000000000..882b0111267
--- /dev/null
+++ b/mysql-test/suite/mariabackup/partition_datadir.test
@@ -0,0 +1,24 @@
+let $targetdir=$MYSQLTEST_VARDIR/backup;
+mkdir $targetdir;
+mkdir $MYSQLTEST_VARDIR/partitdata;
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval CREATE TABLE t(i int)
+ENGINE=InnoDB
+PARTITION BY RANGE (i)
+(PARTITION p0 VALUES LESS THAN (100),
+ PARTITION P1 VALUES LESS THAN (200),
+ PARTITION p2 VALUES LESS THAN (300) DATA DIRECTORY = '$MYSQLTEST_VARDIR/partitdata',
+ PARTITION p3 VALUES LESS THAN (400) DATA DIRECTORY = '$MYSQLTEST_VARDIR/partitdata',
+ PARTITION p4 VALUES LESS THAN MAXVALUE);
+INSERT INTO t VALUES (1), (101), (201), (301), (401);
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir;
+exec $XTRABACKUP --prepare --target-dir=$targetdir;
+DROP TABLE t;
+rmdir $MYSQLTEST_VARDIR/partitdata;
+--source include/restart_and_restore.inc
+--enable_result_log
+SELECT * FROM t;
+DROP TABLE t;
+rmdir $targetdir;
+rmdir $MYSQLTEST_VARDIR/partitdata;
diff --git a/mysql-test/suite/mariabackup/suite.pm b/mysql-test/suite/mariabackup/suite.pm
index 26d5c06cdad..9242bbc051f 100644
--- a/mysql-test/suite/mariabackup/suite.pm
+++ b/mysql-test/suite/mariabackup/suite.pm
@@ -23,9 +23,13 @@ $ENV{XBSTREAM}= ::mtr_exe_maybe_exists(
$ENV{INNOBACKUPEX}= "$mariabackup_exe --innobackupex";
+my $have_qpress = index(`qpress 2>&1`,"Compression") > 0;
+
+
sub skip_combinations {
my %skip;
$skip{'include/have_file_key_management.inc'} = 'needs file_key_management plugin' unless $ENV{FILE_KEY_MANAGEMENT_SO};
+ $skip{'compress_qpress.test'}= 'needs qpress executable in PATH' unless $have_qpress;
%skip;
}
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/inc/part_exch_drop_tabs.inc b/mysql-test/suite/parts/inc/part_exch_drop_tabs.inc
index 5ffc5438a3e..7d6441b15ad 100644
--- a/mysql-test/suite/parts/inc/part_exch_drop_tabs.inc
+++ b/mysql-test/suite/parts/inc/part_exch_drop_tabs.inc
@@ -1,4 +1,3 @@
---disable_warnings
DROP TABLE IF EXISTS t_10;
DROP TABLE IF EXISTS t_100;
DROP TABLE IF EXISTS t_1000;
@@ -11,5 +10,3 @@ DROP TABLE IF EXISTS tsp_03;
DROP TABLE IF EXISTS tsp_04;
DROP TABLE IF EXISTS t_empty;
DROP TABLE IF EXISTS t_null;
---enable_warnings
-
diff --git a/mysql-test/suite/parts/inc/part_exch_tabs.inc b/mysql-test/suite/parts/inc/part_exch_tabs.inc
index 378e0c2278d..482c9d378e7 100644
--- a/mysql-test/suite/parts/inc/part_exch_tabs.inc
+++ b/mysql-test/suite/parts/inc/part_exch_tabs.inc
@@ -1,51 +1,27 @@
---disable_warnings
-DROP TABLE IF EXISTS t_10;
-DROP TABLE IF EXISTS t_100;
-DROP TABLE IF EXISTS t_1000;
-DROP TABLE IF EXISTS tp;
-DROP TABLE IF EXISTS tsp;
-DROP TABLE IF EXISTS t_empty;
-DROP TABLE IF EXISTS t_null;
---enable_warnings
+replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR;
+eval CREATE TABLE t_10 (a INT, b VARCHAR(55), PRIMARY KEY (a)) $data_directory $index_directory ENGINE = $engine_table;
-eval CREATE TABLE t_10 (a INT,
- b VARCHAR(55),
- PRIMARY KEY (a)) $data_directory $index_directory
-ENGINE = $engine_table;
+replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR;
+eval CREATE TABLE t_100 (a INT, b VARCHAR(55), PRIMARY KEY (a)) $data_directory $index_directory ENGINE = $engine_table;
-eval CREATE TABLE t_100 (a INT,
- b VARCHAR(55),
- PRIMARY KEY (a)) $data_directory $index_directory
-ENGINE = $engine_table;
+replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR;
+eval CREATE TABLE t_1000 (a INT, b VARCHAR(55), PRIMARY KEY (a)) $data_directory $index_directory ENGINE = $engine_table;
-eval CREATE TABLE t_1000 (a INT,
- b VARCHAR(55),
- PRIMARY KEY (a)) $data_directory $index_directory
-ENGINE = $engine_table;
+replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR;
+eval CREATE TABLE t_empty (a INT, b VARCHAR(55), PRIMARY KEY (a)) $data_directory $index_directory ENGINE = $engine_table;
-eval CREATE TABLE t_empty (a INT,
- b VARCHAR(55),
- PRIMARY KEY (a)) $data_directory $index_directory
-ENGINE = $engine_table;
+replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR;
+eval CREATE TABLE t_null (a INT, b VARCHAR(55), PRIMARY KEY (a)) $data_directory $index_directory ENGINE = $engine_table;
-eval CREATE TABLE t_null (a INT,
- b VARCHAR(55),
- PRIMARY KEY (a)) $data_directory $index_directory
-ENGINE = $engine_table;
-
-eval CREATE TABLE tp (a INT,
- b VARCHAR(55),
- PRIMARY KEY (a)) $data_directory $index_directory
-ENGINE = $engine_part
+replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR;
+eval CREATE TABLE tp (a INT, b VARCHAR(55), PRIMARY KEY (a)) $data_directory $index_directory ENGINE = $engine_part
PARTITION BY RANGE (a)
(PARTITION p0 VALUES LESS THAN (10) $p_data_directory $p_index_directory,
PARTITION p1 VALUES LESS THAN (100) $p_data_directory $p_index_directory,
PARTITION p2 VALUES LESS THAN (1000) $p_data_directory $p_index_directory);
-eval CREATE TABLE tsp (a INT,
- b VARCHAR(55),
- PRIMARY KEY (a)) $data_directory $index_directory
-ENGINE = $engine_subpart
+replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR;
+eval CREATE TABLE tsp (a INT, b VARCHAR(55), PRIMARY KEY (a)) $data_directory $index_directory ENGINE = $engine_subpart
PARTITION BY RANGE (a)
SUBPARTITION BY HASH(a)
(PARTITION p0 VALUES LESS THAN (10) $p_data_directory $p_index_directory
@@ -53,8 +29,7 @@ SUBPARTITION BY HASH(a)
SUBPARTITION sp01,
SUBPARTITION sp02,
SUBPARTITION sp03,
- SUBPARTITION sp04),
- PARTITION p1 VALUES LESS THAN (100)
+ SUBPARTITION sp04), PARTITION p1 VALUES LESS THAN (100)
(SUBPARTITION sp10 $p_data_directory $p_index_directory,
SUBPARTITION sp11 $p_data_directory $p_index_directory,
SUBPARTITION sp12 $p_data_directory $p_index_directory,
@@ -99,41 +74,13 @@ INSERT INTO tsp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four")
INSERT INTO tsp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
INSERT INTO tsp VALUES (182, "Hundred eight-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
-eval CREATE TABLE tsp_01(a INT,b VARCHAR(55),PRIMARY KEY (a))
- ENGINE = $engine_table $data_directory $index_directory
- AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 1;
-eval CREATE TABLE tsp_02(a INT,b VARCHAR(55),PRIMARY KEY (a))
- ENGINE = $engine_table $data_directory $index_directory
- AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 2;
-eval CREATE TABLE tsp_03(a INT,b VARCHAR(55),PRIMARY KEY (a))
- ENGINE = $engine_table $data_directory $index_directory
- AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 3;
-eval CREATE TABLE tsp_04(a INT,b VARCHAR(55),PRIMARY KEY (a))
- ENGINE = $engine_table $data_directory $index_directory
- AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 4;
-eval CREATE TABLE tsp_00(a INT,b VARCHAR(55),PRIMARY KEY (a))
- ENGINE = $engine_table $data_directory $index_directory
- AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 0;
-
-SHOW CREATE TABLE t_10;
-SHOW CREATE TABLE t_100;
-SHOW CREATE TABLE t_1000;
-SHOW CREATE TABLE tp;
-SHOW CREATE TABLE tsp;
-
---sorted_result
-SELECT * FROM t_10;
---sorted_result
-SELECT * FROM t_100;
---sorted_result
-SELECT * FROM t_1000;
---sorted_result
-SELECT * FROM tp;
---sorted_result
-SELECT * FROM tp WHERE a< 10;
---sorted_result
-SELECT * FROM tp WHERE a BETWEEN 11 AND 100;
---sorted_result
-SELECT * FROM tp WHERE a BETWEEN 101 AND 200;
---sorted_result
-SELECT * FROM tsp;
+replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR;
+eval CREATE TABLE tsp_01(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = $engine_table $data_directory $index_directory AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 1;
+replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR;
+eval CREATE TABLE tsp_02(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = $engine_table $data_directory $index_directory AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 2;
+replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR;
+eval CREATE TABLE tsp_03(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = $engine_table $data_directory $index_directory AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 3;
+replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR;
+eval CREATE TABLE tsp_04(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = $engine_table $data_directory $index_directory AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 4;
+replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR;
+eval CREATE TABLE tsp_00(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = $engine_table $data_directory $index_directory AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 0;
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..29076a3c178
--- /dev/null
+++ b/mysql-test/suite/parts/r/partition_alter_innodb.result
@@ -0,0 +1,49 @@
+#
+# 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;
+Warnings:
+Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT.
+Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT.
+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
+/*!50500 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
+/*!50100 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
new file mode 100644
index 00000000000..fd09c0bd4bb
--- /dev/null
+++ b/mysql-test/suite/parts/r/partition_alter_maria.result
@@ -0,0 +1,62 @@
+create table t1 (
+pk bigint not null auto_increment,
+dt datetime default null,
+unique (pk, dt)
+) engine=aria row_format=dynamic
+partition by range columns(dt) (
+partition `p20171231` values less than ('2017-12-31'),
+partition `p20181231` values less than ('2018-12-31')
+);
+insert into t1 values (1,'2017-09-28 15:12:00');
+select * from t1;
+pk dt
+1 2017-09-28 15:12:00
+alter table t1 drop partition p20181231;
+select * from t1;
+pk dt
+1 2017-09-28 15:12:00
+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
+/*!50500 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
+/*!50100 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..41af6af72fc
--- /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
+/*!50500 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
+/*!50100 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 d7a77e5e54a..405511543bf 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
+/*!50100 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
+/*!50100 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
+/*!50100 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
+/*!50100 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_exch_myisam_innodb.result b/mysql-test/suite/parts/r/partition_exch_myisam_innodb.result
index 9ff4afcfe35..a2a58c22c42 100644
--- a/mysql-test/suite/parts/r/partition_exch_myisam_innodb.result
+++ b/mysql-test/suite/parts/r/partition_exch_myisam_innodb.result
@@ -1,3 +1,58 @@
+CREATE TABLE t_10 (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_100 (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_1000 (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_empty (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_null (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE tp (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = InnoDB
+PARTITION BY RANGE (a)
+(PARTITION p0 VALUES LESS THAN (10) ,
+PARTITION p1 VALUES LESS THAN (100) ,
+PARTITION p2 VALUES LESS THAN (1000) );
+CREATE TABLE tsp (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = InnoDB
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH(a)
+(PARTITION p0 VALUES LESS THAN (10)
+(SUBPARTITION sp00,
+SUBPARTITION sp01,
+SUBPARTITION sp02,
+SUBPARTITION sp03,
+SUBPARTITION sp04), PARTITION p1 VALUES LESS THAN (100)
+(SUBPARTITION sp10 ,
+SUBPARTITION sp11 ,
+SUBPARTITION sp12 ,
+SUBPARTITION sp13 ,
+SUBPARTITION sp14 ),
+PARTITION p2 VALUES LESS THAN (1000)
+(SUBPARTITION sp20,
+SUBPARTITION sp21,
+SUBPARTITION sp22,
+SUBPARTITION sp23,
+SUBPARTITION sp24));
+INSERT INTO t_10 VALUES (1, "One"), (3, "Three"), (5, "Five"), (9, "Nine");
+INSERT INTO t_100 VALUES (11, "Eleven"), (13, "Thirdteen"), (15, "Fifeteen"), (19, "Nineteen");
+INSERT INTO t_100 VALUES (91, "Ninety-one"), (93, "Ninety-three"), (95, "Ninety-five"), (99, "Ninety-nine");
+INSERT INTO t_1000 VALUES (111, "Hundred elven"), (113, "Hundred thirdteen"), (115, "Hundred fiveteen"), (119, "Hundred nineteen");
+INSERT INTO t_1000 VALUES (131, "Hundred thirty-one"), (133, "Hundred thirty-three"), (135, "Hundred thirty-five"), (139, "Hundred thirty-nine");
+INSERT INTO t_1000 VALUES (151, "Hundred fifty-one"), (153, "Hundred fifty-three"), (155, "Hundred fity-five"), (159, "Hundred fifty-nine");
+INSERT INTO t_1000 VALUES (191, "Hundred ninety-one"), (193, "Hundred ninety-three"), (195, "Hundred ninety-five"), (199, "Hundred ninety-nine");
+INSERT INTO t_null VALUES (1, "NULL");
+INSERT INTO tp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tp VALUES (182, "Hundred eighty-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+INSERT INTO tsp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tsp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tsp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tsp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tsp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tsp VALUES (182, "Hundred eight-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+CREATE TABLE tsp_01(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 1;
+CREATE TABLE tsp_02(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 2;
+CREATE TABLE tsp_03(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 3;
+CREATE TABLE tsp_04(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 4;
+CREATE TABLE tsp_00(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 0;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
ERROR HY000: The mix of handlers in the partitions is not allowed in this version of MariaDB
DROP TABLE IF EXISTS t_10;
diff --git a/mysql-test/suite/parts/r/partition_exch_qa_14.result b/mysql-test/suite/parts/r/partition_exch_qa_14.result
index f6866727184..1420982436a 100644
--- a/mysql-test/suite/parts/r/partition_exch_qa_14.result
+++ b/mysql-test/suite/parts/r/partition_exch_qa_14.result
@@ -1,4 +1,198 @@
-use test;
+# === Data/Index directories are identical
+CREATE TABLE t_10 (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE t_100 (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE t_1000 (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE t_empty (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE t_null (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE tp (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM
+PARTITION BY RANGE (a)
+(PARTITION p0 VALUES LESS THAN (10) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir',
+PARTITION p1 VALUES LESS THAN (100) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir',
+PARTITION p2 VALUES LESS THAN (1000) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir');
+CREATE TABLE tsp (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH(a)
+(PARTITION p0 VALUES LESS THAN (10) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir'
+(SUBPARTITION sp00,
+SUBPARTITION sp01,
+SUBPARTITION sp02,
+SUBPARTITION sp03,
+SUBPARTITION sp04), PARTITION p1 VALUES LESS THAN (100)
+(SUBPARTITION sp10 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir',
+SUBPARTITION sp11 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir',
+SUBPARTITION sp12 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir',
+SUBPARTITION sp13 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir',
+SUBPARTITION sp14 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir'),
+PARTITION p2 VALUES LESS THAN (1000) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir'
+(SUBPARTITION sp20,
+SUBPARTITION sp21,
+SUBPARTITION sp22,
+SUBPARTITION sp23,
+SUBPARTITION sp24));
+INSERT INTO t_10 VALUES (1, "One"), (3, "Three"), (5, "Five"), (9, "Nine");
+INSERT INTO t_100 VALUES (11, "Eleven"), (13, "Thirdteen"), (15, "Fifeteen"), (19, "Nineteen");
+INSERT INTO t_100 VALUES (91, "Ninety-one"), (93, "Ninety-three"), (95, "Ninety-five"), (99, "Ninety-nine");
+INSERT INTO t_1000 VALUES (111, "Hundred elven"), (113, "Hundred thirdteen"), (115, "Hundred fiveteen"), (119, "Hundred nineteen");
+INSERT INTO t_1000 VALUES (131, "Hundred thirty-one"), (133, "Hundred thirty-three"), (135, "Hundred thirty-five"), (139, "Hundred thirty-nine");
+INSERT INTO t_1000 VALUES (151, "Hundred fifty-one"), (153, "Hundred fifty-three"), (155, "Hundred fity-five"), (159, "Hundred fifty-nine");
+INSERT INTO t_1000 VALUES (191, "Hundred ninety-one"), (193, "Hundred ninety-three"), (195, "Hundred ninety-five"), (199, "Hundred ninety-nine");
+INSERT INTO t_null VALUES (1, "NULL");
+INSERT INTO tp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tp VALUES (182, "Hundred eighty-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+INSERT INTO tsp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tsp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tsp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tsp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tsp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tsp VALUES (182, "Hundred eight-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+CREATE TABLE tsp_01(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 1;
+CREATE TABLE tsp_02(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 2;
+CREATE TABLE tsp_03(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 3;
+CREATE TABLE tsp_04(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 4;
+CREATE TABLE tsp_00(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 0;
+ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
+DROP TABLE IF EXISTS t_10;
+DROP TABLE IF EXISTS t_100;
+DROP TABLE IF EXISTS t_1000;
+DROP TABLE IF EXISTS tp;
+DROP TABLE IF EXISTS tsp;
+DROP TABLE IF EXISTS tsp_00;
+DROP TABLE IF EXISTS tsp_01;
+DROP TABLE IF EXISTS tsp_02;
+DROP TABLE IF EXISTS tsp_03;
+DROP TABLE IF EXISTS tsp_04;
+DROP TABLE IF EXISTS t_empty;
+DROP TABLE IF EXISTS t_null;
+# === partition has directories, the table does not
+CREATE TABLE t_10 (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_100 (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_1000 (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_empty (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_null (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE tp (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM
+PARTITION BY RANGE (a)
+(PARTITION p0 VALUES LESS THAN (10) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir',
+PARTITION p1 VALUES LESS THAN (100) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir',
+PARTITION p2 VALUES LESS THAN (1000) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir');
+CREATE TABLE tsp (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH(a)
+(PARTITION p0 VALUES LESS THAN (10) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir'
+(SUBPARTITION sp00,
+SUBPARTITION sp01,
+SUBPARTITION sp02,
+SUBPARTITION sp03,
+SUBPARTITION sp04), PARTITION p1 VALUES LESS THAN (100)
+(SUBPARTITION sp10 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir',
+SUBPARTITION sp11 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir',
+SUBPARTITION sp12 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir',
+SUBPARTITION sp13 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir',
+SUBPARTITION sp14 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir'),
+PARTITION p2 VALUES LESS THAN (1000) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir'
+(SUBPARTITION sp20,
+SUBPARTITION sp21,
+SUBPARTITION sp22,
+SUBPARTITION sp23,
+SUBPARTITION sp24));
+INSERT INTO t_10 VALUES (1, "One"), (3, "Three"), (5, "Five"), (9, "Nine");
+INSERT INTO t_100 VALUES (11, "Eleven"), (13, "Thirdteen"), (15, "Fifeteen"), (19, "Nineteen");
+INSERT INTO t_100 VALUES (91, "Ninety-one"), (93, "Ninety-three"), (95, "Ninety-five"), (99, "Ninety-nine");
+INSERT INTO t_1000 VALUES (111, "Hundred elven"), (113, "Hundred thirdteen"), (115, "Hundred fiveteen"), (119, "Hundred nineteen");
+INSERT INTO t_1000 VALUES (131, "Hundred thirty-one"), (133, "Hundred thirty-three"), (135, "Hundred thirty-five"), (139, "Hundred thirty-nine");
+INSERT INTO t_1000 VALUES (151, "Hundred fifty-one"), (153, "Hundred fifty-three"), (155, "Hundred fity-five"), (159, "Hundred fifty-nine");
+INSERT INTO t_1000 VALUES (191, "Hundred ninety-one"), (193, "Hundred ninety-three"), (195, "Hundred ninety-five"), (199, "Hundred ninety-nine");
+INSERT INTO t_null VALUES (1, "NULL");
+INSERT INTO tp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tp VALUES (182, "Hundred eighty-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+INSERT INTO tsp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tsp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tsp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tsp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tsp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tsp VALUES (182, "Hundred eight-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+CREATE TABLE tsp_01(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 1;
+CREATE TABLE tsp_02(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 2;
+CREATE TABLE tsp_03(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 3;
+CREATE TABLE tsp_04(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 4;
+CREATE TABLE tsp_00(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 0;
+ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
+ERROR HY000: Tables have different definitions
+DROP TABLE IF EXISTS t_10;
+DROP TABLE IF EXISTS t_100;
+DROP TABLE IF EXISTS t_1000;
+DROP TABLE IF EXISTS tp;
+DROP TABLE IF EXISTS tsp;
+DROP TABLE IF EXISTS tsp_00;
+DROP TABLE IF EXISTS tsp_01;
+DROP TABLE IF EXISTS tsp_02;
+DROP TABLE IF EXISTS tsp_03;
+DROP TABLE IF EXISTS tsp_04;
+DROP TABLE IF EXISTS t_empty;
+DROP TABLE IF EXISTS t_null;
+# === the table has directories, partition does not
+CREATE TABLE t_10 (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE t_100 (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE t_1000 (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE t_empty (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE t_null (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE tp (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM
+PARTITION BY RANGE (a)
+(PARTITION p0 VALUES LESS THAN (10) ,
+PARTITION p1 VALUES LESS THAN (100) ,
+PARTITION p2 VALUES LESS THAN (1000) );
+CREATE TABLE tsp (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH(a)
+(PARTITION p0 VALUES LESS THAN (10)
+(SUBPARTITION sp00,
+SUBPARTITION sp01,
+SUBPARTITION sp02,
+SUBPARTITION sp03,
+SUBPARTITION sp04), PARTITION p1 VALUES LESS THAN (100)
+(SUBPARTITION sp10 ,
+SUBPARTITION sp11 ,
+SUBPARTITION sp12 ,
+SUBPARTITION sp13 ,
+SUBPARTITION sp14 ),
+PARTITION p2 VALUES LESS THAN (1000)
+(SUBPARTITION sp20,
+SUBPARTITION sp21,
+SUBPARTITION sp22,
+SUBPARTITION sp23,
+SUBPARTITION sp24));
+INSERT INTO t_10 VALUES (1, "One"), (3, "Three"), (5, "Five"), (9, "Nine");
+INSERT INTO t_100 VALUES (11, "Eleven"), (13, "Thirdteen"), (15, "Fifeteen"), (19, "Nineteen");
+INSERT INTO t_100 VALUES (91, "Ninety-one"), (93, "Ninety-three"), (95, "Ninety-five"), (99, "Ninety-nine");
+INSERT INTO t_1000 VALUES (111, "Hundred elven"), (113, "Hundred thirdteen"), (115, "Hundred fiveteen"), (119, "Hundred nineteen");
+INSERT INTO t_1000 VALUES (131, "Hundred thirty-one"), (133, "Hundred thirty-three"), (135, "Hundred thirty-five"), (139, "Hundred thirty-nine");
+INSERT INTO t_1000 VALUES (151, "Hundred fifty-one"), (153, "Hundred fifty-three"), (155, "Hundred fity-five"), (159, "Hundred fifty-nine");
+INSERT INTO t_1000 VALUES (191, "Hundred ninety-one"), (193, "Hundred ninety-three"), (195, "Hundred ninety-five"), (199, "Hundred ninety-nine");
+INSERT INTO t_null VALUES (1, "NULL");
+INSERT INTO tp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tp VALUES (182, "Hundred eighty-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+INSERT INTO tsp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tsp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tsp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tsp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tsp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tsp VALUES (182, "Hundred eight-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+CREATE TABLE tsp_01(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 1;
+CREATE TABLE tsp_02(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 2;
+CREATE TABLE tsp_03(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 3;
+CREATE TABLE tsp_04(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 4;
+CREATE TABLE tsp_00(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 0;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
ERROR HY000: Tables have different definitions
DROP TABLE IF EXISTS t_10;
@@ -13,7 +207,62 @@ DROP TABLE IF EXISTS tsp_03;
DROP TABLE IF EXISTS tsp_04;
DROP TABLE IF EXISTS t_empty;
DROP TABLE IF EXISTS t_null;
-use test;
+# === data directory differs
+CREATE TABLE t_10 (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE t_100 (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE t_1000 (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE t_empty (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE t_null (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE tp (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM
+PARTITION BY RANGE (a)
+(PARTITION p0 VALUES LESS THAN (10) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir',
+PARTITION p1 VALUES LESS THAN (100) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir',
+PARTITION p2 VALUES LESS THAN (1000) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir');
+CREATE TABLE tsp (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH(a)
+(PARTITION p0 VALUES LESS THAN (10) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir'
+(SUBPARTITION sp00,
+SUBPARTITION sp01,
+SUBPARTITION sp02,
+SUBPARTITION sp03,
+SUBPARTITION sp04), PARTITION p1 VALUES LESS THAN (100)
+(SUBPARTITION sp10 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir',
+SUBPARTITION sp11 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir',
+SUBPARTITION sp12 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir',
+SUBPARTITION sp13 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir',
+SUBPARTITION sp14 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir'),
+PARTITION p2 VALUES LESS THAN (1000) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir'
+(SUBPARTITION sp20,
+SUBPARTITION sp21,
+SUBPARTITION sp22,
+SUBPARTITION sp23,
+SUBPARTITION sp24));
+INSERT INTO t_10 VALUES (1, "One"), (3, "Three"), (5, "Five"), (9, "Nine");
+INSERT INTO t_100 VALUES (11, "Eleven"), (13, "Thirdteen"), (15, "Fifeteen"), (19, "Nineteen");
+INSERT INTO t_100 VALUES (91, "Ninety-one"), (93, "Ninety-three"), (95, "Ninety-five"), (99, "Ninety-nine");
+INSERT INTO t_1000 VALUES (111, "Hundred elven"), (113, "Hundred thirdteen"), (115, "Hundred fiveteen"), (119, "Hundred nineteen");
+INSERT INTO t_1000 VALUES (131, "Hundred thirty-one"), (133, "Hundred thirty-three"), (135, "Hundred thirty-five"), (139, "Hundred thirty-nine");
+INSERT INTO t_1000 VALUES (151, "Hundred fifty-one"), (153, "Hundred fifty-three"), (155, "Hundred fity-five"), (159, "Hundred fifty-nine");
+INSERT INTO t_1000 VALUES (191, "Hundred ninety-one"), (193, "Hundred ninety-three"), (195, "Hundred ninety-five"), (199, "Hundred ninety-nine");
+INSERT INTO t_null VALUES (1, "NULL");
+INSERT INTO tp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tp VALUES (182, "Hundred eighty-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+INSERT INTO tsp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tsp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tsp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tsp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tsp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tsp VALUES (182, "Hundred eight-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+CREATE TABLE tsp_01(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 1;
+CREATE TABLE tsp_02(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 2;
+CREATE TABLE tsp_03(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 3;
+CREATE TABLE tsp_04(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 4;
+CREATE TABLE tsp_00(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 0;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
ERROR HY000: Tables have different definitions
DROP TABLE IF EXISTS t_10;
@@ -28,7 +277,62 @@ DROP TABLE IF EXISTS tsp_03;
DROP TABLE IF EXISTS tsp_04;
DROP TABLE IF EXISTS t_empty;
DROP TABLE IF EXISTS t_null;
-use test;
+# === index directory differs
+CREATE TABLE t_10 (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE t_100 (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE t_1000 (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE t_empty (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE t_null (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM;
+CREATE TABLE tp (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM
+PARTITION BY RANGE (a)
+(PARTITION p0 VALUES LESS THAN (10) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir',
+PARTITION p1 VALUES LESS THAN (100) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir',
+PARTITION p2 VALUES LESS THAN (1000) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir');
+CREATE TABLE tsp (a INT, b VARCHAR(55), PRIMARY KEY (a)) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' ENGINE = MYISAM
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH(a)
+(PARTITION p0 VALUES LESS THAN (10) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir'
+(SUBPARTITION sp00,
+SUBPARTITION sp01,
+SUBPARTITION sp02,
+SUBPARTITION sp03,
+SUBPARTITION sp04), PARTITION p1 VALUES LESS THAN (100)
+(SUBPARTITION sp10 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir',
+SUBPARTITION sp11 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir',
+SUBPARTITION sp12 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir',
+SUBPARTITION sp13 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir',
+SUBPARTITION sp14 DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir'),
+PARTITION p2 VALUES LESS THAN (1000) DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir'
+(SUBPARTITION sp20,
+SUBPARTITION sp21,
+SUBPARTITION sp22,
+SUBPARTITION sp23,
+SUBPARTITION sp24));
+INSERT INTO t_10 VALUES (1, "One"), (3, "Three"), (5, "Five"), (9, "Nine");
+INSERT INTO t_100 VALUES (11, "Eleven"), (13, "Thirdteen"), (15, "Fifeteen"), (19, "Nineteen");
+INSERT INTO t_100 VALUES (91, "Ninety-one"), (93, "Ninety-three"), (95, "Ninety-five"), (99, "Ninety-nine");
+INSERT INTO t_1000 VALUES (111, "Hundred elven"), (113, "Hundred thirdteen"), (115, "Hundred fiveteen"), (119, "Hundred nineteen");
+INSERT INTO t_1000 VALUES (131, "Hundred thirty-one"), (133, "Hundred thirty-three"), (135, "Hundred thirty-five"), (139, "Hundred thirty-nine");
+INSERT INTO t_1000 VALUES (151, "Hundred fifty-one"), (153, "Hundred fifty-three"), (155, "Hundred fity-five"), (159, "Hundred fifty-nine");
+INSERT INTO t_1000 VALUES (191, "Hundred ninety-one"), (193, "Hundred ninety-three"), (195, "Hundred ninety-five"), (199, "Hundred ninety-nine");
+INSERT INTO t_null VALUES (1, "NULL");
+INSERT INTO tp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tp VALUES (182, "Hundred eighty-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+INSERT INTO tsp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tsp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tsp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tsp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tsp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tsp VALUES (182, "Hundred eight-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+CREATE TABLE tsp_01(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 1;
+CREATE TABLE tsp_02(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 2;
+CREATE TABLE tsp_03(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 3;
+CREATE TABLE tsp_04(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 4;
+CREATE TABLE tsp_00(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-data-dir' DATA DIRECTORY = 'MYSQLTEST_VARDIR/mysql-test-idx-dir' AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 0;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
ERROR HY000: Tables have different definitions
DROP TABLE IF EXISTS t_10;
diff --git a/mysql-test/suite/parts/r/partition_exch_qa_15.result b/mysql-test/suite/parts/r/partition_exch_qa_15.result
index 87671a74253..355cf43d886 100644
--- a/mysql-test/suite/parts/r/partition_exch_qa_15.result
+++ b/mysql-test/suite/parts/r/partition_exch_qa_15.result
@@ -1,10 +1,65 @@
use test;
+CREATE TABLE t_10 (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = InnoDB;
+CREATE TABLE t_100 (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = InnoDB;
+CREATE TABLE t_1000 (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = InnoDB;
+CREATE TABLE t_empty (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = InnoDB;
+CREATE TABLE t_null (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = InnoDB;
+CREATE TABLE tp (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = InnoDB
+PARTITION BY RANGE (a)
+(PARTITION p0 VALUES LESS THAN (10) ,
+PARTITION p1 VALUES LESS THAN (100) ,
+PARTITION p2 VALUES LESS THAN (1000) );
+CREATE TABLE tsp (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = InnoDB
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH(a)
+(PARTITION p0 VALUES LESS THAN (10)
+(SUBPARTITION sp00,
+SUBPARTITION sp01,
+SUBPARTITION sp02,
+SUBPARTITION sp03,
+SUBPARTITION sp04), PARTITION p1 VALUES LESS THAN (100)
+(SUBPARTITION sp10 ,
+SUBPARTITION sp11 ,
+SUBPARTITION sp12 ,
+SUBPARTITION sp13 ,
+SUBPARTITION sp14 ),
+PARTITION p2 VALUES LESS THAN (1000)
+(SUBPARTITION sp20,
+SUBPARTITION sp21,
+SUBPARTITION sp22,
+SUBPARTITION sp23,
+SUBPARTITION sp24));
+INSERT INTO t_10 VALUES (1, "One"), (3, "Three"), (5, "Five"), (9, "Nine");
+INSERT INTO t_100 VALUES (11, "Eleven"), (13, "Thirdteen"), (15, "Fifeteen"), (19, "Nineteen");
+INSERT INTO t_100 VALUES (91, "Ninety-one"), (93, "Ninety-three"), (95, "Ninety-five"), (99, "Ninety-nine");
+INSERT INTO t_1000 VALUES (111, "Hundred elven"), (113, "Hundred thirdteen"), (115, "Hundred fiveteen"), (119, "Hundred nineteen");
+INSERT INTO t_1000 VALUES (131, "Hundred thirty-one"), (133, "Hundred thirty-three"), (135, "Hundred thirty-five"), (139, "Hundred thirty-nine");
+INSERT INTO t_1000 VALUES (151, "Hundred fifty-one"), (153, "Hundred fifty-three"), (155, "Hundred fity-five"), (159, "Hundred fifty-nine");
+INSERT INTO t_1000 VALUES (191, "Hundred ninety-one"), (193, "Hundred ninety-three"), (195, "Hundred ninety-five"), (199, "Hundred ninety-nine");
+INSERT INTO t_null VALUES (1, "NULL");
+INSERT INTO tp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tp VALUES (182, "Hundred eighty-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+INSERT INTO tsp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tsp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tsp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tsp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tsp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tsp VALUES (182, "Hundred eight-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+CREATE TABLE tsp_01(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = InnoDB AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 1;
+CREATE TABLE tsp_02(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = InnoDB AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 2;
+CREATE TABLE tsp_03(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = InnoDB AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 3;
+CREATE TABLE tsp_04(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = InnoDB AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 4;
+CREATE TABLE tsp_00(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = InnoDB AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 0;
CREATE TABLE t_11 (a INT, b VARCHAR(55),
FOREIGN KEY (a) REFERENCES t_10 (a) ON DELETE CASCADE)
ENGINE= InnoDB;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_11;
ERROR HY000: Table to exchange with partition has foreign key references: 't_11'
-DROP TABLE IF EXISTS t_11;
+DROP TABLE t_11;
DROP TABLE IF EXISTS t_10;
DROP TABLE IF EXISTS t_100;
DROP TABLE IF EXISTS t_1000;
diff --git a/mysql-test/suite/parts/r/partition_exch_qa_2.result b/mysql-test/suite/parts/r/partition_exch_qa_2.result
index ea4983db3dc..956cb0af695 100644
--- a/mysql-test/suite/parts/r/partition_exch_qa_2.result
+++ b/mysql-test/suite/parts/r/partition_exch_qa_2.result
@@ -1,4 +1,59 @@
use test;
+CREATE TABLE t_10 (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_100 (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_1000 (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_empty (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_null (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE tp (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM
+PARTITION BY RANGE (a)
+(PARTITION p0 VALUES LESS THAN (10) ,
+PARTITION p1 VALUES LESS THAN (100) ,
+PARTITION p2 VALUES LESS THAN (1000) );
+CREATE TABLE tsp (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH(a)
+(PARTITION p0 VALUES LESS THAN (10)
+(SUBPARTITION sp00,
+SUBPARTITION sp01,
+SUBPARTITION sp02,
+SUBPARTITION sp03,
+SUBPARTITION sp04), PARTITION p1 VALUES LESS THAN (100)
+(SUBPARTITION sp10 ,
+SUBPARTITION sp11 ,
+SUBPARTITION sp12 ,
+SUBPARTITION sp13 ,
+SUBPARTITION sp14 ),
+PARTITION p2 VALUES LESS THAN (1000)
+(SUBPARTITION sp20,
+SUBPARTITION sp21,
+SUBPARTITION sp22,
+SUBPARTITION sp23,
+SUBPARTITION sp24));
+INSERT INTO t_10 VALUES (1, "One"), (3, "Three"), (5, "Five"), (9, "Nine");
+INSERT INTO t_100 VALUES (11, "Eleven"), (13, "Thirdteen"), (15, "Fifeteen"), (19, "Nineteen");
+INSERT INTO t_100 VALUES (91, "Ninety-one"), (93, "Ninety-three"), (95, "Ninety-five"), (99, "Ninety-nine");
+INSERT INTO t_1000 VALUES (111, "Hundred elven"), (113, "Hundred thirdteen"), (115, "Hundred fiveteen"), (119, "Hundred nineteen");
+INSERT INTO t_1000 VALUES (131, "Hundred thirty-one"), (133, "Hundred thirty-three"), (135, "Hundred thirty-five"), (139, "Hundred thirty-nine");
+INSERT INTO t_1000 VALUES (151, "Hundred fifty-one"), (153, "Hundred fifty-three"), (155, "Hundred fity-five"), (159, "Hundred fifty-nine");
+INSERT INTO t_1000 VALUES (191, "Hundred ninety-one"), (193, "Hundred ninety-three"), (195, "Hundred ninety-five"), (199, "Hundred ninety-nine");
+INSERT INTO t_null VALUES (1, "NULL");
+INSERT INTO tp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tp VALUES (182, "Hundred eighty-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+INSERT INTO tsp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tsp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tsp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tsp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tsp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tsp VALUES (182, "Hundred eight-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+CREATE TABLE tsp_01(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 1;
+CREATE TABLE tsp_02(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 2;
+CREATE TABLE tsp_03(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 3;
+CREATE TABLE tsp_04(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 4;
+CREATE TABLE tsp_00(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 0;
SELECT * FROM t_10;
a b
1 One
@@ -102,20 +157,20 @@ a b
CREATE TABLE t_11(a INT,b VARCHAR(55)) SELECT * FROM t_10;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_11;
ERROR HY000: Tables have different definitions
-DROP TABLE IF EXISTS t_11;
+DROP TABLE t_11;
CREATE TABLE t_11(a INT,b CHAR(55),PRIMARY KEY(a)) ENGINE= MYISAM SELECT * FROM t_10;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_11;
ERROR HY000: Tables have different definitions
-DROP TABLE IF EXISTS t_11;
+DROP TABLE t_11;
CREATE TABLE t_11(a INT,b VARCHAR(55),PRIMARY KEY(a)) ENGINE= MEMORY SELECT * FROM t_10;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_11;
ERROR HY000: The mix of handlers in the partitions is not allowed in this version of MariaDB
-DROP TABLE IF EXISTS t_11;
+DROP TABLE t_11;
CREATE TABLE t_11(a INT,b CHAR(55),PRIMARY KEY(a)) ENGINE= MYISAM
PARTITION BY KEY() AS SELECT * FROM t_10;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_11;
ERROR HY000: Table to exchange with partition is partitioned: 't_11'
-DROP TABLE IF EXISTS t_11;
+DROP TABLE t_11;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE tsp;
ERROR HY000: Table to exchange with partition is partitioned: 'tsp'
ALTER TABLE tsp EXCHANGE PARTITION p0 WITH TABLE t_10;
diff --git a/mysql-test/suite/parts/r/partition_exch_qa_3.result b/mysql-test/suite/parts/r/partition_exch_qa_3.result
index 9f4043a055a..791757c95f2 100644
--- a/mysql-test/suite/parts/r/partition_exch_qa_3.result
+++ b/mysql-test/suite/parts/r/partition_exch_qa_3.result
@@ -1,4 +1,159 @@
use test;
+CREATE TABLE t_10 (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_100 (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_1000 (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_empty (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_null (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE tp (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = InnoDB
+PARTITION BY RANGE (a)
+(PARTITION p0 VALUES LESS THAN (10) ,
+PARTITION p1 VALUES LESS THAN (100) ,
+PARTITION p2 VALUES LESS THAN (1000) );
+CREATE TABLE tsp (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = InnoDB
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH(a)
+(PARTITION p0 VALUES LESS THAN (10)
+(SUBPARTITION sp00,
+SUBPARTITION sp01,
+SUBPARTITION sp02,
+SUBPARTITION sp03,
+SUBPARTITION sp04), PARTITION p1 VALUES LESS THAN (100)
+(SUBPARTITION sp10 ,
+SUBPARTITION sp11 ,
+SUBPARTITION sp12 ,
+SUBPARTITION sp13 ,
+SUBPARTITION sp14 ),
+PARTITION p2 VALUES LESS THAN (1000)
+(SUBPARTITION sp20,
+SUBPARTITION sp21,
+SUBPARTITION sp22,
+SUBPARTITION sp23,
+SUBPARTITION sp24));
+INSERT INTO t_10 VALUES (1, "One"), (3, "Three"), (5, "Five"), (9, "Nine");
+INSERT INTO t_100 VALUES (11, "Eleven"), (13, "Thirdteen"), (15, "Fifeteen"), (19, "Nineteen");
+INSERT INTO t_100 VALUES (91, "Ninety-one"), (93, "Ninety-three"), (95, "Ninety-five"), (99, "Ninety-nine");
+INSERT INTO t_1000 VALUES (111, "Hundred elven"), (113, "Hundred thirdteen"), (115, "Hundred fiveteen"), (119, "Hundred nineteen");
+INSERT INTO t_1000 VALUES (131, "Hundred thirty-one"), (133, "Hundred thirty-three"), (135, "Hundred thirty-five"), (139, "Hundred thirty-nine");
+INSERT INTO t_1000 VALUES (151, "Hundred fifty-one"), (153, "Hundred fifty-three"), (155, "Hundred fity-five"), (159, "Hundred fifty-nine");
+INSERT INTO t_1000 VALUES (191, "Hundred ninety-one"), (193, "Hundred ninety-three"), (195, "Hundred ninety-five"), (199, "Hundred ninety-nine");
+INSERT INTO t_null VALUES (1, "NULL");
+INSERT INTO tp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tp VALUES (182, "Hundred eighty-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+INSERT INTO tsp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tsp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tsp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tsp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tsp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tsp VALUES (182, "Hundred eight-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+CREATE TABLE tsp_01(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 1;
+CREATE TABLE tsp_02(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 2;
+CREATE TABLE tsp_03(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 3;
+CREATE TABLE tsp_04(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 4;
+CREATE TABLE tsp_00(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 0;
+SELECT * FROM t_10;
+a b
+1 One
+3 Three
+5 Five
+9 Nine
+SELECT * FROM t_100;
+a b
+11 Eleven
+13 Thirdteen
+15 Fifeteen
+19 Nineteen
+91 Ninety-one
+93 Ninety-three
+95 Ninety-five
+99 Ninety-nine
+SELECT * FROM t_1000;
+a b
+111 Hundred elven
+113 Hundred thirdteen
+115 Hundred fiveteen
+119 Hundred nineteen
+131 Hundred thirty-one
+133 Hundred thirty-three
+135 Hundred thirty-five
+139 Hundred thirty-nine
+151 Hundred fifty-one
+153 Hundred fifty-three
+155 Hundred fity-five
+159 Hundred fifty-nine
+191 Hundred ninety-one
+193 Hundred ninety-three
+195 Hundred ninety-five
+199 Hundred ninety-nine
+SELECT * FROM tp;
+a b
+112 Hundred twelve
+114 Hundred fourteen
+116 Hundred sixteen
+118 Hundred eightteen
+12 twelve
+122 Hundred twenty-two
+124 Hundred twenty-four
+126 Hundred twenty-six
+128 Hundred twenty-eight
+14 Fourteen
+16 Sixteen
+162 Hundred sixty-two
+164 Hundred sixty-four
+166 Hundred sixty-six
+168 Hundred sixty-eight
+18 Eightteen
+182 Hundred eighty-two
+184 Hundred eighty-four
+186 Hundred eighty-six
+188 Hundred eighty-eight
+2 Two
+4 Four
+6 Six
+8 Eight
+SELECT * FROM tsp;
+a b
+112 Hundred twelve
+114 Hundred fourteen
+116 Hundred sixteen
+118 Hundred eightteen
+12 twelve
+122 Hundred twenty-two
+124 Hundred twenty-four
+126 Hundred twenty-six
+128 Hundred twenty-eight
+14 Fourteen
+16 Sixteen
+162 Hundred sixty-two
+164 Hundred sixty-four
+166 Hundred sixty-six
+168 Hundred sixty-eight
+18 Eightteen
+182 Hundred eight-two
+184 Hundred eighty-four
+186 Hundred eighty-six
+188 Hundred eighty-eight
+2 Two
+4 Four
+6 Six
+8 Eight
+SELECT * FROM tsp_00;
+a b
+5 Five
+SELECT * FROM tsp_01;
+a b
+1 One
+SELECT * FROM tsp_02;
+a b
+SELECT * FROM tsp_03;
+a b
+3 Three
+SELECT * FROM tsp_04;
+a b
+9 Nine
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
ERROR HY000: The mix of handlers in the partitions is not allowed in this version of MariaDB
ALTER TABLE tsp EXCHANGE PARTITION sp00 WITH TABLE tsp_00;
diff --git a/mysql-test/suite/parts/r/partition_exch_qa_6.result b/mysql-test/suite/parts/r/partition_exch_qa_6.result
index 92527ab1dd9..1d285a19390 100644
--- a/mysql-test/suite/parts/r/partition_exch_qa_6.result
+++ b/mysql-test/suite/parts/r/partition_exch_qa_6.result
@@ -1,8 +1,61 @@
CREATE USER test2@localhost;
+CREATE TABLE t_10 (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_100 (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_1000 (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_empty (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE t_null (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM;
+CREATE TABLE tp (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM
+PARTITION BY RANGE (a)
+(PARTITION p0 VALUES LESS THAN (10) ,
+PARTITION p1 VALUES LESS THAN (100) ,
+PARTITION p2 VALUES LESS THAN (1000) );
+CREATE TABLE tsp (a INT, b VARCHAR(55), PRIMARY KEY (a)) ENGINE = MYISAM
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH(a)
+(PARTITION p0 VALUES LESS THAN (10)
+(SUBPARTITION sp00,
+SUBPARTITION sp01,
+SUBPARTITION sp02,
+SUBPARTITION sp03,
+SUBPARTITION sp04), PARTITION p1 VALUES LESS THAN (100)
+(SUBPARTITION sp10 ,
+SUBPARTITION sp11 ,
+SUBPARTITION sp12 ,
+SUBPARTITION sp13 ,
+SUBPARTITION sp14 ),
+PARTITION p2 VALUES LESS THAN (1000)
+(SUBPARTITION sp20,
+SUBPARTITION sp21,
+SUBPARTITION sp22,
+SUBPARTITION sp23,
+SUBPARTITION sp24));
+INSERT INTO t_10 VALUES (1, "One"), (3, "Three"), (5, "Five"), (9, "Nine");
+INSERT INTO t_100 VALUES (11, "Eleven"), (13, "Thirdteen"), (15, "Fifeteen"), (19, "Nineteen");
+INSERT INTO t_100 VALUES (91, "Ninety-one"), (93, "Ninety-three"), (95, "Ninety-five"), (99, "Ninety-nine");
+INSERT INTO t_1000 VALUES (111, "Hundred elven"), (113, "Hundred thirdteen"), (115, "Hundred fiveteen"), (119, "Hundred nineteen");
+INSERT INTO t_1000 VALUES (131, "Hundred thirty-one"), (133, "Hundred thirty-three"), (135, "Hundred thirty-five"), (139, "Hundred thirty-nine");
+INSERT INTO t_1000 VALUES (151, "Hundred fifty-one"), (153, "Hundred fifty-three"), (155, "Hundred fity-five"), (159, "Hundred fifty-nine");
+INSERT INTO t_1000 VALUES (191, "Hundred ninety-one"), (193, "Hundred ninety-three"), (195, "Hundred ninety-five"), (199, "Hundred ninety-nine");
+INSERT INTO t_null VALUES (1, "NULL");
+INSERT INTO tp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tp VALUES (182, "Hundred eighty-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+INSERT INTO tsp VALUES (2, "Two"), (4, "Four"), (6, "Six"), (8, "Eight");
+INSERT INTO tsp VALUES (12, "twelve"), (14, "Fourteen"), (16, "Sixteen"), (18, "Eightteen");
+INSERT INTO tsp VALUES (112, "Hundred twelve"), (114, "Hundred fourteen"), (116, "Hundred sixteen"), (118, "Hundred eightteen");
+INSERT INTO tsp VALUES (122, "Hundred twenty-two"), (124, "Hundred twenty-four"), (126, "Hundred twenty-six"), (128, "Hundred twenty-eight");
+INSERT INTO tsp VALUES (162, "Hundred sixty-two"), (164, "Hundred sixty-four"), (166, "Hundred sixty-six"), (168, "Hundred sixty-eight");
+INSERT INTO tsp VALUES (182, "Hundred eight-two"), (184, "Hundred eighty-four"), (186, "Hundred eighty-six"), (188, "Hundred eighty-eight");
+CREATE TABLE tsp_01(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 1;
+CREATE TABLE tsp_02(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 2;
+CREATE TABLE tsp_03(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 3;
+CREATE TABLE tsp_04(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 4;
+CREATE TABLE tsp_00(a INT,b VARCHAR(55),PRIMARY KEY (a)) ENGINE = MYISAM AS SELECT a, b FROM t_10 WHERE MOD(a,5)= 0;
GRANT USAGE ON *.* TO test2@localhost;
GRANT CREATE, DROP, ALTER, UPDATE, INSERT, SELECT ON test.* TO test2@localhost;
-connect (test2,localhost,test2,,test,MASTER_MYPORT,MASTER_MYSOCK);
-USE test;
SHOW GRANTS FOR CURRENT_USER;
Grants for test2@localhost
GRANT USAGE ON *.* TO 'test2'@'localhost'
@@ -53,10 +106,7 @@ a b
4 Four
6 Six
8 Eight
-disconnect test2;
-connection default;
REVOKE INSERT ON test.* FROM test2@localhost;
-connect (test2,localhost,test2,,test,MASTER_MYPORT,MASTER_MYSOCK);
USE test;
SHOW GRANTS FOR CURRENT_USER;
Grants for test2@localhost
@@ -64,11 +114,8 @@ GRANT USAGE ON *.* TO 'test2'@'localhost'
GRANT SELECT, UPDATE, CREATE, DROP, ALTER ON `test`.* TO 'test2'@'localhost'
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
ERROR 42000: INSERT command denied to user 'test2'@'localhost' for table 'tp'
-disconnect test2;
-connection default;
GRANT INSERT ON test.* TO test2@localhost;
REVOKE CREATE ON test.* FROM test2@localhost;
-connect (test2,localhost,test2,,test,MASTER_MYPORT,MASTER_MYSOCK);
USE test;
SHOW GRANTS FOR CURRENT_USER;
Grants for test2@localhost
@@ -76,20 +123,14 @@ GRANT USAGE ON *.* TO 'test2'@'localhost'
GRANT SELECT, INSERT, UPDATE, DROP, ALTER ON `test`.* TO 'test2'@'localhost'
ALTER TABLE tsp EXCHANGE PARTITION sp00 WITH TABLE tsp_00;
ERROR 42000: CREATE command denied to user 'test2'@'localhost' for table 'tsp'
-disconnect test2;
-connection default;
GRANT CREATE ON test.* TO test2@localhost;
REVOKE DROP ON test.* FROM test2@localhost;
-connect (test2,localhost,test2,,test,MASTER_MYPORT,MASTER_MYSOCK);
-USE test;
SHOW GRANTS FOR CURRENT_USER;
Grants for test2@localhost
GRANT USAGE ON *.* TO 'test2'@'localhost'
GRANT SELECT, INSERT, UPDATE, CREATE, ALTER ON `test`.* TO 'test2'@'localhost'
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
ERROR 42000: DROP command denied to user 'test2'@'localhost' for table 'tp'
-disconnect test2;
-connection default;
DROP TABLE IF EXISTS t_10;
DROP TABLE IF EXISTS t_100;
DROP TABLE IF EXISTS t_1000;
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
new file mode 100644
index 00000000000..e21f0dfab82
--- /dev/null
+++ b/mysql-test/suite/parts/t/partition_alter_maria.test
@@ -0,0 +1,21 @@
+#
+# MDEV-13937 Aria engine: Internal Error 160 after partition handling
+#
+source include/have_partition.inc;
+create table t1 (
+ pk bigint not null auto_increment,
+ dt datetime default null,
+ unique (pk, dt)
+) engine=aria row_format=dynamic
+ partition by range columns(dt) (
+ partition `p20171231` values less than ('2017-12-31'),
+ partition `p20181231` values less than ('2018-12-31')
+);
+insert into t1 values (1,'2017-09-28 15:12:00');
+select * from t1;
+alter table t1 drop partition p20181231;
+select * from 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..b2bd0e72e4c
--- /dev/null
+++ b/mysql-test/suite/parts/t/partition_alter_myisam.test
@@ -0,0 +1,22 @@
+--source include/have_partition.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;
+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');
+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_exch_myisam_innodb.test b/mysql-test/suite/parts/t/partition_exch_myisam_innodb.test
index fa956f19aec..c625ad93775 100644
--- a/mysql-test/suite/parts/t/partition_exch_myisam_innodb.test
+++ b/mysql-test/suite/parts/t/partition_exch_myisam_innodb.test
@@ -1,21 +1,17 @@
# Author: Horst Hunger
# Created: 2010-07-05
---source include/have_innodb.inc
---source include/have_partition.inc
+source include/have_innodb.inc;
+source include/have_partition.inc;
let $engine_table= MYISAM;
let $engine_part= InnoDB;
let $engine_subpart= InnoDB;
---disable_result_log
---disable_query_log
---source suite/parts/inc/part_exch_tabs.inc
---enable_result_log
---enable_query_log
+source suite/parts/inc/part_exch_tabs.inc;
---error 1497
+error ER_MIX_HANDLER_ERROR;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
---source suite/parts/inc/part_exch_drop_tabs.inc
+source suite/parts/inc/part_exch_drop_tabs.inc;
diff --git a/mysql-test/suite/parts/t/partition_exch_qa_14.test b/mysql-test/suite/parts/t/partition_exch_qa_14.test
index 7c6699a0a72..8d9f201f1db 100644
--- a/mysql-test/suite/parts/t/partition_exch_qa_14.test
+++ b/mysql-test/suite/parts/t/partition_exch_qa_14.test
@@ -1,94 +1,66 @@
# Author: Horst Hunger
# Created: 2010-07-13
---source include/not_windows.inc
---source include/have_partition.inc
---source include/have_symlink.inc
+source include/not_windows.inc;
+source include/have_partition.inc;
+source include/have_symlink.inc;
let $engine_table= MYISAM;
let $engine_part= MYISAM;
let $engine_subpart= MYISAM;
-
-# DATA DIRECTORY
-# Make directory for partition data
-let $data_dir_path= $MYSQLTEST_VARDIR/mysql-test-data-dir;
---mkdir $data_dir_path
-let $p_data_directory= DATA DIRECTORY = '$data_dir_path';
-let $data_directory= DATA DIRECTORY = '$data_dir_path';
-
-# INDEX DIRECTORY
-# Make directory for partition index
-let $idx_dir_path= $MYSQLTEST_VARDIR/mysql-test-idx-dir;
---mkdir $idx_dir_path
-let $p_index_directory= INDEX DIRECTORY = '$idx_dir_path';
-let $index_directory= INDEX DIRECTORY = '$idx_dir_path';
-
-use test;
-
---disable_result_log
---disable_query_log
---source suite/parts/inc/part_exch_tabs.inc
---enable_result_log
---enable_query_log
-
---error ER_TABLES_DIFFERENT_METADATA
-ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
-
---source suite/parts/inc/part_exch_drop_tabs.inc
---rmdir $data_dir_path
---rmdir $idx_dir_path
-
-# DATA DIRECTORY
-# Make directory for partition data
let $data_dir_path= $MYSQLTEST_VARDIR/mysql-test-data-dir;
---mkdir $data_dir_path
-let $p_data_directory= DATA DIRECTORY = '$data_dir_path';
-
-# INDEX DIRECTORY
-# Make directory for partition index
let $idx_dir_path= $MYSQLTEST_VARDIR/mysql-test-idx-dir;
---mkdir $idx_dir_path
-let $p_index_directory= INDEX DIRECTORY = '$idx_dir_path';
-
-use test;
-
---disable_result_log
---disable_query_log
---source suite/parts/inc/part_exch_tabs.inc
---enable_result_log
---enable_query_log
-
---error ER_TABLES_DIFFERENT_METADATA
-ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
-
---source suite/parts/inc/part_exch_drop_tabs.inc
---rmdir $data_dir_path
---rmdir $idx_dir_path
-
-# DATA DIRECTORY
-# Make directory for partition data
-let $data_dir_path= $MYSQLTEST_VARDIR/mysql-test-data-dir;
---mkdir $data_dir_path
-let $data_directory= DATA DIRECTORY = '$data_dir_path';
-
-# INDEX DIRECTORY
-# Make directory for partition index
-let $idx_dir_path= $MYSQLTEST_VARDIR/mysql-test-idx-dir;
---mkdir $idx_dir_path
-let $index_directory= INDEX DIRECTORY = '$idx_dir_path';
-
-use test;
-
---disable_result_log
---disable_query_log
---source suite/parts/inc/part_exch_tabs.inc
---enable_result_log
---enable_query_log
-
---error ER_TABLES_DIFFERENT_METADATA
-ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
-
---source suite/parts/inc/part_exch_drop_tabs.inc
---rmdir $data_dir_path
---rmdir $idx_dir_path
-
+mkdir $data_dir_path;
+mkdir $idx_dir_path;
+
+echo # === Data/Index directories are identical;
+ let $p_data_directory= DATA DIRECTORY = '$data_dir_path';
+ let $data_directory= DATA DIRECTORY = '$data_dir_path';
+ let $p_index_directory= INDEX DIRECTORY = '$idx_dir_path';
+ let $index_directory= INDEX DIRECTORY = '$idx_dir_path';
+ source suite/parts/inc/part_exch_tabs.inc;
+ ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
+ source suite/parts/inc/part_exch_drop_tabs.inc;
+
+echo # === partition has directories, the table does not;
+ let $p_data_directory= DATA DIRECTORY = '$data_dir_path';
+ let $data_directory= ;
+ let $p_index_directory= INDEX DIRECTORY = '$idx_dir_path';
+ let $index_directory= ;
+ source suite/parts/inc/part_exch_tabs.inc;
+ error ER_TABLES_DIFFERENT_METADATA;
+ ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
+ source suite/parts/inc/part_exch_drop_tabs.inc;
+
+echo # === the table has directories, partition does not;
+ let $p_data_directory= ;
+ let $data_directory= DATA DIRECTORY = '$data_dir_path';
+ let $p_index_directory= ;
+ let $index_directory= INDEX DIRECTORY = '$idx_dir_path';
+ source suite/parts/inc/part_exch_tabs.inc;
+ error ER_TABLES_DIFFERENT_METADATA;
+ ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
+ source suite/parts/inc/part_exch_drop_tabs.inc;
+
+echo # === data directory differs;
+ let $p_data_directory= DATA DIRECTORY = '$data_dir_path';
+ let $data_directory= DATA DIRECTORY = '$idx_dir_path';
+ let $p_index_directory= INDEX DIRECTORY = '$idx_dir_path';
+ let $index_directory= INDEX DIRECTORY = '$idx_dir_path';
+ source suite/parts/inc/part_exch_tabs.inc;
+ error ER_TABLES_DIFFERENT_METADATA;
+ ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
+ source suite/parts/inc/part_exch_drop_tabs.inc;
+
+echo # === index directory differs;
+ let $p_data_directory= DATA DIRECTORY = '$data_dir_path';
+ let $data_directory= DATA DIRECTORY = '$data_dir_path';
+ let $p_index_directory= DATA DIRECTORY = '$data_dir_path';
+ let $index_directory= DATA DIRECTORY = '$idx_dir_path';
+ source suite/parts/inc/part_exch_tabs.inc;
+ error ER_TABLES_DIFFERENT_METADATA;
+ ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
+ source suite/parts/inc/part_exch_drop_tabs.inc;
+
+rmdir $idx_dir_path;
+rmdir $data_dir_path;
diff --git a/mysql-test/suite/parts/t/partition_exch_qa_15.test b/mysql-test/suite/parts/t/partition_exch_qa_15.test
index 51d09be5ed9..8ea641c8178 100644
--- a/mysql-test/suite/parts/t/partition_exch_qa_15.test
+++ b/mysql-test/suite/parts/t/partition_exch_qa_15.test
@@ -1,8 +1,8 @@
# Author: Horst Hunger
# Created: 2010-07-15
---source include/have_innodb.inc
---source include/have_partition.inc
+source include/have_innodb.inc;
+source include/have_partition.inc;
let $engine_table= InnoDB;
let $engine_part= InnoDB;
@@ -10,11 +10,7 @@ let $engine_subpart= InnoDB;
use test;
---disable_result_log
---disable_query_log
---source suite/parts/inc/part_exch_tabs.inc
---enable_result_log
---enable_query_log
+source suite/parts/inc/part_exch_tabs.inc;
# 21) Foreign Key.
# Exchange of partition with table differing in structure.
@@ -22,10 +18,8 @@ CREATE TABLE t_11 (a INT, b VARCHAR(55),
FOREIGN KEY (a) REFERENCES t_10 (a) ON DELETE CASCADE)
ENGINE= InnoDB;
#--error ER_TABLES_DIFFERENT_METADATA
---error ER_PARTITION_EXCHANGE_FOREIGN_KEY
+error ER_PARTITION_EXCHANGE_FOREIGN_KEY;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_11;
---disable_warnings
-DROP TABLE IF EXISTS t_11;
---enable_warnings
---source suite/parts/inc/part_exch_drop_tabs.inc
+DROP TABLE t_11;
+source suite/parts/inc/part_exch_drop_tabs.inc;
diff --git a/mysql-test/suite/parts/t/partition_exch_qa_2.test b/mysql-test/suite/parts/t/partition_exch_qa_2.test
index 83dc0a81fca..1858131ce10 100644
--- a/mysql-test/suite/parts/t/partition_exch_qa_2.test
+++ b/mysql-test/suite/parts/t/partition_exch_qa_2.test
@@ -1,7 +1,7 @@
# Author: Horst Hunger
# Created: 2010-07-05
---source include/have_partition.inc
+source include/have_partition.inc;
let $engine_table= MYISAM;
let $engine_part= MYISAM;
@@ -9,72 +9,61 @@ let $engine_subpart= MYISAM;
use test;
---disable_result_log
---disable_query_log
---source suite/parts/inc/part_exch_tabs.inc
---enable_result_log
---enable_query_log
+source suite/parts/inc/part_exch_tabs.inc;
---sorted_result
+sorted_result;
SELECT * FROM t_10;
---sorted_result
+sorted_result;
SELECT * FROM t_100;
---sorted_result
+sorted_result;
SELECT * FROM t_1000;
---sorted_result
+sorted_result;
SELECT * FROM tp;
---sorted_result
+sorted_result;
SELECT * FROM tsp;
---sorted_result
+sorted_result;
SELECT * FROM tsp_00;
---sorted_result
+sorted_result;
SELECT * FROM tsp_01;
---sorted_result
+sorted_result;
SELECT * FROM tsp_02;
---sorted_result
+sorted_result;
SELECT * FROM tsp_03;
---sorted_result
+sorted_result;
SELECT * FROM tsp_04;
# 3) Invalid exchanges.
# Exchange of partition with table differing in structure.
CREATE TABLE t_11(a INT,b VARCHAR(55)) SELECT * FROM t_10;
---error ER_TABLES_DIFFERENT_METADATA
+error ER_TABLES_DIFFERENT_METADATA;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_11;
---disable_warnings
-DROP TABLE IF EXISTS t_11;
---enable_warnings
+DROP TABLE t_11;
eval CREATE TABLE t_11(a INT,b CHAR(55),PRIMARY KEY(a)) ENGINE= $engine_table SELECT * FROM t_10;
---error ER_TABLES_DIFFERENT_METADATA
+error ER_TABLES_DIFFERENT_METADATA;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_11;
---disable_warnings
-DROP TABLE IF EXISTS t_11;
+DROP TABLE t_11;
CREATE TABLE t_11(a INT,b VARCHAR(55),PRIMARY KEY(a)) ENGINE= MEMORY SELECT * FROM t_10;
---error ER_MIX_HANDLER_ERROR
+error ER_MIX_HANDLER_ERROR;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_11;
---disable_warnings
-DROP TABLE IF EXISTS t_11;
---enable_warnings
+DROP TABLE t_11;
# Exchange of partition with partitioned table.
eval CREATE TABLE t_11(a INT,b CHAR(55),PRIMARY KEY(a)) ENGINE= $engine_table
PARTITION BY KEY() AS SELECT * FROM t_10;
---error ER_PARTITION_EXCHANGE_PART_TABLE
+error ER_PARTITION_EXCHANGE_PART_TABLE;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_11;
---disable_warnings
-DROP TABLE IF EXISTS t_11;
---enable_warnings
+DROP TABLE t_11;
# Exchange of subpartition with partitioned table.
---error ER_PARTITION_EXCHANGE_PART_TABLE
+error ER_PARTITION_EXCHANGE_PART_TABLE;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE tsp;
# Exchange of subpartitioned partition with table.
---error ER_PARTITION_INSTEAD_OF_SUBPARTITION
+error ER_PARTITION_INSTEAD_OF_SUBPARTITION;
ALTER TABLE tsp EXCHANGE PARTITION p0 WITH TABLE t_10;
# Exchange of values in partition not fitting the hash.
---error ER_ROW_DOES_NOT_MATCH_PARTITION
+error ER_ROW_DOES_NOT_MATCH_PARTITION;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_100;
# Exchange of values in subpartition not fitting the hash.
---error ER_ROW_DOES_NOT_MATCH_PARTITION
+error ER_ROW_DOES_NOT_MATCH_PARTITION;
ALTER TABLE tp EXCHANGE PARTITION p2 WITH TABLE t_10;
---source suite/parts/inc/part_exch_drop_tabs.inc
+source suite/parts/inc/part_exch_drop_tabs.inc;
diff --git a/mysql-test/suite/parts/t/partition_exch_qa_3.test b/mysql-test/suite/parts/t/partition_exch_qa_3.test
index aa79e97adb6..fc49eb1da90 100644
--- a/mysql-test/suite/parts/t/partition_exch_qa_3.test
+++ b/mysql-test/suite/parts/t/partition_exch_qa_3.test
@@ -1,8 +1,8 @@
# Author: Horst Hunger
# Created: 2010-07-05
---source include/have_partition.inc
---source include/have_innodb.inc
+source include/have_partition.inc;
+source include/have_innodb.inc;
let $engine_table= MYISAM;
let $engine_part= InnoDB;
@@ -10,38 +10,34 @@ let $engine_subpart= InnoDB;
use test;
---disable_result_log
---disable_query_log
---source suite/parts/inc/part_exch_tabs.inc
+source suite/parts/inc/part_exch_tabs.inc;
---sorted_result
+sorted_result;
SELECT * FROM t_10;
---sorted_result
+sorted_result;
SELECT * FROM t_100;
---sorted_result
+sorted_result;
SELECT * FROM t_1000;
---sorted_result
+sorted_result;
SELECT * FROM tp;
---sorted_result
+sorted_result;
SELECT * FROM tsp;
---sorted_result
+sorted_result;
SELECT * FROM tsp_00;
---sorted_result
+sorted_result;
SELECT * FROM tsp_01;
---sorted_result
+sorted_result;
SELECT * FROM tsp_02;
---sorted_result
+sorted_result;
SELECT * FROM tsp_03;
---sorted_result
+sorted_result;
SELECT * FROM tsp_04;
---enable_result_log
---enable_query_log
# 5) Exchanges with different engines.
---error ER_MIX_HANDLER_ERROR
+error ER_MIX_HANDLER_ERROR;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
---error ER_MIX_HANDLER_ERROR
+error ER_MIX_HANDLER_ERROR;
ALTER TABLE tsp EXCHANGE PARTITION sp00 WITH TABLE tsp_00;
---source suite/parts/inc/part_exch_drop_tabs.inc
+source suite/parts/inc/part_exch_drop_tabs.inc;
diff --git a/mysql-test/suite/parts/t/partition_exch_qa_6.test b/mysql-test/suite/parts/t/partition_exch_qa_6.test
index bad1e134af7..7b6b42480b0 100644
--- a/mysql-test/suite/parts/t/partition_exch_qa_6.test
+++ b/mysql-test/suite/parts/t/partition_exch_qa_6.test
@@ -1,8 +1,8 @@
# Author: Horst Hunger
# Created: 2010-07-06
---source include/not_embedded.inc
---source include/have_partition.inc
+source include/not_embedded.inc;
+source include/have_partition.inc;
let $engine_table= MYISAM;
let $engine_part= MYISAM;
@@ -10,93 +10,75 @@ let $engine_subpart= MYISAM;
CREATE USER test2@localhost;
---disable_result_log
---disable_query_log
---source suite/parts/inc/part_exch_tabs.inc
---enable_result_log
---enable_query_log
+source suite/parts/inc/part_exch_tabs.inc;
GRANT USAGE ON *.* TO test2@localhost;
GRANT CREATE, DROP, ALTER, UPDATE, INSERT, SELECT ON test.* TO test2@localhost;
---echo connect (test2,localhost,test2,,test,MASTER_MYPORT,MASTER_MYSOCK);
connect (test2,localhost,test2,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
-USE test;
SHOW GRANTS FOR CURRENT_USER;
# 9) Exchanges with different owner.
# Privilege for ALTER and SELECT
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
---sorted_result
+sorted_result;
SELECT * FROM t_10;
---sorted_result
+sorted_result;
SELECT * FROM tp WHERE a BETWEEN 0 AND 10;
# Back to former values.
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
---sorted_result
+sorted_result;
SELECT * FROM t_10;
---sorted_result
+sorted_result;
SELECT * FROM tp WHERE a BETWEEN 0 AND 10;
ALTER TABLE tsp EXCHANGE PARTITION sp00 WITH TABLE tsp_00;
---sorted_result
+sorted_result;
SELECT * FROM tsp_00;
---sorted_result
+sorted_result;
SELECT * FROM tsp WHERE a BETWEEN 0 AND 10;
# Back to former values.
ALTER TABLE tsp EXCHANGE PARTITION sp00 WITH TABLE tsp_00;
---sorted_result
+sorted_result;
SELECT * FROM tsp_00;
---sorted_result
+sorted_result;
SELECT * FROM tsp WHERE a BETWEEN 0 AND 10;
---echo disconnect test2;
disconnect test2;
---echo connection default;
connection default;
REVOKE INSERT ON test.* FROM test2@localhost;
---echo connect (test2,localhost,test2,,test,MASTER_MYPORT,MASTER_MYSOCK);
connect (test2,localhost,test2,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
USE test;
SHOW GRANTS FOR CURRENT_USER;
# Privilege for ALTER and SELECT
---error ER_TABLEACCESS_DENIED_ERROR
+error ER_TABLEACCESS_DENIED_ERROR;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
---echo disconnect test2;
disconnect test2;
---echo connection default;
connection default;
GRANT INSERT ON test.* TO test2@localhost;
REVOKE CREATE ON test.* FROM test2@localhost;
---echo connect (test2,localhost,test2,,test,MASTER_MYPORT,MASTER_MYSOCK);
connect (test2,localhost,test2,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
USE test;
SHOW GRANTS FOR CURRENT_USER;
---error ER_TABLEACCESS_DENIED_ERROR
+error ER_TABLEACCESS_DENIED_ERROR;
ALTER TABLE tsp EXCHANGE PARTITION sp00 WITH TABLE tsp_00;
---echo disconnect test2;
disconnect test2;
---echo connection default;
connection default;
GRANT CREATE ON test.* TO test2@localhost;
REVOKE DROP ON test.* FROM test2@localhost;
---echo connect (test2,localhost,test2,,test,MASTER_MYPORT,MASTER_MYSOCK);
connect (test2,localhost,test2,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
-USE test;
SHOW GRANTS FOR CURRENT_USER;
# Privilege for ALTER and SELECT
---error ER_TABLEACCESS_DENIED_ERROR
+error ER_TABLEACCESS_DENIED_ERROR;
ALTER TABLE tp EXCHANGE PARTITION p0 WITH TABLE t_10;
---echo disconnect test2;
disconnect test2;
---echo connection default;
connection default;
---source suite/parts/inc/part_exch_drop_tabs.inc
+source suite/parts/inc/part_exch_drop_tabs.inc;
DROP USER test2@localhost;
diff --git a/mysql-test/suite/parts/t/rpl_partition.test b/mysql-test/suite/parts/t/rpl_partition.test
index e278b236f7b..cb6f84bbc71 100644
--- a/mysql-test/suite/parts/t/rpl_partition.test
+++ b/mysql-test/suite/parts/t/rpl_partition.test
@@ -1,7 +1,7 @@
--source include/have_partition.inc
--source include/have_innodb.inc
---source include/master-slave.inc
--source include/big_test.inc
+--source include/master-slave.inc
--vertical_results
diff --git a/mysql-test/suite/perfschema/r/misc.result b/mysql-test/suite/perfschema/r/misc.result
index 2adf2cba851..7a097a27576 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/start_server_low_digest.result b/mysql-test/suite/perfschema/r/start_server_low_digest.result
index 8cc92f21964..6fc41fbb715 100644
--- a/mysql-test/suite/perfschema/r/start_server_low_digest.result
+++ b/mysql-test/suite/perfschema/r/start_server_low_digest.result
@@ -8,5 +8,5 @@ SELECT 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+1+1+1+1+1
####################################
SELECT event_name, digest, digest_text, sql_text FROM events_statements_history_long;
event_name digest digest_text sql_text
-statement/sql/truncate e1c917a43f978456fab15240f89372ca TRUNCATE TABLE truncate table events_statements_history_long
-statement/sql/select 3f7ca34376814d0e985337bd588b5ffd SELECT ? + ? + SELECT 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+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+1+1+1+1+1+1+1+1+1+1
+statement/sql/truncate 6206ac02a54d832f55015e480e6f2213 TRUNCATE TABLE truncate table events_statements_history_long
+statement/sql/select 4cc1c447d79877c4e8df0423fd0cde9a SELECT ? + ? + SELECT 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+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+1+1+1+1+1+1+1+1+1+1
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/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/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result
index ceb75176b43..3971504b238 100644
--- a/mysql-test/suite/plugins/r/server_audit.result
+++ b/mysql-test/suite/plugins/r/server_audit.result
@@ -47,6 +47,7 @@ alter table t1 rename renamed_t1;
set global server_audit_events='connect,query';
select 1,
2,
+# comment
3;
1 2 3
1 2 3
@@ -161,7 +162,9 @@ id
2
CREATE USER u1 IDENTIFIED BY 'pwd-123';
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
-SET PASSWORD FOR u1 = PASSWORD('pwd 098');
+SET PASSWORD
+# comment
+FOR u1 = PASSWORD('pwd 098');
SET PASSWORD FOR u1=<secret>;
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 '<secret>' at line 1
CREATE USER u3 IDENTIFIED BY '';
@@ -253,7 +256,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,index_stats,
TIME,HOSTNAME,root,localhost,ID,ID,RENAME,test,t1|test.renamed_t1,
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'alter table t1 rename renamed_t1',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_events=\'connect,query\'',0
-TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1, 2, 3',0
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1,\n2,\n# comment\n3',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'insert into t2 values (1), (2)',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t2',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t_doesnt_exist',ID
@@ -336,7 +339,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*! select 2*/',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*comment*/ select 2',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u1 IDENTIFIED BY *****',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'GRANT ALL ON sa_db TO u2 IDENTIFIED BY *****',0
-TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1 = PASSWORD(*****)',0
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD \n# comment\nFOR u1 = PASSWORD(*****)',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1=<secret>',ID
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop user u1, u2, u3',0
diff --git a/mysql-test/suite/plugins/r/thread_pool_server_audit.result b/mysql-test/suite/plugins/r/thread_pool_server_audit.result
index ceb75176b43..912cef2761a 100644
--- a/mysql-test/suite/plugins/r/thread_pool_server_audit.result
+++ b/mysql-test/suite/plugins/r/thread_pool_server_audit.result
@@ -47,6 +47,7 @@ alter table t1 rename renamed_t1;
set global server_audit_events='connect,query';
select 1,
2,
+# comment
3;
1 2 3
1 2 3
@@ -161,7 +162,9 @@ id
2
CREATE USER u1 IDENTIFIED BY 'pwd-123';
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
-SET PASSWORD FOR u1 = PASSWORD('pwd 098');
+SET PASSWORD
+# comment
+FOR u1 = PASSWORD('pwd 098');
SET PASSWORD FOR u1=<secret>;
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 '<secret>' at line 1
CREATE USER u3 IDENTIFIED BY '';
@@ -253,7 +256,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,index_stats,
TIME,HOSTNAME,root,localhost,ID,ID,RENAME,test,t1|test.renamed_t1,
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'alter table t1 rename renamed_t1',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_events=\'connect,query\'',0
-TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1, 2, 3',0
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1,\n2,\n# comment\n3',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'insert into t2 values (1), (2)',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t2',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t_doesnt_exist',ID
@@ -336,7 +339,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*! select 2*/',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*comment*/ select 2',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u1 IDENTIFIED BY *****',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'GRANT ALL ON sa_db TO u2 IDENTIFIED BY *****',0
-TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1 = PASSWORD(*****)',0
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD\n# comment\nFOR u1 = PASSWORD(*****)',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1=<secret>',ID
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop user u1, u2, u3',0
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 52428909c3b..9be0d5556f0 100644
--- a/mysql-test/suite/plugins/t/server_audit.test
+++ b/mysql-test/suite/plugins/t/server_audit.test
@@ -38,6 +38,7 @@ alter table t1 rename renamed_t1;
set global server_audit_events='connect,query';
select 1,
2,
+# comment
3;
insert into t2 values (1), (2);
select * from t2;
@@ -106,7 +107,9 @@ insert into t1 values (1), (2);
select * from t1;
CREATE USER u1 IDENTIFIED BY 'pwd-123';
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
-SET PASSWORD FOR u1 = PASSWORD('pwd 098');
+SET PASSWORD
+# comment
+FOR u1 = PASSWORD('pwd 098');
--error 1064
SET PASSWORD FOR u1=<secret>;
CREATE USER u3 IDENTIFIED BY '';
diff --git a/mysql-test/suite/plugins/t/thread_pool_server_audit.test b/mysql-test/suite/plugins/t/thread_pool_server_audit.test
index 626d4136c47..724000c9789 100644
--- a/mysql-test/suite/plugins/t/thread_pool_server_audit.test
+++ b/mysql-test/suite/plugins/t/thread_pool_server_audit.test
@@ -38,6 +38,7 @@ alter table t1 rename renamed_t1;
set global server_audit_events='connect,query';
select 1,
2,
+# comment
3;
insert into t2 values (1), (2);
select * from t2;
@@ -106,7 +107,9 @@ insert into t1 values (1), (2);
select * from t1;
CREATE USER u1 IDENTIFIED BY 'pwd-123';
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
-SET PASSWORD FOR u1 = PASSWORD('pwd 098');
+SET PASSWORD
+# comment
+FOR u1 = PASSWORD('pwd 098');
--error 1064
SET PASSWORD FOR u1=<secret>;
CREATE USER u3 IDENTIFIED BY '';
diff --git a/mysql-test/suite/roles/definer.result b/mysql-test/suite/roles/definer.result
index 7ced6255629..f2fca91f0ea 100644
--- a/mysql-test/suite/roles/definer.result
+++ b/mysql-test/suite/roles/definer.result
@@ -626,3 +626,117 @@ show grants for utest;
Grants for utest
GRANT SELECT ON *.* TO 'utest'
drop role utest;
+#
+# MDEV-13676: Field "create Procedure" is NULL, even if the the user
+# has role which is the definer. (SHOW CREATE PROCEDURE)
+#
+create database rtest;
+create role r1;
+create role r2;
+create role r3;
+grant all privileges on rtest.* to r1;
+create user user1;
+grant r1 to user1;
+grant r1 to r2;
+grant r2 to user1;
+grant r3 to user1;
+set role r2;
+use rtest;
+CREATE DEFINER=current_role() PROCEDURE user1_proc() SQL SECURITY INVOKER
+BEGIN
+SELECT NOW(), VERSION();
+END;//
+set role r2;
+show create procedure user1_proc;
+Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
+user1_proc NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`r2` PROCEDURE `user1_proc`()
+ SQL SECURITY INVOKER
+BEGIN
+SELECT NOW(), VERSION();
+END latin1 latin1_swedish_ci latin1_swedish_ci
+#
+# Currently one can not use as definer any role except CURRENT_ROLE
+#
+CREATE DEFINER='r1' PROCEDURE user1_proc2() SQL SECURITY INVOKER
+BEGIN
+SELECT NOW(), VERSION();
+END;//
+ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
+set role r1;
+CREATE DEFINER='r1' PROCEDURE user1_proc2() SQL SECURITY INVOKER
+BEGIN
+SELECT NOW(), VERSION();
+END;//
+show create procedure user1_proc2;
+Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
+user1_proc2 NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`r1` PROCEDURE `user1_proc2`()
+ SQL SECURITY INVOKER
+BEGIN
+SELECT NOW(), VERSION();
+END latin1 latin1_swedish_ci latin1_swedish_ci
+#
+# Test to see if the user can still see the procedure code if the
+# role that owns it is granted to him indirectly.
+#
+set role r2;
+show create procedure user1_proc2;
+Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
+user1_proc2 NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`r1` PROCEDURE `user1_proc2`()
+ SQL SECURITY INVOKER
+BEGIN
+SELECT NOW(), VERSION();
+END latin1 latin1_swedish_ci latin1_swedish_ci
+#
+# One should not be able to see the procedure code if the role that owns
+# the procedure is not set by the user or is not in the subgraph of the
+# currently active role.
+#
+set role r3;
+show create procedure user1_proc2;
+ERROR 42000: PROCEDURE user1_proc2 does not exist
+use rtest;
+#
+# Try a few edge cases, with usernames identical to role name;
+#
+create user user_like_role;
+create user foo;
+create role user_like_role;
+grant select on rtest.* to user_like_role;
+grant select on rtest.* to foo;
+grant select on rtest.* to user_like_role@'%';
+grant user_like_role to foo;
+#
+# Here we have a procedure that is owned by user_like_role USER
+# We don't want user_like_role ROLE to have access to its code.
+#
+CREATE DEFINER=`user_like_role`@`%` PROCEDURE sensitive_proc() SQL SECURITY INVOKER
+BEGIN
+SELECT NOW(), VERSION();
+END;//
+use rtest;
+show create procedure sensitive_proc;
+Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
+sensitive_proc NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`user_like_role`@`%` PROCEDURE `sensitive_proc`()
+ SQL SECURITY INVOKER
+BEGIN
+SELECT NOW(), VERSION();
+END latin1 latin1_swedish_ci latin1_swedish_ci
+set role user_like_role;
+use rtest;
+#
+# Foo has the set rolename identical to the procedure's definer's username.
+# Foo should not have access to this procedure.
+#
+show create procedure sensitive_proc;
+ERROR 42000: PROCEDURE sensitive_proc does not exist
+drop role r1;
+drop role r2;
+drop role r3;
+drop role user_like_role;
+drop user user1;
+drop user foo;
+drop user user_like_role;
+drop procedure user1_proc;
+drop procedure user1_proc2;
+drop procedure sensitive_proc;
+drop database rtest;
diff --git a/mysql-test/suite/roles/definer.test b/mysql-test/suite/roles/definer.test
index 3de4a6922c2..89a1c90ee24 100644
--- a/mysql-test/suite/roles/definer.test
+++ b/mysql-test/suite/roles/definer.test
@@ -332,3 +332,125 @@ execute stmt1;
show grants for utest;
drop role utest;
+--echo #
+--echo # MDEV-13676: Field "create Procedure" is NULL, even if the the user
+--echo # has role which is the definer. (SHOW CREATE PROCEDURE)
+--echo #
+
+create database rtest;
+create role r1;
+create role r2;
+create role r3;
+grant all privileges on rtest.* to r1;
+
+create user user1;
+grant r1 to user1;
+grant r1 to r2;
+grant r2 to user1;
+grant r3 to user1;
+
+connect (user1, localhost,user1,,,,,);
+set role r2;
+use rtest;
+
+DELIMITER //;
+CREATE DEFINER=current_role() PROCEDURE user1_proc() SQL SECURITY INVOKER
+ BEGIN
+ SELECT NOW(), VERSION();
+ END;//
+DELIMITER ;//
+
+set role r2;
+show create procedure user1_proc;
+
+--echo #
+--echo # Currently one can not use as definer any role except CURRENT_ROLE
+--echo #
+DELIMITER //;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+CREATE DEFINER='r1' PROCEDURE user1_proc2() SQL SECURITY INVOKER
+ BEGIN
+ SELECT NOW(), VERSION();
+ END;//
+DELIMITER ;//
+
+set role r1;
+DELIMITER //;
+CREATE DEFINER='r1' PROCEDURE user1_proc2() SQL SECURITY INVOKER
+ BEGIN
+ SELECT NOW(), VERSION();
+ END;//
+DELIMITER ;//
+
+show create procedure user1_proc2;
+--echo #
+--echo # Test to see if the user can still see the procedure code if the
+--echo # role that owns it is granted to him indirectly.
+--echo #
+set role r2;
+show create procedure user1_proc2;
+
+--echo #
+--echo # One should not be able to see the procedure code if the role that owns
+--echo # the procedure is not set by the user or is not in the subgraph of the
+--echo # currently active role.
+--echo #
+set role r3;
+--error ER_SP_DOES_NOT_EXIST
+show create procedure user1_proc2;
+
+connection default;
+
+use rtest;
+
+--echo #
+--echo # Try a few edge cases, with usernames identical to role name;
+--echo #
+
+create user user_like_role;
+create user foo;
+create role user_like_role;
+grant select on rtest.* to user_like_role;
+grant select on rtest.* to foo;
+grant select on rtest.* to user_like_role@'%';
+
+grant user_like_role to foo;
+
+--echo #
+--echo # Here we have a procedure that is owned by user_like_role USER
+--echo # We don't want user_like_role ROLE to have access to its code.
+--echo #
+DELIMITER //;
+CREATE DEFINER=`user_like_role`@`%` PROCEDURE sensitive_proc() SQL SECURITY INVOKER
+ BEGIN
+ SELECT NOW(), VERSION();
+ END;//
+DELIMITER ;//
+
+connect (user_like_role, localhost, user_like_role,,,,,);
+use rtest;
+show create procedure sensitive_proc;
+
+connect (foo, localhost, foo,,,,,);
+set role user_like_role;
+use rtest;
+
+--echo #
+--echo # Foo has the set rolename identical to the procedure's definer's username.
+--echo # Foo should not have access to this procedure.
+--echo #
+--error ER_SP_DOES_NOT_EXIST
+show create procedure sensitive_proc;
+
+connection default;
+drop role r1;
+drop role r2;
+drop role r3;
+drop role user_like_role;
+drop user user1;
+drop user foo;
+drop user user_like_role;
+drop procedure user1_proc;
+drop procedure user1_proc2;
+drop procedure sensitive_proc;
+drop database rtest;
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..5897e480cd4
--- /dev/null
+++ b/mysql-test/suite/roles/flush_roles-12366.result
@@ -0,0 +1,539 @@
+#
+# 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;
+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
+FLUSH PRIVILEGES;
+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
+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/rpl_grant_revoke_current_role-8638.test b/mysql-test/suite/roles/rpl_grant_revoke_current_role-8638.test
index 6a6c4f2a756..10e5e938884 100644
--- a/mysql-test/suite/roles/rpl_grant_revoke_current_role-8638.test
+++ b/mysql-test/suite/roles/rpl_grant_revoke_current_role-8638.test
@@ -1,5 +1,5 @@
---source include/master-slave.inc
--source include/have_binlog_format_mixed.inc
+--source include/master-slave.inc
--enable_connect_log
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..1c4841c8afd
--- /dev/null
+++ b/mysql-test/suite/roles/set_role-13655.result
@@ -0,0 +1,50 @@
+#
+# 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;
+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;
+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/rpl/r/rpl_gtid_delete_domain.result b/mysql-test/suite/rpl/r/rpl_gtid_delete_domain.result
new file mode 100644
index 00000000000..3558a6764d1
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_gtid_delete_domain.result
@@ -0,0 +1,30 @@
+include/master-slave.inc
+[connection master]
+SET @@SESSION.gtid_domain_id=0;
+CREATE TABLE t (a INT);
+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;
+SET @@SESSION.gtid_domain_id=11;
+SET @@SESSION.server_id=111;
+SET @@SESSION.gtid_seq_no=1;
+INSERT INTO t SET a=1;
+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]
+FLUSH BINARY LOGS;
+PURGE BINARY LOGS TO 'master-bin.000002';;
+FLUSH BINARY LOGS DELETE_DOMAIN_ID=(11);
+include/start_slave.inc
+INSERT INTO t SET a=1;
+include/wait_for_slave_io_error.inc [errno=1236]
+FLUSH BINARY LOGS;
+PURGE BINARY LOGS TO 'master-bin.000004';;
+FLUSH BINARY LOGS DELETE_DOMAIN_ID=(11);
+include/start_slave.inc
+SET @@SESSION.gtid_domain_id=0;
+DROP TABLE t;
+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 83ec26486e0..4ff3d45e2bb 100644
--- a/mysql-test/suite/rpl/r/rpl_row_log.result
+++ b/mysql-test/suite/rpl/r/rpl_row_log.result
@@ -215,7 +215,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 #-#-#
@@ -253,7 +252,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 3b9733a18e8..c78e0e4816e 100644
--- a/mysql-test/suite/rpl/r/rpl_row_log_innodb.result
+++ b/mysql-test/suite/rpl/r/rpl_row_log_innodb.result
@@ -215,7 +215,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 #-#-#
@@ -253,7 +252,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_sp_variables.result b/mysql-test/suite/rpl/r/rpl_sp_variables.result
new file mode 100644
index 00000000000..d64bc1a80f0
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_sp_variables.result
@@ -0,0 +1,24 @@
+include/master-slave.inc
+[connection master]
+#
+# MDEV-13685 Can not replay binary log due to Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8mb4_general_ci,COERCIBLE) for operation 'concat'
+#
+SET NAMES utf8;
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8);
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE v_id INT DEFAULT 2017;
+INSERT INTO test.t1 SELECT CONCAT(v_id, '오');
+END;
+$$
+CALL p1;
+SELECT * FROM t1;
+a
+2017오
+SET NAMES utf8;
+SELECT * FROM t1;
+a
+2017오
+DROP PROCEDURE p1;
+DROP TABLE t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_stm_log.result b/mysql-test/suite/rpl/r/rpl_stm_log.result
index da925035c9c..4d187095d17 100644
--- a/mysql-test/suite/rpl/r/rpl_stm_log.result
+++ b/mysql-test/suite/rpl/r/rpl_stm_log.result
@@ -215,7 +215,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 #-#-#
@@ -252,7 +251,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_temporal_format_mariadb53_to_mysql56_dst.result b/mysql-test/suite/rpl/r/rpl_temporal_format_mariadb53_to_mysql56_dst.result
new file mode 100644
index 00000000000..352101cb8cd
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_temporal_format_mariadb53_to_mysql56_dst.result
@@ -0,0 +1,28 @@
+include/master-slave.inc
+[connection master]
+set global time_zone='Europe/Moscow';
+set time_zone='UTC';
+stop slave;
+start slave;
+set global mysql56_temporal_format=false;
+set global time_zone='Europe/Moscow';
+set time_zone='UTC';
+create table t1 (pk int primary key, t timestamp not null);
+set timestamp = 1288477526;
+insert into t1 values (1,null);
+set timestamp = 1288481126;
+insert into t1 values (2,null);
+select pk, t, unix_timestamp(t) from t1;
+pk t unix_timestamp(t)
+1 2010-10-30 22:25:26 1288477526
+2 2010-10-30 23:25:26 1288481126
+set time_zone=default;
+select pk, t, unix_timestamp(t) from t1;
+pk t unix_timestamp(t)
+1 2010-10-31 02:25:26 1288477526
+2 2010-10-31 02:25:26 1288481126
+set global time_zone=default;
+drop table t1;
+set global time_zone=default;
+set global mysql56_temporal_format=default;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_alter_extra_persistent.test b/mysql-test/suite/rpl/t/rpl_alter_extra_persistent.test
index 3b2fff1cb13..4e604787c70 100644
--- a/mysql-test/suite/rpl/t/rpl_alter_extra_persistent.test
+++ b/mysql-test/suite/rpl/t/rpl_alter_extra_persistent.test
@@ -1,5 +1,5 @@
---source include/master-slave.inc
--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
--enable_connect_log
--connection master
diff --git a/mysql-test/suite/rpl/t/rpl_auto_increment_bug45679.test b/mysql-test/suite/rpl/t/rpl_auto_increment_bug45679.test
index 6996e1c73c7..32f08be7c4d 100644
--- a/mysql-test/suite/rpl/t/rpl_auto_increment_bug45679.test
+++ b/mysql-test/suite/rpl/t/rpl_auto_increment_bug45679.test
@@ -5,9 +5,9 @@
# is replication unsafe.
#
-source include/master-slave.inc;
source include/have_binlog_format_mixed.inc;
source include/have_innodb.inc;
+source include/master-slave.inc;
call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.');
diff --git a/mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test b/mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test
index b4798691ca3..49fbe9af570 100644
--- a/mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test
+++ b/mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test
@@ -1,6 +1,6 @@
-source include/master-slave.inc;
source include/have_innodb.inc;
source include/have_binlog_format_statement.inc;
+source include/master-slave.inc;
connection slave;
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
diff --git a/mysql-test/suite/rpl/t/rpl_blackhole.test b/mysql-test/suite/rpl/t/rpl_blackhole.test
index 5f9b955aaa4..76b2e2421c9 100644
--- a/mysql-test/suite/rpl/t/rpl_blackhole.test
+++ b/mysql-test/suite/rpl/t/rpl_blackhole.test
@@ -15,8 +15,8 @@
# primary key lookup), and index/key with multiple matches (forcing an
# index search).
-source include/master-slave.inc;
source include/have_blackhole.inc;
+source include/master-slave.inc;
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
diff --git a/mysql-test/suite/rpl/t/rpl_concurrency_error.test b/mysql-test/suite/rpl/t/rpl_concurrency_error.test
index 15d5d5502a1..c5cebb953e4 100644
--- a/mysql-test/suite/rpl/t/rpl_concurrency_error.test
+++ b/mysql-test/suite/rpl/t/rpl_concurrency_error.test
@@ -17,9 +17,9 @@
# log, the error is ignored and only the non-transactional tables are changed.
###############################################################################
---source include/master-slave.inc
--source include/have_innodb.inc
--source include/have_binlog_format_statement.inc
+--source include/master-slave.inc
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
diff --git a/mysql-test/suite/rpl/t/rpl_conditional_comments.test b/mysql-test/suite/rpl/t/rpl_conditional_comments.test
index 0e2c108bf6e..bcc964a92c7 100644
--- a/mysql-test/suite/rpl/t/rpl_conditional_comments.test
+++ b/mysql-test/suite/rpl/t/rpl_conditional_comments.test
@@ -8,8 +8,8 @@
# will be binlogged as
# 'INSERT INTO t1 VALUES (1) /*!10000, (2)*/ /* 99999 ,(3)*/'.
###############################################################################
-source include/master-slave.inc;
source include/have_binlog_format_statement.inc;
+source include/master-slave.inc;
CREATE TABLE t1(c1 INT);
source include/show_binlog_events.inc;
diff --git a/mysql-test/suite/rpl/t/rpl_empty_master_host.test b/mysql-test/suite/rpl/t/rpl_empty_master_host.test
index 66d30375a59..0fc2d11a29d 100644
--- a/mysql-test/suite/rpl/t/rpl_empty_master_host.test
+++ b/mysql-test/suite/rpl/t/rpl_empty_master_host.test
@@ -16,8 +16,8 @@
# along the way if error/no error is thrown and/or if replication starts
# working when expected.
---source include/master-slave.inc
--source include/have_binlog_format_mixed.inc
+--source include/master-slave.inc
connection slave;
STOP SLAVE;
diff --git a/mysql-test/suite/rpl/t/rpl_extra_col_master_innodb.test b/mysql-test/suite/rpl/t/rpl_extra_col_master_innodb.test
index f48880b5dfa..201392346be 100644
--- a/mysql-test/suite/rpl/t/rpl_extra_col_master_innodb.test
+++ b/mysql-test/suite/rpl/t/rpl_extra_col_master_innodb.test
@@ -2,8 +2,8 @@
# Purpose: To test having extra columns on the master WL#3915
#############################################################
-- source include/have_binlog_format_row.inc
--- source include/master-slave.inc
-- source include/have_innodb.inc
+-- source include/master-slave.inc
let $engine_type = 'InnoDB';
--source extra/rpl_tests/rpl_extra_col_master.test
diff --git a/mysql-test/suite/rpl/t/rpl_flush_logs.test b/mysql-test/suite/rpl/t/rpl_flush_logs.test
index 1d19576d47c..6dad588f217 100644
--- a/mysql-test/suite/rpl/t/rpl_flush_logs.test
+++ b/mysql-test/suite/rpl/t/rpl_flush_logs.test
@@ -4,8 +4,8 @@
# works fine.
#
---source include/master-slave.inc
--source include/have_binlog_format_statement.inc
+--source include/master-slave.inc
connection master;
# Test 'flush error logs' statement.
diff --git a/mysql-test/suite/rpl/t/rpl_geometry.test b/mysql-test/suite/rpl/t/rpl_geometry.test
index 769c49c96b1..415732a0228 100644
--- a/mysql-test/suite/rpl/t/rpl_geometry.test
+++ b/mysql-test/suite/rpl/t/rpl_geometry.test
@@ -1,5 +1,5 @@
-source include/master-slave.inc;
source include/have_binlog_format_row.inc;
+source include/master-slave.inc;
#
# Bug#48776, Bug#43784
diff --git a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test
index 17417a55b8c..dca32c30a94 100644
--- a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test
+++ b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test
@@ -8,9 +8,9 @@
# Finish the following tests by calling its common test script:
# extra/rpl_tests/rpl_get_master_version_and_clock.test.
-source include/master-slave.inc;
source include/have_debug.inc;
source include/have_debug_sync.inc;
+source include/master-slave.inc;
#
# The test is not supposed to have any binglog affairs.
diff --git a/mysql-test/suite/rpl/t/rpl_grant.test b/mysql-test/suite/rpl/t/rpl_grant.test
index 1091e5aab0d..b40d400afbd 100644
--- a/mysql-test/suite/rpl/t/rpl_grant.test
+++ b/mysql-test/suite/rpl/t/rpl_grant.test
@@ -1,7 +1,7 @@
# Tests of grants and users
-source include/master-slave.inc;
source include/not_embedded.inc;
+source include/master-slave.inc;
--echo **** On Master ****
connection master;
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..5abedd7eb37
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_gtid_delete_domain.test
@@ -0,0 +1,95 @@
+# 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)
+
+--connection slave
+# start the slave sucessfully
+--source include/start_slave.inc
+
+--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_gtid_mdev4484.test b/mysql-test/suite/rpl/t/rpl_gtid_mdev4484.test
index 43634ec1528..5b13a5e1fc1 100644
--- a/mysql-test/suite/rpl/t/rpl_gtid_mdev4484.test
+++ b/mysql-test/suite/rpl/t/rpl_gtid_mdev4484.test
@@ -1,6 +1,6 @@
---source include/master-slave.inc
--source include/have_innodb.inc
--source include/have_debug.inc
+--source include/master-slave.inc
CREATE TABLE t1 (i int) ENGINE=InnoDB;
diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat_debug.test b/mysql-test/suite/rpl/t/rpl_heartbeat_debug.test
index 7cdf67d6532..6a426ed1e9f 100644
--- a/mysql-test/suite/rpl/t/rpl_heartbeat_debug.test
+++ b/mysql-test/suite/rpl/t/rpl_heartbeat_debug.test
@@ -1,7 +1,7 @@
# Testing master to slave heartbeat protocol, test cases that need debug build.
---source include/master-slave.inc
--source include/have_debug.inc
+--source include/master-slave.inc
connection slave;
--source include/stop_slave.inc
diff --git a/mysql-test/suite/rpl/t/rpl_innodb_bug68220.test b/mysql-test/suite/rpl/t/rpl_innodb_bug68220.test
index 76e7c60fd59..1e4f40a0019 100644
--- a/mysql-test/suite/rpl/t/rpl_innodb_bug68220.test
+++ b/mysql-test/suite/rpl/t/rpl_innodb_bug68220.test
@@ -1,6 +1,6 @@
--source include/have_innodb.inc
---source include/master-slave.inc
--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
#
# Bug#68220: innodb_rows_updated is misleading on slave when *info_repository=TABLE
diff --git a/mysql-test/suite/rpl/t/rpl_insert.test b/mysql-test/suite/rpl/t/rpl_insert.test
index 2a29139ac48..48814508818 100644
--- a/mysql-test/suite/rpl/t/rpl_insert.test
+++ b/mysql-test/suite/rpl/t/rpl_insert.test
@@ -2,9 +2,9 @@
--echo # Bug#20821: INSERT DELAYED fails to write some rows to binlog
--echo #
---source include/master-slave.inc
--source include/not_embedded.inc
--source include/not_windows.inc
+--source include/master-slave.inc
disable_query_log;
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
diff --git a/mysql-test/suite/rpl/t/rpl_invoked_features.test b/mysql-test/suite/rpl/t/rpl_invoked_features.test
index 7770c36c397..91391cf8372 100644
--- a/mysql-test/suite/rpl/t/rpl_invoked_features.test
+++ b/mysql-test/suite/rpl/t/rpl_invoked_features.test
@@ -5,8 +5,8 @@
# Features for Replication.
#########################################
---source include/master-slave.inc
--source include/have_innodb.inc
+--source include/master-slave.inc
disable_query_log;
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_symlink.test b/mysql-test/suite/rpl/t/rpl_loaddata_symlink.test
index c73fa2897f3..e5ee400d231 100644
--- a/mysql-test/suite/rpl/t/rpl_loaddata_symlink.test
+++ b/mysql-test/suite/rpl/t/rpl_loaddata_symlink.test
@@ -4,8 +4,8 @@
# if the path of the load data file is a symbolic link.
#
--source include/not_windows.inc
---source include/master-slave.inc
--source include/have_binlog_format_statement.inc
+--source include/master-slave.inc
create table t1(a int not null auto_increment, b int, primary key(a) );
load data infile '../../std_data/rpl_loaddata.dat' into table t1;
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_mariadb_slave_capability.test b/mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test
index 0e6608fd848..2761f169e83 100644
--- a/mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test
+++ b/mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test
@@ -1,8 +1,8 @@
---source include/master-slave.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
--source include/have_binlog_format_row.inc
--source include/have_innodb.inc
+--source include/master-slave.inc
connection master;
diff --git a/mysql-test/suite/rpl/t/rpl_mdev-11092.test b/mysql-test/suite/rpl/t/rpl_mdev-11092.test
index c8b2b7f2ad1..31a385b40e6 100644
--- a/mysql-test/suite/rpl/t/rpl_mdev-11092.test
+++ b/mysql-test/suite/rpl/t/rpl_mdev-11092.test
@@ -1,8 +1,8 @@
--source include/have_innodb.inc
---source include/master-slave.inc
--source include/not_embedded.inc
--source include/not_windows.inc
--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
########################################################################################
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
diff --git a/mysql-test/suite/rpl/t/rpl_mdev8193.test b/mysql-test/suite/rpl/t/rpl_mdev8193.test
index 29c26bb3da4..dcad3e5f9b0 100644
--- a/mysql-test/suite/rpl/t/rpl_mdev8193.test
+++ b/mysql-test/suite/rpl/t/rpl_mdev8193.test
@@ -1,5 +1,5 @@
---source include/master-slave.inc
--source include/have_binlog_format_statement.inc
+--source include/master-slave.inc
--connection slave
diff --git a/mysql-test/suite/rpl/t/rpl_mixed_binlog_max_cache_size.test b/mysql-test/suite/rpl/t/rpl_mixed_binlog_max_cache_size.test
index 3850a84cbf1..81b01cc9140 100644
--- a/mysql-test/suite/rpl/t/rpl_mixed_binlog_max_cache_size.test
+++ b/mysql-test/suite/rpl/t/rpl_mixed_binlog_max_cache_size.test
@@ -1,8 +1,8 @@
--source include/have_innodb.inc
---source include/master-slave.inc
--source include/not_embedded.inc
--source include/not_windows.inc
--source include/have_binlog_format_mixed.inc
+--source include/master-slave.inc
--source extra/rpl_tests/rpl_binlog_max_cache_size.test
--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_mixed_implicit_commit_binlog.test b/mysql-test/suite/rpl/t/rpl_mixed_implicit_commit_binlog.test
index b2e8308b34d..fa948f8f5fe 100644
--- a/mysql-test/suite/rpl/t/rpl_mixed_implicit_commit_binlog.test
+++ b/mysql-test/suite/rpl/t/rpl_mixed_implicit_commit_binlog.test
@@ -3,8 +3,8 @@
################################################################################
--source include/have_udf.inc
--source include/have_binlog_format_mixed.inc
---source include/master-slave.inc
--source include/have_innodb.inc
+--source include/master-slave.inc
--let $engine=Innodb
set session storage_engine=innodb;
diff --git a/mysql-test/suite/rpl/t/rpl_mixed_mixing_engines.test b/mysql-test/suite/rpl/t/rpl_mixed_mixing_engines.test
index 747374b89c2..a9c8f6fe3e1 100644
--- a/mysql-test/suite/rpl/t/rpl_mixed_mixing_engines.test
+++ b/mysql-test/suite/rpl/t/rpl_mixed_mixing_engines.test
@@ -3,8 +3,8 @@
# tables. For further details, please, read WL#2687 and WL#5072.
###################################################################################
--source include/have_binlog_format_mixed.inc
---source include/master-slave.inc
--source include/have_innodb.inc
+--source include/master-slave.inc
let $engine_type=Innodb;
let $database_name=test;
diff --git a/mysql-test/suite/rpl/t/rpl_non_direct_mixed_mixing_engines.test b/mysql-test/suite/rpl/t/rpl_non_direct_mixed_mixing_engines.test
index 8092ff141db..93ec9acf5ea 100644
--- a/mysql-test/suite/rpl/t/rpl_non_direct_mixed_mixing_engines.test
+++ b/mysql-test/suite/rpl/t/rpl_non_direct_mixed_mixing_engines.test
@@ -3,8 +3,8 @@
# tables. For further details, please, read WL#2687 and WL#5072.
###################################################################################
--source include/have_binlog_format_mixed.inc
---source include/master-slave.inc
--source include/have_innodb.inc
+--source include/master-slave.inc
--disable_query_log
SET SESSION binlog_direct_non_transactional_updates = OFF;
diff --git a/mysql-test/suite/rpl/t/rpl_not_null_innodb.test b/mysql-test/suite/rpl/t/rpl_not_null_innodb.test
index 1e67ba4eda1..6a1cc341060 100644
--- a/mysql-test/suite/rpl/t/rpl_not_null_innodb.test
+++ b/mysql-test/suite/rpl/t/rpl_not_null_innodb.test
@@ -11,9 +11,9 @@
# 3 - NULL --> NOT NULL ( sql-mode != STRICT and no failures)
#
#################################################################################
---source include/master-slave.inc
--source include/have_innodb.inc
--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
let $engine=Innodb;
--source extra/rpl_tests/rpl_not_null.test
diff --git a/mysql-test/suite/rpl/t/rpl_not_null_myisam.test b/mysql-test/suite/rpl/t/rpl_not_null_myisam.test
index dcfaf006dad..6ef0b65d5ff 100644
--- a/mysql-test/suite/rpl/t/rpl_not_null_myisam.test
+++ b/mysql-test/suite/rpl/t/rpl_not_null_myisam.test
@@ -11,8 +11,8 @@
# 3 - NULL --> NOT NULL ( sql-mode != STRICT and no failures)
#
#################################################################################
---source include/master-slave.inc
--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
let $engine=MyISAM;
--source extra/rpl_tests/rpl_not_null.test
diff --git a/mysql-test/suite/rpl/t/rpl_performance_schema.test b/mysql-test/suite/rpl/t/rpl_performance_schema.test
index 0562b0ea658..18aabe5272d 100644
--- a/mysql-test/suite/rpl/t/rpl_performance_schema.test
+++ b/mysql-test/suite/rpl/t/rpl_performance_schema.test
@@ -1,6 +1,6 @@
---source include/master-slave.inc
--source include/have_perfschema.inc
--source include/have_binlog_format_mixed.inc
+--source include/master-slave.inc
UPDATE performance_schema.setup_instruments SET ENABLED="NO";
diff --git a/mysql-test/suite/rpl/t/rpl_read_only.test b/mysql-test/suite/rpl/t/rpl_read_only.test
index fb92803847a..c4781bbbb3b 100644
--- a/mysql-test/suite/rpl/t/rpl_read_only.test
+++ b/mysql-test/suite/rpl/t/rpl_read_only.test
@@ -1,6 +1,6 @@
# Test case for BUG #11733
--- source include/master-slave.inc
-- source include/have_innodb.inc
+-- source include/master-slave.inc
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
diff --git a/mysql-test/suite/rpl/t/rpl_report_port.test b/mysql-test/suite/rpl/t/rpl_report_port.test
index 6e728a678ad..2a14d278d48 100644
--- a/mysql-test/suite/rpl/t/rpl_report_port.test
+++ b/mysql-test/suite/rpl/t/rpl_report_port.test
@@ -17,8 +17,8 @@
# case on doing SHOW SLAVE HOSTS on the master, we get the actual port number
# of the slave (ie. SLAVE_PORT).
-source include/master-slave.inc;
source include/have_binlog_format_mixed.inc;
+source include/master-slave.inc;
connection master;
diff --git a/mysql-test/suite/rpl/t/rpl_row_binlog_max_cache_size.test b/mysql-test/suite/rpl/t/rpl_row_binlog_max_cache_size.test
index 9c8489658f8..cc031d382e0 100644
--- a/mysql-test/suite/rpl/t/rpl_row_binlog_max_cache_size.test
+++ b/mysql-test/suite/rpl/t/rpl_row_binlog_max_cache_size.test
@@ -1,8 +1,8 @@
--source include/have_innodb.inc
---source include/master-slave.inc
--source include/not_embedded.inc
--source include/not_windows.inc
--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
--source extra/rpl_tests/rpl_binlog_max_cache_size.test
--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_row_colSize.test b/mysql-test/suite/rpl/t/rpl_row_colSize.test
index cdffe2e333b..21c68b55e92 100644
--- a/mysql-test/suite/rpl/t/rpl_row_colSize.test
+++ b/mysql-test/suite/rpl/t/rpl_row_colSize.test
@@ -6,8 +6,8 @@
# having columns that are smaller (shorter) than the slave. #
##################################################################
--- source include/master-slave.inc
-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
--disable_warnings
DROP TABLE IF EXISTS t1;
diff --git a/mysql-test/suite/rpl/t/rpl_row_corruption.test b/mysql-test/suite/rpl/t/rpl_row_corruption.test
index e05273a2f9c..acf3964f0c5 100644
--- a/mysql-test/suite/rpl/t/rpl_row_corruption.test
+++ b/mysql-test/suite/rpl/t/rpl_row_corruption.test
@@ -1,7 +1,7 @@
#
---source include/master-slave.inc
--source include/have_debug.inc
--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
# BUG#11753004: 44360: REPLICATION FAILED
diff --git a/mysql-test/suite/rpl/t/rpl_row_create_table.test b/mysql-test/suite/rpl/t/rpl_row_create_table.test
index da73d753dcd..03f9d6a953b 100644
--- a/mysql-test/suite/rpl/t/rpl_row_create_table.test
+++ b/mysql-test/suite/rpl/t/rpl_row_create_table.test
@@ -1,8 +1,8 @@
# Testing table creations for row-based replication.
--source include/have_binlog_format_row.inc
---source include/master-slave.inc
--source include/have_innodb.inc
+--source include/master-slave.inc
connection slave;
--source include/have_innodb.inc
connection master;
diff --git a/mysql-test/suite/rpl/t/rpl_row_find_row.test b/mysql-test/suite/rpl/t/rpl_row_find_row.test
index 7f633c5aa97..444706aca7f 100644
--- a/mysql-test/suite/rpl/t/rpl_row_find_row.test
+++ b/mysql-test/suite/rpl/t/rpl_row_find_row.test
@@ -16,8 +16,8 @@
# has been fixed.
#
--- source include/master-slave.inc
-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
#
# Case #1: master has key, but slave has not.
diff --git a/mysql-test/suite/rpl/t/rpl_row_implicit_commit_binlog.test b/mysql-test/suite/rpl/t/rpl_row_implicit_commit_binlog.test
index 2b35f68ff63..6fdcd885930 100644
--- a/mysql-test/suite/rpl/t/rpl_row_implicit_commit_binlog.test
+++ b/mysql-test/suite/rpl/t/rpl_row_implicit_commit_binlog.test
@@ -3,8 +3,8 @@
################################################################################
--source include/have_udf.inc
--source include/have_binlog_format_row.inc
---source include/master-slave.inc
--source include/have_innodb.inc
+--source include/master-slave.inc
--let $engine=Innodb
set session storage_engine=innodb;
diff --git a/mysql-test/suite/rpl/t/rpl_row_index_choice.test b/mysql-test/suite/rpl/t/rpl_row_index_choice.test
index 6d4053f9737..0ad9b315d66 100644
--- a/mysql-test/suite/rpl/t/rpl_row_index_choice.test
+++ b/mysql-test/suite/rpl/t/rpl_row_index_choice.test
@@ -1,7 +1,7 @@
--source include/have_binlog_format_row.inc
---source include/master-slave.inc
--source include/have_debug.inc
--source include/have_innodb.inc
+--source include/master-slave.inc
# Bug#58997: Row-based replication breaks on table with only fulltext index:
connection master;
diff --git a/mysql-test/suite/rpl/t/rpl_row_merge_engine.test b/mysql-test/suite/rpl/t/rpl_row_merge_engine.test
index dcbb8b891d8..c28d4a89651 100644
--- a/mysql-test/suite/rpl/t/rpl_row_merge_engine.test
+++ b/mysql-test/suite/rpl/t/rpl_row_merge_engine.test
@@ -12,8 +12,8 @@
# deletes their contents through the merge table. Finally, the slave
# is synchronized with the master and (after the fix) it won't crash.
#
---source include/master-slave.inc
--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
--connection master
CREATE TABLE t1 (a int) ENGINE=MyISAM;
diff --git a/mysql-test/suite/rpl/t/rpl_row_rec_comp_innodb.test b/mysql-test/suite/rpl/t/rpl_row_rec_comp_innodb.test
index 57d67c5c71b..b3808680db2 100644
--- a/mysql-test/suite/rpl/t/rpl_row_rec_comp_innodb.test
+++ b/mysql-test/suite/rpl/t/rpl_row_rec_comp_innodb.test
@@ -1,6 +1,6 @@
-- source include/have_binlog_format_row.inc
--- source include/master-slave.inc
-- source include/have_innodb.inc
+-- source include/master-slave.inc
#
# BUG#52868 Wrong handling of NULL value during update, replication out of sync
diff --git a/mysql-test/suite/rpl/t/rpl_row_show_relaylog_events.test b/mysql-test/suite/rpl/t/rpl_row_show_relaylog_events.test
index a78f7ad4271..0882d603203 100644
--- a/mysql-test/suite/rpl/t/rpl_row_show_relaylog_events.test
+++ b/mysql-test/suite/rpl/t/rpl_row_show_relaylog_events.test
@@ -12,8 +12,8 @@
# This test issues SHOW [BINLOG|RELAYLOG] EVENTS both on master and slave after
# some statements have been issued.
--- source include/master-slave.inc
-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
-- source extra/rpl_tests/rpl_show_relaylog_events.inc
--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test
index e8ac74f0125..5bdd1ff8b6b 100644
--- a/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test
+++ b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test
@@ -26,9 +26,9 @@
# with mysqlbinlog reporting that it was unable to succeed in
# reading the event.
--- source include/master-slave.inc
-- source include/have_innodb.inc
-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
-- disable_warnings
DROP TABLE IF EXISTS `t1`;
diff --git a/mysql-test/suite/rpl/t/rpl_row_trunc_temp.test b/mysql-test/suite/rpl/t/rpl_row_trunc_temp.test
index 394bf949f72..a8d7f77d930 100644
--- a/mysql-test/suite/rpl/t/rpl_row_trunc_temp.test
+++ b/mysql-test/suite/rpl/t/rpl_row_trunc_temp.test
@@ -6,8 +6,8 @@
# table was binlogged in RBR.
#
---source include/master-slave.inc
--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
#This statement is not binlogged in RBR.
CREATE TEMPORARY TABLE t1(c1 INTEGER);
diff --git a/mysql-test/suite/rpl/t/rpl_row_utf16.test b/mysql-test/suite/rpl/t/rpl_row_utf16.test
index e3e7a51c002..595a149e5e6 100644
--- a/mysql-test/suite/rpl/t/rpl_row_utf16.test
+++ b/mysql-test/suite/rpl/t/rpl_row_utf16.test
@@ -1,6 +1,6 @@
--- source include/master-slave.inc
-- source include/have_binlog_format_row.inc
-- source include/have_utf16.inc
+-- source include/master-slave.inc
#
# BUG#51716: Char column with utf16 character set gives wrong padding on slave
diff --git a/mysql-test/suite/rpl/t/rpl_row_wide_table.test b/mysql-test/suite/rpl/t/rpl_row_wide_table.test
index b1d16133096..01473f991bf 100644
--- a/mysql-test/suite/rpl/t/rpl_row_wide_table.test
+++ b/mysql-test/suite/rpl/t/rpl_row_wide_table.test
@@ -8,8 +8,8 @@
# in corrupt binlog
##################################################################
--- source include/master-slave.inc
-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
--disable_warnings
DROP TABLE IF EXISTS t300;
diff --git a/mysql-test/suite/rpl/t/rpl_savepoint.test b/mysql-test/suite/rpl/t/rpl_savepoint.test
index 2aacd1fa81e..a61c506f12f 100644
--- a/mysql-test/suite/rpl/t/rpl_savepoint.test
+++ b/mysql-test/suite/rpl/t/rpl_savepoint.test
@@ -1,5 +1,5 @@
---source include/master-slave.inc
--source include/have_innodb.inc
+--source include/master-slave.inc
--echo #
--echo # Bug#50124 Rpl failure on DROP table with concurrent txn/non-txn
diff --git a/mysql-test/suite/rpl/t/rpl_server_id_ignore.test b/mysql-test/suite/rpl/t/rpl_server_id_ignore.test
index 1e6d46c9d40..537978f1701 100644
--- a/mysql-test/suite/rpl/t/rpl_server_id_ignore.test
+++ b/mysql-test/suite/rpl/t/rpl_server_id_ignore.test
@@ -17,8 +17,8 @@
# b. nullifying the list and resuming of taking binlog from the very beginning with
# executing events this time
-source include/master-slave.inc;
source include/have_binlog_format_mixed.inc;
+source include/master-slave.inc;
connection slave;
diff --git a/mysql-test/suite/rpl/t/rpl_set_null_innodb.test b/mysql-test/suite/rpl/t/rpl_set_null_innodb.test
index 2d0c34e1d0a..5ef10263498 100644
--- a/mysql-test/suite/rpl/t/rpl_set_null_innodb.test
+++ b/mysql-test/suite/rpl/t/rpl_set_null_innodb.test
@@ -1,6 +1,6 @@
-- source include/have_binlog_format_mixed_or_row.inc
--- source include/master-slave.inc
-- source include/have_innodb.inc
+-- source include/master-slave.inc
-- let $engine= InnoDB
-- source extra/rpl_tests/rpl_set_null.test
diff --git a/mysql-test/suite/rpl/t/rpl_skip_error.test b/mysql-test/suite/rpl/t/rpl_skip_error.test
index 4348675884b..6cf3113daf5 100644
--- a/mysql-test/suite/rpl/t/rpl_skip_error.test
+++ b/mysql-test/suite/rpl/t/rpl_skip_error.test
@@ -23,8 +23,8 @@
# bug in this test: BUG#30594: rpl.rpl_skip_error is nondeterministic:
# BUG#39393: slave-skip-errors does not work when using ROW based replication
-source include/master-slave.inc;
source include/have_innodb.inc;
+source include/master-slave.inc;
--echo ==== Test Without sql_mode=strict_trans_tables ====
diff --git a/mysql-test/suite/rpl/t/rpl_skip_incident.test b/mysql-test/suite/rpl/t/rpl_skip_incident.test
index 959fde9374e..50e466b1329 100644
--- a/mysql-test/suite/rpl/t/rpl_skip_incident.test
+++ b/mysql-test/suite/rpl/t/rpl_skip_incident.test
@@ -1,5 +1,5 @@
---source include/master-slave.inc
--source include/have_debug.inc
+--source include/master-slave.inc
--echo **** On Master ****
CREATE TABLE t1 (a INT);
diff --git a/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test b/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test
index b1af6e92c29..69319bad4a0 100644
--- a/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test
+++ b/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test
@@ -20,9 +20,9 @@
--source include/have_binlog_format_statement.inc
--source include/have_innodb.inc
--source include/have_debug.inc
---source include/master-slave.inc
--source include/not_embedded.inc
--source include/not_var_link.inc
+--source include/master-slave.inc
##########################################################################
# Loading data
diff --git a/mysql-test/suite/rpl/t/rpl_slave_skip.test b/mysql-test/suite/rpl/t/rpl_slave_skip.test
index f2129bd7f18..d64f394055c 100644
--- a/mysql-test/suite/rpl/t/rpl_slave_skip.test
+++ b/mysql-test/suite/rpl/t/rpl_slave_skip.test
@@ -4,8 +4,8 @@
# test for MIXED mode.
source include/have_binlog_format_mixed.inc;
-source include/master-slave.inc;
source include/have_innodb.inc;
+source include/master-slave.inc;
--echo **** On Slave ****
connection slave;
diff --git a/mysql-test/suite/rpl/t/rpl_slow_query_log.test b/mysql-test/suite/rpl/t/rpl_slow_query_log.test
index 3505883c58e..df88d42ed68 100644
--- a/mysql-test/suite/rpl/t/rpl_slow_query_log.test
+++ b/mysql-test/suite/rpl/t/rpl_slow_query_log.test
@@ -25,8 +25,8 @@
# Note that due to the sleep() command the insert is written to the binary
# log in row format.
-source include/master-slave.inc;
source include/have_binlog_format_statement.inc;
+source include/master-slave.inc;
CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group");
diff --git a/mysql-test/suite/rpl/t/rpl_sp_variables.test b/mysql-test/suite/rpl/t/rpl_sp_variables.test
new file mode 100644
index 00000000000..87e9fe194ea
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_sp_variables.test
@@ -0,0 +1,28 @@
+source include/master-slave.inc;
+
+--echo #
+--echo # MDEV-13685 Can not replay binary log due to Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8mb4_general_ci,COERCIBLE) for operation 'concat'
+--echo #
+
+connection master;
+SET NAMES utf8;
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8);
+DELIMITER $$;
+CREATE PROCEDURE p1()
+BEGIN
+ DECLARE v_id INT DEFAULT 2017;
+ INSERT INTO test.t1 SELECT CONCAT(v_id, '오');
+END;
+$$
+DELIMITER ;$$
+CALL p1;
+SELECT * FROM t1;
+sync_slave_with_master;
+SET NAMES utf8;
+SELECT * FROM t1;
+connection master;
+DROP PROCEDURE p1;
+DROP TABLE t1;
+sync_slave_with_master;
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_stm_binlog_max_cache_size.test b/mysql-test/suite/rpl/t/rpl_stm_binlog_max_cache_size.test
index 352213304b6..93cc06111e4 100644
--- a/mysql-test/suite/rpl/t/rpl_stm_binlog_max_cache_size.test
+++ b/mysql-test/suite/rpl/t/rpl_stm_binlog_max_cache_size.test
@@ -1,8 +1,8 @@
--source include/have_innodb.inc
---source include/master-slave.inc
--source include/not_embedded.inc
--source include/not_windows.inc
--source include/have_binlog_format_statement.inc
+--source include/master-slave.inc
--source extra/rpl_tests/rpl_binlog_max_cache_size.test
--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_stm_drop_create_temp_table.test b/mysql-test/suite/rpl/t/rpl_stm_drop_create_temp_table.test
index 7770fc77748..b395654a714 100644
--- a/mysql-test/suite/rpl/t/rpl_stm_drop_create_temp_table.test
+++ b/mysql-test/suite/rpl/t/rpl_stm_drop_create_temp_table.test
@@ -5,8 +5,8 @@
###################################################################################
--source include/big_test.inc
--source include/have_binlog_format_statement.inc
---source include/master-slave.inc
--source include/have_innodb.inc
+--source include/master-slave.inc
--source extra/rpl_tests/rpl_drop_create_temp_table.test
--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_stm_implicit_commit_binlog.test b/mysql-test/suite/rpl/t/rpl_stm_implicit_commit_binlog.test
index 1e66b76abc8..774c87f551e 100644
--- a/mysql-test/suite/rpl/t/rpl_stm_implicit_commit_binlog.test
+++ b/mysql-test/suite/rpl/t/rpl_stm_implicit_commit_binlog.test
@@ -3,8 +3,8 @@
################################################################################
--source include/have_udf.inc
--source include/have_binlog_format_statement.inc
---source include/master-slave.inc
--source include/have_innodb.inc
+--source include/master-slave.inc
--let $engine=Innodb
set session storage_engine=innodb;
diff --git a/mysql-test/suite/rpl/t/rpl_stm_loadfile.test b/mysql-test/suite/rpl/t/rpl_stm_loadfile.test
index e82c951ce0c..016d3ed6090 100644
--- a/mysql-test/suite/rpl/t/rpl_stm_loadfile.test
+++ b/mysql-test/suite/rpl/t/rpl_stm_loadfile.test
@@ -12,8 +12,8 @@
##########
# Includes
--- source include/master-slave.inc
-- source include/have_binlog_format_statement.inc
+-- source include/master-slave.inc
disable_query_log;
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
diff --git a/mysql-test/suite/rpl/t/rpl_stm_start_stop_slave.test b/mysql-test/suite/rpl/t/rpl_stm_start_stop_slave.test
index dfe2e49bb90..76b2aed3f24 100644
--- a/mysql-test/suite/rpl/t/rpl_stm_start_stop_slave.test
+++ b/mysql-test/suite/rpl/t/rpl_stm_start_stop_slave.test
@@ -1,9 +1,9 @@
################################################################################
# Please, check ./extra/rpl_tests/rpl_start_stop_slave.test
################################################################################
---source include/master-slave.inc
--source include/have_binlog_format_statement.inc
--source include/have_innodb.inc
+--source include/master-slave.inc
# make innodb updates run fast
--connection slave
diff --git a/mysql-test/suite/rpl/t/rpl_stm_user_variables.test b/mysql-test/suite/rpl/t/rpl_stm_user_variables.test
index 64691a1b634..22a6600105e 100644
--- a/mysql-test/suite/rpl/t/rpl_stm_user_variables.test
+++ b/mysql-test/suite/rpl/t/rpl_stm_user_variables.test
@@ -2,8 +2,8 @@
# BUG#49562: SBR out of sync when using numeric data types + user variable
#
--- source include/master-slave.inc
-- source include/have_binlog_format_statement.inc
+-- source include/master-slave.inc
## Setup user variables for several numeric types, so that we get
## coverage on the User_var_log_event different val types
diff --git a/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test b/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test
index 57954698a2c..1cc975e6ad4 100644
--- a/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test
+++ b/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test
@@ -9,9 +9,9 @@
# 4: sync to slave and check the number of temp tables on slave.
#
-source include/master-slave.inc;
source include/have_binlog_format_mixed.inc;
source include/have_innodb.inc;
+source include/master-slave.inc;
--echo ==== Initialize ====
diff --git a/mysql-test/suite/rpl/t/rpl_temporal_format_mariadb53_to_mysql56_dst.test b/mysql-test/suite/rpl/t/rpl_temporal_format_mariadb53_to_mysql56_dst.test
new file mode 100644
index 00000000000..511bdc15184
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_temporal_format_mariadb53_to_mysql56_dst.test
@@ -0,0 +1,37 @@
+#
+# MDEV-12672 Replicated TIMESTAMP fields given wrong value near DST change
+#
+source include/have_binlog_format_row.inc;
+source include/master-slave.inc;
+
+connection slave;
+set global time_zone='Europe/Moscow';
+set time_zone='UTC';
+stop slave;
+start slave;
+
+connection master;
+set global mysql56_temporal_format=false;
+set global time_zone='Europe/Moscow';
+set time_zone='UTC';
+
+create table t1 (pk int primary key, t timestamp not null);
+set timestamp = 1288477526;
+insert into t1 values (1,null);
+set timestamp = 1288481126;
+insert into t1 values (2,null);
+
+sync_slave_with_master;
+
+select pk, t, unix_timestamp(t) from t1;
+set time_zone=default;
+select pk, t, unix_timestamp(t) from t1;
+
+set global time_zone=default;
+
+connection master;
+drop table t1;
+set global time_zone=default;
+set global mysql56_temporal_format=default;
+
+source include/rpl_end.inc;
diff --git a/mysql-test/suite/rpl/t/rpl_temporary_errors.test b/mysql-test/suite/rpl/t/rpl_temporary_errors.test
index 250ccf4c1cd..4a532976787 100644
--- a/mysql-test/suite/rpl/t/rpl_temporary_errors.test
+++ b/mysql-test/suite/rpl/t/rpl_temporary_errors.test
@@ -1,6 +1,6 @@
source include/have_binlog_format_row.inc;
-source include/master-slave.inc;
source include/have_innodb.inc;
+source include/master-slave.inc;
call mtr.add_suppression("Deadlock found");
call mtr.add_suppression("Can't find record in 't.'");
diff --git a/mysql-test/suite/rpl/t/sec_behind_master-5114.test b/mysql-test/suite/rpl/t/sec_behind_master-5114.test
index ff8cab54c4f..d1d21bfa766 100644
--- a/mysql-test/suite/rpl/t/sec_behind_master-5114.test
+++ b/mysql-test/suite/rpl/t/sec_behind_master-5114.test
@@ -1,5 +1,5 @@
-source include/master-slave.inc;
source include/have_binlog_format_statement.inc;
+source include/master-slave.inc;
call mtr.add_suppression("Unsafe statement written to the binary log");
diff --git a/mysql-test/suite/sys_vars/inc/explicit_defaults_for_timestamp.inc b/mysql-test/suite/sys_vars/inc/explicit_defaults_for_timestamp.inc
index 4cf3914e60a..1fea4ca5bb9 100644
--- a/mysql-test/suite/sys_vars/inc/explicit_defaults_for_timestamp.inc
+++ b/mysql-test/suite/sys_vars/inc/explicit_defaults_for_timestamp.inc
@@ -97,3 +97,16 @@ CREATE TABLE t1 (a INT);
ALTER TABLE t1 ADD b TIMESTAMP;
SHOW CREATE TABLE t1;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-10802 TIMESTAMP NOT NULL field with explicit_defaults_for_timestamp and NO_ZERO_DATE shouldn't throw error
+--echo #
+
+SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30');
+SET sql_mode='ANSI,NO_ZERO_DATE';
+CREATE TABLE t1 (a TIMESTAMP NOT NULL);
+INSERT INTO t1 VALUES ();
+SELECT * FROM t1;
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+SET timestamp=DEFAULT;
diff --git a/mysql-test/suite/sys_vars/r/explicit_defaults_for_timestamp_off.result b/mysql-test/suite/sys_vars/r/explicit_defaults_for_timestamp_off.result
index cdf612e6db8..61a4eb8a934 100644
--- a/mysql-test/suite/sys_vars/r/explicit_defaults_for_timestamp_off.result
+++ b/mysql-test/suite/sys_vars/r/explicit_defaults_for_timestamp_off.result
@@ -173,3 +173,16 @@ t1 CREATE TABLE `t1` (
`b` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
+#
+# MDEV-10802 TIMESTAMP NOT NULL field with explicit_defaults_for_timestamp and NO_ZERO_DATE shouldn't throw error
+#
+SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30');
+SET sql_mode='ANSI,NO_ZERO_DATE';
+CREATE TABLE t1 (a TIMESTAMP NOT NULL);
+INSERT INTO t1 VALUES ();
+SELECT * FROM t1;
+a
+2001-01-01 10:20:30
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+SET timestamp=DEFAULT;
diff --git a/mysql-test/suite/sys_vars/r/explicit_defaults_for_timestamp_on.result b/mysql-test/suite/sys_vars/r/explicit_defaults_for_timestamp_on.result
index 1c42da57bfc..fb820dc167d 100644
--- a/mysql-test/suite/sys_vars/r/explicit_defaults_for_timestamp_on.result
+++ b/mysql-test/suite/sys_vars/r/explicit_defaults_for_timestamp_on.result
@@ -178,3 +178,18 @@ t1 CREATE TABLE `t1` (
`b` timestamp NULL DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
+#
+# MDEV-10802 TIMESTAMP NOT NULL field with explicit_defaults_for_timestamp and NO_ZERO_DATE shouldn't throw error
+#
+SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30');
+SET sql_mode='ANSI,NO_ZERO_DATE';
+CREATE TABLE t1 (a TIMESTAMP NOT NULL);
+INSERT INTO t1 VALUES ();
+Warnings:
+Warning 1364 Field 'a' doesn't have a default value
+SELECT * FROM t1;
+a
+0000-00-00 00:00:00
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+SET timestamp=DEFAULT;
diff --git a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_now_basic.result b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_now_basic.result
index 9c3a37f892b..522d5731a6d 100644
--- a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_now_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_now_basic.result
@@ -1,7 +1,8 @@
-SET @orig = @@global.innodb_buffer_pool_dump_now;
-SELECT @orig;
-@orig
+SELECT @@global.innodb_buffer_pool_dump_now;
+@@global.innodb_buffer_pool_dump_now
0
+SELECT variable_value INTO @old_dump_status FROM information_schema.global_status
+WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status';
SET GLOBAL innodb_buffer_pool_dump_now = ON;
SELECT @@global.innodb_buffer_pool_dump_now;
@@global.innodb_buffer_pool_dump_now
diff --git a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result
index 51c72cfe791..70fcdd3cb56 100644
--- a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result
@@ -2,7 +2,8 @@ SET @orig = @@global.innodb_buffer_pool_dump_pct;
SELECT @orig;
@orig
100
-SET GLOBAL innodb_buffer_pool_dump_pct=3, GLOBAL innodb_buffer_pool_dump_now = ON;
+SET GLOBAL innodb_buffer_pool_dump_pct=3;
+# Do the dump
SET GLOBAL innodb_buffer_pool_dump_pct=0;
SELECT @@global.innodb_buffer_pool_dump_pct;
@@global.innodb_buffer_pool_dump_pct
diff --git a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_load_now_basic.result b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_load_now_basic.result
index 3185d1ca170..eebed4d0f4a 100644
--- a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_load_now_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_load_now_basic.result
@@ -1,8 +1,6 @@
-SET @orig = @@global.innodb_buffer_pool_load_now;
-SELECT @orig;
-@orig
+SELECT @@global.innodb_buffer_pool_load_now;
+@@global.innodb_buffer_pool_load_now
0
-SET GLOBAL innodb_buffer_pool_dump_now = ON;
SET GLOBAL innodb_buffer_pool_load_now = ON;
SELECT variable_value
FROM information_schema.global_status
diff --git a/mysql-test/suite/sys_vars/r/innodb_print_lock_wait_timeout_info_basic.result b/mysql-test/suite/sys_vars/r/innodb_print_lock_wait_timeout_info_basic.result
new file mode 100644
index 00000000000..cc035e4f8bc
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/innodb_print_lock_wait_timeout_info_basic.result
@@ -0,0 +1,104 @@
+SET @start_global_value = @@global.innodb_print_lock_wait_timeout_info;
+SELECT @start_global_value;
+@start_global_value
+0
+Valid values are 'ON' and 'OFF'
+SELECT @@global.innodb_print_lock_wait_timeout_info in (0, 1);
+@@global.innodb_print_lock_wait_timeout_info in (0, 1)
+1
+SELECT @@global.innodb_print_lock_wait_timeout_info;
+@@global.innodb_print_lock_wait_timeout_info
+0
+SELECT @@session.innodb_print_lock_wait_timeout_info;
+ERROR HY000: Variable 'innodb_print_lock_wait_timeout_info' is a GLOBAL variable
+SHOW global variables LIKE 'innodb_print_lock_wait_timeout_info';
+Variable_name Value
+innodb_print_lock_wait_timeout_info OFF
+SHOW session variables LIKE 'innodb_print_lock_wait_timeout_info';
+Variable_name Value
+innodb_print_lock_wait_timeout_info OFF
+SELECT * FROM information_schema.global_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_PRINT_LOCK_WAIT_TIMEOUT_INFO OFF
+SELECT * FROM information_schema.session_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_PRINT_LOCK_WAIT_TIMEOUT_INFO OFF
+SET global innodb_print_lock_wait_timeout_info='OFF';
+SELECT @@global.innodb_print_lock_wait_timeout_info;
+@@global.innodb_print_lock_wait_timeout_info
+0
+SELECT * FROM information_schema.global_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_PRINT_LOCK_WAIT_TIMEOUT_INFO OFF
+SELECT * FROM information_schema.session_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_PRINT_LOCK_WAIT_TIMEOUT_INFO OFF
+SET @@global.innodb_print_lock_wait_timeout_info=1;
+SELECT @@global.innodb_print_lock_wait_timeout_info;
+@@global.innodb_print_lock_wait_timeout_info
+1
+SELECT * FROM information_schema.global_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_PRINT_LOCK_WAIT_TIMEOUT_INFO ON
+SELECT * FROM information_schema.session_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_PRINT_LOCK_WAIT_TIMEOUT_INFO ON
+SET global innodb_print_lock_wait_timeout_info=0;
+SELECT @@global.innodb_print_lock_wait_timeout_info;
+@@global.innodb_print_lock_wait_timeout_info
+0
+SELECT * FROM information_schema.global_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_PRINT_LOCK_WAIT_TIMEOUT_INFO OFF
+SELECT * FROM information_schema.session_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_PRINT_LOCK_WAIT_TIMEOUT_INFO OFF
+SET @@global.innodb_print_lock_wait_timeout_info='ON';
+SELECT @@global.innodb_print_lock_wait_timeout_info;
+@@global.innodb_print_lock_wait_timeout_info
+1
+SELECT * FROM information_schema.global_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_PRINT_LOCK_WAIT_TIMEOUT_INFO ON
+SELECT * FROM information_schema.session_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_PRINT_LOCK_WAIT_TIMEOUT_INFO ON
+SET session innodb_print_lock_wait_timeout_info='OFF';
+ERROR HY000: Variable 'innodb_print_lock_wait_timeout_info' is a GLOBAL variable and should be set with SET GLOBAL
+SET @@session.innodb_print_lock_wait_timeout_info='ON';
+ERROR HY000: Variable 'innodb_print_lock_wait_timeout_info' is a GLOBAL variable and should be set with SET GLOBAL
+SET global innodb_print_lock_wait_timeout_info=1.1;
+ERROR 42000: Incorrect argument type to variable 'innodb_print_lock_wait_timeout_info'
+SET global innodb_print_lock_wait_timeout_info=1e1;
+ERROR 42000: Incorrect argument type to variable 'innodb_print_lock_wait_timeout_info'
+SET global innodb_print_lock_wait_timeout_info=2;
+ERROR 42000: Variable 'innodb_print_lock_wait_timeout_info' can't be set to the value of '2'
+SET global innodb_print_lock_wait_timeout_info=-3;
+ERROR 42000: Variable 'innodb_print_lock_wait_timeout_info' can't be set to the value of '-3'
+SELECT @@global.innodb_print_lock_wait_timeout_info;
+@@global.innodb_print_lock_wait_timeout_info
+1
+SELECT * FROM information_schema.global_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_PRINT_LOCK_WAIT_TIMEOUT_INFO ON
+SELECT * FROM information_schema.session_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_PRINT_LOCK_WAIT_TIMEOUT_INFO ON
+SET global innodb_print_lock_wait_timeout_info='AUTO';
+ERROR 42000: Variable 'innodb_print_lock_wait_timeout_info' can't be set to the value of 'AUTO'
+SET @@global.innodb_print_lock_wait_timeout_info = @start_global_value;
+SELECT @@global.innodb_print_lock_wait_timeout_info;
+@@global.innodb_print_lock_wait_timeout_info
+0
diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff b/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff
index 8638fd00be6..f04fd5ed399 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff
@@ -829,10 +829,24 @@
VARIABLE_COMMENT Page size to use for all InnoDB tablespaces.
NUMERIC_MIN_VALUE 4096
NUMERIC_MAX_VALUE 65536
-@@ -1727,13 +2035,69 @@
+@@ -1727,13 +2035,83 @@
ENUM_VALUE_LIST OFF,ON
READ_ONLY NO
COMMAND_LINE_ARGUMENT OPTIONAL
++VARIABLE_NAME INNODB_PRINT_LOCK_WAIT_TIMEOUT_INFO
++SESSION_VALUE NULL
++GLOBAL_VALUE OFF
++GLOBAL_VALUE_ORIGIN COMPILE-TIME
++DEFAULT_VALUE OFF
++VARIABLE_SCOPE GLOBAL
++VARIABLE_TYPE BOOLEAN
++VARIABLE_COMMENT Print lock wait timeout info to MySQL error log (off 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 INNODB_PRIORITY_CLEANER
+SESSION_VALUE NULL
+GLOBAL_VALUE OFF
@@ -1222,7 +1236,7 @@
VARIABLE_NAME INNODB_VERSION
SESSION_VALUE NULL
-GLOBAL_VALUE 5.6.37
-+GLOBAL_VALUE 5.6.36-82.1
++GLOBAL_VALUE 5.6.38-83.0
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE NULL
VARIABLE_SCOPE GLOBAL
diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff b/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff
index dc9a5fd05e6..313be8f99f6 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff
@@ -415,10 +415,24 @@
VARIABLE_NAME INNODB_MAX_DIRTY_PAGES_PCT
SESSION_VALUE NULL
GLOBAL_VALUE 75.000000
-@@ -1727,6 +2035,62 @@
+@@ -1727,6 +2035,76 @@
ENUM_VALUE_LIST OFF,ON
READ_ONLY NO
COMMAND_LINE_ARGUMENT OPTIONAL
++VARIABLE_NAME INNODB_PRINT_LOCK_WAIT_TIMEOUT_INFO
++SESSION_VALUE NULL
++GLOBAL_VALUE OFF
++GLOBAL_VALUE_ORIGIN COMPILE-TIME
++DEFAULT_VALUE OFF
++VARIABLE_SCOPE GLOBAL
++VARIABLE_TYPE BOOLEAN
++VARIABLE_COMMENT Print lock wait timeout info to MySQL error log (off 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 INNODB_PRIORITY_CLEANER
+SESSION_VALUE NULL
+GLOBAL_VALUE OFF
@@ -478,7 +492,7 @@
VARIABLE_NAME INNODB_PURGE_BATCH_SIZE
SESSION_VALUE NULL
GLOBAL_VALUE 300
-@@ -1895,6 +2259,48 @@
+@@ -1895,6 +2273,48 @@
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT OPTIONAL
@@ -527,7 +541,7 @@
VARIABLE_NAME INNODB_SCRUB_LOG
SESSION_VALUE NULL
GLOBAL_VALUE OFF
-@@ -1923,6 +2329,34 @@
+@@ -1923,6 +2343,34 @@
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT OPTIONAL
@@ -562,7 +576,7 @@
VARIABLE_NAME INNODB_SIMULATE_COMP_FAILURES
SESSION_VALUE NULL
GLOBAL_VALUE 0
-@@ -2000,7 +2434,7 @@
+@@ -2000,7 +2448,7 @@
DEFAULT_VALUE nulls_equal
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE ENUM
@@ -571,7 +585,7 @@
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
-@@ -2245,6 +2679,34 @@
+@@ -2245,6 +2693,34 @@
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT OPTIONAL
@@ -606,7 +620,7 @@
VARIABLE_NAME INNODB_TRX_PURGE_VIEW_UPDATE_ONLY_DEBUG
SESSION_VALUE NULL
GLOBAL_VALUE OFF
-@@ -2322,7 +2784,7 @@
+@@ -2322,7 +2798,7 @@
DEFAULT_VALUE OFF
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BOOLEAN
@@ -615,7 +629,7 @@
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
-@@ -2343,6 +2805,20 @@
+@@ -2343,6 +2819,20 @@
ENUM_VALUE_LIST OFF,ON
READ_ONLY YES
COMMAND_LINE_ARGUMENT NONE
@@ -636,7 +650,7 @@
VARIABLE_NAME INNODB_USE_MTFLUSH
SESSION_VALUE NULL
GLOBAL_VALUE OFF
-@@ -2357,6 +2833,20 @@
+@@ -2357,6 +2847,20 @@
ENUM_VALUE_LIST OFF,ON
READ_ONLY YES
COMMAND_LINE_ARGUMENT NONE
@@ -657,12 +671,12 @@
VARIABLE_NAME INNODB_USE_SYS_MALLOC
SESSION_VALUE NULL
GLOBAL_VALUE ON
-@@ -2387,12 +2877,12 @@
+@@ -2387,12 +2891,12 @@
COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME INNODB_VERSION
SESSION_VALUE NULL
-GLOBAL_VALUE 5.6.37
-+GLOBAL_VALUE 5.6.36-82.1
++GLOBAL_VALUE 5.6.38-83.0
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE NULL
VARIABLE_SCOPE GLOBAL
diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
index acdbd007e6e..161f740dbfb 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
@@ -1347,7 +1347,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
diff --git a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_now_basic.test b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_now_basic.test
index 0bae347428e..8c5f8fa7bf0 100644
--- a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_now_basic.test
+++ b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_now_basic.test
@@ -5,8 +5,31 @@
-- source include/have_innodb.inc
# Check the default value
-SET @orig = @@global.innodb_buffer_pool_dump_now;
-SELECT @orig;
+SELECT @@global.innodb_buffer_pool_dump_now;
+
+-- let $file = `SELECT CONCAT(@@datadir, @@global.innodb_buffer_pool_filename)`
+-- error 0,1
+-- remove_file $file
+
+SELECT variable_value INTO @old_dump_status FROM information_schema.global_status
+ WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status';
+
+# A previous test could have run buffer pool dump already;
+# in this case we want to make sure that the current time is different
+# from the timestamp in the status variable.
+# We should have had a smart wait condition here, like the commented one below,
+# let $wait_condition =
+# SELECT TRIM(SUBSTR('$old_status', -8)) != DATE_FORMAT(CURTIME(), '%k:%i:%s');
+# -- source include/wait_condition.inc
+
+# ... but we can't because of MDEV-9867, so there will be just sleep instead.
+# And it might be not enough to sleep one second, so we'll have to sleep two.
+
+if (`SELECT variable_value LIKE '%completed at%' FROM information_schema.global_status
+ WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status'`)
+{
+ -- sleep 2
+}
# Do the dump
SET GLOBAL innodb_buffer_pool_dump_now = ON;
@@ -15,11 +38,11 @@ SELECT @@global.innodb_buffer_pool_dump_now;
# Wait for the dump to complete
let $wait_condition =
- SELECT SUBSTR(variable_value, 1, 33) = 'Buffer pool(s) dump completed at '
+ SELECT variable_value != @old_dump_status
+ AND 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
# Confirm that the dump file has been created
--- let $file = `SELECT CONCAT(@@datadir, @@global.innodb_buffer_pool_filename)`
-- file_exists $file
diff --git a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_pct_basic.test b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_pct_basic.test
index d2f5cb4a0de..1cf6775e06d 100644
--- a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_pct_basic.test
+++ b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_pct_basic.test
@@ -8,19 +8,15 @@
SET @orig = @@global.innodb_buffer_pool_dump_pct;
SELECT @orig;
-# Do the dump
-SET GLOBAL innodb_buffer_pool_dump_pct=3, GLOBAL innodb_buffer_pool_dump_now = ON;
+SET GLOBAL innodb_buffer_pool_dump_pct=3;
-# Wait 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 # Do the dump
-# Confirm that the dump file has been created
--- let $file = `SELECT CONCAT(@@datadir, @@global.innodb_buffer_pool_filename)`
--- file_exists $file
+--disable_query_log
+--disable_result_log
+--source innodb_buffer_pool_dump_now_basic.test
+--enable_result_log
+--enable_query_log
--disable_warnings
SET GLOBAL innodb_buffer_pool_dump_pct=0;
diff --git a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.opt b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.opt
new file mode 100644
index 00000000000..e462be3c368
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.opt
@@ -0,0 +1 @@
+--innodb-buffer-pool-load-at-startup=off
diff --git a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.test b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.test
index a0409901865..abb78ce5260 100644
--- a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.test
+++ b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.test
@@ -5,42 +5,22 @@
-- source include/have_innodb.inc
# Check the default value
-SET @orig = @@global.innodb_buffer_pool_load_now;
-SELECT @orig;
+SELECT @@global.innodb_buffer_pool_load_now;
-let $old_status= `SELECT variable_value FROM information_schema.global_status
- WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status'`;
+# Make sure there is a dump file to load
-# A previous test could have run buffer pool dump already;
-# in this case we want to make sure that the current time is different
-# from the timestamp in the status variable.
-# We should have had a smart wait condition here, like the commented one below,
-# but we can't because of MDEV-9867, so there will be just sleep instead.
-# And it might be not enough to sleep one second, so we'll have to sleep two.
-# let $wait_condition =
-# SELECT TRIM(SUBSTR('$old_status', -8)) != DATE_FORMAT(CURTIME(), '%k:%i:%s');
-# -- source include/wait_condition.inc
-
-if (`SELECT variable_value LIKE '%dump completed at%' FROM information_schema.global_status
- WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status'`)
-{
- -- sleep 2
-}
-
-# Do the dump
-SET GLOBAL innodb_buffer_pool_dump_now = ON;
-
-# Wait for the dump to complete
-let $wait_condition =
- SELECT variable_value != '$old_status'
- AND 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
-
-# Confirm the file is really created
-- let $file = `SELECT CONCAT(@@datadir, @@global.innodb_buffer_pool_filename)`
+-- error 0,1
-- file_exists $file
+if ($errno)
+{
+ # Dump file does not exist, get it created
+ --disable_query_log
+ --disable_result_log
+ --source innodb_buffer_pool_dump_now_basic.test
+ --enable_result_log
+ --enable_query_log
+}
# Load the dump
SET GLOBAL innodb_buffer_pool_load_now = ON;
diff --git a/mysql-test/suite/sys_vars/t/innodb_print_lock_wait_timeout_info_basic.test b/mysql-test/suite/sys_vars/t/innodb_print_lock_wait_timeout_info_basic.test
new file mode 100644
index 00000000000..23d8ba667ce
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/innodb_print_lock_wait_timeout_info_basic.test
@@ -0,0 +1,89 @@
+--source include/have_xtradb.inc
+
+SET @start_global_value = @@global.innodb_print_lock_wait_timeout_info;
+SELECT @start_global_value;
+
+#
+# exists as global only
+#
+--echo Valid values are 'ON' and 'OFF'
+SELECT @@global.innodb_print_lock_wait_timeout_info in (0, 1);
+SELECT @@global.innodb_print_lock_wait_timeout_info;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT @@session.innodb_print_lock_wait_timeout_info;
+SHOW global variables LIKE 'innodb_print_lock_wait_timeout_info';
+SHOW session variables LIKE 'innodb_print_lock_wait_timeout_info';
+--disable_warnings
+SELECT * FROM information_schema.global_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+SELECT * FROM information_schema.session_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+--enable_warnings
+
+#
+# SHOW that it's writable
+#
+SET global innodb_print_lock_wait_timeout_info='OFF';
+SELECT @@global.innodb_print_lock_wait_timeout_info;
+--disable_warnings
+SELECT * FROM information_schema.global_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+SELECT * FROM information_schema.session_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+--enable_warnings
+SET @@global.innodb_print_lock_wait_timeout_info=1;
+SELECT @@global.innodb_print_lock_wait_timeout_info;
+--disable_warnings
+SELECT * FROM information_schema.global_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+SELECT * FROM information_schema.session_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+--enable_warnings
+SET global innodb_print_lock_wait_timeout_info=0;
+SELECT @@global.innodb_print_lock_wait_timeout_info;
+--disable_warnings
+SELECT * FROM information_schema.global_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+SELECT * FROM information_schema.session_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+--enable_warnings
+SET @@global.innodb_print_lock_wait_timeout_info='ON';
+SELECT @@global.innodb_print_lock_wait_timeout_info;
+--disable_warnings
+SELECT * FROM information_schema.global_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+SELECT * FROM information_schema.session_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+--enable_warnings
+--error ER_GLOBAL_VARIABLE
+SET session innodb_print_lock_wait_timeout_info='OFF';
+--error ER_GLOBAL_VARIABLE
+SET @@session.innodb_print_lock_wait_timeout_info='ON';
+
+#
+# incorrect types
+#
+--error ER_WRONG_TYPE_FOR_VAR
+SET global innodb_print_lock_wait_timeout_info=1.1;
+--error ER_WRONG_TYPE_FOR_VAR
+SET global innodb_print_lock_wait_timeout_info=1e1;
+--error ER_WRONG_VALUE_FOR_VAR
+SET global innodb_print_lock_wait_timeout_info=2;
+--error ER_WRONG_VALUE_FOR_VAR
+SET global innodb_print_lock_wait_timeout_info=-3;
+SELECT @@global.innodb_print_lock_wait_timeout_info;
+--disable_warnings
+SELECT * FROM information_schema.global_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+SELECT * FROM information_schema.session_variables
+WHERE variable_name='innodb_print_lock_wait_timeout_info';
+--enable_warnings
+--error ER_WRONG_VALUE_FOR_VAR
+SET global innodb_print_lock_wait_timeout_info='AUTO';
+
+#
+# Cleanup
+#
+
+SET @@global.innodb_print_lock_wait_timeout_info = @start_global_value;
+SELECT @@global.innodb_print_lock_wait_timeout_info;
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/vcol/r/vcol_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result
index 659bc00c2b7..179d1b54c21 100644
--- a/mysql-test/suite/vcol/r/vcol_misc.result
+++ b/mysql-test/suite/vcol/r/vcol_misc.result
@@ -338,7 +338,26 @@ tsv timestamp as (adddate(ts, interval 1 day)) virtual
drop table t1;
set sql_mode=default;
#
-# Start of 10.1 tests
+# MDEV-11819 NO_ZERO_IN_DATE: Incorrect generated column value
+#
+SET sql_mode='NO_ZERO_IN_DATE';
+CREATE TABLE t1
+(
+a datetime DEFAULT NULL,
+b datetime DEFAULT NULL,
+c time GENERATED ALWAYS AS (timediff(`a`,`b`)) VIRTUAL
+);
+INSERT INTO t1 VALUES ('2008-12-31 23:59:59.000001','2008-12-30 01:01:01.000002',DEFAULT);
+SELECT * FROM t1;
+a b c
+2008-12-31 23:59:59 2008-12-30 01:01:01 46:58:58
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+#
+# End of 5.5 tests
+#
+#
+# End of 10.0 tests
#
#
# MDEV-8441 Bad SHOW CREATE TABLE output for a table with a virtual column
diff --git a/mysql-test/suite/vcol/t/vcol_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test
index d9c1f64991c..1eed47269c2 100644
--- a/mysql-test/suite/vcol/t/vcol_misc.test
+++ b/mysql-test/suite/vcol/t/vcol_misc.test
@@ -302,9 +302,28 @@ create table t1 (
drop table t1;
set sql_mode=default;
+--echo #
+--echo # MDEV-11819 NO_ZERO_IN_DATE: Incorrect generated column value
+--echo #
+
+SET sql_mode='NO_ZERO_IN_DATE';
+CREATE TABLE t1
+(
+ a datetime DEFAULT NULL,
+ b datetime DEFAULT NULL,
+ c time GENERATED ALWAYS AS (timediff(`a`,`b`)) VIRTUAL
+);
+INSERT INTO t1 VALUES ('2008-12-31 23:59:59.000001','2008-12-30 01:01:01.000002',DEFAULT);
+SELECT * FROM t1;
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
--echo #
---echo # Start of 10.1 tests
+--echo # End of 5.5 tests
+--echo #
+
+--echo #
+--echo # End of 10.0 tests
--echo #
--echo #
@@ -328,7 +347,6 @@ SELECT COLUMN_GET(@aaa, 'price' AS DECIMAL) aaa;
SELECT COLUMN_GET(@aaa, 'price' AS INT) aaa;
SELECT COLUMN_GET(@aaa, 'price' AS DOUBLE) aaa;
-
--echo #
--echo # End of 10.1 tests
--echo #
diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test
index eef6f17efec..5cb33516ed2 100644
--- a/mysql-test/t/alter_table.test
+++ b/mysql-test/t/alter_table.test
@@ -1254,6 +1254,48 @@ execute stmt1;
deallocate prepare stmt1;
drop table t2;
+--echo #
+--echo # MDEV-8960 Can't refer the same column twice in one ALTER TABLE
+--echo #
+
+CREATE TABLE t1 (
+ `a` int(11) DEFAULT NULL
+) DEFAULT CHARSET=utf8;
+
+ALTER TABLE t1 ADD COLUMN `consultant_id` integer NOT NULL,
+ALTER COLUMN `consultant_id` DROP DEFAULT;
+
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+ `a` int(11) DEFAULT NULL
+) DEFAULT CHARSET=utf8;
+
+ALTER TABLE t1 ADD COLUMN `consultant_id` integer NOT NULL,
+ALTER COLUMN `consultant_id` SET DEFAULT 2;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+ `a` int(11) DEFAULT NULL
+) DEFAULT CHARSET=utf8;
+
+ALTER TABLE t1 ADD COLUMN `consultant_id` integer NOT NULL DEFAULT 2,
+ALTER COLUMN `consultant_id` DROP DEFAULT;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+ `a` int(11) DEFAULT NULL
+) DEFAULT CHARSET=utf8;
+
+ALTER TABLE t1 ADD COLUMN `consultant_id` integer NOT NULL DEFAULT 2,
+ALTER COLUMN `consultant_id` DROP DEFAULT,
+MODIFY COLUMN `consultant_id` BIGINT;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
#
# Test of ALTER TABLE IF [NOT] EXISTS
#
@@ -1768,49 +1810,7 @@ SHOW CREATE TABLE t1;
DROP TABLE t1;
--echo #
---echo # MDEV-8960 Can't refer the same column twice in one ALTER TABLE
---echo #
-
-CREATE TABLE t1 (
- `a` int(11) DEFAULT NULL
-) DEFAULT CHARSET=utf8;
-
-ALTER TABLE t1 ADD COLUMN `consultant_id` integer NOT NULL,
-ALTER COLUMN `consultant_id` DROP DEFAULT;
-
-SHOW CREATE TABLE t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 (
- `a` int(11) DEFAULT NULL
-) DEFAULT CHARSET=utf8;
-
-ALTER TABLE t1 ADD COLUMN `consultant_id` integer NOT NULL,
-ALTER COLUMN `consultant_id` SET DEFAULT 2;
-SHOW CREATE TABLE t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 (
- `a` int(11) DEFAULT NULL
-) DEFAULT CHARSET=utf8;
-
-ALTER TABLE t1 ADD COLUMN `consultant_id` integer NOT NULL DEFAULT 2,
-ALTER COLUMN `consultant_id` DROP DEFAULT;
-SHOW CREATE TABLE t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 (
- `a` int(11) DEFAULT NULL
-) DEFAULT CHARSET=utf8;
-
-ALTER TABLE t1 ADD COLUMN `consultant_id` integer NOT NULL DEFAULT 2,
-ALTER COLUMN `consultant_id` DROP DEFAULT,
-MODIFY COLUMN `consultant_id` BIGINT;
-SHOW CREATE TABLE t1;
-DROP TABLE t1;
-
---echo #
---echo # Start of 10.1 tests
+--echo # End of 10.0 tests
--echo #
--echo #
@@ -1830,3 +1830,7 @@ CREATE INDEX i1 ON t1(a) COMMENT 'comment1';
ALTER TABLE t1 DROP INDEX i1, ADD INDEX i1(a) COMMENT 'comment2';
SHOW CREATE TABLE t1;
DROP TABLE t1;
+
+--echo #
+--echo # End of 10.1 tests
+--echo #
diff --git a/mysql-test/t/case.test b/mysql-test/t/case.test
index 7cc74c52b28..702592374b6 100644
--- a/mysql-test/t/case.test
+++ b/mysql-test/t/case.test
@@ -174,6 +174,18 @@ drop table t1, t2;
--echo End of 5.0 tests
+--echo #
+--echo # Bug#19875294 ASSERTION `SRC' FAILED IN MY_STRNXFRM_UNICODE
+--echo # (SIG 6 -STRINGS/CTYPE-UTF8.C:5151)
+--echo #
+
+set @@sql_mode='';
+CREATE TABLE t1(c1 SET('','')CHARACTER SET ucs2);
+INSERT INTO t1 VALUES(990101.102);
+SELECT COALESCE(c1)FROM t1 ORDER BY 1;
+DROP TABLE t1;
+set @@sql_mode=default;
+
#
# lp:1001510
# Bug #11764313 57135: CRASH IN ITEM_FUNC_CASE::FIND_ITEM WITH CASE WHEN
diff --git a/mysql-test/t/count_distinct.test b/mysql-test/t/count_distinct.test
index a00574b6cba..86045e862e7 100644
--- a/mysql-test/t/count_distinct.test
+++ b/mysql-test/t/count_distinct.test
@@ -121,5 +121,34 @@ drop table t1;
set @@tmp_table_size = default;
#
+# MDEV-13457: Wrong result for aggregate function with distinct clause when the value for
+# tmp_table_size is small
+#
+
+create table t1 (
+a VARCHAR(1020),
+b int
+);
+insert into t1 values
+( 0 , 1 ),
+( 1 , 2 ),
+( 2 , 3 ),
+( 3 , 4 ),
+( 4 , 5 ),
+( 5 , 6 ),
+( 6 , 7 ),
+( 7 , 8 ),
+( 8 , 9 ),
+( 9 , 10 ),
+( 0 , 11 ),
+( 1 , 12 ),
+( 2 , 13 ),
+( 3 , 14 );
+set @@tmp_table_size=1024;
+select count(distinct a) from t1;
+drop table t1;
+set @@tmp_table_size = default;
+
+#
# End of 5.5 tests
#
diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test
index 7306a819ad7..c6a91a18965 100644
--- a/mysql-test/t/create.test
+++ b/mysql-test/t/create.test
@@ -1765,6 +1765,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_or_replace2.test b/mysql-test/t/create_or_replace2.test
index be1bd9a3d81..da451796e12 100644
--- a/mysql-test/t/create_or_replace2.test
+++ b/mysql-test/t/create_or_replace2.test
@@ -3,9 +3,9 @@
#
--source include/have_debug.inc
---source include/master-slave.inc
--source include/have_binlog_format_row.inc
--source include/have_xtradb.inc
+--source include/master-slave.inc
--disable_warnings
drop table if exists t1;
diff --git a/mysql-test/t/ctype_gbk.test b/mysql-test/t/ctype_gbk.test
index 07e73cdf745..022d4a3705a 100644
--- a/mysql-test/t/ctype_gbk.test
+++ b/mysql-test/t/ctype_gbk.test
@@ -199,6 +199,20 @@ let $ctype_unescape_combinations=selected;
SET NAMES gbk;
--source include/ctype_E05C.inc
+--echo #
+--echo # MDEV-9886 Illegal mix of collations with a view comparing a field to a binary constant
+--echo #
+
+SET NAMES latin1;
+CREATE TABLE t1 (a TEXT CHARACTER SET gbk);
+INSERT INTO t1 VALUES (0xEE5D);
+SELECT a<>0xEE5D AS a FROM t1;
+CREATE VIEW v1 AS SELECT a<>0xEE5D AS a FROM t1;
+SHOW CREATE VIEW v1;
+SELECT * FROM v1;
+DROP VIEW v1;
+DROP TABLE t1;
+
--echo #
--echo # End of 10.0 tests
diff --git a/mysql-test/t/ctype_latin1.test b/mysql-test/t/ctype_latin1.test
index a30c7ae9a5d..1ee48eed18c 100644
--- a/mysql-test/t/ctype_latin1.test
+++ b/mysql-test/t/ctype_latin1.test
@@ -245,6 +245,22 @@ DROP TABLE t1;
--echo #
SELECT _latin1 0x7E, _latin1 X'7E', _latin1 B'01111110';
+
+--echo #
+--echo # MDEV-9886 Illegal mix of collations with a view comparing a field to a binary constant
+--echo #
+
+SET NAMES latin1;
+CREATE TABLE t1 (a TEXT CHARACTER SET latin1);
+INSERT INTO t1 VALUES (0xC0);
+SELECT a<>0xEE5D AS a FROM t1;
+CREATE VIEW v1 AS SELECT a<>0xC0 AS a FROM t1;
+SHOW CREATE VIEW v1;
+SELECT * FROM v1;
+DROP VIEW v1;
+DROP TABLE t1;
+
+
--echo #
--echo # End of 10.0 tests
--echo #
diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
index 316b81f697b..e21cd1f0022 100644
--- a/mysql-test/t/ctype_ucs.test
+++ b/mysql-test/t/ctype_ucs.test
@@ -826,6 +826,29 @@ SET sql_mode=DEFAULT;
SET NAMES utf8;
--echo #
+--echo # MDEV-13972 crash in Item_func_sec_to_time::get_date
+--echo #
+
+SELECT SEC_TO_TIME(CONVERT(900*24*60*60 USING ucs2));
+
+--echo #
+--echo # MDEV-13530 VARBINARY doesn't convert to to BLOB for sizes 65533, 65534 and 65535
+--echo #
+
+CREATE TABLE t1 (c1 VARCHAR(32766) CHARACTER SET ucs2);
+DESCRIBE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 VARCHAR(32767) CHARACTER SET ucs2);
+DESCRIBE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 VARCHAR(32768) CHARACTER SET ucs2);
+DESCRIBE t1;
+DROP TABLE t1;
+
+
+--echo #
--echo # End of 5.5 tests
--echo #
diff --git a/mysql-test/t/ctype_utf32.test b/mysql-test/t/ctype_utf32.test
index 96e9ecdd805..3bef1524e5b 100644
--- a/mysql-test/t/ctype_utf32.test
+++ b/mysql-test/t/ctype_utf32.test
@@ -904,6 +904,19 @@ SET sql_mode=DEFAULT;
SET NAMES utf8;
--echo #
+--echo # MDEV-13530 VARBINARY doesn't convert to to BLOB for sizes 65533, 65534 and 65535
+--echo #
+
+CREATE TABLE t1 (c1 VARCHAR(16383) CHARACTER SET utf32);
+DESCRIBE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 VARCHAR(16384) CHARACTER SET utf32);
+DESCRIBE t1;
+DROP TABLE t1;
+
+
+--echo #
--echo # End of 5.5 tests
--echo #
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index 5f1de609df1..e013109d0a7 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -1716,6 +1716,22 @@ SET sql_mode=DEFAULT;
DROP TABLE t1;
--echo #
+--echo # MDEV-13530 VARBINARY doesn't convert to to BLOB for sizes 65533, 65534 and 65535
+--echo #
+
+CREATE TABLE t1 (c1 VARCHAR(21844) CHARACTER SET utf8);
+DESCRIBE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 VARCHAR(21845) CHARACTER SET utf8);
+DESCRIBE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 VARCHAR(21846) CHARACTER SET utf8);
+DESCRIBE t1;
+DROP TABLE t1;
+
+--echo #
--echo # End of 5.5 tests
--echo #
@@ -1854,6 +1870,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 #
@@ -1983,6 +2011,18 @@ SET @@SQL_MODE=default;
#DROP FUNCTION f1;
#SET NAMES utf8;
+--echo #
+--echo # MDEV-10191 non convertible chars convert() resulted in Null instead "?" on Windows
+--echo #
+
+SET sql_mode='STRICT_TRANS_TABLES';
+SELECT CONVERT(_utf8 0xC499 USING latin1);
+SELECT CAST(_utf8 0xC499 AS CHAR CHARACTER SET latin1);
+
+SET sql_mode=default;
+SELECT CONVERT(_utf8 0xC499 USING latin1);
+SELECT CAST(_utf8 0xC499 AS CHAR CHARACTER SET latin1);
+
--echo #
--echo # End of 10.1 tests
diff --git a/mysql-test/t/ctype_utf8mb4.test b/mysql-test/t/ctype_utf8mb4.test
index 060c2aa1afb..77ace195217 100644
--- a/mysql-test/t/ctype_utf8mb4.test
+++ b/mysql-test/t/ctype_utf8mb4.test
@@ -1914,6 +1914,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/delete_returning.test b/mysql-test/t/delete_returning.test
index 3790d0905a5..4448a6bcccd 100644
--- a/mysql-test/t/delete_returning.test
+++ b/mysql-test/t/delete_returning.test
@@ -155,3 +155,18 @@ SELECT * FROM t1;
DROP PROCEDURE p1;
DROP TABLE t1;
+--echo #
+--echo # MDEV-13776: DELETE ... RETURNING with sql_mode='ONLY_FULL_GROUP_BY'
+--echo #
+
+set @sql_mode_save= @@sql_mode;
+set sql_mode='ONLY_FULL_GROUP_BY';
+
+CREATE TABLE t1 (id INT);
+INSERT INTO t1 VALUE(1),(2),(3);
+
+DELETE FROM t1 WHERE id > 2 RETURNING *;
+
+set sql_mode=@sql_mode_save;
+
+DROP TABLE t1;
diff --git a/mysql-test/t/delimiter_case_mdev_10728.sql b/mysql-test/t/delimiter_case_mdev_10728.sql
new file mode 100644
index 00000000000..72a1dcd9a9e
--- /dev/null
+++ b/mysql-test/t/delimiter_case_mdev_10728.sql
@@ -0,0 +1,3 @@
+DeLiMiTeR A;
+SELECT 1 A;
+delimiter ;
diff --git a/mysql-test/t/delimiter_command_case_sensitivity.test b/mysql-test/t/delimiter_command_case_sensitivity.test
new file mode 100644
index 00000000000..11d1cf75aa0
--- /dev/null
+++ b/mysql-test/t/delimiter_command_case_sensitivity.test
@@ -0,0 +1,4 @@
+source include/not_embedded.inc;
+
+# MDEV-10728
+--exec $MYSQL --default-character-set=binary < "t/delimiter_case_mdev_10728.sql"
diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test
index d881430a060..b0415cf3b04 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/dyncol.test b/mysql-test/t/dyncol.test
index 03e2345ba1c..7807d1a9f9e 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/fulltext.test b/mysql-test/t/fulltext.test
index 9dfc49d3dfd..fc7b15c052d 100644
--- a/mysql-test/t/fulltext.test
+++ b/mysql-test/t/fulltext.test
@@ -682,6 +682,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_in.test b/mysql-test/t/func_in.test
index 9e848aa1847..8a1af6ef872 100644
--- a/mysql-test/t/func_in.test
+++ b/mysql-test/t/func_in.test
@@ -605,11 +605,20 @@ EXECUTE s;
DROP TABLE t1;
+--echo #
--echo # End of 5.3 tests
+--echo #
+#
+# Bug#26361149 MYSQL SERVER CRASHES AT: COL IN(IFNULL(CONST, COL), NAME_CONST('NAME', NULL))
+#
+create table t1 (a int);
+insert t1 values (1),(2),(3);
+select * from t1 where 1 in (a, name_const('a', null));
+drop table t1;
--echo #
---echo # Start of 10.0 tests
+--echo # End of 5.5 tests
--echo #
--echo #
@@ -626,7 +635,7 @@ SELECT * FROM t1 WHERE b NOT IN (NULL, '', 'A');
DROP TABLE t1;
--echo #
---echo # Start of 10.1 tests
+--echo # End of 10.0 tests
--echo #
--echo #
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_misc.test b/mysql-test/t/func_misc.test
index b874700f29d..ffb7838ee78 100644
--- a/mysql-test/t/func_misc.test
+++ b/mysql-test/t/func_misc.test
@@ -1107,3 +1107,30 @@ select release_lock('test');
--echo
--echo # -- Done.
--echo
+
+
+--echo #
+--echo # MDEV-13685 Can not replay binary log due to Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8mb4_general_ci,COERCIBLE) for operation 'concat'
+--echo #
+SET NAMES utf8;
+SELECT COERCIBILITY(NAME_CONST('name','test'));
+SELECT COERCIBILITY(NAME_CONST('name',TIME'00:00:00'));
+SELECT COERCIBILITY(NAME_CONST('name',15));
+SELECT CONCAT(NAME_CONST('name',15),'오');
+SET NAMES latin1;
+
+--echo #
+--echo # MDEV-14116 INET6_NTOA output is set as null to varchar(39) variable
+--echo #
+
+DELIMITER $$;
+CREATE PROCEDURE p1()
+BEGIN
+ DECLARE ip_full_addr varchar(39) DEFAULT "";
+ SELECT INET6_NTOA(UNHEX('20000000000000000000000000000000')) into ip_full_addr;
+ SELECT ip_full_addr;
+END;
+$$
+DELIMITER ;$$
+CALL p1();
+DROP PROCEDURE p1;
diff --git a/mysql-test/t/func_regexp_pcre.test b/mysql-test/t/func_regexp_pcre.test
index cf83db794cf..83a17e16831 100644
--- a/mysql-test/t/func_regexp_pcre.test
+++ b/mysql-test/t/func_regexp_pcre.test
@@ -434,19 +434,19 @@ SELECT 1 FROM dual WHERE ('Alpha,Bravo,Charlie,Delta,Echo,Foxtrot,StrataCentral,
#
# MDEV-13173 An RLIKE that previously worked on 10.0 now returns "Got error 'pcre_exec: recursion limit of 100 exceeded' from regexp"
#
-SELECT CONCAT(REPEAT('100,',133),'101') RLIKE '^(([1-9][0-9]*),)*[1-9][0-9]*$';
+SELECT CONCAT(REPEAT('100,',60),'101') RLIKE '^(([1-9][0-9]*),)*[1-9][0-9]*$';
--replace_regex /[0-9]+ exceeded/NUM exceeded/
SELECT CONCAT(REPEAT('100,',200),'101') RLIKE '^(([1-9][0-9]*),)*[1-9][0-9]*$';
-SELECT REGEXP_INSTR(CONCAT(REPEAT('100,',133),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$');
+SELECT REGEXP_INSTR(CONCAT(REPEAT('100,',60),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$');
--replace_regex /[0-9]+ exceeded/NUM exceeded/
SELECT REGEXP_INSTR(CONCAT(REPEAT('100,',200),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$');
-SELECT LENGTH(REGEXP_SUBSTR(CONCAT(REPEAT('100,',133),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$'));
+SELECT LENGTH(REGEXP_SUBSTR(CONCAT(REPEAT('100,',60),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$'));
--replace_regex /[0-9]+ exceeded/NUM exceeded/
SELECT LENGTH(REGEXP_SUBSTR(CONCAT(REPEAT('100,',200),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$'));
-SELECT LENGTH(REGEXP_REPLACE(CONCAT(REPEAT('100,',133),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$', ''));
+SELECT LENGTH(REGEXP_REPLACE(CONCAT(REPEAT('100,',60),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$', ''));
--replace_regex /[0-9]+ exceeded/NUM exceeded/
SELECT LENGTH(REGEXP_REPLACE(CONCAT(REPEAT('100,',200),'101'), '^(([1-9][0-9]*),)*[1-9][0-9]*$', ''));
diff --git a/mysql-test/t/func_set.test b/mysql-test/t/func_set.test
index 13f8661db49..887b1948498 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 48872edcd4b..b3143ecbc86 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -1757,6 +1757,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 #
@@ -1800,7 +1812,6 @@ SELECT f1,HEX(f2) FROM t1 WHERE f1='YQ==' AND (f2= from_base64(
SELECT f1,HEX(f2) FROM t1 WHERE f1='YQ==' AND (f2= from_base64("Yq==") OR f2= from_base64("YQ=="));
DROP TABLE t1;
-
--echo #
--echo # End of 10.1 tests
--echo #
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 5cfb7f7d05f..bc553e6f049 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -1677,9 +1677,33 @@ DROP TABLE t1;
--echo #
SELECT 1 MOD ADDTIME( '13:58:57', '00:00:01' ) + 2;
+--echo #
+--echo # MDEV-11819 NO_ZERO_IN_DATE: Incorrect generated column value
+--echo #
+
+SET sql_mode='NO_ZERO_IN_DATE';
+CREATE TABLE t1 (a TIME(6));
+INSERT INTO t1 SELECT timediff(timestamp'2008-12-31 23:59:59.000001',timestamp'2008-12-30 01:01:01.000002');
+SELECT * FROM t1;
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+
+
+--echo #
+--echo # MDEV-13972 crash in Item_func_sec_to_time::get_date
+--echo #
+
+# The below query can return warning sporadically
+--disable_warnings
+DO TO_DAYS(SEC_TO_TIME(TIME(CEILING(UUID()))));
+--enable_warnings
+
+DO TO_DAYS(SEC_TO_TIME(MAKEDATE('',RAND(~('')))));
+SELECT SEC_TO_TIME(MAKEDATE(0,RAND(~0)));
+
--echo #
---echo # Start of 10.0 tests
+--echo # End of 5.5 tests
--echo #
--echo #
diff --git a/mysql-test/t/gis-precise.test b/mysql-test/t/gis-precise.test
index 5e57569a912..7391b2114f3 100644
--- a/mysql-test/t/gis-precise.test
+++ b/mysql-test/t/gis-precise.test
@@ -362,5 +362,24 @@ select ST_Touches(ST_LineFromText('LINESTRING(0 0,5 5)'),ST_PointFromText('POINT
select ST_Touches(ST_PolygonFromText('POLYGON((0 0,0 5,5 5,5 0,0 0))'),ST_PointFromText('POINT(0 0)'));
select ST_Touches(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'));
+# MDEV-12705 10.1.18-MariaDB-1~jessie - mysqld got signal 11.
+SELECT ST_RELATE(
+ ST_DIFFERENCE(
+ GEOMETRYFROMTEXT('
+ MULTILINESTRING(
+ ( 12841 36140, 8005 31007, 26555 31075, 52765 41191,
+ 28978 6548, 45720 32057, 53345 3221 ),
+ ( 8304 59107, 25233 31592, 40502 25303, 8205 42940 ),
+ ( 7829 7305, 58841 56759, 64115 8512, 37562 54145, 2210 14701 ),
+ ( 20379 2805, 40807 27770, 28147 14883, 26439 29383, 55663 5086 ),
+ ( 35944 64702, 14433 23728, 49317 26241, 790 16941 )
+ )
+ '),
+ GEOMETRYFROMTEXT('POINT(46061 13545)')
+ ),
+ GEOMETRYFROMTEXT('POINT(4599 60359)'),
+ 'F*FFFF**F'
+ ) as relate_res;
+
--source include/gis_debug.inc
diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test
index 46d341affb4..0401ad9780c 100644
--- a/mysql-test/t/group_by.test
+++ b/mysql-test/t/group_by.test
@@ -1765,6 +1765,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 f826feff5c0..1bbde3e7c5e 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 5b0e2910889..5b3fa7b653c 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -1910,3 +1910,29 @@ disconnect con1;
--source include/wait_until_count_sessions.inc
set global sql_mode=default;
+
+USE test;
+
+--echo #
+--echo # End of 10.0 tests
+--echo #
+
+
+--echo #
+--echo # Start of 10.1 tests
+--echo #
+
+
+--echo #
+--echo # MDEV-13242 Wrong results for queries with row constructors and information_schema
+--echo #
+
+CREATE TABLE tt1(c1 INT);
+CREATE TABLE tt2(c2 INT);
+SELECT count(*) FROM information_schema.columns WHERE table_schema='test' AND (table_name, column_name) IN (('tt1', 'c1'));
+SELECT count(*) FROM information_schema.columns WHERE table_schema='test' AND (table_name, column_name) IN (('tt2', 'c2'));
+SELECT count(*) FROM information_schema.columns WHERE table_schema='test' AND (table_name, column_name) IN (('tt1','c1'),('tt2', 'c2'));
+SELECT count(*) FROM information_schema.columns WHERE table_schema='test' AND (table_name, column_name) IN (SELECT 'tt1','c1' FROM dual UNION SELECT 'tt2', 'c2' FROM dual);
+SELECT count(*) FROM information_schema.columns WHERE table_schema='test' AND (table_name='tt1' AND column_name='c1') OR (table_name='tt2' AND column_name='c2');
+SELECT column_name FROM information_schema.columns WHERE (table_name, column_name) IN (('tt1','c1'),('tt2', 'c2')) ORDER BY column_name;
+DROP TABLE tt1, tt2;
diff --git a/mysql-test/t/insert.test b/mysql-test/t/insert.test
index 2d95dffa17a..3092608f893 100644
--- a/mysql-test/t/insert.test
+++ b/mysql-test/t/insert.test
@@ -573,3 +573,42 @@ insert ignore into t1 values (1,12) on duplicate key update f2=13;
set @@old_mode="";
insert ignore into t1 values (1,12);
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-13290 Assertion Assertion `!is_set() || (m_status == DA_OK_BULK
+--echo # && is_bulk_op())' or `! is_set()' failed
+--echo #
+
+SET @save_mode= @@sql_mode;
+SET sql_mode= 'STRICT_ALL_TABLES';
+CREATE TABLE t1 (f1 INT DEFAULT 0, f2 INT);
+CREATE ALGORITHM = MERGE VIEW v1 AS SELECT f1, f2 FROM t1 WHERE f1 = 'x' WITH CHECK OPTION;
+--error ER_TRUNCATED_WRONG_VALUE
+REPLACE INTO v1 SET f2 = 1;
+SELECT * from t1;
+drop view v1;
+CREATE ALGORITHM = MERGE VIEW v1 AS SELECT f1, f2 FROM t1 WHERE f1 = cast('' as decimal) WITH CHECK OPTION;
+--error ER_TRUNCATED_WRONG_VALUE
+REPLACE INTO v1 SET f2 = 1;
+SELECT * from t1;
+drop view v1;
+SELECT 0,0 INTO OUTFILE 't1.txt';
+CREATE ALGORITHM = MERGE VIEW v1 AS SELECT f1, f2 FROM t1 WHERE f1 = 'x' WITH CHECK OPTION;
+--error ER_TRUNCATED_WRONG_VALUE
+LOAD DATA INFILE 't1.txt' INTO TABLE v1;
+SELECT * from t1;
+let $MYSQLD_DATADIR= `select @@datadir`;
+remove_file $MYSQLD_DATADIR/test/t1.txt;
+drop view v1;
+drop table t1;
+SET @@sql_mode= @save_mode;
+
+#
+# MDEV-13861 Assertion `0' failed in Protocol::end_statement
+#
+CREATE TABLE t1 (f INT);
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE f <=> 'foo' WITH CHECK OPTION;
+--error ER_VIEW_CHECK_FAILED
+REPLACE INTO v1 SET f = NULL;
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test
index 5ee868b4177..ee3e324cd80 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/log_tables-big.test b/mysql-test/t/log_tables-big.test
index 8936a163d73..fa8810ecd3b 100644
--- a/mysql-test/t/log_tables-big.test
+++ b/mysql-test/t/log_tables-big.test
@@ -7,6 +7,7 @@
# check that CSV engine was compiled in
--source include/have_csv.inc
+set @log_output.saved = @@global.log_output;
set @@global.log_output = 'TABLE';
connect (con1,localhost,root,,);
@@ -21,13 +22,13 @@ select get_lock('bug27638', 1);
connection con2;
set session long_query_time=1;
select get_lock('bug27638', 2);
-select if (query_time >= '00:00:01', 'OK', 'WRONG') as qt, sql_text from mysql.slow_log
+select if (query_time >= '00:00:01', 'OK', concat('WRONG: ',query_time)) as qt, sql_text from mysql.slow_log
where sql_text = 'select get_lock(\'bug27638\', 2)';
select get_lock('bug27638', 60);
-select if (query_time >= '00:00:59', 'OK', 'WRONG') as qt, sql_text from mysql.slow_log
+select if (query_time >= '00:00:59', 'OK', concat('WRONG: ',query_time)) as qt, sql_text from mysql.slow_log
where sql_text = 'select get_lock(\'bug27638\', 60)';
select get_lock('bug27638', 101);
-select if (query_time >= '00:01:40', 'OK', 'WRONG') as qt, sql_text from mysql.slow_log
+select if (query_time >= '00:01:40', 'OK', concat('WRONG: ',query_time)) as qt, sql_text from mysql.slow_log
where sql_text = 'select get_lock(\'bug27638\', 101)';
connection con1;
select release_lock('bug27638');
@@ -36,4 +37,4 @@ connection default;
disconnect con1;
disconnect con2;
-set @@global.log_output=default;
+set @@global.log_output = @log_output.saved;
diff --git a/mysql-test/t/mdev13607.test b/mysql-test/t/mdev13607.test
new file mode 100644
index 00000000000..45fdb0a74d4
--- /dev/null
+++ b/mysql-test/t/mdev13607.test
@@ -0,0 +1,60 @@
+--echo #
+--echo # Bug mdev-13607: overflow of current_record_count
+--echo #
+
+--source include/have_innodb.inc
+
+CREATE TABLE t1 (id INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),
+(11),(12),(13),(14),(15),(16),(17),(18),(19),(20),
+(21),(22),(23),(24),(25),(26),(27),(28),(29),(30),
+(31),(32),(33),(34),(35),(36),(37),(38),(39),(40),
+(41),(42),(43),(44),(45),(46),(47),(48),(49),(50);
+
+CREATE TABLE t2 (id INT) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (1),(2);
+
+CREATE TABLE t3 (id INT) ENGINE=InnoDB;
+INSERT INTO t3 VALUES (1),(2);
+
+ANALYZE TABLE t1, t2, t3;
+
+let $q=
+SELECT * FROM
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_1
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_2
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_3
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_4
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_5
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_6
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_7
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_8
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_9
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_10
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_11
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_12
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_13
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_14
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_15
+INNER JOIN
+(SELECT p1.* FROM t1 p1 NATURAL JOIN t2 r1 NATURAL JOIN t3 d1 NATURAL JOIN t1 p2 NATURAL JOIN t2 r2 NATURAL JOIN t3 d2 NATURAL JOIN t1 p3 NATURAL JOIN t2 r3 NATURAL JOIN t3 d3 NATURAL JOIN t1 p4 NATURAL JOIN t2 r4 NATURAL JOIN t3 d4 NATURAL JOIN t1 p5 NATURAL JOIN t2 r5 NATURAL JOIN t3 d5 NATURAL JOIN t1 p6 NATURAL JOIN t2 r6 NATURAL JOIN t3 d6 NATURAL JOIN t1 p7 NATURAL JOIN t2 r7 NATURAL JOIN t3 d7 NATURAL JOIN t1 p8 NATURAL JOIN t2 r8 NATURAL JOIN t3 d8 NATURAL JOIN t1 p9 ) gp_16
+;
+
+eval explain $q;
+
+DROP TABLE t1,t2,t3;
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 e9d69b446d5..d2f4ce0e44a 100644
--- a/mysql-test/t/merge.test
+++ b/mysql-test/t/merge.test
@@ -1559,7 +1559,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 +1593,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 9ac49a9063d..62260ba43aa 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -1030,8 +1030,9 @@ show create table t1;
drop table t1;
# MyISAM specific varchar tests
---error 1118
create table t1 (v varchar(65535));
+show create table t1;
+drop table t1;
eval set storage_engine=$default;
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/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/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/old-mode.test b/mysql-test/t/old-mode.test
index 0572570d122..ed33da523c7 100644
--- a/mysql-test/t/old-mode.test
+++ b/mysql-test/t/old-mode.test
@@ -83,3 +83,37 @@ SELECT TO_DAYS(a), TO_DAYS(b) FROM t1;
DROP TABLE t1;
SET @@global.mysql56_temporal_format=DEFAULT;
+#
+# MDEV-12672 Replicated TIMESTAMP fields given wrong value near DST change
+#
+
+# Copy_field
+set time_zone='Europe/Moscow';
+set global mysql56_temporal_format=false;
+create table t1 (a timestamp);
+set timestamp=1288477526;
+insert t1 values (null);
+set timestamp=1288481126;
+insert t1 values (null);
+select a, unix_timestamp(a) from t1;
+set global mysql56_temporal_format=true;
+select a, unix_timestamp(a) from t1;
+alter table t1 modify a timestamp;
+select a, unix_timestamp(a) from t1;
+drop table t1;
+
+# field_conv_incompatible()
+set global mysql56_temporal_format=false;
+create table t1 (a timestamp);
+set timestamp=1288477526;
+insert t1 values (null);
+set timestamp=1288481126;
+insert t1 values (null);
+select a, unix_timestamp(a) from t1;
+set global mysql56_temporal_format=true;
+select a, unix_timestamp(a) from t1;
+create table t2 (a timestamp);
+insert t2 select a from t1;
+select a, unix_timestamp(a) from t2;
+drop table t1, t2;
+set time_zone=DEFAULT;
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index f61a6a8be34..1ca258d1d48 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -1955,6 +1955,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 #
diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test
index d3161c9338c..35dfdead916 100644
--- a/mysql-test/t/partition.test
+++ b/mysql-test/t/partition.test
@@ -2884,8 +2884,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_datatype.test b/mysql-test/t/partition_datatype.test
index a6035fcb592..4ec0232718e 100644
--- a/mysql-test/t/partition_datatype.test
+++ b/mysql-test/t/partition_datatype.test
@@ -217,11 +217,13 @@ select * from t1 where a = 'bbbb';
drop table t1;
-- error ER_PARTITION_FIELDS_TOO_LONG
create table t1 (a varchar(3070)) partition by key (a);
--- error ER_TOO_BIG_ROWSIZE
+-- error ER_PARTITION_FIELDS_TOO_LONG
+create table t1 (a varchar(65532) not null) partition by key (a);
+-- error ER_BLOB_FIELD_IN_PART_FUNC_ERROR
create table t1 (a varchar(65533)) partition by key (a);
--- error ER_TOO_BIG_ROWSIZE
+-- error ER_BLOB_FIELD_IN_PART_FUNC_ERROR
create table t1 (a varchar(65534) not null) partition by key (a);
--- error ER_TOO_BIG_ROWSIZE
+-- error ER_BLOB_FIELD_IN_PART_FUNC_ERROR
create table t1 (a varchar(65535)) partition by key (a);
#
diff --git a/mysql-test/t/partition_symlink.test b/mysql-test/t/partition_symlink.test
index f2e3eba5de6..8f6e837299a 100644
--- a/mysql-test/t/partition_symlink.test
+++ b/mysql-test/t/partition_symlink.test
@@ -38,11 +38,10 @@ SHOW CREATE TABLE t1;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
SHOW CREATE TABLE t2;
INSERT INTO t1 VALUES (0), (1), (2);
---error ER_TABLES_DIFFERENT_METADATA
ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE t2;
--error ER_TABLES_DIFFERENT_METADATA
ALTER TABLE t1 EXCHANGE PARTITION p2 WITH TABLE t2;
---sorted_result
+SELECT * FROM t1;
SELECT * FROM t2;
DROP TABLE t1, t2;
# skipped because of bug#52354
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 66cd173d512..f7008f570b8 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -3731,4 +3731,148 @@ deallocate prepare stmt2;
drop table t1;
+--echo #
+--echo # MDEV-9208: Function->Function->View = Mysqld segfault
+--echo # (Server crashes in Dependency_marker::visit_field on 2nd
+--echo # execution with merged subquery)
+--echo #
+
+CREATE TABLE t1 (i1 INT);
+insert into t1 values(1),(2);
+
+CREATE TABLE t2 (i2 INT);
+insert into t2 values(1),(2);
+
+prepare stmt from "
+ select 1 from (
+ select
+ if (i1<0, 0, 0) as f1,
+ (select f1) as f2
+ from t1, t2
+ ) sq
+";
+
+execute stmt;
+execute stmt;
+
+drop table t1,t2;
+
+--echo #
+--echo # MDEV-9619: Assertion `null_ref_table' failed in virtual
+--echo # table_map Item_direct_view_ref::used_tables() const on 2nd
+--echo # execution of PS
+--echo #
+
+CREATE TABLE t1 (f1 VARCHAR(10)) ENGINE=MyISAM;
+CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES ('a'),('b');
+
+CREATE TABLE t2 (f2 VARCHAR(10)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('c'),('d');
+
+PREPARE stmt FROM "SELECT * FROM v1 WHERE f1 = SOME ( SELECT f2 FROM t2 )";
+EXECUTE stmt;
+EXECUTE stmt;
+insert into t1 values ('c');
+EXECUTE stmt;
+EXECUTE stmt;
+
+deallocate prepare stmt;
+drop view v1;
+drop table t1,t2;
+
+CREATE TABLE t1 (f1 VARCHAR(10)) ENGINE=MyISAM;
+CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES ('a'),('b');
+
+CREATE TABLE t2 (f2 VARCHAR(10)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('c'),('d');
+
+PREPARE stmt FROM "SELECT * FROM v1 WHERE (f1,f1) = SOME ( SELECT f2,f2 FROM t2 )";
+EXECUTE stmt;
+EXECUTE stmt;
+insert into t1 values ('c');
+EXECUTE stmt;
+EXECUTE stmt;
+
+deallocate prepare stmt;
+drop view v1;
+drop table t1,t2;
+
+
+
+CREATE TABLE t1 (column1 INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (3),(9);
+
+CREATE TABLE t2 (column2 INT) ENGINE=MyISAM;
+
+INSERT INTO t2 VALUES (1),(4);
+
+CREATE TABLE t3 (column3 INT) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (6),(8);
+
+CREATE TABLE t4 (column4 INT) ENGINE=MyISAM;
+INSERT INTO t4 VALUES (2),(5);
+
+PREPARE stmt FROM "
+SELECT (
+ SELECT MAX( table1.column1 ) AS field1
+ FROM t1 AS table1
+ WHERE (111,table3.column3) IN ( SELECT 111,table2.column2 AS field2 FROM t2 AS table2 )
+) AS sq
+FROM t3 AS table3, t4 AS table4 GROUP BY sq
+";
+
+EXECUTE stmt;
+EXECUTE stmt;
+
+deallocate prepare stmt;
+drop table t1,t2,t3,t4;
+
+create table t1 (a int, b int, c int);
+create table t2 (x int, y int, z int);
+create table t3 as select * from t1;
+insert into t1 values (1,2,3),(4,5,6),(100,200,300),(400,500,600);
+insert into t2 values (1,2,3),(7,8,9),(100,200,300),(400,500,600);
+insert into t3 values (1,2,3),(11,12,13),(100,0,0),(400,500,600);
+
+
+set @optimizer_switch_save=@@optimizer_switch;
+set @join_cache_level_save=@@join_cache_level;
+set optimizer_switch='materialization=off';
+set join_cache_level=0;
+select * from t1 where (select a,b from t3 where t3.c=t1.c) in (select x,y from t2 where t1.c= t2.z);
+prepare stmt from "select * from t1 where (select a,b from t3 where t3.c=t1.c) in (select x,y from t2 where t1.c= t2.z)";
+EXECUTE stmt;
+EXECUTE stmt;
+
+create view v1 as select * from t1;
+create view v2 as select * from t2;
+create view v3 as select * from t3;
+select * from v1 where (select a,b from v3 where v3.c=v1.c) in (select x,y from v2 where v1.c= v2.z);
+prepare stmt from "select * from v1 where (select a,b from v3 where v3.c=v1.c) in (select x,y from v2 where v1.c= v2.z)";
+EXECUTE stmt;
+EXECUTE stmt;
+set optimizer_switch=@optimizer_switch_save;
+set join_cache_level=@join_cache_level_save;
+
+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
diff --git a/mysql-test/t/query_cache_debug.test b/mysql-test/t/query_cache_debug.test
index 5eba778cf9e..cebe5b1c88f 100644
--- a/mysql-test/t/query_cache_debug.test
+++ b/mysql-test/t/query_cache_debug.test
@@ -320,3 +320,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_vs_index_merge.test b/mysql-test/t/range_vs_index_merge.test
index 5d12d46c9e9..84b87579e85 100644
--- a/mysql-test/t/range_vs_index_merge.test
+++ b/mysql-test/t/range_vs_index_merge.test
@@ -1241,6 +1241,59 @@ WHERE ( state = 'Alabama' OR state >= 'Colorado' ) AND id != 9
DROP TABLE t1;
+--echo #
+--echo # mdev-11574: do not build index merge of two indexes when
+--echo # one index is an infix of the other index
+--echo #
+
+set names utf8;
+
+CREATE DATABASE world;
+
+use world;
+
+--source include/world_schema.inc
+
+--disable_query_log
+--disable_result_log
+--disable_warnings
+--source include/world.inc
+--enable_warnings
+--enable_result_log
+--enable_query_log
+
+DROP INDEX Country ON City;
+CREATE INDEX CountryName ON City(Country,Name);
+CREATE INDEX Name ON City(Name);
+
+--disable_query_log
+--disable_result_log
+--disable_warnings
+ANALYZE TABLE City;
+--enable_warnings
+--enable_result_log
+--enable_query_log
+
+let $q=
+select * from City
+where
+ Country='FIN' AND Name IN ('Lahti','Imatra') OR
+ Country='RUS' AND Name IN ('St Petersburg', 'Moscow') OR
+ Country='SWE' AND Name IN ('Stockholm', 'Uppsala') OR
+ Country='DEU' AND Name IN ('Berlin', 'Bonn') OR
+ Country='BEL' AND Name IN ('Antwerpen', 'Gent') OR
+ Country='PRT' AND Name IN ('Braga', 'Porto') OR
+ Country='FRA' AND Name IN ('Paris', 'Marcel') OR
+ Country='POL' AND Name IN ('Warszawa', 'Wroclaw') OR
+ Country='NOR' AND Name IN ('Oslo', 'Bergen') OR
+ Country='ITA' AND Name IN ('Napoli', 'Venezia');
+
+eval $q;
+eval explain $q;
+
+
+DROP DATABASE world;
+
#the following command must be the last one in the file
set session optimizer_switch='index_merge_sort_intersection=default';
diff --git a/mysql-test/t/read_only.test b/mysql-test/t/read_only.test
index cd556684e4c..6b608dacf26 100644
--- a/mysql-test/t/read_only.test
+++ b/mysql-test/t/read_only.test
@@ -119,6 +119,11 @@ drop table t1;
insert into t1 values(1);
#
+# MDEV-14056 DROP TEMPORARY TABLE IF EXISTS causes error 1290 with read_only option
+#
+drop temporary table if exists t1;
+
+#
# Bug#11733 COMMITs should not happen if read-only is set
#
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/show_function_with_pad_char_to_full_length.test b/mysql-test/t/show_function_with_pad_char_to_full_length.test
new file mode 100644
index 00000000000..f47f36294d4
--- /dev/null
+++ b/mysql-test/t/show_function_with_pad_char_to_full_length.test
@@ -0,0 +1,23 @@
+#
+# Test that show function status succeeds with
+# sql_mode = 'PAD_CHAR_TO_FULL_LENGTH (MDEV-13149)
+
+# show function status
+
+create function f() returns int return 1;
+--replace_column 1 T 3 T 4 T 5 T 6 T 7 T 8 T 9 T 10 T 11 T
+show function status;
+set sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';
+--replace_column 1 T 3 T 4 T 5 T 6 T 7 T 8 T 9 T 10 T 11 T
+show function status;
+drop function f;
+select @@sql_mode;
+
+# select ROUTINE_NAME from information_schema.ROUTINES
+
+create function f() returns int return 1;
+select ROUTINE_NAME from information_schema.ROUTINES where ROUTINE_NAME='f';
+set sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';
+select ROUTINE_NAME from information_schema.ROUTINES where ROUTINE_NAME='f';
+drop function f;
+select @@sql_mode;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 6eba2522089..4b2230ea7da 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -9556,5 +9556,202 @@ CALL sp1();
drop user 'foo'@'%';
drop procedure sp1;
+--echo #
+--echo # MDEV-10972: Insert from select / view / union --
+--echo # repeatable crash in 10.1, 10.2 Linux/Mac/Windows
+--echo #
+
+create table t (id int auto_increment primary key);
+insert into t values (9494),(9495),(9496),(9497),(9498),(9499),(9500),(9501),(9502),(9503);
+
+create VIEW v AS
+select id from t
+union
+select id from t
+;
+
+drop procedure if exists p;
+create procedure p()
+insert into tmp_t select t.id from (
+ select id from v
+ union
+ select id from v
+) sq
+inner join t on (sq.id = t.id);
+
+--error ER_NO_SUCH_TABLE
+CALL p();
+create table tmp_t (id int null);
+CALL p();
+
+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
diff --git a/mysql-test/t/stat_tables_repl.test b/mysql-test/t/stat_tables_repl.test
index 999c49d37cf..ac24c9dcbd7 100644
--- a/mysql-test/t/stat_tables_repl.test
+++ b/mysql-test/t/stat_tables_repl.test
@@ -1,6 +1,6 @@
--source include/have_stat_tables.inc
---source include/master-slave.inc
--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
--echo #
--echo # Bug mdev-485: unexpected failure with replication of DROP/ALTER table
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index e0e3ed1a14c..717871db61d 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -6072,6 +6072,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/subselect_exists2in.test b/mysql-test/t/subselect_exists2in.test
index a4fdbe5c50b..5a8ddb3612f 100644
--- a/mysql-test/t/subselect_exists2in.test
+++ b/mysql-test/t/subselect_exists2in.test
@@ -786,6 +786,46 @@ set optimizer_switch= @optimizer_switch_save;
DROP TABLE t1;
+--echo #
+--echo # MDEV-14164: Unknown column error when adding aggregate to function
+--echo # in oracle style procedure FOR loop
+--echo #
+
+CREATE TABLE t1(id INT, val INT);
+DELIMITER //;
+CREATE PROCEDURE p1()
+BEGIN
+ DECLARE cur1 CURSOR FOR SELECT * FROM (
+ SELECT DISTINCT id FROM t1) a
+ WHERE NOT EXISTS (SELECT * FROM ( SELECT id FROM t1) b
+ WHERE a.id=b.id);
+ OPEN cur1;
+ CLOSE cur1;
+ OPEN cur1;
+ CLOSE cur1;
+END;
+//
+DELIMITER ;//
+CALL p1();
+DROP PROCEDURE p1;
+DROP TABLE t1;
+
+CREATE TABLE t1(id INT, val INT);
+DELIMITER //;
+CREATE PROCEDURE p1()
+BEGIN
+ SELECT * FROM (SELECT DISTINCT id FROM t1) a
+ WHERE NOT a.id IN (SELECT b.id FROM t1 b);
+ SELECT * FROM (SELECT DISTINCT id FROM t1) a
+ WHERE NOT EXISTS (SELECT * FROM t1 b WHERE a.id=b.id);
+END;
+//
+DELIMITER ;//
+CALL p1();
+CALL p1();
+DROP PROCEDURE p1;
+DROP TABLE t1;
+
--echo # End of 10.0 tests
#restore defaults
diff --git a/mysql-test/t/subselect_mat_cost_bugs.test b/mysql-test/t/subselect_mat_cost_bugs.test
index 35f2b9588fe..67af6e3a54a 100644
--- a/mysql-test/t/subselect_mat_cost_bugs.test
+++ b/mysql-test/t/subselect_mat_cost_bugs.test
@@ -522,4 +522,23 @@ select * from t1 where a in (select max(a) from t1 where a < 4) or a > 5;
drop table t1;
+--echo #
+--echo # MDEV-13135: subquery with ON expression subject to
+--echo # semi-join optimizations
+--echo #
+
+CREATE TABLE t1 (a INT);
+CREATE ALGORITHM=MERGE VIEW v1 AS SELECT a AS v_a FROM t1;
+INSERT INTO t1 VALUES (1),(3);
+
+CREATE TABLE t2 (b INT, KEY(b));
+INSERT INTO t2 VALUES (3),(4);
+
+SELECT * FROM t1 WHERE a NOT IN (
+ SELECT b FROM t2 INNER JOIN v1 ON (b IN ( SELECT a FROM t1 ))
+ WHERE v_a = b
+);
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test
index e17ea07ca3c..cf95d4cb938 100644
--- a/mysql-test/t/symlink.test
+++ b/mysql-test/t/symlink.test
@@ -316,3 +316,28 @@ eval CREATE TABLE test.t1(id INT(11)) ENGINE MYISAM
DATA DIRECTORY "$MYSQLTEST_VARDIR/tmp";
DROP TABLE test.t1;
+use test;
+
+#
+# End of 5.5 tests
+#
+
+#
+# End of 10.0 tests
+#
+
+#
+# MDEV-13636 ALTER TABLE ... DELAY_KEY_WRITE=1 creates table copy for MyISAM table with DATA DIRECTORY/INDEX DIRECTORY options
+#
+replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR;
+eval
+create table t1(c1 int, c2 int, c3 varchar(100)) engine=MyISAM data directory='$MYSQL_TMP_DIR' index directory = '$MYSQL_TMP_DIR';
+insert t1 values (1,2,3), (2,3,4), (3,4,5), (4,5,6), (5,6,7), (6,7,8), (7,8,9);
+alter online table t1 delay_key_write=1;
+replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR;
+show create table t1;
+drop table t1;
+
+#
+# End of 10.1 tests
+#
diff --git a/mysql-test/t/tc_heuristic_recover.test b/mysql-test/t/tc_heuristic_recover.test
new file mode 100644
index 00000000000..5766f9b5e85
--- /dev/null
+++ b/mysql-test/t/tc_heuristic_recover.test
@@ -0,0 +1,106 @@
+# The test verifies a few server/engine recovery option combinations.
+# Specifically, MDEV-13437,13438 are concerned with no crashes
+# due to InnoDB being read-only during --tc-heuristic-recover=ROLLBACK|COMMIT.
+#
+# Initially the test commits a transaction and in the following proceeds
+# throughout some phases.
+# Within them the server is shut down and attempted to restart, to succeed
+# that in the end.
+# All this proves no crashes and effective rollback of the transaction.
+#
+--source include/have_innodb.inc
+# The test logics really requires --log-bin.
+--source include/have_binlog_format_mixed.inc
+--source include/have_debug_sync.inc
+--source include/not_embedded.inc
+
+call mtr.add_suppression("Can't init tc log");
+call mtr.add_suppression("Found 1 prepared transactions!");
+call mtr.add_suppression("Aborting");
+
+# Now take a shapshot of the last time server options.
+#
+# The "restart" expect-file facility can't be engaged because the server
+# having conflicting options may not succeed to boot up.
+# Also notice $MYSQLD_CMD is too "static" being unaware of the actual options
+# of the last (before shutdown or kill) server run.
+# That's why $MYSQLD_LAST_CMD that allows for the server new start
+# with more options appended to a stub set which is settled at this very point.
+--let $mysqld_stub_cmd= $MYSQLD_LAST_CMD
+--let $error_log= $MYSQLTEST_VARDIR/log/mysqld.1.err
+--let SEARCH_FILE= $error_log
+set debug_sync='RESET';
+
+CREATE TABLE t1 (i INT) ENGINE=InnoDB;
+SET GLOBAL innodb_flush_log_at_trx_commit=1;
+FLUSH TABLES; # we need the table post crash-restart, see MDEV-8841.
+
+# Run transaction in a separate "prey" connection
+--connect (con1,localhost,root,,)
+# The signal won't arrive though
+set debug_sync='ha_commit_trans_after_prepare WAIT_FOR go';
+--send INSERT INTO t1 VALUES (1);
+
+--connection default
+
+--let $table= information_schema.processlist
+--let $where= where state = 'debug sync point: ha_commit_trans_after_prepare'
+--let $wait_condition= SELECT count(*) = 1 FROM $table $where
+--source include/wait_condition.inc
+
+--echo # Prove that no COMMIT or ROLLBACK occurred yet.
+SELECT * FROM t1;
+SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+SELECT * FROM t1;
+
+# TODO: MDEV-12700 Allow innodb_read_only startup without prior slow shutdown.
+--source include/kill_mysqld.inc
+--let $restart_parameters= --innodb-force-recovery=4
+--source include/fail_start_mysqld.inc
+
+--let SEARCH_PATTERN= was in the XA prepared state
+--source include/search_pattern_in_file++.inc
+--let SEARCH_PATTERN= Found 1 prepared transactions!
+--source include/search_pattern_in_file++.inc
+--let SEARCH_PATTERN= \\[ERROR\\] Can\\'t init tc log
+--source include/search_pattern_in_file++.inc
+
+--let $restart_parameters= --innodb-force-recovery=4 --tc-heuristic-recover=COMMIT
+--source include/fail_start_mysqld.inc
+--let SEARCH_PATTERN= was in the XA prepared state
+--source include/search_pattern_in_file++.inc
+--let SEARCH_PATTERN= Found 1 prepared transactions!
+--source include/search_pattern_in_file++.inc
+--let SEARCH_PATTERN= \\[ERROR\\] Can\\'t init tc log
+--source include/search_pattern_in_file++.inc
+--let SEARCH_PATTERN= Please restart mysqld without --tc-heuristic-recover
+--source include/search_pattern_in_file++.inc
+
+--let $restart_parameters= --tc-heuristic-recover=ROLLBACK
+--source include/fail_start_mysqld.inc
+
+--let SEARCH_PATTERN= was in the XA prepared state
+--source include/search_pattern_in_file++.inc
+--let SEARCH_PATTERN= Found 1 prepared transactions!
+--source include/search_pattern_in_file++.inc
+--let SEARCH_PATTERN= \\[ERROR\\] Can\\'t init tc log
+--source include/search_pattern_in_file++.inc
+--let SEARCH_PATTERN= Please restart mysqld without --tc-heuristic-recover
+--source include/search_pattern_in_file++.inc
+
+--let $restart_parameters=
+--source include/start_mysqld.inc
+
+--let SEARCH_PATTERN= was in the XA prepared state
+--source include/search_pattern_in_file++.inc
+--let SEARCH_PATTERN= Found 1 prepared transactions!
+--source include/search_pattern_in_file++.inc
+
+SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
+SELECT * FROM t1;
+SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+SELECT * FROM t1;
+#
+# Cleanup
+#
+DROP TABLE t1;
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index a02dce34837..ff6f38b719d 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -2634,3 +2634,27 @@ INSERT INTO t1 VALUES ('a');
DROP TRIGGER t1_bi;
DROP TABLE t1;
+--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.
diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test
index 2ca608e76ff..01a610999bd 100644
--- a/mysql-test/t/type_bit.test
+++ b/mysql-test/t/type_bit.test
@@ -439,3 +439,22 @@ SELECT SUM(a) FROM t1 GROUP BY c, b, a;
DROP TABLE t1;
--echo End of 5.1 tests
+
+--echo #
+--echo # Start of 10.1 tests
+--echo #
+
+--echo #
+--echo # MDEV-8867 Wrong field type or metadata for COALESCE(bit_column, 1)
+--echo #
+
+CREATE TABLE t1 (val bit(1));
+INSERT INTO t1 VALUES (0);
+CREATE TABLE t2 AS SELECT COALESCE(val, 1) AS c FROM t1;
+SELECT * FROM t2;
+SHOW CREATE TABLE t2;
+DROP TABLE t2;
+--enable_metadata
+SELECT COALESCE(val, 1) FROM t1;
+--disable_metadata
+DROP TABLE t1;
diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test
index 63c89f318fc..8248386a93f 100644
--- a/mysql-test/t/type_date.test
+++ b/mysql-test/t/type_date.test
@@ -576,6 +576,15 @@ SELECT DATE(a), DATE(b), DATE(c) FROM t1;
SELECT DATE(COALESCE(a)), DATE(COALESCE(b)), DATE(COALESCE(c)) FROM t1;
DROP TABLE t1;
+--echo #
+--echo # MDEV-14221 Assertion `0' failed in Item::field_type_for_temporal_comparison
+--echo #
+
+CREATE TABLE t1 (d DATE);
+INSERT INTO t1 VALUES ('1985-05-13'),('1989-12-24');
+SELECT d, COUNT(*) FROM t1 GROUP BY d WITH ROLLUP HAVING CASE d WHEN '2017-05-25' THEN 0 ELSE 1 END;
+DROP TABLE t1;
+
--echo #
--echo # End of 10.1 tests
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/type_varchar.test b/mysql-test/t/type_varchar.test
index cc09069508f..edf60927a32 100644
--- a/mysql-test/t/type_varchar.test
+++ b/mysql-test/t/type_varchar.test
@@ -219,7 +219,51 @@ SELECT 5 = a FROM t1;
DROP TABLE t1;
--echo #
---echo # Start of 10.0 tests
+--echo # MDEV-13530 VARBINARY doesn't convert to to BLOB for sizes 65533, 65534 and 65535
+--echo #
+
+CREATE TABLE t1 (c1 VARBINARY(65532));
+DESCRIBE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 VARBINARY(65533));
+DESCRIBE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 VARBINARY(65534));
+DESCRIBE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 VARBINARY(65535));
+DESCRIBE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 VARBINARY(65536));
+DESCRIBE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 VARCHAR(65532));
+DESCRIBE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 VARCHAR(65533));
+DESCRIBE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 VARCHAR(65534));
+DESCRIBE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 VARCHAR(65535));
+DESCRIBE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 VARCHAR(65536));
+DESCRIBE t1;
+DROP TABLE t1;
+
+--echo #
+--echo # End of 5.5 tests
--echo #
--echo #
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
index 059bf9154cb..cbd19a73a80 100644
--- a/mysql-test/t/union.test
+++ b/mysql-test/t/union.test
@@ -1418,6 +1418,43 @@ 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);
+
+--error ER_INVALID_GROUP_FUNC_USE
+(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/user_var.test b/mysql-test/t/user_var.test
index 2c889c2cc0c..1e9b6a7bb14 100644
--- a/mysql-test/t/user_var.test
+++ b/mysql-test/t/user_var.test
@@ -1,7 +1,5 @@
# Initialise
---disable_warnings
-drop table if exists t1,t2;
---enable_warnings
+source include/have_sequence.inc;
--error 1054
set @a := foo;
@@ -501,3 +499,9 @@ eval select $tmp < $tmp2;
--enable_column_names
--enable_query_log
+#
+# MDEV-13897 SELECT @a := MAX(col) FROM t requires full index scan
+#
+explain select @a:=max(seq) from seq_1_to_1000000;
+
+# End of 10.1 tests
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index a1ebc683ed6..68adc6e19e1 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -1,3 +1,4 @@
+--source include/have_partition.inc
--disable_warnings
drop table if exists t1,t2,t3,t4,t5,t6,t9,`t1a``b`,v1,v2,v3,v4,v5,v6;
@@ -5585,14 +5586,23 @@ drop table t1,t2,t3;
CREATE TABLE t3 (a INT);
CREATE ALGORITHM = MERGE VIEW v1 AS SELECT t2.a FROM t3 AS t1, t3 AS t2;
CREATE ALGORITHM = MERGE VIEW v2 AS SELECT * FROM v1;
-PREPARE stmt FROM 'REPLACE INTO v2 SELECT a FROM t3';
---error ER_VIEW_NO_INSERT_FIELD_LIST
-EXECUTE stmt;
--error ER_VIEW_NO_INSERT_FIELD_LIST
-EXECUTE stmt;
+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/xa.test b/mysql-test/t/xa.test
index 1709886eb0c..0995b8c26b2 100644
--- a/mysql-test/t/xa.test
+++ b/mysql-test/t/xa.test
@@ -328,6 +328,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
diff --git a/mysql-test/t/xml.test b/mysql-test/t/xml.test
index 3e7c9b78673..c68790b7045 100644
--- a/mysql-test/t/xml.test
+++ b/mysql-test/t/xml.test
@@ -674,9 +674,7 @@ SELECT ExtractValue('<a><b>xxx</c></a>','/a/b');
--echo # Bug#58175 xml functions read initialized bytes when conversions happen
--echo #
SET NAMES latin1;
---enable_prepare_warnings
SELECT UPDATEXML(CONVERT('' USING swe7), TRUNCATE('',1), 0);
---disable_prepare_warnings
--echo #
--echo # Bug#12375190: UPDATEXML CRASHES ON SIMPLE INPUTS
@@ -715,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;
@@ -750,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/mysql-test/unstable-tests b/mysql-test/unstable-tests
index 5ec491171b1..34639ef321f 100644
--- a/mysql-test/unstable-tests
+++ b/mysql-test/unstable-tests
@@ -24,86 +24,82 @@
##############################################################################
main.alter_table_trans : MDEV-12084 - timeout
-main.analyze_format_json : MDEV-11866 - Wrong result
-main.analyze_stmt_orderby : MDEV-11866 - Wrong result
main.analyze_stmt_slow_query_log : MDEV-12237 - Wrong result
-main.binary_to_hex : Added in 10.1.26
-main.bootstrap : Modified in 10.1.25
-main.count_distinct : Modified in 10.1.26
+main.auth_named_pipe : MDEV-14724 - System error 2
+main.create : Modified in 10.1.31
main.create_delayed : MDEV-10605 - failed with timeout
-main.create_drop_event : Modified in 10.1.26
-main.ctype_ucs : Modified in 10.1.25
main.ctype_utf16le : MDEV-10675: timeout or extra warnings
-main.drop-no_root : MDEV-12633 - Valgrind warnings
-main.errors : Modified in 10.1.26
+main.ctype_utf8 : Modified in 10.1.30
+main.ctype_utf8mb4 : Modified in 10.1.30
+main.derived : Modified in 10.1.31
+main.dyncol : Modified in 10.1.31
+main.events_2 : MDEV-13277 - Server crash
main.events_bugs : MDEV-12892 - Crash in fill_schema_processlist
main.events_restart : MDEV-12236 - Server shutdown problem
-main.func_concat : Modified in 10.1.25
-main.func_crypt : Modified in 10.1.25
-main.func_regexp_pcre : MDEV-13412 - Crash; modified in 10.1.26
-main.gis : Modified in 10.1.26
-main.gis-rt-precise : Modified in 10.1.26
-main.group_by : Modified in 10.1.26
+main.fulltext : Modified in 10.1.31
+main.func_concat : Modified in 10.1.31
+main.func_isnull : Modified in 10.1.31
+main.func_set : Modified in 10.1.30
+main.func_str : Modified in 10.1.30
+main.group_by : Modified in 10.1.30
+main.having : Modified in 10.1.30
main.host_cache_size_functionality : MDEV-10606 - sporadic failure on shutdown
main.index_intersect_innodb : MDEV-10643 - failed with timeout
main.index_merge_innodb : MDEV-7142 - Wrong execution plan, timeout with valgrind
main.innodb_mysql_lock : MDEV-7861 - sporadic lock detection failure
-main.join_outer : Modified in 10.1.25
+main.join_cache : Modified in 10.1.31
+main.join_outer : Modified in 10.1.30
main.kill_processlist-6619 : MDEV-10793 - wrong result in processlist
-main.loadxml : Data file modified in 10.1.26
+main.mdev_14586 : Added in 10.1.31
main.mdev-504 : MDEV-10607 - sporadic "can't connect"
main.mdev375 : MDEV-10607 - sporadic "can't connect"
-main.mdl_sync : Modified in 10.1.25
-main.merge : MDEV-10607 - sporadic "can't connect"
-main.mysql : Modified in 10.1.25
-main.mysqlcheck : MDEV-12633 - Valgrind warnings
-main.mysqld--help : Modified in 10.1.25
+main.merge : MDEV-10607 - sporadic "can't connect"; modified in 10.1.31
+main.myisam_optimize : Modified in 10.1.31
+main.mysql_client_test_nonblock : MDEV-15096 - exec failed
+main.mysql_upgrade_noengine : MDEV-14355 - Plugin is busy
+main.mysqldump-nl : Modified in 10.1.31
main.mysqlslap : MDEV-11801 - timeout
-main.mysqltest : MDEV-9269 - fails on Alpha; modified in 10.1.25
-main.mysql_client_test : MDEV-12633 - Valgrind warnings
-main.mysql_client_test_comp : MDEV-12633 - Valgrind warnings
-main.mysql_client_test_nonblock : MDEV-12633 - Valgrind warnings
-main.mysql_upgrade : Modified in 10.1.26
-main.openssl_1 : Modified in 10.1.26
-main.openssl_6975 : Modified in 10.1.26
-main.order_by : MOdified in 10.1.25
+main.mysqltest : MDEV-9269 - fails on Alpha
+main.order_by : Modified in 10.1.31
main.order_by_optimizer_innodb : MDEV-10683 - wrong execution plan
-main.partition_alter : Modified in 10.1.25
+main.partition : Modified in 10.1.31
main.partition_innodb_plugin : MDEV-12901 - Valgrind warnings
-main.ps : MDEV-11017 - sporadic wrong Prepared_stmt_count
+main.ps : MDEV-11017 - sporadic wrong Prepared_stmt_count; modified in 10.1.31
main.query_cache : MDEV-12895 - Wrong result
+main.query_cache_debug : Modified in 10.1.31
main.range_vs_index_merge_innodb : MDEV-12637 - Timeout
-main.read_only : Modified in 10.1.26
-main.repair_symlink-5543 : MDEV-12215 - Wrong error codes
+main.repair : Modified in 10.1.31
main.set_statement : MDEV-13183 - Wrong result
-main.show_check : MDEV-12633 - Valgrind warnings
main.show_explain : MDEV-10674 - sporadic failure
+main.sp : Modified in 10.1.31
main.sp-security : MDEV-10607 - sporadic "can't connect"
-main.ssl : Modified in 10.1.26
main.status : MDEV-8510 - sporadic wrong result
-main.subselect : Modified in 10.1.26
+main.subselect : Modified in 10.1.31
main.subselect_innodb : MDEV-10614 - sporadic wrong results
-main.subselect_mat_cost_bugs : Modified in 10.1.25
-main.subselect_nulls : Modified in 10.1.26
-main.subselect_sj_mat : Modified in 10.1.25
-main.subselect_sj2_mat : Modified in 10.1.25
-main.symlink-aria-11902 : MDEV-12215 - Unexpected errors
-main.symlink-myisam-11902 : MDEV-12215 - Unexpected errors
+main.symlink-aria-11902 : MDEV-15098 - error 40 from storage engine
+main.symlink-myisam-11902 : MDEV-15098 - error 40 from storage engine
+main.tc_heuristic_recover : MDEV-15200 - wrong error on mysqld_stub_cmd
+main.trigger : Modified in 10.1.30
+main.type_blob : MDEV-15195 - Wrong result
main.type_datetime_hires : MDEV-10687 - timeout
-main.union : Modified in 10.1.26
-main.view : Modified in 10.1.26
+main.union : Modified in 10.1.31
+main.update_innodb : Modified in 10.1.31
+main.view : Modified in 10.1.30
+main.xa : Modified in 10.1.31
+main.xml : Modified in 10.1.31
#----------------------------------------------------------------
-archive.discover : MDEV-10510 - table is marked as crashed
+archive.archive_bitfield : MDEV-11771 - Extra warning
+archive.discover : MDEV-10510 - Table is marked as crashed
+archive.mysqlhotcopy_archive : MDEV-14726 - Table is marked as crashed
#----------------------------------------------------------------
binlog.binlog_commit_wait : MDEV-10150 - Error: too much time elapsed
+binlog.binlog_flush_binlogs_delete_domain : MDEV-14431 - Wrong error code; added in 10.1.30
+binlog.binlog_gtid_delete_domain_debug : Added in 10.1.30
binlog.binlog_killed : MDEV-12925 - Wrong result
-binlog.binlog_parallel_replication_marks_row : Added in 10.1.26
-binlog.binlog_parallel_replication_marks_stm_mix : Added in 10.1.26
-binlog.binlog_unsafe : Modified in 10.1.26
binlog.binlog_xa_recover : MDEV-8517 - Extra checkpoint
#----------------------------------------------------------------
@@ -111,26 +107,31 @@ binlog.binlog_xa_recover : MDEV-8517 - Extra checkpoint
binlog_encryption.binlog_xa_recover : MDEV-12908 - Extra checkpoint
binlog_encryption.encrypted_master : MDEV-12906 - Failed to sync
binlog_encryption.rpl_parallel : MDEV-10653 - Timeout
+binlog_encryption.rpl_relayrotate : MDEV-15194 - Timeout
binlog_encryption.rpl_semi_sync : MDEV-11220 - Wrong result, MDEV-11673 - Valgrind warning
+binlog_encryption.rpl_ssl : MDEV-14507 - Timeout on SLES 11.4
+binlog_encryption.rpl_typeconv : MDEV-14362 - Lost connection to MySQL server during query
#----------------------------------------------------------------
-connect.tbl : MDEV-9844, MDEV-10179 - sporadic crashes, valgrind warnings, wrong results
+connect.pivot : MDEV-14803 - failed to discover table
+connect.zip : MDEV-13884 - Wrong result
#----------------------------------------------------------------
-encryption.create_or_replace : MDEV-9359 - Assertion failure
+encryption.create_or_replace : MDEV-9359 - Assertion failure, MDEV-13516 - Assertion failure
+encryption.debug_key_management : MDEV-13841 - Timeout on wait condition; modified in 10.1.31
+encryption.encrypt_and_grep : MDEV-13765 - Wrong result; modified in 10.1.31
encryption.innodb-bad-key-change2 : MDEV-12632 - Valgrind warnings
-encryption.innochecksum : Modified in 10.1.26
-encryption.innodb-checksum-algorithm : MDEV-13167 - Assertion failure; added in 10.1.25
-encryption.innodb-compressed-blob : Modified in 10.1.25
+encryption.innodb-compressed-blob : MDEV-14728 - Unable to get certificate
encryption.innodb-discard-import-change : MDEV-12632 - Valgrind warnings
+encryption.innodb_encryption : Modified in 10.1.31
encryption.innodb_encryption_discard_import : MDEV-12903 - Wrong result
encryption.innodb_encryption_filekeys : MDEV-9962 - timeouts
encryption.innodb_encryption-page-compression : MDEV-12630 - crash or assertion failure
encryption.innodb_encryption_tables : MDEV-9359 - Assertion failure
encryption.innodb_first_page : MDEV-10689 - crashes
-encryption.innodb-first-page-read : MDEV-13181 - Signal 8; added in 10.1.25
+encryption.innodb-first-page-read : MDEV-14356 - Timeout on wait condition
encryption.innodb_lotoftables : MDEV-11531 - InnoDB error
encryption.innodb-missing-key : MDEV-9359 - assertion failure
encryption.innodb-page_encryption : MDEV-10641 - mutex problem
@@ -138,7 +139,6 @@ encryption.innodb-redo-badkey : MDEV-12898 - Server hang on startu
encryption.innodb_scrub : MDEV-8139 - scrubbing tests need fixing
encryption.innodb_scrub_background : MDEV-8139 - scrubbing tests need fixing
encryption.innodb_scrub_compressed : MDEV-8139 - scrubbing tests need fixing
-encryption.second_plugin-12863 : Added in 10.1.26
#----------------------------------------------------------------
@@ -147,12 +147,12 @@ engines/funcs.* : Not maintained in timely manner
#----------------------------------------------------------------
-federated.federated_bug_585688 : MDEV-12907 - Valgrind
+federated.federated_bug_585688 : MDEV-12907 - Valgrind, MDEV-14805 - server crash
federated.federated_innodb : MDEV-10617, MDEV-10417 - Wrong checksum, timeouts, fails on Mips
federated.federated_partition : MDEV-10417 - Fails on Mips
federated.federated_transactions : MDEV-10617, MDEV-10417 - Wrong checksum, timeouts, fails on Mips
federated.federatedx : MDEV-10617 - Wrong checksum, timeouts
-federated.net_thd_crash-12725 : Added in 10.1.26
+federated.net_thd_crash-12951 : Added in 10.1.31
#----------------------------------------------------------------
@@ -164,63 +164,66 @@ funcs_2.myisam_charset : MDEV-11535 - Timeout
#----------------------------------------------------------------
-galera.galera_defaults : Modified in 10.1.25
-galera.MW-369 : Added in 10.1.25
+galera.* : The suite was enabled in 10.1.27 and is still unstable
+galera_3nodes.* : The suite has not been stabilized yet
+
+galera.galera_applier_ftwrl_table_alter : MDEV-13738 - MySQL server has gone away
+galera.galera_gcs_fc_limit : MDEV-13877 - Timeout
+galera.galera_suspend_slave : MDEV-13873 - Wrong error code
+galera.galera_toi_truncate : MDEV-13743 - query 'reap' succeeded
+galera.galera_unicode_identifiers : MDEV-13871 - Unknown database
+galera.galera_var_node_address : MDEV-13880 - Failed to start mysqld
+galera.galera_wan : MDEV-13879 - Stray state UUID msg warnings
+galera.galera_wsrep_log_conficts : MDEV-13874 - check-testcase failed
+galera.partition : MDEV-13881 - Wrong result
+galera.query_cache : MDEV-13883 - Wrong result
+galera.MW-328A : MDEV-13876 - Wrong result
#----------------------------------------------------------------
-innodb.101_compatibility : Modified in 10.1.26
innodb.binlog_consistent : MDEV-10618 - Server fails to start
-innodb.doublewrite : MDEV-12905 - Lost connection to MySQL server; modified in 10.1.25
-innodb.innodb-32k : Option file modified in 10.1.26
-innodb.innodb-32k-crash : Option file modified in 10.1.26
-innodb.innodb-64k : Modified in 10.1.26
-innodb.innodb-64k-crash : Option file modified in 10.1.26
-innodb.innodb-alter-debug : MDEV-13182 - InnoDB: adjusting FSP_SPACE_FLAGS; modified in 10.1.25
-innodb.innodb-alter-discard : Modified in 10.1.25
-innodb.innodb-alter-nullable : Modified in 10.1.25
-innodb.innodb-alter-table : MDEV-10619 - Testcase timeout; modified in 10.1.25
-innodb.innodb-alter-tempfile : Modified in 10.1.25
+innodb.doublewrite : MDEV-12905 - Lost connection to MySQL server
+innodb_fts.fulltext2 : MDEV-14727 - Long semaphore wait
+innodb.innodb : Opt file modified in 10.1.31
+innodb.innodb-64k-crash : MDEV-13872 - Failure and crash on startup
+innodb.innodb-alter-debug : MDEV-13182 - InnoDB: adjusting FSP_SPACE_FLAGS
+innodb.innodb-alter-table : MDEV-10619 - Testcase timeout
+innodb.innodb-autoinc : Modified in 10.1.30
innodb.innodb-blob : MDEV-12053 - Client crash
innodb.innodb_bug14147491 : MDEV-11808 - wrong error codes
innodb.innodb_bug30423 : MDEV-7311 - Wrong number of rows in the plan
-innodb.innodb_bug53290 : MDEV-12634 - Valgrind warnings
-innodb.innodb-enlarge-blob : Added in 10.1.26
-innodb.innodb_max_recordsize_32k : Added in 10.1.26
-innodb.innodb_max_recordsize_64k : Added in 10.1.26
+innodb.innodb_bug48024 : MDEV-14352 - Assertion failure
+innodb.innodb_corrupt_bit : Modified in 10.1.31
+innodb.innodb-fk : MDEV-13832 - Assertion failure on shutdown
+innodb.innodb-index-online : Modified in 10.1.31
+innodb.innodb-lru-force-no-free-page : Added in 10.1.31
+innodb.innodb_max_recordsize_64k : MDEV-15203 - wrong result
+innodb.innodb-page_compression_lzma : MDEV-14353 - wrong result on Fedora 25
innodb.innodb-page_compression_zip : MDEV-10641 - mutex problem
-innodb.innodb_prefix_index_restart_server : MDEV-12899 - Server crash on shutdown
+innodb.innodb-replace-debug : Modified in 10.1.31
innodb.innodb_stats : MDEV-10682 - wrong result
innodb.innodb_sys_semaphore_waits : MDEV-10331 - wrong result
-innodb.innodb_zip_innochecksum : Added in 10.1.26
-innodb.innodb_zip_innochecksum2 : Added in 10.1.26
-innodb.innodb_zip_innochecksum3 : Added in 10.1.26
-innodb.log_data_file_size : MDEV-12893 - Database page corruption; modified in 10.1.25
-innodb.log_file_size : Modified in 10.1.25
-innodb.row_format_redundant : Added in 10.1.25
-innodb.table_flags : Added in 10.1.25
+innodb.innodb_zip_innochecksum2 : MDEV-13882 - Warning: difficult to find free blocks
+innodb.log_file_size : MDEV-15202 - Cannot resize log files in read-only mode
+innodb.recovery_shutdown : Added in 10.1.30
+innodb.row_format_redundant : MDEV-15192 - Trying to access missing tablespace
+innodb.table_definition_cache_debug : MDEV-14206 - Extra warning; opt file modified in 10.1.31
+innodb.table_flags : MDEV-14363 - Operating system error number 2
innodb_fts.fulltext_misc : MDEV-12636 - Valgrind warnings
-innodb_zip.innodb_bug36169 : Modified in 10.1.25
-innodb_zip.innodb_bug36172 : Modified in 10.1.25
-innodb_zip.innodb_bug52745 : Modified in 10.1.25
-innodb_zip.innodb_bug53591 : Modified in 10.1.25
-innodb_zip.innodb_bug56680 : Modified in 10.1.25
-innodb_zip.innodb-create-options : Modified in 10.1.25
-innodb_zip.innodb-zip : Modified in 10.1.25
+#----------------------------------------------------------------
+
+maria.lock : Modified in 10.1.31
+maria.maria : MDEV-14430 - Wrong result; modified in 10.1.31
+maria.repair : Added in 10.1.31
#----------------------------------------------------------------
-mariabackup.full_backup : Modified in 10.1.25
-mariabackup.incremental_backup : Uses include file modified in 10.1.25
-mariabackup.incremental_encrypted : Modified in 10.1.25
-mariabackup.xb_aws_key_management : Uses include file modified in 10.1.25
-mariabackup.xb_compressed_encrypted : Modified in 10.1.25
-mariabackup.xb_file_key_management : Modified in 10.1.25
-mariabackup.xb_fulltext_encrypted : Uses include file modified in 10.1.25
-mariabackup.xb_partition : Uses include file modified in 10.1.25
-mariabackup.xbstream : Uses include file modified in 10.1.25
+mariabackup.huge_lsn : Added in 10.1.31
+mariabackup.mdev-14447 : MDEV-15201 - Timeout; added in 10.1.30
+mariabackup.missing_ibd : Added in 10.1.31
+mariabackup.xb_compressed_encrypted : MDEV-14812 - Segfault
#----------------------------------------------------------------
@@ -231,13 +234,20 @@ mroonga/storage.column_datetime_32bit_out_of_range : Wrong resul
mroonga/storage.index_multiple_column_unique_date_32bit_equal : Wrong result on Alpha
mroonga/storage.index_multiple_column_unique_date_order_32bit_desc : Wrong result on Alpha
mroonga/storage.index_multiple_column_unique_datetime_index_read : MDEV-8643 - valgrind warnings
-mroonga/storage.repair_table_no_index_file : MDEV-9364 - wrong result
+mroonga/storage.repair_table_no_index_file : MDEV-9364 - wrong result, MDEV-14807 - wrong error message
+mroonga/storage.variable_query_log_file_disabled_empty_value : Modified in 10.1.30
+mroonga/storage.variable_query_log_file_disabled_null_value : Modified in 10.1.30
+mroonga/storage.variable_query_log_file_enabled_empty_value : Modified in 10.1.30
+mroonga/storage.variable_query_log_file_enabled_null_value : Modified in 10.1.30
+mroonga/storage.variable_query_log_file_new_value : Modified in 10.1.30
+mroonga/storage.variable_query_log_file_same_value : Modified in 10.1.30
+
+mroonga/wrapper.repair_table_no_index_file : MDEV-14807 - Wrong error message
#----------------------------------------------------------------
multi_source.gtid : MDEV-10417 - Fails on Mips
multi_source.info_logs : MDEV-10042 - Wrong result, MDEV-12629 - Valgrind warnings
-multi_source.mdev-9544 : Added in 10.1.25
multi_source.multisource : MDEV-10417 - Fails on Mips
multi_source.reset_slave : MDEV-10690 - wrong result
multi_source.simple : MDEV-4633 - Wrong slave status output
@@ -245,16 +255,20 @@ multi_source.status_vars : MDEV-4632 - failed while waiting for Slave_received_h
#----------------------------------------------------------------
-parts.longname : Added in 10.1.26
+parts.partition_alter_innodb : Added in 10.1.30
+parts.partition_alter_maria : Modified in 10.1.30
+parts.partition_alter_myisam : Modified in 10.1.31
+parts.partition_alter2_2_maria : MDEV-14364 - Lost connection to MySQL server during query
+parts.partition_auto_increment_maria : MDEV-14430 - Wrong result
+parts.partition_debug_innodb : MDEV-15095 - table does not exist
parts.partition_innodb_status_file : MDEV-12901 - Valgrind
-parts.quoting : Modified in 10.1.25
#----------------------------------------------------------------
-perfschema.bad_option_2 : Modified in 10.1.25
perfschema.func_file_io : MDEV-5708 - fails for s390x
perfschema.func_mutex : MDEV-5708 - fails for s390x
-perfschema.privilege_table_io : MDEV-13184 - Extra lines; modified in 10.1.26
+perfschema.misc : Modified in 10.1.30
+perfschema.privilege_table_io : MDEV-13184 - Extra lines
perfschema.setup_actors : MDEV-10679 - rare crash
perfschema.socket_summary_by_event_name_func : MDEV-10622 - Socket summary tables do not match
perfschema.stage_mdl_global : MDEV-11803 - wrong result on slow builders
@@ -263,76 +277,79 @@ perfschema.threads_mysql : MDEV-10677 - sporadic wrong resul
#----------------------------------------------------------------
+plugins.binlog-simple_plugin_check : Added in 10.1.30
plugins.feedback_plugin_send : MDEV-7932 - ssl failed for url
plugins.server_audit : MDEV-9562 - crashes on sol10-sparc
plugins.thread_pool_server_audit : MDEV-9562 - crashes on sol10-sparc
#----------------------------------------------------------------
-roles.current_role_view-12666 : Added in 10.1.25
-roles.show_create_database-10463 : Added in 10.1.25
+roles.flush_roles-12366 : Added in 10.1.30
+roles.set_role-13655 : Added in 10.1.30
#----------------------------------------------------------------
-rpl.circular_serverid0 : Added in 10.1.26
rpl.last_insert_id : MDEV-10625 - warnings in error log
rpl.rpl_auto_increment : MDEV-10417 - Fails on Mips
rpl.rpl_auto_increment_bug45679 : MDEV-10417 - Fails on Mips
rpl.rpl_auto_increment_update_failure : MDEV-10625 - warnings in error log
rpl.rpl_binlog_index : MDEV-9501 - Warning: failed registering on master
-rpl.rpl_checksum_cache : MDEV-12173 - Unexpected error
rpl.rpl_ddl : MDEV-10417 - Fails on Mips
+rpl.rpl_domain_id_filter_io_crash : MDEV-14357 - Wrong result
rpl.rpl_domain_id_filter_restart : MDEV-10684 - Wrong result
-rpl.rpl_extra_col_master_innodb : Include file modified in 10.1.26
-rpl.rpl_extra_col_master_myisam : Include file modified in 10.1.26
-rpl.rpl_extra_col_slave_innodb : Include file modified in 10.1.26
-rpl.rpl_extra_col_slave_myisam : Include file modified in 10.1.26
-rpl.rpl_filter_tables_dynamic : Include file modified in 10.1.26
-rpl.rpl_filter_tables_not_exist : Include file modified in 10.1.26
rpl.rpl_gtid_basic : MDEV-10681 - server startup problem
rpl.rpl_gtid_crash : MDEV-9501 - Warning: failed registering on master
+rpl.rpl_gtid_delete_domain : MDEV-14463 - Timeout in include; added in 10.1.30
rpl.rpl_gtid_mdev9033 : MDEV-10680 - warnings
+rpl.rpl_gtid_reconnect : MDEV-14497 - Timeout
rpl.rpl_gtid_stop_start : MDEV-10629 - Crash on shutdown, MDEV-12629 - Valgrind warnings
rpl.rpl_gtid_until : MDEV-10625 - warnings in error log
rpl.rpl_innodb_bug30888 : MDEV-10417 - Fails on Mips
rpl.rpl_insert : MDEV-9329 - Fails on Ubuntu/s390x
rpl.rpl_insert_delayed : MDEV-9329 - Fails on Ubuntu/s390x
+rpl.rpl_insert_id : MDEV-15197 - Wrong result
+rpl.rpl_insert_ignore : MDEV-14365 - Lost connection to MySQL server during query
rpl.rpl_invoked_features : MDEV-10417 - Fails on Mips
-rpl.rpl_loaddata : Include file modified in 10.1.26
-rpl.rpl_loaddata_fatal : Include file modified in 10.1.26
+rpl.rpl_manual_change_index_file : Modified in 10.1.31
rpl.rpl_mariadb_slave_capability : MDEV-11018 - sporadic wrong events in binlog
rpl.rpl_mdev6020 : MDEV-10630, MDEV-10417 - Timeouts, fails on Mips
-rpl.rpl_mdev-11092 : Include file modified in 10.1.26
-rpl.rpl_mixed_binlog_max_cache_size : Include file modified in 10.1.26
-rpl.rpl_old_decimal : Include file modified in 10.1.26
+rpl.rpl_mixed_mixing_engines : MDEV-14489 - Sync slave with master failed
+rpl.rpl_non_direct_mixed_mixing_engines : MDEV-14489 - Sync slave with master failed
+rpl.rpl_non_direct_row_mixing_engines : MDEV-14491 - Long semaphore wait
+rpl.rpl_non_direct_stm_mixing_engines : MDEV-14489 - Sync slave with master failed
rpl.rpl_parallel : MDEV-10653 - Timeouts
rpl.rpl_parallel_mdev6589 : MDEV-12979 - Assertion failure
-rpl.rpl_parallel_optimistic : MDEV-10511 - timeout; modified in 10.1.26
+rpl.rpl_parallel_multilevel2 : MDEV-14723 - Timeout
+rpl.rpl_parallel_optimistic : MDEV-10511 - Timeout
rpl.rpl_parallel_retry : MDEV-11119 - Server crash
rpl.rpl_parallel_temptable : MDEV-10356 - Crash in close_thread_tables
rpl.rpl_partition_innodb : MDEV-10417 - Fails on Mips
rpl.rpl_password_boundaries : MDEV-11534 - Slave IO warnings
-rpl.rpl_reset_slave_fail : Added in 10.1.26
-rpl.rpl_rotate_logs : Include file modified in 10.1.26
-rpl.rpl_row_binlog_max_cache_size : Include file modified in 10.1.26
-rpl.rpl_row_loaddata_concurrent : Include file modified in 10.1.26
-rpl.rpl_row_log_innodb : MDEV-10688 - Wrong result
+rpl.rpl_row_drop_create_temp_table : MDEV-14487 - Wrong result
+rpl.rpl_row_img_blobs : MDEV-13875 - command "diff_files" failed
+rpl.rpl_row_img_eng_min : MDEV-13875 - command "diff_files" failed
+rpl.rpl_row_img_eng_noblob : MDEV-13875 - command "diff_files" failed
+rpl.rpl_row_index_choice : MDEV-15196 - Slave crash
+rpl.rpl_row_log : Include file modified in 10.1.30
+rpl.rpl_row_log_innodb : Include file modified in 10.1.30
+rpl.rpl_row_mixing_engines : MDEV-14491 - Long semaphore wait
rpl.rpl_row_sp001 : MDEV-9329 - Fails on Ubuntu/s390x
-rpl.rpl_row_tabledefs_2myisam : Include file modified in 10.1.26
-rpl.rpl_row_tabledefs_3innodb : Include file modified in 10.1.26
-rpl.rpl_row_utf32 : One-time server startup timeout on ppc64le in 10.1.25
rpl.rpl_semi_sync : MDEV-11220 - Wrong result
+rpl.rpl_semi_sync_after_sync : MDEV-14366 - Wrong result
+rpl.rpl_semi_sync_after_sync_row : MDEV-14366 - Wrong result
rpl.rpl_semi_sync_event_after_sync : MDEV-11806 - warnings
-rpl.rpl_semi_sync_uninstall_plugin : MDEV-7140 - Wrong plugin status, MDEV-10892 - Assertion failure
+rpl.rpl_semi_sync_uninstall_plugin : MDEV-7140 - Wrong plugin status
rpl.rpl_semi_sync_wait_point : MDEV-11807 - timeout in wait condition
rpl.rpl_show_slave_hosts : MDEV-10681 - server startup problem
rpl.rpl_skip_replication : MDEV-9268 - Fails with timeout in sync_slave_with_master on Alpha
rpl.rpl_slave_grp_exec : MDEV-10514 - Unexpected deadlock
-rpl.rpl_stm_000001 : Include file modified in 10.1.26
-rpl.rpl_stm_binlog_max_cache_size : Include file modified in 10.1.26
-rpl.rpl_stm_loaddata_concurrent : Include file modified in 10.1.26
+rpl.rpl_start_stop_slave : MDEV-13567 - Replication failure
+rpl.rpl_stm_log : Include file modified in 10.1.30
+rpl.rpl_stm_mixing_engines : MDEV-14489 - Sync slave with master failed
+rpl.rpl_stm_relay_ign_space : MDEV-14360 - Test assertion
rpl.rpl_sync : MDEV-10633 - Database page corruption
rpl.rpl_temporary_error2 : MDEV-10634 - Wrong number of retries
+rpl.sec_behind_master-5114 : MDEV-13878 - Wrong result
#----------------------------------------------------------------
@@ -369,19 +386,16 @@ stress.ddl_innodb : MDEV-10635 - Testcase timeout
sys_vars.autocommit_func2 : MDEV-9329 - Fails on Ubuntu/s390x
sys_vars.keep_files_on_create_basic : MDEV-10676 - timeout
-sys_vars.innodb_buffer_pool_dump_pct_basic : MDEV-10651 - sporadic failure on file_exists
sys_vars.innodb_fatal_semaphore_wait_threshold : MDEV-10513 - crashes
-sys_vars.innodb_sched_priority_cleaner_basic : Modified in 10.1.25
+sys_vars.innodb_print_lock_wait_timeout_info_basic : Added in 10.1.31
sys_vars.log_slow_admin_statements_func : MDEV-12235 - Server crash
sys_vars.rpl_init_slave_func : MDEV-10149 - wrong results
-sys_vars.sysvars_innodb : MDEV-6958 - error-prone rdiffs
-sys_vars.sysvars_server_embedded : MDEV-6958 - error-prone rdiffs
-sys_vars.sysvars_wsrep : MDEV-12522 - Dependency on specific wsrep_provider
sys_vars.thread_cache_size_func : MDEV-11775 - Wrong result
sys_vars.wait_timeout_func : MDEV-12896 - Wrong result
#----------------------------------------------------------------
+tokudb.card_scale_percent : Modified in 10.1.31
tokudb.change_column_all_1000_10 : MDEV-12640 - Crash
tokudb.change_column_bin : MDEV-12640 - Crash
tokudb.change_column_char : MDEV-12822 - Lost connection to MySQL server
@@ -389,54 +403,32 @@ tokudb.cluster_filter : MDEV-10678 - Wrong execution plan
tokudb.cluster_filter_hidden : MDEV-10678 - Wrong execution plan
tokudb.cluster_filter_unpack_varchar : MDEV-10636 - Wrong execution plan
tokudb.dir_per_db : MDEV-11537 - Wrong result
+tokudb.dir_per_db_rename_to_nonexisting_schema : MDEV-14359 - Directory not empty
tokudb.hotindex-insert-bigchar : MDEV-12640 - Crash
+tokudb.hotindex-insert-1 : MDEV-13870 - Lost connection to MySQL server
+tokudb.hotindex-update-0 : MDEV-15198 - Timeout
tokudb.hotindex-update-1 : MDEV-12640 - Crash
-tokudb.kill_query_blocked_in_lt : Added in 10.1.26
-tokudb.locks-select-update-3 : Modified in 10.1.26
+tokudb.locking-read-repeatable-read-1 : Added in 10.1.31
+tokudb.locking-read-repeatable-read-2 : Added in 10.1.31
+tokudb.nonflushing_analyze_debug : Added in 10.1.31
+tokudb.row_format : Modified in 10.1.31
tokudb.rows-32m-rand-insert : MDEV-12640 - Crash
tokudb.rows-32m-seq-insert : MDEV-12640 - Crash
-
-tokudb_backup.rpl_safe_slave : Include file modified in 10.1.26
+tokudb.type_datetime : MDEV-15193 - Wrong result
tokudb_bugs.checkpoint_lock : MDEV-10637 - Wrong processlist output
tokudb_bugs.checkpoint_lock_3 : MDEV-10637 - Wrong processlist output
tokudb_bugs.xa : MDEV-11804 - Lock wait timeout
tokudb_mariadb.mdev6657 : MDEV-12737 - Wrong plan, valgrind warnings
-tokudb_mariadb.mdev12972 : Added in 10.1.26
-
-rpl-tokudb.rpl_extra_col_master_tokudb : Include file modified in 10.1.26
-rpl-tokudb.rpl_extra_col_slave_tokudb : Include file modified in 10.1.26
-rpl-tokudb.rpl_not_null_tokudb : Modified in 10.1.26
-rpl-tokudb.rpl_parallel_tokudb_delete_pk : Option file modified in 10.1.26
-rpl-tokudb.rpl_parallel_tokudb_update_pk_uc0_lookup0 : Modified in 10.1.26
-rpl-tokudb.rpl_parallel_tokudb_write_pk : Modified in 10.1.26
-rpl-tokudb.rpl_rfr_disable_on_expl_pk_absence : Added in 10.1.26
-rpl-tokudb.rpl_row_basic_3tokudb : Modified in 10.1.26
-rpl-tokudb.rpl_row_tabledefs_3tokudb : Include file modified in 10.1.26
-rpl-tokudb.rpl_tokudb_commit_after_flush : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_insert_id : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_insert_id_pk : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_multi_update : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_multi_update2 : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_multi_update3 : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_rfr_partition_table : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_row_crash_safe : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_row_img_blobs : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_row_img_eng_full : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_row_img_eng_min : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_row_img_eng_noblob : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_row_img_idx_full : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_row_img_idx_min : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_row_img_idx_noblob : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_row_log : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_row_lower_case_table_names : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_row_sp003 : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_row_sp006 : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_row_trig004 : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_stm_log : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_stm_mixed_crash_safe : Added in 10.1.26
-rpl-tokudb.rpl_tokudb_stm_mixed_lower_case_table_names : Added in 10.1.26
+
+tokudb_parts.nonflushing_analyze_debug : Added in 10.1.31
+
+tokudb_perfschema.crash_tokudb : Added in 10.1.31
+tokudb_perfschema.start_server_tokudb : Added in 10.1.31
+
+rpl-tokudb.rpl_tokudb_row_log : Include file modified in 10.1.30
+rpl-tokudb.rpl_tokudb_stm_log : Include file modified in 10.1.30
#----------------------------------------------------------------
@@ -451,7 +443,8 @@ vcol.vcol_keys_innodb : MDEV-10639 - Testcase timeout
#----------------------------------------------------------------
wsrep.binlog_format : MDEV-11532 - WSREP has not yet prepared node
+wsrep.foreign_key : MDEV-14725 - WSREP has not yet prepared node
+wsrep.mdev_6832 : MDEV-14195 - Failure upon check-testcase
wsrep.pool_of_threads : MDEV-12234 - Library problem on Power
-wsrep.variables : Include file modified in 10.1.25
wsrep_info.plugin : MDEV-12909 - Wrong result
diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c
index e3357e389c2..53edfc5d87b 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)
+{
+ uint additional= ((str->alloc_increment && str->alloc_increment > 6) ?
+ str->alloc_increment :
+ 10);
+ uint lim= additional;
+ uint 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 d861c2c3d4f..56b1ae3fc6e 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -300,7 +300,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
@@ -440,7 +440,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
diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c
index 72b04119855..82043dc03fe 100644
--- a/mysys/my_addr_resolve.c
+++ b/mysys/my_addr_resolve.c
@@ -133,16 +133,52 @@ err:
#include <m_string.h>
#include <ctype.h>
-#if defined(HAVE_LINK_H) && defined(HAVE_DLOPEN)
-#include <link.h>
-static ptrdiff_t offset= 0;
-#else
-#define offset 0
-#endif
+#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];
@@ -150,26 +186,47 @@ 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 1;
+ }
+ /* 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;
- /* 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);
@@ -180,35 +237,33 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
break;
total_bytes_read += extra_bytes_read;
- }
-
- /* Failed starting addr2line. */
- if (total_bytes_read == 0)
- return 1;
- /* 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 1;
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)
@@ -221,41 +276,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 7275f602525..1b0ef857afa 100644
--- a/mysys/my_alloc.c
+++ b/mysys/my_alloc.c
@@ -26,6 +26,8 @@
#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
@@ -73,12 +75,13 @@ void init_alloc_root(MEM_ROOT *mem_root, size_t block_size,
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->free->left= pre_alloc_size;
mem_root->free->next= 0;
+ TRASH_MEM(mem_root->free);
}
}
#endif
@@ -148,6 +151,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
{
@@ -248,6 +252,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));
@@ -316,8 +321,6 @@ 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 */
static inline void mark_blocks_free(MEM_ROOT* root)
diff --git a/mysys/my_default.c b/mysys/my_default.c
index 655e9a57747..2358aed8f3b 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
@@ -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;
}
diff --git a/mysys/my_lib.c b/mysys/my_lib.c
index abc7b8a3161..8daed1101ec 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)))
@@ -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);
diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c
index dc02d3896bd..719c13a040e 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
{
diff --git a/mysys/my_new.cc b/mysys/my_new.cc
index 4266452da43..a401ccff135 100644
--- a/mysys/my_new.cc
+++ b/mysys/my_new.cc
@@ -47,6 +47,11 @@ void* operator new[](std::size_t sz, const std::nothrow_t&) throw()
return (void *) my_malloc (sz ? sz : 1, MYF(0));
}
+void operator delete (void *ptr, std::size_t)
+{
+ my_free(ptr);
+}
+
void operator delete (void *ptr)
{
my_free(ptr);
@@ -57,6 +62,11 @@ void operator delete[] (void *ptr) throw ()
my_free(ptr);
}
+void operator delete[] (void *ptr, std::size_t) throw ()
+{
+ my_free(ptr);
+}
+
void operator delete(void* ptr, const std::nothrow_t&) throw()
{
my_free(ptr);
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index 1d3c3059bd5..f827fb136d3 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -385,7 +385,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_winerr.c b/mysys/my_winerr.c
index 92e1fa83d78..a3f6229b74e 100644
--- a/mysys/my_winerr.c
+++ b/mysys/my_winerr.c
@@ -75,7 +75,9 @@ static struct errentry errtable[]= {
{ ERROR_ALREADY_EXISTS, EEXIST }, /* 183 */
{ ERROR_FILENAME_EXCED_RANGE, ENOENT }, /* 206 */
{ ERROR_NESTING_NOT_ALLOWED, EAGAIN }, /* 215 */
- { ERROR_NOT_ENOUGH_QUOTA, ENOMEM } /* 1816 */
+ { ERROR_FILE_SYSTEM_LIMITATION, EFBIG }, /* 665 */
+ { ERROR_NO_SYSTEM_RESOURCES, ENOMEM }, /* 1450 */
+ { ERROR_NOT_ENOUGH_QUOTA, ENOMEM } /* 1816 */
};
/* size of the table */
diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c
index 9d917d3dd59..61ef3657161 100644
--- a/mysys/thr_alarm.c
+++ b/mysys/thr_alarm.c
@@ -273,7 +273,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.
*/
@@ -425,7 +425,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/typelib.c b/mysys/typelib.c
index 96842b1a3ad..9ca0847570f 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_ssl/my_crypt.cc b/mysys_ssl/my_crypt.cc
index a0937a83e17..439339423cd 100644
--- a/mysys_ssl/my_crypt.cc
+++ b/mysys_ssl/my_crypt.cc
@@ -26,6 +26,7 @@
#include <openssl/evp.h>
#include <openssl/aes.h>
#include <openssl/err.h>
+#include <openssl/rand.h>
#ifdef HAVE_ERR_remove_thread_state
#define ERR_remove_state(X) ERR_remove_thread_state(NULL)
@@ -292,31 +293,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
-#include <openssl/rand.h>
-
int my_random_bytes(uchar *buf, int num)
{
- /*
- 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.
- */
- RAND_METHOD *rand = RAND_SSLeay();
- 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/yassl.cc b/mysys_ssl/yassl.cc
index 9717870fe26..e9f8e650347 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 0x1
#define EVP_CIPH_CBC_MODE 0x2
diff --git a/pcre/CMakeLists.txt b/pcre/CMakeLists.txt
index 30b06a46fef..31d4358f14d 100644
--- a/pcre/CMakeLists.txt
+++ b/pcre/CMakeLists.txt
@@ -128,9 +128,9 @@ SET(PCREGREP_BUFSIZE "20480" CACHE STRING
SET(PCRE_NEWLINE "LF" CACHE STRING
"What to recognize as a newline (one of CR, LF, CRLF, ANY, ANYCRLF).")
-# MARIADB: Changed the default from OFF to ON as pcre_test.bat on Windows
-# MARIADB: fails complaining about too small stack size on Windows.
-SET(PCRE_NO_RECURSE ON CACHE BOOL
+# Windows has much smaller stack (pcre recursion limit of 112, vs
+# 250-500 on Linuxes)
+SET(PCRE_NO_RECURSE "${WIN32}" CACHE BOOL
"If ON, then don't use stack recursion when matching. See NO_RECURSE in config.h.in for details.")
SET(PCRE_POSIX_MALLOC_THRESHOLD "10" CACHE STRING
diff --git a/pcre/pcre_compile.c b/pcre/pcre_compile.c
index 42f204cdfff..1a916693e69 100644
--- a/pcre/pcre_compile.c
+++ b/pcre/pcre_compile.c
@@ -1249,6 +1249,7 @@ else
if ((c = *ptr) >= CHAR_8) break;
+ /* fall through */
/* Fall through with a digit less than 8 */
/* \0 always starts an octal number, but we may drop through to here with a
@@ -5097,6 +5098,8 @@ for (;; ptr++)
either not match or match, depending on whether the class is or is
not negated. */
+ /* fall through */
+
default:
if (local_negate &&
(xclass || tempptr[2] != CHAR_RIGHT_SQUARE_BRACKET))
@@ -7165,7 +7168,7 @@ for (;; ptr++)
goto FAILED;
}
/* Fall through to handle (?P< as (?< is handled */
-
+ /* fall through */
/* ------------------------------------------------------------ */
DEFINE_NAME: /* Come here from (?< handling */
diff --git a/pcre/pcre_exec.c b/pcre/pcre_exec.c
index 1a9bdd546ee..fa84d924a4c 100644
--- a/pcre/pcre_exec.c
+++ b/pcre/pcre_exec.c
@@ -509,6 +509,12 @@ Returns: MATCH_MATCH if matched ) these values are >= 0
(e.g. stopped by repeated call or recursion limit)
*/
+#ifdef __GNUC__
+static int
+match(REGISTER PCRE_PUCHAR eptr, REGISTER const pcre_uchar *ecode,
+ PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb,
+ unsigned int rdepth) __attribute__((noinline,noclone));
+#endif
static int
match(REGISTER PCRE_PUCHAR eptr, REGISTER const pcre_uchar *ecode,
PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb,
@@ -1053,6 +1059,8 @@ for (;;)
group. At this point, the return is converted into MATCH_NOMATCH so that
previous backup points can be taken. */
+ /* fall through */
+
case OP_ONCE:
case OP_BRA:
case OP_SBRA:
diff --git a/plugin/handler_socket/CMakeLists.txt b/plugin/handler_socket/CMakeLists.txt
index a10743210e9..bd656ebc5b7 100644
--- a/plugin/handler_socket/CMakeLists.txt
+++ b/plugin/handler_socket/CMakeLists.txt
@@ -8,6 +8,12 @@ ENDIF()
#Remove -fno-implicit-templates from compiler flags(handlersocket would not work with it)
STRING(REPLACE "-fno-implicit-templates" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
+include(CheckCXXCompilerFlag)
+check_cxx_compiler_flag(" -Wdeprecated-declarations" HAVE_CXX_WDEPRECATED_DECLARATIONS)
+IF (HAVE_CXX_WDEPRECATED_DECLARATIONS)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")
+ENDIF()
+
INCLUDE_DIRECTORIES(libhsclient)
# Handlersocket client library. We do not distribute it,
diff --git a/plugin/metadata_lock_info/metadata_lock_info.cc b/plugin/metadata_lock_info/metadata_lock_info.cc
index 915ad8d2b88..39ac390b0bd 100644
--- a/plugin/metadata_lock_info/metadata_lock_info.cc
+++ b/plugin/metadata_lock_info/metadata_lock_info.cc
@@ -44,12 +44,6 @@ static const LEX_STRING metadata_lock_info_lock_mode[] = {
{ C_STRING_WITH_LEN("MDL_EXCLUSIVE") },
};
-static const LEX_STRING metadata_lock_info_duration[] = {
- { C_STRING_WITH_LEN("MDL_STATEMENT") },
- { C_STRING_WITH_LEN("MDL_TRANSACTION") },
- { C_STRING_WITH_LEN("MDL_EXPLICIT") },
-};
-
static ST_FIELD_INFO i_s_metadata_lock_info_fields_info[] =
{
{"THREAD_ID", 20, MYSQL_TYPE_LONGLONG, 0,
@@ -128,8 +122,6 @@ static int i_s_metadata_lock_info_init(
== MDL_key::NAMESPACE_END);
compile_time_assert(sizeof(metadata_lock_info_lock_mode)/sizeof(LEX_STRING)
== MDL_TYPE_END);
- compile_time_assert(sizeof(metadata_lock_info_duration)/sizeof(LEX_STRING)
- == MDL_DURATION_END);
ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *) p;
DBUG_ENTER("i_s_metadata_lock_info_init");
diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c
index e9827b90402..0a266ab19fe 100644
--- a/plugin/server_audit/server_audit.c
+++ b/plugin/server_audit/server_audit.c
@@ -15,7 +15,7 @@
#define PLUGIN_VERSION 0x104
-#define PLUGIN_STR_VERSION "1.4.1"
+#define PLUGIN_STR_VERSION "1.4.3"
#define _my_thread_var loc_thread_var
@@ -1089,6 +1089,7 @@ static void setup_connection_connect(struct connection_info *cn,
const struct mysql_event_connection *event)
{
cn->query_id= 0;
+ cn->query_length= 0;
cn->log_always= 0;
cn->thread_id= event->thread_id;
get_str_n(cn->db, &cn->db_length, sizeof(cn->db),
@@ -1120,6 +1121,21 @@ do { \
} while(0)
+#define ESC_MAP_SIZE 0x60
+static const char esc_map[ESC_MAP_SIZE]=
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 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, 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, 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, 0, 0
+};
+
+static char escaped_char(char c)
+{
+ return ((unsigned char ) c) >= ESC_MAP_SIZE ? 0 : esc_map[(unsigned char) c];
+}
static void setup_connection_initdb(struct connection_info *cn,
@@ -1130,6 +1146,7 @@ static void setup_connection_initdb(struct connection_info *cn,
cn->thread_id= event->general_thread_id;
cn->query_id= 0;
+ cn->query_length= 0;
cn->log_always= 0;
get_str_n(cn->db, &cn->db_length, sizeof(cn->db),
event->general_query, event->general_query_length);
@@ -1145,7 +1162,7 @@ static void setup_connection_initdb(struct connection_info *cn,
}
else
{
- get_str_n(cn->user, &cn->user_length, sizeof(cn->db),
+ get_str_n(cn->user, &cn->user_length, sizeof(cn->user),
uh_buffer, user_len);
get_str_n(cn->host, &cn->host_length, sizeof(cn->host),
uh_buffer+user_len+1, host_len);
@@ -1162,6 +1179,7 @@ static void setup_connection_table(struct connection_info *cn,
cn->thread_id= event->thread_id;
cn->query_id= query_counter++;
cn->log_always= 0;
+ cn->query_length= 0;
get_str_n(cn->db, &cn->db_length, sizeof(cn->db),
event->database, event->database_length);
get_str_n(cn->user, &cn->user_length, sizeof(cn->db),
@@ -1183,6 +1201,7 @@ static void setup_connection_query(struct connection_info *cn,
cn->thread_id= event->general_thread_id;
cn->query_id= query_counter++;
cn->log_always= 0;
+ cn->query_length= 0;
get_str_n(cn->db, &cn->db_length, sizeof(cn->db), "", 0);
if (get_user_host(event->general_user, event->general_user_length,
@@ -1196,7 +1215,7 @@ static void setup_connection_query(struct connection_info *cn,
}
else
{
- get_str_n(cn->user, &cn->user_length, sizeof(cn->db),
+ get_str_n(cn->user, &cn->user_length, sizeof(cn->user),
uh_buffer, user_len);
get_str_n(cn->host, &cn->host_length, sizeof(cn->host),
uh_buffer+user_len+1, host_len);
@@ -1323,21 +1342,16 @@ static size_t escape_string(const char *str, unsigned int len,
const char *res_end= result + result_len - 2;
while (len)
{
+ char esc_c;
+
if (result >= res_end)
break;
- if (*str == '\'')
- {
- if (result+1 >= res_end)
- break;
- *(result++)= '\\';
- *(result++)= '\'';
- }
- else if (*str == '\\')
+ if ((esc_c= escaped_char(*str)))
{
if (result+1 >= res_end)
break;
*(result++)= '\\';
- *(result++)= '\\';
+ *(result++)= esc_c;
}
else if (is_space(*str))
*(result++)= ' ';
@@ -1426,19 +1440,12 @@ static size_t escape_string_hide_passwords(const char *str, unsigned int len,
no_password:
if (result >= res_end)
break;
- if (*str == '\'')
+ if ((b_char= escaped_char(*str)))
{
if (result+1 >= res_end)
break;
*(result++)= '\\';
- *(result++)= '\'';
- }
- else if (*str == '\\')
- {
- if (result+1 >= res_end)
- break;
- *(result++)= '\\';
- *(result++)= '\\';
+ *(result++)= b_char;
}
else if (is_space(*str))
*(result++)= ' ';
@@ -1956,7 +1963,7 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev)
/* That one is important as this function can be called with */
/* &lock_operations locked when the server logs an error reported */
/* by this plugin. */
- if (internal_stop_logging)
+ if (!thd || internal_stop_logging)
return;
flogger_mutex_lock(&lock_operations);
@@ -2007,6 +2014,7 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev)
event_query_command(event))
{
log_statement(cn, event, "QUERY");
+ cn->query_length= 0; /* So the log_current_query() won't log this again. */
}
}
else if (event_class == MYSQL_AUDIT_TABLE_CLASS && FILTER(EVENT_TABLE) && cn)
@@ -2522,7 +2530,8 @@ static void log_current_query(MYSQL_THD thd)
if (!thd)
return;
cn= get_loc_info(thd);
- if (!ci_needs_setup(cn) && FILTER(EVENT_QUERY) && do_log_user(cn->user))
+ if (!ci_needs_setup(cn) && cn->query_length &&
+ FILTER(EVENT_QUERY) && do_log_user(cn->user))
{
log_statement_ex(cn, cn->query_time, thd_get_thread_id(thd),
cn->query, cn->query_length, 0, "QUERY");
diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
index 2f9c18569e3..880458c1517 100644
--- a/scripts/CMakeLists.txt
+++ b/scripts/CMakeLists.txt
@@ -221,6 +221,11 @@ ELSE()
SET(localstatedir ${MYSQL_DATADIR})
ENDIF()
+SET(resolveip_locations "$basedir/${INSTALL_BINDIR} $basedir/bin")
+SET(mysqld_locations "$basedir/${INSTALL_SBINDIR} $basedir/libexec $basedir/sbin $basedir/bin")
+SET(errmsg_locations "$basedir/${INSTALL_MYSQLSHAREDIR}/english $basedir/share/english $basedir/share/mysql/english")
+SET(pkgdata_locations "$basedir/${INSTALL_MYSQLSHAREDIR} $basedir/share $basedir/share/mysql")
+
IF(UNIX)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/mysql_install_db.sh
${CMAKE_CURRENT_BINARY_DIR}/mysql_install_db ESCAPE_QUOTES @ONLY)
diff --git a/scripts/galera_recovery.sh b/scripts/galera_recovery.sh
index d734ceb7ac7..09de6721762 100644
--- a/scripts/galera_recovery.sh
+++ b/scripts/galera_recovery.sh
@@ -68,8 +68,8 @@ parse_arguments() {
wsrep_recover_position() {
# Redirect server's error log to the log file.
- eval /usr/sbin/mysqld $cmdline_args --user=$user --wsrep_recover \
- --log-error="$log_file"
+ eval @sbindir@/mysqld $cmdline_args --user=$user --wsrep_recover \
+ --disable-log-error 2> "$log_file"
ret=$?
if [ $ret -ne 0 ]; then
# Something went wrong, let us also print the error log so that it
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index 364cc4fb9e0..2768faccd69 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -27,6 +27,7 @@ srcdir=""
args=""
defaults=""
+defaults_group_suffix=""
mysqld_opt=""
user=""
@@ -64,6 +65,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.
@@ -146,6 +150,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
@@ -187,7 +193,7 @@ SET @skip_auth_anonymous=1;" ;;
# Try to find a specific file within --basedir which can either be a binary
# release or installed source directory and return the path.
-find_in_basedir()
+find_in_dirs()
{
case "$1" in
--dir)
@@ -199,13 +205,13 @@ find_in_basedir()
for dir in "$@"
do
- if test -f "$basedir/$dir/$file"
+ if test -f "$dir/$file"
then
if test -n "$return_dir"
then
- echo "$basedir/$dir"
+ echo "$dir"
else
- echo "$basedir/$dir/$file"
+ echo "$dir/$file"
fi
break
fi
@@ -269,7 +275,7 @@ then
print_defaults="$builddir/extra/my_print_defaults"
elif test -n "$basedir"
then
- print_defaults=`find_in_basedir my_print_defaults bin extra`
+ print_defaults=`find_in_dirs my_print_defaults $basedir/bin $basedir/extra`
if test -z "$print_defaults"
then
cannot_find_file my_print_defaults $basedir/bin $basedir/extra
@@ -287,7 +293,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
@@ -295,44 +301,46 @@ if test -n "$srcdir"
then
basedir="$builddir"
bindir="$basedir/client"
- extra_bindir="$basedir/extra"
+ resolveip="$basedir/extra/resolveip"
mysqld="$basedir/sql/mysqld"
langdir="$basedir/sql/share/english"
srcpkgdatadir="$srcdir/scripts"
buildpkgdatadir="$builddir/scripts"
- scriptdir="$srcdir/scripts"
elif test -n "$basedir"
then
- bindir="$basedir/bin"
- extra_bindir="$bindir"
- mysqld=`find_in_basedir mysqld libexec sbin bin`
+ bindir="$basedir/bin" # only used in the help text
+ resolveip=`find_in_dirs resolveip @resolveip_locations@`
+ if test -z "$resolveip"
+ then
+ cannot_find_file resolveip @resolveip_locations@
+ exit 1
+ fi
+ mysqld=`find_in_dirs mysqld @mysqld_locations@`
if test -z "$mysqld"
then
- cannot_find_file mysqld $basedir/libexec $basedir/sbin $basedir/bin
+ cannot_find_file mysqld @mysqld_locations@
exit 1
fi
- langdir=`find_in_basedir --dir errmsg.sys share/english share/mysql/english`
+ langdir=`find_in_dirs --dir errmsg.sys @errmsg_locations@`
if test -z "$langdir"
then
- cannot_find_file errmsg.sys $basedir/share/english $basedir/share/mysql/english
+ cannot_find_file errmsg.sys @errmsg_locations@
exit 1
fi
- srcpkgdatadir=`find_in_basedir --dir fill_help_tables.sql share share/mysql`
+ srcpkgdatadir=`find_in_dirs --dir fill_help_tables.sql @pkgdata_locations@`
buildpkgdatadir=$srcpkgdatadir
if test -z "$srcpkgdatadir"
then
- cannot_find_file fill_help_tables.sql $basedir/share $basedir/share/mysql
+ cannot_find_file fill_help_tables.sql @pkgdata_locations@
exit 1
fi
- scriptdir="$basedir/scripts"
else
basedir="@prefix@"
bindir="@bindir@"
- extra_bindir="$bindir"
+ resolveip="$bindir/resolveip"
mysqld="@libexecdir@/mysqld"
srcpkgdatadir="@pkgdatadir@"
buildpkgdatadir="@pkgdatadir@"
- scriptdir="@scriptdir@"
fi
# Set up paths to SQL scripts required for bootstrap
@@ -376,14 +384,14 @@ hostname=`@HOSTNAME@`
# Check if hostname is valid
if test "$cross_bootstrap" -eq 0 -a "$in_rpm" -eq 0 -a "$force" -eq 0
then
- resolved=`"$extra_bindir/resolveip" $hostname 2>&1`
+ resolved=`"$resolveip" $hostname 2>&1`
if test $? -ne 0
then
- resolved=`"$extra_bindir/resolveip" localhost 2>&1`
+ resolved=`"$resolveip" localhost 2>&1`
if test $? -ne 0
then
echo "Neither host '$hostname' nor 'localhost' could be looked up with"
- echo "'$extra_bindir/resolveip'"
+ echo "'$resolveip'"
echo "Please configure the 'hostname' command to return a correct"
echo "hostname."
echo "If you want to solve this at a later stage, restart this script"
@@ -391,7 +399,7 @@ then
link_to_help
exit 1
fi
- echo "WARNING: The host '$hostname' could not be looked up with resolveip."
+ echo "WARNING: The host '$hostname' could not be looked up with $resolveip."
echo "This probably means that your libc libraries are not 100 % compatible"
echo "with this binary MariaDB version. The MariaDB daemon, mysqld, should work"
echo "normally with the exception that host name resolving will not work."
@@ -449,7 +457,7 @@ fi
mysqld_bootstrap="${MYSQLD_BOOTSTRAP-$mysqld}"
mysqld_install_cmd_line()
{
- "$mysqld_bootstrap" $defaults "$mysqld_opt" --bootstrap \
+ "$mysqld_bootstrap" $defaults $defaults_group_suffix "$mysqld_opt" --bootstrap \
"--basedir=$basedir" "--datadir=$ldata" --log-warnings=0 --enforce-storage-engine="" \
$args --max_allowed_packet=8M \
--net_buffer_length=16K
@@ -479,11 +487,11 @@ else
echo "The problem could be conflicting information in an external"
echo "my.cnf files. You can ignore these by doing:"
echo
- echo " shell> $scriptdir/scripts/mysql_install_db --defaults-file=~/.my.cnf"
+ echo " shell> $0 --defaults-file=~/.my.cnf"
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:"
@@ -494,8 +502,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/mysqld_safe.sh b/scripts/mysqld_safe.sh
index e5708b51be5..f21e697953f 100644
--- a/scripts/mysqld_safe.sh
+++ b/scripts/mysqld_safe.sh
@@ -246,7 +246,7 @@ wsrep_recover_position() {
local euid=$(id -u)
local ret=0
- local wr_logfile=$(mktemp $DATADIR/wsrep_recovery.XXXXXX)
+ local wr_logfile=$(mktemp /tmp/wsrep_recovery.XXXXXX)
# safety checks
if [ -z $wr_logfile ]; then
@@ -264,11 +264,11 @@ wsrep_recover_position() {
local wr_pidfile="$DATADIR/"`@HOSTNAME@`"-recover.pid"
- local wr_options="--log_error='$wr_logfile' --pid-file='$wr_pidfile'"
+ local wr_options="--disable-log-error --pid-file='$wr_pidfile'"
log_notice "WSREP: Running position recovery with $wr_options"
- eval_log_error "$mysqld_cmd --wsrep_recover $wr_options"
+ eval "$mysqld_cmd --wsrep_recover $wr_options 2> $wr_logfile"
local rp="$(grep 'WSREP: Recovered position:' $wr_logfile)"
if [ -z "$rp" ]; then
@@ -989,8 +989,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 723fd311f88..a8f671de224 100644
--- 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,22 @@ case "$1" in
#
# Break address string into host:port/path parts
#
- if echo $WSREP_SST_OPT_ADDR | grep -qe '^\[.*\]'
+ readonly WSREP_SST_OPT_HOST=${WSREP_SST_OPT_ADDR%%[:/]*}
+ if [ ${WSREP_SST_OPT_HOST:0:1} = '[' ]
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)
+ readonly WSREP_SST_OPT_HOST_UNESCAPED=${WSREP_SST_OPT_HOST:1:-1}
else
- # "traditional" notation
- readonly WSREP_SST_OPT_HOST=${WSREP_SST_OPT_ADDR%%[:/]*}
+ readonly WSREP_SST_OPT_HOST_UNESCAPED=${WSREP_SST_OPT_HOST}
fi
readonly WSREP_SST_OPT_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 +69,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,7 +125,6 @@ shift
done
readonly WSREP_SST_OPT_BYPASS
readonly WSREP_SST_OPT_BINLOG
-readonly WSREP_SST_OPT_CONF_SUFFIX
# try to use my_print_defaults, mysql and mysqldump that come with the sources
# (for MTR suite)
@@ -150,19 +152,18 @@ else
MY_PRINT_DEFAULTS=$(which 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
@@ -241,7 +242,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()
@@ -250,24 +251,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 -c $WSREP_SST_OPT_CONF "${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 -c $WSREP_SST_OPT_CONF $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_mysqldump.sh b/scripts/wsrep_sst_mysqldump.sh
index 59d9a3c5c9c..358247359e6 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.1' >/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
@@ -117,8 +113,8 @@ GTID_BINLOG_STATE=$(echo "SHOW GLOBAL VARIABLES LIKE 'gtid_binlog_state'" |\
$MYSQL_CLIENT $AUTH -S$WSREP_SST_OPT_SOCKET --disable-reconnect --connect_timeout=10 |\
tail -1 | awk -F ' ' '{ print $2 }')
-MYSQL="$MYSQL_CLIENT --defaults-extra-file=$WSREP_SST_OPT_CONF "\
-"$AUTH -h${WSREP_SST_OPT_HOST_UNESCAPED:-$WSREP_SST_OPT_HOST} "\
+MYSQL="$MYSQL_CLIENT $WSREP_SST_OPT_CONF "\
+"$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 c6e8a7ef4e1..3d76d1780e2 100644
--- a/scripts/wsrep_sst_rsync.sh
+++ b/scripts/wsrep_sst_rsync.sh
@@ -102,19 +102,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 78a7d76da09..64dd182e2f2 100644
--- a/scripts/wsrep_sst_xtrabackup-v2.sh
+++ b/scripts/wsrep_sst_xtrabackup-v2.sh
@@ -32,18 +32,13 @@ ecode=0
ssyslog=""
ssystag=""
XTRABACKUP_PID=""
-SST_PORT=""
-REMOTEIP=""
-REMOTEHOST=""
tca=""
tcert=""
-tpem=""
tkey=""
sockopt=""
progress=""
ttime=0
totime=0
-lsn=""
ecmd=""
rlimit=""
# Initially
@@ -78,11 +73,6 @@ 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
pvopts+=$pvformat
fi
@@ -98,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
@@ -252,11 +249,7 @@ 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
@@ -281,7 +274,7 @@ 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'
@@ -343,7 +336,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"
@@ -358,10 +351,9 @@ get_transfer()
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
wsrep_log_info "Decrypting with CERT: $tcert, KEY: $tkey"
tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tcert},key=${tkey},verify=0${joiner_extra}${sockopt} stdio"
- tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tpem},key=${tkey},verify=0${sockopt} stdio"
- else
+ 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"
@@ -382,7 +374,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
@@ -393,7 +385,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
@@ -402,7 +394,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.
@@ -454,7 +446,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 "")
@@ -472,15 +468,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 "")
@@ -494,7 +490,7 @@ read_cnf()
ssystag+="-"
if [[ $ssyslog -ne -1 ]];then
- if $MY_PRINT_DEFAULTS -c $WSREP_SST_OPT_CONF mysqld_safe | tr '_' '-' | grep -q -- "--syslog";then
+ if $MY_PRINT_DEFAULTS mysqld_safe | grep -q -- "--syslog";then
ssyslog=1
fi
fi
@@ -637,18 +633,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()
@@ -656,22 +640,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)
+ [ -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 -c $WSREP_SST_OPT_CONF 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.
@@ -832,7 +818,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"
@@ -866,20 +851,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} --defaults-file=${WSREP_SST_OPT_CONF} $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_CONF} $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} --defaults-file=${WSREP_SST_OPT_CONF} --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_CONF} $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
@@ -887,13 +876,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"
@@ -950,7 +939,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
@@ -1012,9 +1001,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"
@@ -1074,9 +1063,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)
diff --git a/scripts/wsrep_sst_xtrabackup.sh b/scripts/wsrep_sst_xtrabackup.sh
index ca3c0129837..867aab622ed 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=""
@@ -136,11 +134,7 @@ 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
@@ -155,7 +149,7 @@ 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'
@@ -181,34 +175,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 +337,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 +360,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.
@@ -466,7 +438,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 +519,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
diff --git a/sql-common/client.c b/sql-common/client.c
index b7796cebead..da18a0fdea1 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1148,7 +1148,7 @@ void mysql_read_default_options(struct st_mysql_options *options,
break;
case OPT_pipe:
options->protocol = MYSQL_PROTOCOL_PIPE;
- break;
+ break;
case OPT_connect_timeout:
case OPT_timeout:
if (opt_arg)
@@ -1232,11 +1232,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:
@@ -3133,6 +3134,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 */
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index c34b22c4175..f6ee59a9237 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, 2015, MariaDB
+# Copyright (c) 2010, 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
@@ -48,24 +48,13 @@ ${WSREP_INCLUDES}
SET(GEN_SOURCES
${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.h
${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.cc
-${CMAKE_CURRENT_BINARY_DIR}/lex_hash.h
-)
-SET(GEN_DIGEST_SOURCES
- ${CMAKE_CURRENT_BINARY_DIR}/lex_token.h
+${CMAKE_CURRENT_BINARY_DIR}/lex_hash.h
+${CMAKE_CURRENT_BINARY_DIR}/lex_token.h
)
SET_SOURCE_FILES_PROPERTIES(${GEN_SOURCES}
- ${GEN_DIGEST_SOURCES}
PROPERTIES GENERATED 1)
-# Gen_lex_token
-# Make sure sql_yacc.h is generated before compiling gen_lex_token
-
-IF(NOT CMAKE_GENERATOR MATCHES "Visual Studio")
- SET(DEPENDS_gen_lex_token DEPENDS gen_lex_token)
- SET(DEPENDS_gen_lex_hash DEPENDS gen_lex_hash)
-ENDIF()
-
IF(NOT CMAKE_CROSSCOMPILING)
ADD_EXECUTABLE(gen_lex_token gen_lex_token.cc
@@ -75,7 +64,7 @@ ENDIF()
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lex_token.h
COMMAND gen_lex_token > lex_token.h
- ${DEPENDS_gen_lex_token}
+ DEPENDS gen_lex_token
)
ADD_DEFINITIONS(-DMYSQL_SERVER -DHAVE_EVENT_SCHEDULER)
@@ -148,7 +137,6 @@ SET (SQL_SOURCE
table_cache.cc encryption.cc
${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.cc
${GEN_SOURCES}
- ${GEN_DIGEST_SOURCES}
${MYSYS_LIBWRAP_SOURCE}
)
@@ -169,7 +157,6 @@ RECOMPILE_FOR_EMBEDDED)
ADD_LIBRARY(sql STATIC ${SQL_SOURCE})
ADD_DEPENDENCIES(sql GenServerSource)
-ADD_DEPENDENCIES(sql GenDigestServerSource)
DTRACE_INSTRUMENT(sql)
TARGET_LINK_LIBRARIES(sql ${MYSQLD_STATIC_PLUGIN_LIBS}
mysys mysys_ssl dbug strings vio pcre ${LIBJEMALLOC}
@@ -208,7 +195,7 @@ IF(MSVC AND NOT WITHOUT_DYNAMIC_PLUGINS)
SET(MYSQLD_DEF ${CMAKE_CURRENT_BINARY_DIR}/mysqld_lib.def)
SET(MYSQLD_EXP ${CMAKE_CURRENT_BINARY_DIR}/mysqld_lib.exp)
SET(MYSQLD_LIB ${CMAKE_CURRENT_BINARY_DIR}/mysqld_lib.lib)
- SET(MYSQLD_CORELIBS sql mysys mysys_ssl dbug strings)
+ SET(MYSQLD_CORELIBS sql mysys dbug strings)
FOREACH (CORELIB ${MYSQLD_CORELIBS})
GET_TARGET_PROPERTY(LOC ${CORELIB} LOCATION)
FILE(TO_NATIVE_PATH ${LOC} LOC)
@@ -219,25 +206,45 @@ IF(MSVC AND NOT WITHOUT_DYNAMIC_PLUGINS)
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
SET(_PLATFORM x64)
ENDIF()
+ # Create a cmake script to generate import and export libs
+ # from a .def file
+ SET(CMAKE_CONFIGURABLE_FILE_CONTENT "
+ IF ((mysqld_lib.def IS_NEWER_THAN mysqld_lib.lib) OR
+ (mysqld_lib.def IS_NEWER_THAN mysqld_lib.exp))
+ FILE(REMOVE mysqld_lib.lib mysqld_lib.exp)
+ SET(ENV{VS_UNICODE_OUTPUT})
+ EXECUTE_PROCESS (
+ COMMAND \"${CMAKE_LINKER}\" /lib /NAME:mysqld.exe \"/DEF:${MYSQLD_DEF}\" /MACHINE:${_PLATFORM}
+ RESULT_VARIABLE ret)
+ IF(NOT ret EQUAL 0)
+ MESSAGE(FATAL_ERROR \"process failed ret=\${ret}\")
+ ENDIF()
+ ENDIF()
+ ")
+
+ CONFIGURE_FILE(
+ ${PROJECT_SOURCE_DIR}/cmake/configurable_file_content.in
+ make_mysqld_lib.cmake)
+
+ IF(CMAKE_VERSION VERSION_GREATER "3.2.0")
+ SET(MYSQLD_LIB_BYPRODUCTS BYPRODUCTS ${MYSQLD_DEF} ${MYSQLD_LIB} ${MYSQLD_EXP})
+ ENDIF()
ADD_CUSTOM_COMMAND(
- OUTPUT ${MYSQLD_DEF}
- COMMAND cscript ARGS //nologo ${PROJECT_SOURCE_DIR}/win/create_def_file.js
- ${_PLATFORM} /forLib ${LIB_LOCATIONS} > mysqld_lib.def.tmp
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/mysqld_lib.stamp
+ ${MYSQLD_LIB_BYPRODUCTS}
+ COMMENT "Generating mysqld_lib.def, mysqld_lib.lib, mysqld_lib.exp"
+ COMMAND cscript //nologo ${PROJECT_SOURCE_DIR}/win/create_def_file.js
+ ${_PLATFORM} /forLib ${LIB_LOCATIONS} > mysqld_lib.def.tmp
COMMAND ${CMAKE_COMMAND} -E copy_if_different mysqld_lib.def.tmp mysqld_lib.def
COMMAND ${CMAKE_COMMAND} -E remove mysqld_lib.def.tmp
+ COMMAND ${CMAKE_COMMAND} -P make_mysqld_lib.cmake
+ COMMAND ${CMAKE_COMMAND} -E touch mysqld_lib.stamp
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${MYSQLD_CORELIBS}
)
- ADD_CUSTOM_COMMAND(
- OUTPUT ${MYSQLD_LIB}
- COMMAND lib
- ARGS /NAME:mysqld.exe "/DEF:${MYSQLD_DEF}" "/MACHINE:${_PLATFORM}"
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- DEPENDS ${MYSQLD_DEF}
- )
- ADD_CUSTOM_TARGET(gen_mysqld_lib DEPENDS ${MYSQLD_LIB})
+ ADD_CUSTOM_TARGET(gen_mysqld_lib DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/mysqld_lib.stamp)
ADD_LIBRARY(mysqld_import_lib UNKNOWN IMPORTED GLOBAL)
SET_TARGET_PROPERTIES(mysqld_import_lib PROPERTIES IMPORTED_LOCATION ${MYSQLD_LIB})
ENDIF()
@@ -253,7 +260,9 @@ IF(APPLE)
ENDIF()
IF(NOT WITHOUT_DYNAMIC_PLUGINS)
- SET_TARGET_PROPERTIES(mysqld PROPERTIES ENABLE_EXPORTS TRUE)
+ IF(NOT MSVC)
+ SET_TARGET_PROPERTIES(mysqld PROPERTIES ENABLE_EXPORTS TRUE)
+ ENDIF()
GET_TARGET_PROPERTY(mysqld_link_flags mysqld LINK_FLAGS)
IF(NOT mysqld_link_flags)
SET(mysqld_link_flags)
@@ -267,7 +276,6 @@ IF(NOT WITHOUT_DYNAMIC_PLUGINS)
ENDIF()
ENDIF(NOT WITHOUT_DYNAMIC_PLUGINS)
-SET_TARGET_PROPERTIES(mysqld PROPERTIES ENABLE_EXPORTS TRUE)
TARGET_LINK_LIBRARIES(mysqld sql)
# Provide plugins with minimal set of libraries
@@ -293,10 +301,6 @@ IF(WITH_MYSQLD_LDFLAGS)
SET_TARGET_PROPERTIES(mysqld PROPERTIES LINK_FLAGS
"${MYSQLD_LINK_FLAGS} ${WITH_MYSQLD_LDFLAGS}")
ENDIF()
-INSTALL_DEBUG_TARGET(mysqld
- DESTINATION ${INSTALL_SBINDIR}
- PDB_DESTINATION ${INSTALL_SBINDIR}/debug
- RENAME mysqld-debug)
INCLUDE(${CMAKE_SOURCE_DIR}/cmake/bison.cmake)
@@ -330,7 +334,7 @@ ENDIF()
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lex_hash.h
COMMAND gen_lex_hash > lex_hash.h
- ${DEPENDS_gen_lex_hash}
+ DEPENDS gen_lex_hash
)
MYSQL_ADD_EXECUTABLE(mysql_tzinfo_to_sql tztime.cc COMPONENT Server)
@@ -342,27 +346,13 @@ ADD_CUSTOM_TARGET(
DEPENDS ${GEN_SOURCES}
)
-ADD_CUSTOM_TARGET(
- GenDigestServerSource
- DEPENDS ${GEN_DIGEST_SOURCES}
-)
-
#Need this only for embedded
SET_TARGET_PROPERTIES(GenServerSource PROPERTIES EXCLUDE_FROM_ALL TRUE)
IF(WIN32 OR HAVE_DLOPEN AND NOT DISABLE_SHARED)
- ADD_LIBRARY(udf_example MODULE udf_example.c)
+ ADD_LIBRARY(udf_example MODULE udf_example.c udf_example.def)
SET_TARGET_PROPERTIES(udf_example PROPERTIES PREFIX "")
- # udf_example depends on strings
- IF(WIN32)
- IF(MSVC)
- SET_TARGET_PROPERTIES(udf_example PROPERTIES LINK_FLAGS "/DEF:${CMAKE_CURRENT_SOURCE_DIR}/udf_example.def")
- ENDIF()
- TARGET_LINK_LIBRARIES(udf_example strings)
- ELSE()
- # udf_example is using safemutex exported by mysqld
- TARGET_LINK_LIBRARIES(udf_example mysqld)
- ENDIF()
+ TARGET_LINK_LIBRARIES(udf_example strings)
ENDIF()
FOREACH(tool glibtoolize libtoolize aclocal autoconf autoheader automake gtar
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/datadict.cc b/sql/datadict.cc
index ee0d8805f95..f01d61f531b 100644
--- a/sql/datadict.cc
+++ b/sql/datadict.cc
@@ -45,6 +45,8 @@ static int read_string(File file, uchar**to, size_t length)
engine_name is a LEX_STRING, where engine_name->str must point to
a buffer of at least NAME_CHAR_LEN+1 bytes.
+ If engine_name is 0, then the function will only test if the file is a
+ view or not
@retval FRMTYPE_ERROR error
@retval FRMTYPE_TABLE table
@@ -72,12 +74,23 @@ frm_type_enum dd_frm_type(THD *thd, char *path, LEX_STRING *engine_name)
goto err;
}
+ /*
+ We return FRMTYPE_TABLE if we can read the .frm file. This allows us
+ to drop a bad .frm file with DROP TABLE
+ */
type= FRMTYPE_TABLE;
- if (!is_binary_frm_header(header) || !engine_name)
+ /* engine_name is 0 if we only want to know if table is view or not */
+ if (!engine_name)
goto err;
+ /* Initialize engine name in case we are not able to find it out */
engine_name->length= 0;
+ engine_name->str[0]= 0;
+
+ if (!is_binary_frm_header(header))
+ goto err;
+
dbt= header[3];
/* cannot use ha_resolve_by_legacy_type without a THD */
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index 9e1ee6f30f9..6ef9fa9f8ef 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -1472,19 +1472,33 @@ end:
bool save_tx_read_only= thd->tx_read_only;
thd->tx_read_only= false;
- if (WSREP(thd))
- {
+ /*
+ This code is processing event execution and does not have client
+ connection. Here, event execution will now execute a prepared
+ DROP EVENT statement, but thd->lex->sql_command is set to
+ SQLCOM_CREATE_PROCEDURE
+ DROP EVENT will be logged in binlog, and we have to
+ replicate it to make all nodes have consistent event definitions
+ Wsrep DDL replication is triggered inside Events::drop_event(),
+ and here we need to prepare the THD so that DDL replication is
+ possible, essentially it requires setting sql_command to
+ SQLCOMM_DROP_EVENT, we will switch sql_command for the duration
+ of DDL replication only.
+ */
+ const enum_sql_command sql_command_save= thd->lex->sql_command;
+ const bool sql_command_set= WSREP(thd);
+
+ if (sql_command_set)
thd->lex->sql_command = SQLCOM_DROP_EVENT;
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
- }
ret= Events::drop_event(thd, dbname, name, FALSE);
- WSREP_TO_ISOLATION_END;
+ if (sql_command_set)
+ {
+ WSREP_TO_ISOLATION_END;
+ thd->lex->sql_command = sql_command_save;
+ }
-#ifdef WITH_WSREP
- error:
-#endif
thd->tx_read_only= save_tx_read_only;
thd->security_ctx->master_access= saved_master_access;
}
diff --git a/sql/events.cc b/sql/events.cc
index 728d15e60f6..cb81e98a254 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -188,8 +188,8 @@ common_1_lev_code:
expr= tmp_expr - (tmp_expr/60)*60;
/* the code after the switch will finish */
- }
break;
+ }
case INTERVAL_HOUR_SECOND:
{
ulonglong tmp_expr= expr;
@@ -205,8 +205,8 @@ common_1_lev_code:
expr= tmp_expr - (tmp_expr/60)*60;
/* the code after the switch will finish */
- }
break;
+ }
case INTERVAL_DAY_SECOND:
{
ulonglong tmp_expr= expr;
@@ -228,8 +228,8 @@ common_1_lev_code:
expr= tmp_expr - (tmp_expr/60)*60;
/* the code after the switch will finish */
- }
break;
+ }
case INTERVAL_DAY_MICROSECOND:
case INTERVAL_HOUR_MICROSECOND:
case INTERVAL_MINUTE_MICROSECOND:
@@ -243,7 +243,8 @@ common_1_lev_code:
break;
case INTERVAL_WEEK:
expr/= 7;
- /* fall through */
+ close_quote= FALSE;
+ break;
default:
close_quote= FALSE;
break;
@@ -334,6 +335,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data)
if (check_access(thd, EVENT_ACL, parse_data->dbname.str, NULL, NULL, 0, 0))
DBUG_RETURN(TRUE);
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
if (lock_object_name(thd, MDL_key::EVENT,
parse_data->dbname.str, parse_data->name.str))
@@ -416,6 +418,10 @@ Events::create_event(THD *thd, Event_parse_data *parse_data)
thd->restore_stmt_binlog_format(save_binlog_format);
DBUG_RETURN(ret);
+#ifdef WITH_WSREP
+ error:
+ DBUG_RETURN(TRUE);
+#endif /* WITH_WSREP */
}
@@ -456,6 +462,9 @@ Events::update_event(THD *thd, Event_parse_data *parse_data,
if (check_access(thd, EVENT_ACL, parse_data->dbname.str, NULL, NULL, 0, 0))
DBUG_RETURN(TRUE);
+
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
+
if (lock_object_name(thd, MDL_key::EVENT,
parse_data->dbname.str, parse_data->name.str))
DBUG_RETURN(TRUE);
@@ -540,6 +549,10 @@ Events::update_event(THD *thd, Event_parse_data *parse_data,
thd->restore_stmt_binlog_format(save_binlog_format);
DBUG_RETURN(ret);
+#ifdef WITH_WSREP
+error:
+ DBUG_RETURN(TRUE);
+#endif /* WITH_WSREP */
}
@@ -580,6 +593,8 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists)
if (check_access(thd, EVENT_ACL, dbname.str, NULL, NULL, 0, 0))
DBUG_RETURN(TRUE);
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
+
/*
Turn off row binlogging of this statement and use statement-based so
that all supporting tables are updated for DROP EVENT command.
@@ -601,6 +616,10 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists)
thd->restore_stmt_binlog_format(save_binlog_format);
DBUG_RETURN(ret);
+#ifdef WITH_WSREP
+error:
+ DBUG_RETURN(TRUE);
+#endif
}
diff --git a/sql/field.cc b/sql/field.cc
index 8eb37c56c7e..64c51677c0f 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1,6 +1,6 @@
/*
- Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2008, 2013, Monty Program Ab.
+ Copyright (c) 2000, 2017, Oracle and/or its affiliates.
+ Copyright (c) 2008, 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
@@ -2138,7 +2138,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)
{
@@ -4729,7 +4729,7 @@ double Field_double::val_real(void)
return j;
}
-longlong Field_double::val_int(void)
+longlong Field_double::val_int_from_real(bool want_unsigned_result)
{
ASSERT_COLUMN_MARKED_FOR_READ;
double j;
@@ -4737,8 +4737,15 @@ longlong Field_double::val_int(void)
bool error;
float8get(j,ptr);
- res= double_to_longlong(j, 0, &error);
- if (error)
+ res= double_to_longlong(j, want_unsigned_result, &error);
+ /*
+ Note, val_uint() is currently used for auto_increment purposes only,
+ and we want to suppress all warnings in such cases.
+ If we ever start using val_uint() for other purposes,
+ val_int_from_real() will need a new separate parameter to
+ suppress warnings.
+ */
+ if (error && !want_unsigned_result)
{
THD *thd= get_thd();
ErrConvDouble err(j);
@@ -5064,6 +5071,23 @@ int Field_timestamp::store(longlong nr, bool unsigned_val)
}
+int Field_timestamp::store_timestamp(Field_timestamp *from)
+{
+ ulong sec_part;
+ my_time_t ts= from->get_timestamp(&sec_part);
+ store_TIME(ts, sec_part);
+ if (!ts && !sec_part && get_thd()->variables.sql_mode & MODE_NO_ZERO_DATE)
+ {
+ ErrConvString s(
+ STRING_WITH_LEN("0000-00-00 00:00:00.000000") - (decimals() ? 6 - decimals() : 7),
+ system_charset_info);
+ set_datetime_warning(WARN_DATA_TRUNCATED, &s, MYSQL_TIMESTAMP_DATETIME, 1);
+ return 1;
+ }
+ return 0;
+}
+
+
double Field_timestamp::val_real(void)
{
return (double) Field_timestamp::val_int();
@@ -5764,6 +5788,13 @@ static void calc_datetime_days_diff(MYSQL_TIME *ltime, long days)
ltime->second) * 1000000LL +
ltime->second_part);
unpack_time(timediff, ltime);
+ /*
+ unpack_time() broke down hours into ltime members hour,day,month.
+ Mix them back to ltime->hour using the same factors
+ that pack_time()/unpack_time() use (i.e. 32 for month).
+ */
+ ltime->hour+= (ltime->month * 32 + ltime->day) * 24;
+ ltime->month= ltime->day= 0;
}
ltime->time_type= MYSQL_TIMESTAMP_TIME;
}
@@ -8885,13 +8916,13 @@ String *Field_set::val_str(String *val_buffer,
ulonglong tmp=(ulonglong) Field_enum::val_int();
uint bitnr=0;
+ /*
+ Some callers expect *val_buffer to contain the result,
+ so we assign to it, rather than doing 'return &empty_set_string.
+ */
+ *val_buffer= empty_set_string;
if (tmp == 0)
{
- /*
- Some callers expect *val_buffer to contain the result,
- so we assign to it, rather than doing 'return &empty_set_string.
- */
- *val_buffer= empty_set_string;
return val_buffer;
}
@@ -9398,7 +9429,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);
}
diff --git a/sql/field.h b/sql/field.h
index 30f24ecc1bb..c21bba6936f 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -618,7 +618,7 @@ public:
{ return alloc_root(mem_root, size); }
static void *operator new(size_t size) throw ()
{ return sql_alloc(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); }
@@ -745,6 +745,10 @@ public:
{ return store(ls->str, ls->length, cs); }
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); }
@@ -1999,6 +2003,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,
@@ -2025,7 +2030,8 @@ public:
int store(longlong nr, bool unsigned_val);
int reset(void) { bzero(ptr,sizeof(double)); return 0; }
double val_real(void);
- longlong val_int(void);
+ 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 *);
@@ -2186,6 +2192,7 @@ public:
int store(longlong nr, bool unsigned_val);
int store_time_dec(MYSQL_TIME *ltime, uint dec);
int store_decimal(const my_decimal *);
+ int store_timestamp(Field_timestamp *from);
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 7b57c7da104..c4c843a3bbd 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -219,6 +219,13 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions)
}
+static int copy_timestamp_fields(Field *from, Field *to)
+{
+ DBUG_ASSERT(from->type() == MYSQL_TYPE_TIMESTAMP);
+ DBUG_ASSERT(to->type() == MYSQL_TYPE_TIMESTAMP);
+ return ((Field_timestamp*)to)->store_timestamp((Field_timestamp*)from);
+}
+
static void do_skip(Copy_field *copy __attribute__((unused)))
{
}
@@ -417,6 +424,12 @@ static void do_field_decimal(Copy_field *copy)
}
+static void do_field_timestamp(Copy_field *copy)
+{
+ copy_timestamp_fields(copy->from_field, copy->to_field);
+}
+
+
static void do_field_temporal(Copy_field *copy)
{
MYSQL_TIME ltime;
@@ -594,7 +607,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;
@@ -642,9 +655,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;
@@ -724,7 +737,9 @@ Copy_field::get_copy_func(Field *to,Field *from)
((to->table->in_use->variables.sql_mode &
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE)) &&
mysql_type_to_time_type(to->type()) != MYSQL_TIMESTAMP_TIME))
- return do_field_temporal;
+ return (from->type() == MYSQL_TYPE_TIMESTAMP &&
+ to->type() == MYSQL_TYPE_TIMESTAMP)
+ ? do_field_timestamp : do_field_temporal;
/* Do binary copy */
}
// Check if identical fields
@@ -924,6 +939,10 @@ int field_conv_incompatible(Field *to, Field *from)
my_decimal buff;
return to->store_decimal(from->val_decimal(&buff));
}
+ if (from->type() == MYSQL_TYPE_TIMESTAMP && to->type() == MYSQL_TYPE_TIMESTAMP)
+ {
+ return copy_timestamp_fields(from, to);
+ }
if (from->cmp_type() == TIME_RESULT)
{
MYSQL_TIME ltime;
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 3f174029d48..7f7407fc2dc 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -998,7 +998,8 @@ static void make_sortkey(register Sort_param *param,
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)
{
diff --git a/sql/filesort_utils.cc b/sql/filesort_utils.cc
index 370a4e655b6..1e0cf096145 100644
--- a/sql/filesort_utils.cc
+++ b/sql/filesort_utils.cc
@@ -96,7 +96,7 @@ uchar **Filesort_buffer::alloc_sort_buffer(uint num_records, uint record_length)
if (m_idx_array.is_null())
{
- sort_buff_sz= num_records * (record_length + sizeof(uchar*));
+ sort_buff_sz= ((size_t)num_records) * (record_length + sizeof(uchar*));
set_if_bigger(sort_buff_sz, record_length * MERGEBUFF2);
uchar **sort_keys=
(uchar**) my_malloc(sort_buff_sz, MYF(MY_THREAD_SPECIFIC));
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 8ebc11252e1..34c253cc48a 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -1,6 +1,6 @@
/*
- Copyright (c) 2005, 2013, Oracle and/or its affiliates.
- Copyright (c) 2009, 2013, Monty Program Ab & SkySQL Ab
+ Copyright (c) 2005, 2017, Oracle and/or its affiliates.
+ Copyright (c) 2009, 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
@@ -1929,7 +1929,7 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
cleanup_new_partition(part_count);
DBUG_RETURN(error);
}
-
+
DBUG_PRINT("info", ("Add partition %s", part_name_buff));
if ((error= prepare_new_partition(table, create_info,
new_file_array[i],
@@ -2180,38 +2180,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;
@@ -7897,7 +7878,7 @@ uint32 ha_partition::calculate_key_hash_value(Field **field_array)
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_GEOMETRY:
- /* fall through. */
+ /* fall through */
default:
DBUG_ASSERT(0); // New type?
/* Fall through for default hashing (5.5). */
@@ -8152,20 +8133,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;
}
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 3ea8d4a855d..11e34e1ebb0 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -356,6 +356,10 @@ public:
virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share);
virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
uint table_changes);
+ void update_part_create_info(HA_CREATE_INFO *create_info, uint part_id)
+ {
+ m_file[part_id]->update_create_info(create_info);
+ }
private:
int copy_partitions(ulonglong * const copied, ulonglong * const deleted);
void cleanup_new_partition(uint part_count);
diff --git a/sql/handler.cc b/sql/handler.cc
index 49e9626cb81..b2a00e48d65 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -73,6 +73,14 @@ KEY_CREATE_INFO default_key_create_info=
ulong total_ha= 0;
/* number of storage engines (from handlertons[]) that support 2pc */
ulong total_ha_2pc= 0;
+#ifndef DBUG_OFF
+/*
+ Number of non-mandatory 2pc handlertons whose initialization failed
+ to estimate total_ha_2pc value under supposition of the failures
+ have not occcured.
+*/
+ulong failed_ha_2pc= 0;
+#endif
/* size of savepoint storage area (see ha_init) */
ulong savepoint_alloc_size= 0;
@@ -397,7 +405,7 @@ static int ha_finish_errors(void)
}
static volatile int32 need_full_discover_for_existence= 0;
-static volatile int32 engines_with_discover_table_names= 0;
+static volatile int32 engines_with_discover_file_names= 0;
static volatile int32 engines_with_discover= 0;
static int full_discover_for_existence(handlerton *, const char *, const char *)
@@ -422,8 +430,8 @@ static void update_discovery_counters(handlerton *hton, int val)
if (hton->discover_table_existence == full_discover_for_existence)
my_atomic_add32(&need_full_discover_for_existence, val);
- if (hton->discover_table_names)
- my_atomic_add32(&engines_with_discover_table_names, val);
+ if (hton->discover_table_names && hton->tablefile_extensions[0])
+ my_atomic_add32(&engines_with_discover_file_names, val);
if (hton->discover_table)
my_atomic_add32(&engines_with_discover, val);
@@ -649,6 +657,10 @@ err_deinit:
(void) plugin->plugin->deinit(NULL);
err:
+#ifndef DBUG_OFF
+ if (hton->prepare && hton->state == SHOW_OPTION_YES)
+ failed_ha_2pc++;
+#endif
my_free(hton);
err_no_hton_memory:
plugin->data= NULL;
@@ -1859,7 +1871,7 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
{
#ifndef DBUG_OFF
char buf[XIDDATASIZE*4+6]; // see xid_to_str
- sql_print_information("ignore xid %s", xid_to_str(buf, info->list+i));
+ DBUG_PRINT("info", ("ignore xid %s", xid_to_str(buf, info->list+i)));
#endif
xid_cache_insert(info->list+i, XA_PREPARED);
info->found_foreign_xids++;
@@ -1876,19 +1888,31 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
tc_heuristic_recover == TC_HEURISTIC_RECOVER_COMMIT)
{
#ifndef DBUG_OFF
- char buf[XIDDATASIZE*4+6]; // see xid_to_str
- sql_print_information("commit xid %s", xid_to_str(buf, info->list+i));
+ int rc=
+#endif
+ hton->commit_by_xid(hton, info->list+i);
+#ifndef DBUG_OFF
+ if (rc == 0)
+ {
+ char buf[XIDDATASIZE*4+6]; // see xid_to_str
+ DBUG_PRINT("info", ("commit xid %s", xid_to_str(buf, info->list+i)));
+ }
#endif
- hton->commit_by_xid(hton, info->list+i);
}
else
{
#ifndef DBUG_OFF
- char buf[XIDDATASIZE*4+6]; // see xid_to_str
- sql_print_information("rollback xid %s",
- xid_to_str(buf, info->list+i));
+ int rc=
+#endif
+ hton->rollback_by_xid(hton, info->list+i);
+#ifndef DBUG_OFF
+ if (rc == 0)
+ {
+ char buf[XIDDATASIZE*4+6]; // see xid_to_str
+ DBUG_PRINT("info", ("rollback xid %s",
+ xid_to_str(buf, info->list+i)));
+ }
#endif
- hton->rollback_by_xid(hton, info->list+i);
}
}
if (got < info->len)
@@ -1910,7 +1934,8 @@ int ha_recover(HASH *commit_list)
/* commit_list and tc_heuristic_recover cannot be set both */
DBUG_ASSERT(info.commit_list==0 || tc_heuristic_recover==0);
/* if either is set, total_ha_2pc must be set too */
- DBUG_ASSERT(info.dry_run || total_ha_2pc>(ulong)opt_bin_log);
+ DBUG_ASSERT(info.dry_run ||
+ (failed_ha_2pc + total_ha_2pc) > (ulong)opt_bin_log);
if (total_ha_2pc <= (ulong)opt_bin_log)
DBUG_RETURN(0);
@@ -3300,9 +3325,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
{
@@ -3396,11 +3423,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;
}
}
@@ -5038,10 +5063,15 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name,
{
char engine_buf[NAME_CHAR_LEN + 1];
LEX_STRING engine= { engine_buf, 0 };
+ frm_type_enum type;
- if (dd_frm_type(thd, path, &engine) != FRMTYPE_VIEW)
+ if ((type= dd_frm_type(thd, path, &engine)) == FRMTYPE_ERROR)
+ DBUG_RETURN(0);
+
+ if (type != FRMTYPE_VIEW)
{
- plugin_ref p= plugin_lock_by_name(thd, &engine, MYSQL_STORAGE_ENGINE_PLUGIN);
+ plugin_ref p= plugin_lock_by_name(thd, &engine,
+ MYSQL_STORAGE_ENGINE_PLUGIN);
*hton= p ? plugin_hton(p) : NULL;
if (*hton)
// verify that the table really exists
@@ -5164,6 +5194,7 @@ void Discovered_table_list::remove_duplicates()
{
LEX_STRING **src= tables->front();
LEX_STRING **dst= src;
+ sort();
while (++dst <= tables->back())
{
LEX_STRING *s= *src, *d= *dst;
@@ -5231,10 +5262,12 @@ int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp,
int error;
DBUG_ENTER("ha_discover_table_names");
- if (engines_with_discover_table_names == 0 && !reusable)
+ if (engines_with_discover_file_names == 0 && !reusable)
{
- error= ext_table_discovery_simple(dirp, result);
- result->sort();
+ st_discover_names_args args= {db, NULL, result, 0};
+ error= ext_table_discovery_simple(dirp, result) ||
+ plugin_foreach(thd, discover_names,
+ MYSQL_STORAGE_ENGINE_PLUGIN, &args);
}
else
{
@@ -5247,8 +5280,6 @@ int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp,
error= extension_based_table_discovery(dirp, reg_ext, result) ||
plugin_foreach(thd, discover_names,
MYSQL_STORAGE_ENGINE_PLUGIN, &args);
- result->sort();
-
if (args.possible_duplicates > 0)
result->remove_duplicates();
}
diff --git a/sql/handler.h b/sql/handler.h
index 1d4dded3971..68de7563d8b 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1764,6 +1764,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;
+ }
};
diff --git a/sql/item.cc b/sql/item.cc
index ae77e90fa85..2cc45dc6010 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
@@ -1742,7 +1742,10 @@ bool Item_name_const::fix_fields(THD *thd, Item **ref)
{
set_name(item_name->ptr(), (uint) item_name->length(), system_charset_info);
}
- collation.set(value_item->collation.collation, DERIVATION_IMPLICIT);
+ if (value_item->collation.derivation == DERIVATION_NUMERIC)
+ collation.set_numeric();
+ else
+ collation.set(value_item->collation.collation, DERIVATION_IMPLICIT);
max_length= value_item->max_length;
decimals= value_item->decimals;
fixed= 1;
@@ -2130,6 +2133,9 @@ bool Item_func_or_sum::agg_item_set_converter(const DTCollation &coll,
Item **args, uint nargs,
uint flags, int item_sep)
{
+ THD *thd= current_thd;
+ if (thd->lex->is_ps_or_view_context_analysis())
+ return false;
Item **arg, *safe_args[2]= {NULL, NULL};
/*
@@ -2145,7 +2151,6 @@ bool Item_func_or_sum::agg_item_set_converter(const DTCollation &coll,
safe_args[1]= args[item_sep];
}
- THD *thd= current_thd;
bool res= FALSE;
uint i;
@@ -2676,7 +2681,8 @@ table_map Item_field::all_used_tables() const
return (get_depended_from() ? OUTER_REF_TABLE_BIT : field->table->map);
}
-void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref,
+ bool merge)
{
if (new_parent == get_depended_from())
depended_from= NULL;
@@ -2720,6 +2726,19 @@ void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref)
if (!need_change)
return;
+ if (!merge)
+ {
+ /*
+ It is transformation without merge.
+ This field was "outer" for the inner SELECT where it was taken and
+ moved up.
+ "Outer" fields uses normal SELECT_LEX context of upper SELECTs for
+ name resolution, so we can switch everything to it safely.
+ */
+ this->context= &new_parent->context;
+ return;
+ }
+
Name_resolution_context *ctx= new Name_resolution_context();
if (context->select_lex == new_parent)
{
@@ -4604,7 +4623,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
@@ -5628,7 +5648,7 @@ String_copier_for_item::copy_with_warn(CHARSET_INFO *dstcs, String *dst,
srccs == &my_charset_bin ?
dstcs->csname : srccs->csname,
err.ptr());
- return m_thd->is_strict_mode();
+ return false;
}
if (const char *pos= cannot_convert_error_pos())
{
@@ -5641,7 +5661,7 @@ String_copier_for_item::copy_with_warn(CHARSET_INFO *dstcs, String *dst,
ER_CANNOT_CONVERT_CHARACTER,
ER_THD(m_thd, ER_CANNOT_CONVERT_CHARACTER),
srccs->csname, buf, dstcs->csname);
- return m_thd->is_strict_mode();
+ return false;
}
return false;
}
@@ -5832,7 +5852,7 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table,
Field_string(max_length, maybe_null, name, collation.collation);
break;
}
- /* Fall through */
+ /* fall through */
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
case MYSQL_TYPE_VAR_STRING:
@@ -6637,6 +6657,7 @@ bool Item::cache_const_expr_analyzer(uchar **arg)
*/
if (const_item() &&
!(basic_const_item() || item->basic_const_item() ||
+ item->type() == Item::NULL_ITEM || /* Item_name_const hack */
item->type() == Item::FIELD_ITEM ||
item->type() == SUBSELECT_ITEM ||
item->type() == CACHE_ITEM ||
@@ -6818,7 +6839,11 @@ public:
// Find which select the field is in. This is achieved by walking up
// the select tree and looking for the table of interest.
st_select_lex *sel;
- for (sel= current_select; sel; sel= sel->outer_select())
+ for (sel= current_select;
+ sel ;
+ sel= (sel->context.outer_context ?
+ sel->context.outer_context->select_lex:
+ NULL))
{
List_iterator<TABLE_LIST> li(sel->leaf_tables);
TABLE_LIST *tbl;
@@ -7991,7 +8016,6 @@ bool Item_direct_view_ref::send(Protocol *protocol, String *buffer)
bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
{
- DBUG_ASSERT(1);
/* view fild reference must be defined */
DBUG_ASSERT(*ref);
/* (*ref)->check_cols() will be made in Item_direct_ref::fix_fields */
@@ -8052,18 +8076,19 @@ bool Item_outer_ref::fix_fields(THD *thd, Item **reference)
void Item_outer_ref::fix_after_pullout(st_select_lex *new_parent,
- Item **ref_arg)
+ Item **ref_arg, bool merge)
{
if (get_depended_from() == new_parent)
{
*ref_arg= outer_ref;
- (*ref_arg)->fix_after_pullout(new_parent, ref_arg);
+ (*ref_arg)->fix_after_pullout(new_parent, ref_arg, merge);
}
}
-void Item_ref::fix_after_pullout(st_select_lex *new_parent, Item **refptr)
+void Item_ref::fix_after_pullout(st_select_lex *new_parent, Item **refptr,
+ bool merge)
{
- (*ref)->fix_after_pullout(new_parent, ref);
+ (*ref)->fix_after_pullout(new_parent, ref, merge);
if (get_depended_from() == new_parent)
depended_from= NULL;
}
@@ -8379,7 +8404,7 @@ Item *Item_default_value::transform(THD *thd, Item_transformer transformer,
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);
}
@@ -9844,7 +9869,7 @@ void Item_direct_view_ref::update_used_tables()
table_map Item_direct_view_ref::used_tables() const
{
- DBUG_ASSERT(null_ref_table);
+ DBUG_ASSERT(fixed);
if (get_depended_from())
return OUTER_REF_TABLE_BIT;
@@ -9898,11 +9923,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";
diff --git a/sql/item.h b/sql/item.h
index 8ee76a626d4..a9b8006cdf3 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1,8 +1,8 @@
#ifndef SQL_ITEM_INCLUDED
#define SQL_ITEM_INCLUDED
-/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2009, 2016, MariaDB
+/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
+ 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,6 +54,12 @@ bool trace_unsupported_by_check_vcol_func_processor(const char *where)
return trace_unsupported_func(where, "check_vcol_func_processor");
}
+#ifdef DBUG_OFF
+static inline const char *dbug_print_item(Item *item) { return NULL; }
+#else
+extern const char *dbug_print_item(Item *item);
+#endif
+
class Protocol;
struct TABLE_LIST;
void item_init(void); /* Init item functions */
@@ -548,8 +554,7 @@ class Item_func_not;
class Item_splocal;
/**
- String_copier that honors the current sql_mode (strict vs non strict)
- and can send warnings.
+ String_copier that sends Item specific warnings.
*/
class String_copier_for_item: public String_copier
{
@@ -624,7 +629,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, STRING_ITEM,
@@ -730,7 +735,9 @@ public:
Fix after some tables has been pulled out. Basically re-calculate all
attributes that are dependent on the tables.
*/
- virtual void fix_after_pullout(st_select_lex *new_parent, Item **ref) {};
+ virtual void fix_after_pullout(st_select_lex *new_parent, Item **ref,
+ bool merge)
+ {};
/*
This method should be used in case where we are sure that we do not need
@@ -2385,7 +2392,7 @@ public:
bool send(Protocol *protocol, String *str_arg);
void reset_field(Field *f);
bool fix_fields(THD *, Item **);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
void make_field(Send_field *tmp_field);
int save_in_field(Field *field,bool no_conversions);
void save_org_in_field(Field *field, fast_field_copier optimizer_data);
@@ -2582,6 +2589,17 @@ public:
Field *result_field;
Item_null_result(THD *thd): Item_null(thd), result_field(0) {}
bool is_result_field() { return result_field != 0; }
+#if MARIADB_VERSION_ID < 100300
+ enum_field_types field_type() const
+ {
+ return result_field->type();
+ }
+#else
+ const Type_handler *type_handler() const
+ {
+ return result_field->type_handler();
+ }
+#endif
void save_in_result_field(bool no_conversions)
{
save_in_field(result_field, no_conversions);
@@ -3895,7 +3913,7 @@ public:
bool send(Protocol *prot, String *tmp);
void make_field(Send_field *field);
bool fix_fields(THD *, Item **);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
int save_in_field(Field *field, bool no_conversions);
void save_org_in_field(Field *field, fast_field_copier optimizer_data);
fast_field_copier setup_fast_field_copier(Field *field)
@@ -4132,6 +4150,8 @@ public:
bool fix_fields(THD *thd, Item **it);
void cleanup();
+ Item *get_orig_item() const { return orig_item; }
+
/* Methods of getting value which should be cached in the cache */
void save_val(Field *to);
double val_real();
@@ -4163,9 +4183,9 @@ public:
Item *it= ((Item *) item)->real_item();
return orig_item->eq(it, binary_cmp);
}
- void fix_after_pullout(st_select_lex *new_parent, Item **refptr)
+ void fix_after_pullout(st_select_lex *new_parent, Item **refptr, bool merge)
{
- orig_item->fix_after_pullout(new_parent, &orig_item);
+ orig_item->fix_after_pullout(new_parent, &orig_item, merge);
}
int save_in_field(Field *to, bool no_conversions);
enum Item_result result_type () const { return orig_item->result_type(); }
@@ -4423,7 +4443,7 @@ public:
outer_ref->save_org_in_field(result_field, NULL);
}
bool fix_fields(THD *, Item **);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
table_map used_tables() const
{
return (*ref)->const_item() ? 0 : OUTER_REF_TABLE_BIT;
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index e45e568e3da..4e2e5bd4cac 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1229,10 +1229,12 @@ bool Item_in_optimizer::is_top_level_item()
}
-void Item_in_optimizer::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+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);
+ Item_bool_func::fix_after_pullout(new_parent, ref, merge);
/* Then, re-calculate not_null_tables_cache: */
eval_not_null_tables(NULL);
@@ -1254,6 +1256,33 @@ bool Item_in_optimizer::eval_not_null_tables(uchar *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");
@@ -1428,6 +1457,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);
@@ -1452,6 +1482,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())
{
@@ -1689,6 +1720,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);
@@ -1740,6 +1772,7 @@ Item *Item_in_optimizer::transform(THD *thd, Item_transformer transformer,
bool Item_in_optimizer::is_expensive_processor(uchar *arg)
{
+ DBUG_ASSERT(fixed);
return args[0]->is_expensive_processor(arg) ||
args[1]->is_expensive_processor(arg);
}
@@ -1747,6 +1780,7 @@ bool Item_in_optimizer::is_expensive_processor(uchar *arg)
bool Item_in_optimizer::is_expensive()
{
+ DBUG_ASSERT(fixed);
return args[0]->is_expensive() || args[1]->is_expensive();
}
@@ -1848,6 +1882,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_int_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();
@@ -2060,10 +2107,11 @@ bool Item_func_between::count_sargable_conds(uchar *arg)
}
-void Item_func_between::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_func_between::fix_after_pullout(st_select_lex *new_parent,
+ Item **ref, bool merge)
{
/* This will re-calculate attributes of the arguments */
- Item_func_opt_neg::fix_after_pullout(new_parent, ref);
+ Item_func_opt_neg::fix_after_pullout(new_parent, ref, merge);
/* Then, re-calculate not_null_tables_cache according to our special rules */
eval_not_null_tables(NULL);
}
@@ -2406,10 +2454,11 @@ Item_func_if::eval_not_null_tables(uchar *opt_arg)
}
-void Item_func_if::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_func_if::fix_after_pullout(st_select_lex *new_parent,
+ Item **ref, bool merge)
{
/* This will re-calculate attributes of the arguments */
- Item_func::fix_after_pullout(new_parent, ref);
+ Item_func::fix_after_pullout(new_parent, ref, merge);
/* Then, re-calculate not_null_tables_cache according to our special rules */
eval_not_null_tables(NULL);
}
@@ -2777,7 +2826,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,
@@ -2795,10 +2846,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(')');
@@ -4138,10 +4193,11 @@ Item_func_in::eval_not_null_tables(uchar *opt_arg)
}
-void Item_func_in::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_func_in::fix_after_pullout(st_select_lex *new_parent, Item **ref,
+ bool merge)
{
/* This will re-calculate attributes of the arguments */
- Item_func_opt_neg::fix_after_pullout(new_parent, ref);
+ Item_func_opt_neg::fix_after_pullout(new_parent, ref, merge);
/* Then, re-calculate not_null_tables_cache according to our special rules */
eval_not_null_tables(NULL);
}
@@ -4663,7 +4719,8 @@ Item_cond::eval_not_null_tables(uchar *opt_arg)
}
-void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref,
+ bool merge)
{
List_iterator<Item> li(list);
Item *item;
@@ -4676,7 +4733,7 @@ void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref)
while ((item=li++))
{
table_map tmp_table_map;
- item->fix_after_pullout(new_parent, li.ref());
+ item->fix_after_pullout(new_parent, li.ref(), merge);
item= *li.ref();
used_tables_and_const_cache_join(item);
@@ -5412,7 +5469,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";
@@ -6885,7 +6942,7 @@ 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();
@@ -6895,11 +6952,11 @@ longlong Item_func_dyncol_exists::val_int()
uint strlen;
uint dummy_errors;
buf.str= (char *)sql_alloc((strlen= nm->length() *
- my_charset_utf8_general_ci.mbmaxlen + 1));
+ DYNCOL_UTF->mbmaxlen + 1));
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 a34e70f9918..076e6da953c 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -342,9 +342,11 @@ public:
virtual void get_cache_parameters(List<Item> &parameters);
bool is_top_level_item();
bool eval_not_null_tables(uchar *opt_arg);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
bool invisible_mode();
void reset_cache() { cache= NULL; }
+ virtual void print(String *str, enum_query_type query_type);
+ void restore_first_argument();
};
@@ -824,7 +826,7 @@ public:
void fix_length_and_dec();
virtual void print(String *str, enum_query_type query_type);
bool eval_not_null_tables(uchar *opt_arg);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
bool count_sargable_conds(uchar *arg);
void add_key_fields(JOIN *join, KEY_FIELD **key_fields,
uint *and_level, table_map usable_tables,
@@ -878,6 +880,7 @@ public:
{
allowed_arg_cols= 0; // Fetch this value from first argument
}
+ bool fix_fields(THD *, Item **);
longlong val_int();
void fix_length_and_dec();
const char *func_name() const { return "interval"; }
@@ -980,7 +983,7 @@ public:
}
const char *func_name() const { return "if"; }
bool eval_not_null_tables(uchar *opt_arg);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
private:
void cache_type_info(Item *source);
};
@@ -1595,7 +1598,7 @@ public:
enum Functype functype() const { return IN_FUNC; }
const char *func_name() const { return " IN "; }
bool eval_not_null_tables(uchar *opt_arg);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
bool count_sargable_conds(uchar *arg);
};
@@ -1676,9 +1679,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)) &&
@@ -2063,7 +2066,7 @@ public:
list.append(nlist);
}
bool fix_fields(THD *, Item **ref);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
enum Type type() const { return COND_ITEM; }
List<Item>* argument_list() { return &list; }
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 5539ba7fc48..0700d71a396 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -270,7 +270,8 @@ Item_func::eval_not_null_tables(uchar *opt_arg)
}
-void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref,
+ bool merge)
{
Item **arg,**arg_end;
@@ -281,7 +282,7 @@ void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref)
{
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
{
- (*arg)->fix_after_pullout(new_parent, arg);
+ (*arg)->fix_after_pullout(new_parent, arg, merge);
Item *item= *arg;
used_tables_and_const_cache_join(item);
@@ -549,6 +550,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;
@@ -565,6 +567,7 @@ void Item_udf_func::fix_num_length_and_dec()
max_length= float_length(NOT_FIXED_DEC);
}
}
+#endif
/**
diff --git a/sql/item_func.h b/sql/item_func.h
index 38d5d0aa873..1209fc5cdd8 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -126,7 +126,7 @@ public:
Item_func_or_sum::cleanup();
used_tables_and_const_cache_init();
}
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
void quick_fix_field();
table_map not_null_tables() const;
void update_used_tables()
@@ -1773,12 +1773,6 @@ public:
create_tmp_field(false, table, MY_INT32_NUM_DECIMAL_DIGITS) :
tmp_table_field_from_field_type(table, false, true);
}
- table_map used_tables() const
- {
- return used_tables_cache | RAND_TABLE_BIT;
- }
- bool const_item() const { return 0; }
- bool is_expensive() { return 1; }
virtual void print(String *str, enum_query_type query_type);
void print_as_stmt(String *str, enum_query_type query_type);
const char *func_name() const { return "set_user_var"; }
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc
index fd7241b7bc3..51a4636df1f 100644
--- a/sql/item_geofunc.cc
+++ b/sql/item_geofunc.cc
@@ -1194,6 +1194,8 @@ static int setup_relate_func(Geometry *g1, Geometry *g2,
}
else
func->repeat_expression(shape_a);
+ if (func->reserve_op_buffer(1))
+ return 1;
func->add_operation(op_matrix(nc%3), 1);
if (do_store_shapes)
{
@@ -1364,11 +1366,13 @@ longlong Item_func_spatial_precise_rel::val_int()
Gcalc_function::op_intersection, 2);
func.add_operation(Gcalc_function::op_internals, 1);
shape_a= func.get_next_expression_pos();
- if ((null_value= g1.store_shapes(&trn)))
+ if ((null_value= g1.store_shapes(&trn)) ||
+ func.reserve_op_buffer(1))
break;
func.add_operation(Gcalc_function::op_internals, 1);
shape_b= func.get_next_expression_pos();
- if ((null_value= g2.store_shapes(&trn)))
+ if ((null_value= g2.store_shapes(&trn)) ||
+ func.reserve_op_buffer(1))
break;
func.add_operation(Gcalc_function::v_find_t |
Gcalc_function::op_intersection, 2);
@@ -1603,6 +1607,8 @@ int Item_func_buffer::Transporter::single_point(double x, double y)
{
if (buffer_op == Gcalc_function::op_difference)
{
+ if (m_fn->reserve_op_buffer(1))
+ return 1;
m_fn->add_operation(Gcalc_function::op_false, 0);
return 0;
}
diff --git a/sql/item_inetfunc.cc b/sql/item_inetfunc.cc
index 6a09747fa1a..4c4dfa4497b 100644
--- a/sql/item_inetfunc.cc
+++ b/sql/item_inetfunc.cc
@@ -181,7 +181,8 @@ String *Item_func_inet_str_base::val_str_ascii(String *buffer)
return NULL;
}
- String *arg_str= args[0]->val_str(buffer);
+ StringBuffer<STRING_BUFFER_USUAL_SIZE> tmp;
+ String *arg_str= args[0]->val_str(&tmp);
if (!arg_str) // Out-of memory happened. The error has been reported.
{ // Or: the underlying field is NULL
null_value= true;
@@ -679,7 +680,7 @@ static void ipv6_to_str(const in6_addr *ipv6, char *str)
@retval true The string has been converted sucessfully.
*/
-bool Item_func_inet6_aton::calc_value(String *arg, String *buffer)
+bool Item_func_inet6_aton::calc_value(const String *arg, String *buffer)
{
// ipv4-string -> varbinary(4)
// ipv6-string -> varbinary(16)
@@ -719,7 +720,7 @@ bool Item_func_inet6_aton::calc_value(String *arg, String *buffer)
@retval true The string has been converted sucessfully.
*/
-bool Item_func_inet6_ntoa::calc_value(String *arg, String *buffer)
+bool Item_func_inet6_ntoa::calc_value(const String *arg, String *buffer)
{
if (arg->charset() != &my_charset_bin)
return false;
diff --git a/sql/item_inetfunc.h b/sql/item_inetfunc.h
index 82a4405df1e..eaafd005f91 100644
--- a/sql/item_inetfunc.h
+++ b/sql/item_inetfunc.h
@@ -98,7 +98,7 @@ public:
virtual String *val_str_ascii(String *buffer);
protected:
- virtual bool calc_value(String *arg, String *buffer) = 0;
+ virtual bool calc_value(const String *arg, String *buffer) = 0;
};
@@ -125,7 +125,7 @@ public:
}
protected:
- virtual bool calc_value(String *arg, String *buffer);
+ virtual bool calc_value(const String *arg, String *buffer);
};
@@ -157,7 +157,7 @@ public:
}
protected:
- virtual bool calc_value(String *arg, String *buffer);
+ virtual bool calc_value(const String *arg, String *buffer);
};
diff --git a/sql/item_row.cc b/sql/item_row.cc
index b1575b81087..97f75c4b4cf 100644
--- a/sql/item_row.cc
+++ b/sql/item_row.cc
@@ -24,7 +24,6 @@
#include "sql_class.h" // THD, set_var.h: THD
#include "set_var.h"
-
void Item_row::illegal_method_call(const char *method)
{
DBUG_ENTER("Item_row::illegal_method_call");
@@ -110,13 +109,14 @@ void Item_row::split_sum_func(THD *thd, Item **ref_pointer_array,
}
-void Item_row::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_row::fix_after_pullout(st_select_lex *new_parent, Item **ref,
+ bool merge)
{
used_tables_and_const_cache_init();
not_null_tables_cache= 0;
for (uint i= 0; i < arg_count; i++)
{
- args[i]->fix_after_pullout(new_parent, &args[i]);
+ args[i]->fix_after_pullout(new_parent, &args[i], merge);
used_tables_and_const_cache_join(args[i]);
not_null_tables_cache|= args[i]->not_null_tables();
}
diff --git a/sql/item_row.h b/sql/item_row.h
index 25c9ec7915b..5e8071ec495 100644
--- a/sql/item_row.h
+++ b/sql/item_row.h
@@ -47,13 +47,10 @@ public:
Item_row(THD *thd, List<Item> &list):
Item(thd), Item_args(thd, list), not_null_tables_cache(0), with_null(0)
{ }
- Item_row(THD *thd, Item_row *item):
- Item(thd),
- Item_args(item),
- Used_tables_and_const_cache(item),
- not_null_tables_cache(0),
- with_null(0)
- {}
+ Item_row(THD *thd, Item_row *row):
+ Item(thd), Item_args(thd, static_cast<Item_args*>(row)), Used_tables_and_const_cache(),
+ not_null_tables_cache(0), with_null(0)
+ { }
enum Type type() const { return ROW_ITEM; };
void illegal_method_call(const char *);
@@ -83,7 +80,7 @@ public:
return 0;
};
bool fix_fields(THD *thd, Item **ref);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
void cleanup();
void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields,
uint flags);
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index a89c51ad87b..cd47257a77b 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
@@ -203,9 +203,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;
@@ -546,139 +546,84 @@ 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);
- String *res,*res2,*use_as_buff;
- uint i;
- bool is_const= 0;
+ THD *thd= current_thd;
+ String *res;
null_value=0;
- if (!(res=args[0]->val_str(str)))
+ if (!(res= args[0]->val_str(str)))
goto null;
- use_as_buff= &tmp_value;
- is_const= args[0]->const_item();
- for (i=1 ; i < arg_count ; i++)
- {
- if (res->length() == 0)
- {
- if (!(res=args[i]->val_str(str)))
- goto null;
- /*
- 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.
- */
- is_const= args[i]->const_item();
- }
- else
- {
- if (!(res2=args[i]->val_str(use_as_buff)))
- goto null;
- if (res2->length() == 0)
- continue;
- if (res->length()+res2->length() >
- current_thd->variables.max_allowed_packet)
- {
- THD *thd= current_thd;
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_WARN_ALLOWED_PACKET_OVERFLOWED,
- ER_THD(thd, ER_WARN_ALLOWED_PACKET_OVERFLOWED),
- func_name(),
- thd->variables.max_allowed_packet);
- goto null;
- }
- if (!is_const && res->alloced_length() >= res->length()+res2->length())
- { // Use old buffer
- res->append(*res2);
- }
- else if (str->alloced_length() >= res->length()+res2->length())
- {
- if (str->ptr() == res2->ptr())
- str->replace(0,0,*res);
- else
- {
- str->copy(*res);
- str->append(*res2);
- }
- res= str;
- use_as_buff= &tmp_value;
- }
- else if (res == &tmp_value)
- {
- if (res->append(*res2)) // Must be a blob
- goto null;
- }
- else if (res2 == &tmp_value)
- { // This can happend only 1 time
- if (tmp_value.replace(0,0,*res))
- goto null;
- res= &tmp_value;
- use_as_buff=str; // Put next arg here
- }
- else 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))
- goto null;
- res= &tmp_value;
- use_as_buff=str; // Put next arg here
- }
- else
- { // 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.
- */
- uint concat_len= res->length() + res2->length();
+ if (res != str)
+ str->copy(res->ptr(), res->length(), res->charset());
- if (tmp_value.alloced_length() < concat_len)
- {
- if (tmp_value.alloced_length() == 0)
- {
- if (tmp_value.alloc(concat_len))
- goto null;
- }
- else
- {
- uint new_len = MY_MAX(tmp_value.alloced_length() * 2, concat_len);
-
- if (tmp_value.realloc(new_len))
- goto null;
- }
- }
-
- if (tmp_value.copy(*res) || tmp_value.append(*res2))
- goto null;
-
- res= &tmp_value;
- use_as_buff=str;
- }
- is_const= 0;
+ for (uint i= 1 ; i < arg_count ; i++)
+ {
+ uint concat_len;
+ if (!(res= args[i]->val_str(&tmp_value)))
+ goto null;
+ if (res->length() == 0)
+ continue;
+ if ((concat_len= str->length() + res->length()) >
+ thd->variables.max_allowed_packet)
+ {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
+ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
+ thd->variables.max_allowed_packet);
+ goto null;
}
+ DBUG_ASSERT(!res->uses_buffer_owned_by(str));
+ DBUG_ASSERT(!str->uses_buffer_owned_by(res));
+ if (realloc_result(str, concat_len) || str->append(*res))
+ goto null;
}
- res->set_charset(collation.collation);
- return res;
+
+ str->set_charset(collation.collation);
+ return str;
null:
null_value=1;
@@ -2849,6 +2794,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(C_STRING_WITH_LEN(" using "));
+ str->append(collation.collation->csname);
+ }
+ str->append(')');
+}
+
+
String *Item_func_char::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
@@ -4414,7 +4373,7 @@ bool Item_func_dyncol_create::prepare_arguments(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= sql_strmake(res->ptr(), res->length());
@@ -4425,11 +4384,11 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg)
uint dummy_errors;
char *str=
(char *)sql_alloc((strlen= res->length() *
- my_charset_utf8_general_ci.mbmaxlen + 1));
+ DYNCOL_UTF->mbmaxlen + 1));
if (str)
{
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;
@@ -4648,9 +4607,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:
@@ -4748,7 +4708,7 @@ bool Item_dyncol_get::get_dyn_value(DYNAMIC_COLUMN_VALUE *val, String *tmp)
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();
@@ -4758,11 +4718,11 @@ bool Item_dyncol_get::get_dyn_value(DYNAMIC_COLUMN_VALUE *val, String *tmp)
uint strlen;
uint dummy_errors;
buf.str= (char *)sql_alloc((strlen= nm->length() *
- my_charset_utf8_general_ci.mbmaxlen + 1));
+ DYNCOL_UTF->mbmaxlen + 1));
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);
}
@@ -5201,7 +5161,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);
@@ -5211,6 +5170,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 95eac328a47..e19efd31229 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -230,6 +230,7 @@ public:
class Item_func_concat :public Item_str_func
{
String tmp_value;
+ 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) {}
@@ -784,6 +785,7 @@ public:
max_length= arg_count * 4;
}
const char *func_name() const { return "char"; }
+ void print(String *str, enum_query_type query_type);
};
@@ -1283,14 +1285,14 @@ public:
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;
}
};
@@ -1323,7 +1325,8 @@ public:
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 *);
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 12230014f59..7dbaf313ad9 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -447,7 +447,8 @@ bool Item_subselect::mark_as_dependent(THD *thd, st_select_lex *select,
OUTER_REF_TABLE_BIT.
*/
-void Item_subselect::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_subselect::fix_after_pullout(st_select_lex *new_parent,
+ Item **ref, bool merge)
{
recalc_used_tables(new_parent, TRUE);
parent_select= new_parent;
@@ -1153,7 +1154,8 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
/*
as far as we moved content to upper level we have to fix dependences & Co
*/
- substitution->fix_after_pullout(select_lex->outer_select(), &substitution);
+ substitution->fix_after_pullout(select_lex->outer_select(),
+ &substitution, TRUE);
}
DBUG_RETURN(false);
}
@@ -1439,6 +1441,10 @@ Item_in_subselect::Item_in_subselect(THD *thd, Item * left_exp,
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
DBUG_PRINT("info", ("in_strategy: %u", (uint)in_strategy));
left_expr_orig= left_expr= left_exp;
+ /* prepare to possible disassembling the item in convert_subq_to_sj() */
+ if (left_exp->type() == Item::ROW_ITEM)
+ left_expr_orig= new (thd->mem_root)
+ Item_row(thd, static_cast<Item_row*>(left_exp));
func= &eq_creator;
init(select_lex, new (thd->mem_root) select_exists_subselect(thd, this));
max_columns= UINT_MAX;
@@ -1462,6 +1468,10 @@ Item_allany_subselect::Item_allany_subselect(THD *thd, Item * left_exp,
{
DBUG_ENTER("Item_allany_subselect::Item_allany_subselect");
left_expr_orig= left_expr= left_exp;
+ /* prepare to possible disassembling the item in convert_subq_to_sj() */
+ if (left_exp->type() == Item::ROW_ITEM)
+ left_expr_orig= new (thd->mem_root)
+ Item_row(thd, static_cast<Item_row*>(left_exp));
func= func_creator(all_arg);
init(select_lex, new (thd->mem_root) select_exists_subselect(thd, this));
max_columns= 1;
@@ -2118,7 +2128,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)
{
@@ -2926,7 +2939,7 @@ bool Item_exists_subselect::exists2in_processor(uchar *opt_arg)
goto out;
}
}
- outer_exp->fix_after_pullout(unit->outer_select(), &outer_exp);
+ outer_exp->fix_after_pullout(unit->outer_select(), &outer_exp, FALSE);
outer_exp->update_used_tables();
outer.push_back(outer_exp, thd->mem_root);
}
@@ -3307,10 +3320,11 @@ err:
}
-void Item_in_subselect::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_in_subselect::fix_after_pullout(st_select_lex *new_parent,
+ Item **ref, bool merge)
{
- left_expr->fix_after_pullout(new_parent, &left_expr);
- Item_subselect::fix_after_pullout(new_parent, ref);
+ left_expr->fix_after_pullout(new_parent, &left_expr, merge);
+ Item_subselect::fix_after_pullout(new_parent, ref, merge);
used_tables_cache |= left_expr->used_tables();
}
@@ -5476,7 +5490,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 009aff5ed80..424ea6f0512 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -169,7 +169,7 @@ public:
}
bool fix_fields(THD *thd, Item **ref);
bool mark_as_dependent(THD *thd, st_select_lex *select, Item *item);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ 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);
virtual bool exec();
/*
@@ -607,7 +607,7 @@ public:
virtual void print(String *str, enum_query_type query_type);
bool fix_fields(THD *thd, Item **ref);
void fix_length_and_dec();
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
bool const_item() const
{
return Item_subselect::const_item() && left_expr->const_item();
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 1a4fe3b0ccc..0e2e9f0795d 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -3594,7 +3594,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_timefunc.cc b/sql/item_timefunc.cc
index fa74a1903da..4a94c3a5f89 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1793,9 +1793,18 @@ overflow:
ltime->hour= TIME_MAX_HOUR+1;
check_time_range(ltime, decimals, &unused);
- make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
- err->ptr(), err->length(),
- MYSQL_TIMESTAMP_TIME, NullS);
+ if (!err)
+ {
+ ErrConvInteger err2(sec, unsigned_flag);
+ make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
+ &err2, MYSQL_TIMESTAMP_TIME, NullS);
+ }
+ else
+ {
+ ErrConvString err2(err);
+ make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
+ &err2, MYSQL_TIMESTAMP_TIME, NullS);
+ }
return 0;
}
@@ -2396,7 +2405,7 @@ String *Item_char_typecast::copy(String *str, CHARSET_INFO *strcs)
if (copier.copy_with_warn(cast_cs, &tmp_value, strcs,
str->ptr(), str->length(), cast_length))
{
- null_value= 1; // In strict mode: malformed data or could not convert
+ null_value= 1; // EOM
return 0;
}
check_truncation_with_warn(str, copier.source_end_pos() - str->ptr());
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 0e9329d501c..927ce12f079 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -502,8 +502,16 @@ public:
{ return val_decimal_from_date(decimal_value); }
Field *create_field_for_create_select(TABLE *table)
{ return tmp_table_field_from_field_type(table, false, false); }
+#if MARIADB_VERSION_ID > 100300
+#error This code should be removed in 10.3, to use the derived save_in_field()
+#else
int save_in_field(Field *field, bool no_conversions)
- { return save_date_in_field(field); }
+ {
+ return field_type() == MYSQL_TYPE_TIME ?
+ save_time_in_field(field) :
+ save_date_in_field(field);
+ }
+#endif
void fix_length_and_dec();
};
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index 0741da155ac..c9e6df52de9 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -2702,7 +2702,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;
@@ -2730,7 +2730,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 3758025fc90..92a8f757822 100644
--- a/sql/item_xmlfunc.h
+++ b/sql/item_xmlfunc.h
@@ -67,6 +67,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)
diff --git a/sql/key.cc b/sql/key.cc
index 1b00e951de0..523ddf98640 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -65,7 +65,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 +85,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 */
diff --git a/sql/lex.h b/sql/lex.h
index 85bd20a5f37..6a1cb6653e9 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -179,6 +179,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)},
diff --git a/sql/log.cc b/sql/log.cc
index e36f974709b..29f8c5639cf 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -4947,7 +4947,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.
@@ -5544,7 +5592,37 @@ 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);
+
+ IO_CACHE *file=
+ cache_mngr->get_binlog_cache_log(use_trans_cache(this, true));
+ Log_event_writer writer(file);
+ 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);
/*
@@ -5826,7 +5904,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 {
@@ -5878,6 +5956,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);
@@ -6622,6 +6706,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.
@@ -6631,9 +6829,10 @@ 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;
@@ -6641,7 +6840,14 @@ int MYSQL_BIN_LOG::rotate_and_purge(bool force_rotate)
//todo: fix the macro def and restore safe_mutex_assert_not_owner(&LOCK_log);
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
@@ -7043,8 +7249,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;
@@ -9322,8 +9535,10 @@ int TC_LOG_BINLOG::open(const char *opt_name)
if (using_heuristic_recover())
{
+ mysql_mutex_lock(&LOCK_log);
/* generate a new binlog to mask a corrupted one */
open(opt_name, LOG_BIN, 0, 0, WRITE_CACHE, max_binlog_size, 0, TRUE);
+ mysql_mutex_unlock(&LOCK_log);
cleanup();
return 1;
}
@@ -9365,11 +9580,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,
@@ -9442,6 +9665,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;
@@ -9643,6 +9869,8 @@ binlog_background_thread(void *arg __attribute__((unused)))
{
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);
@@ -10215,6 +10443,73 @@ 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, 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;
+}
+
struct st_mysql_storage_engine binlog_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
diff --git a/sql/log.h b/sql/log.h
index bf076fae31d..2118bd7a059 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -559,7 +559,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
@@ -755,7 +761,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.
@@ -1165,4 +1171,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 92885344cd6..81bc683625f 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -2469,8 +2469,8 @@ log_event_print_value(IO_CACHE *file, const uchar *ptr,
case 2:
{
strmake(typestr, "ENUM(2 bytes)", typestr_length);
- if (!ptr)
- goto return_null;
+ if (!ptr)
+ goto return_null;
int32 i32= uint2korr(ptr);
my_b_printf(file, "%d", i32);
@@ -4184,8 +4184,13 @@ bool test_if_equal_repl_errors(int expected_error, int actual_error)
return 1;
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;
@@ -7857,21 +7862,6 @@ User_var_log_event(const char* buf, uint event_len,
we keep the flags set to UNDEF_F.
*/
uint bytes_read= ((val + val_len) - buf_start);
-#ifndef DBUG_OFF
- bool old_pre_checksum_fd= description_event->is_version_before_checksum(
- &description_event->server_version_split);
-#endif
- DBUG_ASSERT((bytes_read == data_written -
- (old_pre_checksum_fd ||
- (description_event->checksum_alg ==
- BINLOG_CHECKSUM_ALG_OFF)) ?
- 0 : BINLOG_CHECKSUM_LEN)
- ||
- (bytes_read == data_written -1 -
- (old_pre_checksum_fd ||
- (description_event->checksum_alg ==
- BINLOG_CHECKSUM_ALG_OFF)) ?
- 0 : BINLOG_CHECKSUM_LEN));
if ((data_written - bytes_read) > 0)
{
flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
diff --git a/sql/mf_iocache_encr.cc b/sql/mf_iocache_encr.cc
index ae314d826a0..149e6feb605 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);
+ size_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);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 97d63d99458..0de9d7a9f0b 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -3542,8 +3542,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)
{
@@ -3551,17 +3549,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)
@@ -3617,14 +3604,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
@@ -3635,7 +3616,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);
@@ -4115,7 +4096,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");
return 1;
}
@@ -5747,9 +5728,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
}
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index ed283863d31..6d200f55655 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -58,9 +58,11 @@
#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(...) {}
static int inline EXTRA_DEBUG_fflush(...) { return 0; }
+#define EXTRA_DEBUG_ASSERT(X) do {} while(0)
#endif
#ifdef MYSQL_SERVER
#define MYSQL_SERVER_my_error my_error
@@ -1072,7 +1074,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
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 1c41aa79af2..0315b91b8be 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -2081,7 +2081,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 */
@@ -8338,6 +8338,34 @@ bool sel_trees_can_be_ored(RANGE_OPT_PARAM* param,
}
/*
+ Check whether the key parts inf_init..inf_end-1 of one index can compose
+ an infix for the key parts key_init..key_end-1 of another index
+*/
+
+static
+bool is_key_infix(KEY_PART *key_init, KEY_PART *key_end,
+ KEY_PART *inf_init, KEY_PART *inf_end)
+{
+ KEY_PART *key_part, *inf_part;
+ for (key_part= key_init; key_part < key_end; key_part++)
+ {
+ if (key_part->field->eq(inf_init->field))
+ break;
+ }
+ if (key_part == key_end)
+ return false;
+ for (key_part++, inf_part= inf_init + 1;
+ key_part < key_end && inf_part < inf_end;
+ key_part++, inf_part++)
+ {
+ if (!key_part->field->eq(inf_part->field))
+ return false;
+ }
+ return inf_part == inf_end;
+}
+
+
+/*
Check whether range parts of two trees must be ored for some indexes
SYNOPSIS
@@ -8393,14 +8421,9 @@ bool sel_trees_must_be_ored(RANGE_OPT_PARAM* param,
KEY_PART *key2_init= param->key[idx2]+tree2->keys[idx2]->part;
KEY_PART *key2_end= param->key[idx2]+tree2->keys[idx2]->max_part_no;
- KEY_PART *part1, *part2;
- for (part1= key1_init, part2= key2_init;
- part1 < key1_end && part2 < key2_end;
- part1++, part2++)
- {
- if (!part1->field->eq(part2->field))
- DBUG_RETURN(FALSE);
- }
+ if (!is_key_infix(key1_init, key1_end, key2_init, key2_end) &&
+ !is_key_infix(key2_init, key2_end, key1_init, key1_end))
+ DBUG_RETURN(FALSE);
}
}
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 3680dce8117..d7371fa7e3f 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -1612,6 +1612,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
sj-nest.
*/
st_select_lex *subq_lex= subq_pred->unit->first_select();
+ DBUG_ASSERT(subq_lex->next_select() == NULL);
nested_join->join_list.empty();
List_iterator_fast<TABLE_LIST> li(subq_lex->top_join_list);
TABLE_LIST *tl;
@@ -1664,7 +1665,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
{
tl->jtbm_table_no= table_no;
Item *dummy= tl->jtbm_subselect;
- tl->jtbm_subselect->fix_after_pullout(parent_lex, &dummy);
+ tl->jtbm_subselect->fix_after_pullout(parent_lex, &dummy, true);
DBUG_ASSERT(dummy == tl->jtbm_subselect);
}
SELECT_LEX *old_sl= tl->select_lex;
@@ -1715,7 +1716,8 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
if (subq_pred->left_expr->cols() == 1)
{
- nested_join->sj_outer_expr_list.push_back(subq_pred->left_expr,
+ /* add left = select_list_element */
+ nested_join->sj_outer_expr_list.push_back(&subq_pred->left_expr,
thd->mem_root);
/*
Create Item_func_eq. Note that
@@ -1729,26 +1731,62 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
Item_func_eq *item_eq=
new (thd->mem_root) Item_func_eq(thd, subq_pred->left_expr_orig,
subq_lex->ref_pointer_array[0]);
+ if (!item_eq)
+ DBUG_RETURN(TRUE);
if (subq_pred->left_expr_orig != subq_pred->left_expr)
thd->change_item_tree(item_eq->arguments(), subq_pred->left_expr);
item_eq->in_equality_no= 0;
sj_nest->sj_on_expr= and_items(thd, sj_nest->sj_on_expr, item_eq);
}
- else
+ else if (subq_pred->left_expr->type() == Item::ROW_ITEM)
{
+ /*
+ disassemple left expression and add
+ left1 = select_list_element1 and left2 = select_list_element2 ...
+ */
for (uint i= 0; i < subq_pred->left_expr->cols(); i++)
{
- nested_join->sj_outer_expr_list.push_back(subq_pred->left_expr->
- element_index(i),
+ nested_join->sj_outer_expr_list.push_back(subq_pred->left_expr->addr(i),
thd->mem_root);
- Item_func_eq *item_eq=
+ Item_func_eq *item_eq=
new (thd->mem_root)
- Item_func_eq(thd, subq_pred->left_expr->element_index(i),
+ Item_func_eq(thd, subq_pred->left_expr_orig->element_index(i),
subq_lex->ref_pointer_array[i]);
+ if (!item_eq)
+ DBUG_RETURN(TRUE);
+ DBUG_ASSERT(subq_pred->left_expr->element_index(i)->fixed);
+ if (subq_pred->left_expr_orig->element_index(i) !=
+ subq_pred->left_expr->element_index(i))
+ thd->change_item_tree(item_eq->arguments(),
+ subq_pred->left_expr->element_index(i));
item_eq->in_equality_no= i;
sj_nest->sj_on_expr= and_items(thd, sj_nest->sj_on_expr, item_eq);
}
}
+ else
+ {
+ /*
+ add row operation
+ left = (select_list_element1, select_list_element2, ...)
+ */
+ Item_row *row= new (thd->mem_root) Item_row(thd, subq_lex->pre_fix);
+ /* fix fields on subquery was call so they should be the same */
+ DBUG_ASSERT(subq_pred->left_expr->cols() == row->cols());
+ if (!row)
+ DBUG_RETURN(TRUE);
+ nested_join->sj_outer_expr_list.push_back(&subq_pred->left_expr);
+ Item_func_eq *item_eq=
+ new (thd->mem_root) Item_func_eq(thd, subq_pred->left_expr_orig, row);
+ if (!item_eq)
+ DBUG_RETURN(TRUE);
+ for (uint i= 0; i < row->cols(); i++)
+ {
+ if (row->element_index(i) != subq_lex->ref_pointer_array[i])
+ thd->change_item_tree(row->addr(i), subq_lex->ref_pointer_array[i]);
+ }
+ item_eq->in_equality_no= 0;
+ sj_nest->sj_on_expr= and_items(thd, sj_nest->sj_on_expr, item_eq);
+ }
/*
Fix the created equality and AND
@@ -1768,7 +1806,8 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
Walk through sj nest's WHERE and ON expressions and call
item->fix_table_changes() for all items.
*/
- sj_nest->sj_on_expr->fix_after_pullout(parent_lex, &sj_nest->sj_on_expr);
+ sj_nest->sj_on_expr->fix_after_pullout(parent_lex, &sj_nest->sj_on_expr,
+ TRUE);
fix_list_after_tbl_changes(parent_lex, &sj_nest->nested_join->join_list);
@@ -1927,7 +1966,7 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
DBUG_ASSERT(parent_join->table_count < MAX_TABLES);
Item *conds= hash_sj_engine->semi_join_conds;
- conds->fix_after_pullout(parent_lex, &conds);
+ conds->fix_after_pullout(parent_lex, &conds, TRUE);
DBUG_EXECUTE("where", print_where(conds,"SJ-EXPR", QT_ORDINARY););
@@ -1979,7 +2018,7 @@ void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List<TABLE_LIST> *tlist)
while ((table= it++))
{
if (table->on_expr)
- table->on_expr->fix_after_pullout(new_parent, &table->on_expr);
+ table->on_expr->fix_after_pullout(new_parent, &table->on_expr, TRUE);
if (table->nested_join)
fix_list_after_tbl_changes(new_parent, &table->nested_join->join_list);
}
@@ -2665,7 +2704,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, prev_dups_producing_tables,
+ prev_sjm_lookup_tables;
if (idx == join->const_tables)
dups_producing_tables= 0;
@@ -2676,7 +2716,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;
if (idx == join->const_tables)
{
/* First table, initialize pickers */
@@ -2728,23 +2768,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
{
@@ -3302,8 +3373,8 @@ void restore_prev_sj_state(const table_map remaining_tables,
ulonglong get_bound_sj_equalities(TABLE_LIST *sj_nest,
table_map remaining_tables)
{
- List_iterator<Item> li(sj_nest->nested_join->sj_outer_expr_list);
- Item *item;
+ List_iterator<Item_ptr> li(sj_nest->nested_join->sj_outer_expr_list);
+ Item **item;
uint i= 0;
ulonglong res= 0;
while ((item= li++))
@@ -3314,7 +3385,7 @@ ulonglong get_bound_sj_equalities(TABLE_LIST *sj_nest,
class and see if there is an element that is bound?
(this is an optional feature)
*/
- if (!(item->used_tables() & remaining_tables))
+ if (!(item[0]->used_tables() & remaining_tables))
{
res |= 1ULL << i;
}
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index cd0ab970d76..14f301e2d85 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -39,9 +39,6 @@ partition_info *partition_info::get_clone(THD *thd)
{
MEM_ROOT *mem_root= thd->mem_root;
DBUG_ENTER("partition_info::get_clone");
-
- if (!this)
- DBUG_RETURN(NULL);
List_iterator<partition_element> part_it(partitions);
partition_element *part;
partition_info *clone= new (mem_root) partition_info();
@@ -2746,6 +2743,24 @@ end:
DBUG_RETURN(result);
}
+
+bool partition_info::error_if_requires_values() const
+{
+ switch (part_type) {
+ case NOT_A_PARTITION:
+ case HASH_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;
+}
+
+
/**
Fix partition data from parser.
@@ -2835,6 +2850,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);
for (j= 0; j < num_elements; j++)
diff --git a/sql/partition_info.h b/sql/partition_info.h
index ec7374b3e3e..b271ff08e82 100644
--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -368,6 +368,7 @@ public:
bool *prune_needs_default_values,
MY_BITMAP *used_partitions);
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(handler *file, HA_CREATE_INFO *info,
diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc
index 51df8f1a789..7b1acf17ef5 100644
--- a/sql/rpl_gtid.cc
+++ b/sql/rpl_gtid.cc
@@ -26,7 +26,7 @@
#include "key.h"
#include "rpl_gtid.h"
#include "rpl_rli.h"
-
+#include "log_event.h"
const LEX_STRING rpl_gtid_slave_state_table_name=
{ C_STRING_WITH_LEN("gtid_slave_pos") };
@@ -1728,6 +1728,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()
{
diff --git a/sql/rpl_gtid.h b/sql/rpl_gtid.h
index ece6effbef6..79d566bddbf 100644
--- a/sql/rpl_gtid.h
+++ b/sql/rpl_gtid.h
@@ -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.
@@ -256,6 +264,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/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index d335b0b420b..52be5e14e14 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -1732,32 +1732,32 @@ 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: normální ukonÄení\n"
- dan "%s: Normal nedlukning\n"
- nla "%s: Normaal afgesloten \n"
- eng "%s: Normal shutdown\n"
- est "%s: MariaDB lõpetas\n"
- fre "%s: Arrêt normal du serveur\n"
- ger "%s: Normal heruntergefahren\n"
- greek "%s: Φυσιολογική διαδικασία shutdown\n"
- hun "%s: Normal leallitas\n"
- ita "%s: Shutdown normale\n"
- jpn "%s: 通常シャットダウン\n"
- kor "%s: ì •ìƒì ì¸ shutdown\n"
- nor "%s: Normal avslutning\n"
- norwegian-ny "%s: Normal nedkopling\n"
- pol "%s: Standardowe zakończenie działania\n"
- por "%s: 'Shutdown' normal\n"
- rum "%s: Terminare normala\n"
- rus "%s: ÐšÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ Ð¾Ñтановка\n"
- serbian "%s: Normalno gašenje\n"
- slo "%s: normálne ukonÄenie\n"
- spa "%s: Apagado normal\n"
- swe "%s: Normal avslutning\n"
- ukr "%s: Ðормальне завершеннÑ\n"
+ cze "%s: norm-Bální ukonÄení"
+ dan "%s: Normal nedlukning"
+ nla "%s: Normaal afgesloten"
+ eng "%s: Normal shutdown"
+ est "%s: MariaDB lõpetas"
+ fre "%s: Arrêt normal du serveur"
+ ger "%s: Normal heruntergefahren"
+ greek "%s: Φυσιολογική διαδικασία shutdown"
+ hun "%s: Normal leallitas"
+ ita "%s: Shutdown normale"
+ jpn "%s: 通常シャットダウン"
+ kor "%s: ì •ìƒì ì¸ shutdown"
+ nor "%s: Normal avslutning"
+ norwegian-ny "%s: Normal nedkopling"
+ pol "%s: Standardowe zakończenie działania"
+ por "%s: 'Shutdown' normal"
+ rum "%s: Terminare normala"
+ rus "%s: ÐšÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ Ð¾Ñтановка"
+ serbian "%s: Normalno gašenje"
+ slo "%s: normálne ukonÄenie"
+ spa "%s: Apagado normal"
+ swe "%s: Normal avslutning"
+ ukr "%s: Ðормальне завершеннÑ"
ER_GOT_SIGNAL
cze "%s: pÅ™ijat signal %d, konÄím\n"
dan "%s: Fangede signal %d. Afslutter!!\n"
@@ -7118,7 +7118,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"
diff --git a/sql/slave.cc b/sql/slave.cc
index db1c3305b98..da394ff711e 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -3188,7 +3188,6 @@ static int init_slave_thread(THD* thd, Master_info *mi,
thd->variables.sql_log_slow= opt_log_slow_slave_statements;
thd->variables.log_slow_filter= global_system_variables.log_slow_filter;
set_slave_thread_options(thd);
- thd->client_capabilities = CLIENT_LOCAL_FILES;
mysql_mutex_lock(&LOCK_thread_count);
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
mysql_mutex_unlock(&LOCK_thread_count);
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index bf25d45ffaf..8bf78d97670 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -141,7 +141,6 @@ sp_get_item_value(THD *thd, Item *item, String *str)
case DECIMAL_RESULT:
if (item->field_type() != MYSQL_TYPE_BIT)
return item->val_str(str);
- else {/* Bit type is handled as binary string */}
/* fall through */
case STRING_RESULT:
{
@@ -841,7 +840,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);
@@ -1122,7 +1121,7 @@ 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;
@@ -1225,6 +1224,7 @@ 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.
@@ -1372,6 +1372,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
DBUG_ASSERT(thd->change_list.is_empty());
old_change_list.move_elements_to(&thd->change_list);
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;
@@ -2101,7 +2102,6 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
if (!err_status)
{
err_status= execute(thd, TRUE);
- DBUG_PRINT("info", ("execute returned %d", (int) err_status));
}
if (save_log_general)
@@ -2207,7 +2207,7 @@ sp_head::reset_lex(THD *thd)
if (sublex == 0)
DBUG_RETURN(TRUE);
- thd->lex= sublex;
+ thd->lex= thd->stmt_lex= sublex;
(void)m_lex.push_front(oldlex);
/* Reset most stuff. */
@@ -2519,10 +2519,18 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access)
*full_access= ((!check_table_access(thd, SELECT_ACL, &tables, FALSE,
1, TRUE) &&
(tables.grant.privilege & SELECT_ACL) != 0) ||
+ /* Check if user owns the routine. */
(!strcmp(sp->m_definer_user.str,
thd->security_ctx->priv_user) &&
!strcmp(sp->m_definer_host.str,
- thd->security_ctx->priv_host)));
+ thd->security_ctx->priv_host)) ||
+ /* Check if current role or any of the sub-granted roles
+ own the routine. */
+ (sp->m_definer_host.length == 0 &&
+ (!strcmp(sp->m_definer_user.str,
+ thd->security_ctx->priv_role) ||
+ check_role_is_granted(thd->security_ctx->priv_role, NULL,
+ sp->m_definer_user.str))));
if (!*full_access)
return check_some_routine_access(thd, sp->m_db.str, sp->m_name.str,
sp->m_type == TYPE_ENUM_PROCEDURE);
@@ -2945,7 +2953,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
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());
@@ -4307,4 +4315,3 @@ sp_add_to_query_tables(THD *thd, LEX *lex,
lex->add_to_query_tables(table);
return table;
}
-
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index f72614790e1..07b0715dc84 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -634,9 +634,6 @@ bool ROLE_GRANT_PAIR::init(MEM_ROOT *mem, char *username,
char *hostname, char *rolename,
bool with_admin_option)
{
- if (!this)
- return true;
-
size_t uname_l = safe_strlen(username);
size_t hname_l = safe_strlen(hostname);
size_t rname_l = safe_strlen(rolename);
@@ -2285,37 +2282,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;
}
@@ -3749,9 +3751,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 */
@@ -5654,9 +5668,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)
@@ -6746,11 +6763,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;
@@ -6823,7 +6839,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);
@@ -8473,6 +8489,17 @@ void get_mqh(const char *user, const char *host, USER_CONN *uc)
mysql_mutex_unlock(&acl_cache->lock);
}
+static int check_role_is_granted_callback(ACL_USER_BASE *grantee, void *data)
+{
+ LEX_CSTRING *rolename= static_cast<LEX_CSTRING *>(data);
+ if (rolename->length == grantee->user.length &&
+ !strcmp(rolename->str, grantee->user.str))
+ return -1; // End search, we've found our role.
+
+ /* Keep looking, we haven't found our role yet. */
+ return 0;
+}
+
/*
Initialize a TABLE_LIST array and open grant tables
@@ -9499,13 +9526,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].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)
@@ -10452,7 +10479,6 @@ bool check_grant(THD *, ulong, TABLE_LIST *, bool, uint, bool)
}
#endif /*NO_EMBEDDED_ACCESS_CHECKS */
-
SHOW_VAR acl_statistics[] = {
#ifndef NO_EMBEDDED_ACCESS_CHECKS
{"column_grants", (char*)show_column_grants, SHOW_SIMPLE_FUNC},
@@ -10468,6 +10494,43 @@ SHOW_VAR acl_statistics[] = {
{NullS, NullS, SHOW_LONG},
};
+/* Check if a role is granted to a user/role. We traverse the role graph
+ and return true if we find a match.
+
+ hostname == NULL means we are looking for a role as a starting point,
+ otherwise a user.
+*/
+bool check_role_is_granted(const char *username,
+ const char *hostname,
+ const char *rolename)
+{
+ DBUG_ENTER("check_role_is_granted");
+ bool result= false;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ ACL_USER_BASE *root;
+ mysql_mutex_lock(&acl_cache->lock);
+ if (hostname)
+ root= find_user_exact(username, hostname);
+ else
+ root= find_acl_role(username);
+
+ LEX_CSTRING role_lex;
+ role_lex.str= rolename;
+ role_lex.length= strlen(rolename);
+
+ if (root && /* No grantee, nothing to search. */
+ traverse_role_graph_down(root, &role_lex, check_role_is_granted_callback,
+ NULL) == -1)
+ {
+ /* We have found the role during our search. */
+ result= true;
+ }
+
+ /* We haven't found the role or we had no initial grantee to start from. */
+ mysql_mutex_unlock(&acl_cache->lock);
+#endif
+ DBUG_RETURN(result);
+}
int fill_schema_enabled_roles(THD *thd, TABLE_LIST *tables, COND *cond)
{
@@ -12839,4 +12902,3 @@ maria_declare_plugin(mysql_password)
MariaDB_PLUGIN_MATURITY_STABLE /* Maturity */
}
maria_declare_plugin_end;
-
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index 0893504b72d..c2ad9a649e5 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -406,6 +406,14 @@ int acl_set_default_role(THD *thd, const char *host, const char *user,
extern SHOW_VAR acl_statistics[];
+/* Check if a role is granted to a user/role.
+
+ If hostname == NULL, search for a role as the starting grantee.
+*/
+bool check_role_is_granted(const char *username,
+ const char *hostname,
+ const char *rolename);
+
#ifndef DBUG_OFF
extern ulong role_global_merges, role_db_merges, role_table_merges,
role_column_merges, role_routine_merges;
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index 1f4426f2043..98584ec4630 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -66,7 +66,6 @@ static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list)
if (thd->get_stmt_da()->is_ok())
thd->get_stmt_da()->reset_diagnostics_area();
table_list->table= NULL;
- result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK;
DBUG_RETURN(result_code);
}
@@ -664,8 +663,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. */
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 1aaeb2a5584..01f40bb2247 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -7853,13 +7853,15 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
bool setup_fields(THD *thd, Item **ref_pointer_array,
List<Item> &fields, enum_mark_columns mark_used_columns,
- List<Item> *sum_func_list, bool allow_sum_func)
+ 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;
nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
List_iterator<Item> it(fields);
bool save_is_item_list_lookup;
+ bool make_pre_fix= (pre_fix && (pre_fix->elements == 0));
DBUG_ENTER("setup_fields");
DBUG_PRINT("enter", ("ref_pointer_array: %p", ref_pointer_array));
@@ -7906,6 +7908,9 @@ bool setup_fields(THD *thd, Item **ref_pointer_array,
thd->lex->current_select->cur_pos_in_select_list= 0;
while ((item= it++))
{
+ if (make_pre_fix)
+ pre_fix->push_back(item, thd->stmt_arena->mem_root);
+
if ((!item->fixed && item->fix_fields(thd, it.ref())) ||
(item= *(it.ref()))->check_cols(1))
{
@@ -9210,7 +9215,16 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order)
DBUG_PRINT("info",("Performing FULLTEXT search"));
while ((ifm=li++))
- ifm->init_search(thd, no_order);
+#if MYSQL_VERSION_ID < 100213
+ 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
+#endif
+ ifm->init_search(thd, no_order);
}
return 0;
}
diff --git a/sql/sql_base.h b/sql/sql_base.h
index 9e37a43aab8..c73ea374507 100644
--- a/sql/sql_base.h
+++ b/sql/sql_base.h
@@ -174,7 +174,8 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
List<Item> *sum_func_list, uint wild_num);
bool setup_fields(THD *thd, Item** ref_pointer_array,
List<Item> &item, enum_mark_columns mark_used_columns,
- List<Item> *sum_func_list, bool allow_sum_func);
+ List<Item> *sum_func_list, List<Item> *pre_fix,
+ bool allow_sum_func);
void unfix_fields(List<Item> &items);
bool fill_record(THD * thd, TABLE *table_arg, List<Item> &fields,
List<Item> &values, bool ignore_errors);
@@ -405,7 +406,7 @@ inline bool setup_fields_with_no_wrap(THD *thd, Item **ref_pointer_array,
bool res;
thd->lex->select_lex.no_wrap_view_item= TRUE;
res= setup_fields(thd, ref_pointer_array, item, mark_used_columns,
- sum_func_list, allow_sum_func);
+ sum_func_list, NULL, allow_sum_func);
thd->lex->select_lex.no_wrap_view_item= FALSE;
return res;
}
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 66ac2449519..df6c7c35e5a 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1187,7 +1187,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)
@@ -1552,6 +1556,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);
}
@@ -1788,7 +1794,7 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length)
sql++;
continue;
}
- /* fall trough */
+ /* fall through */
default:
break;
}
@@ -2541,6 +2547,7 @@ void Query_cache::init()
*/
if (global_system_variables.query_cache_type == 0)
{
+ m_cache_status= DISABLE_REQUEST;
free_cache();
m_cache_status= DISABLED;
}
@@ -2749,13 +2756,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)
@@ -2763,6 +2774,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);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index ce1f69b76a9..e3b7b31b01d 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -236,7 +236,7 @@ bool Foreign_key::validate(List<Create_field> &table_fields)
sql_field->field_name)) {}
if (!sql_field)
{
- my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name);
+ my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
DBUG_RETURN(TRUE);
}
if (type == Key::FOREIGN_KEY && sql_field->vcol_info)
@@ -2657,6 +2657,8 @@ void THD::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.
@@ -2669,12 +2671,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;
}
/**
@@ -2696,6 +2699,9 @@ void THD::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++))
{
@@ -2705,6 +2711,7 @@ 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;
}
@@ -2712,13 +2719,13 @@ void THD::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;
}
@@ -3647,7 +3654,7 @@ void Statement::set_statement(Statement *stmt)
{
id= stmt->id;
mark_used_columns= stmt->mark_used_columns;
- lex= stmt->lex;
+ stmt_lex= lex= stmt->lex;
query_string= stmt->query_string;
}
@@ -4858,11 +4865,14 @@ extern "C" int thd_non_transactional_update(const MYSQL_THD thd)
extern "C" int thd_binlog_format(const MYSQL_THD thd)
{
- if (((WSREP(thd) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()) &&
- thd->variables.option_bits & OPTION_BIN_LOG)
+ if (WSREP(thd))
+ {
+ /* for wsrep binlog format is meaningful also when binlogging is off */
return (int) thd->wsrep_binlog_format();
- else
- return BINLOG_FORMAT_UNSPEC;
+ }
+ if (mysql_bin_log.is_open() && (thd->variables.option_bits & OPTION_BIN_LOG))
+ return (int) thd->variables.binlog_format;
+ return BINLOG_FORMAT_UNSPEC;
}
extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all)
diff --git a/sql/sql_class.h b/sql/sql_class.h
index d8fc9303949..91030145022 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1028,6 +1028,21 @@ public:
LEX_STRING 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.
@@ -1177,6 +1192,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);
@@ -1549,6 +1587,29 @@ public:
/**
+ Implements the trivial error handler which counts errors as they happen.
+*/
+
+class Counting_error_handler : public Internal_error_handler
+{
+public:
+ int errors;
+ bool handle_condition(THD *thd,
+ uint sql_errno,
+ const char* sqlstate,
+ Sql_condition::enum_warning_level level,
+ const char* msg,
+ Sql_condition ** cond_hdl)
+ {
+ if (level == Sql_condition::WARN_LEVEL_ERROR)
+ errors++;
+ return false;
+ }
+ Counting_error_handler() : errors(0) {}
+};
+
+
+/**
This class is an internal error handler implementation for
DROP TABLE statements. The thing is that there may be warnings during
execution of these statements, which should not be exposed to the user.
@@ -2667,7 +2728,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
@@ -3376,10 +3436,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
@@ -5106,7 +5170,7 @@ public:
{
DBUG_ENTER("unique_add");
DBUG_PRINT("info", ("tree %u - %lu", tree.elements_in_tree, max_elements));
- if (!(tree.flag & TREE_ONLY_DUPS) &&
+ if (!(tree.flag & TREE_ONLY_DUPS) &&
tree.elements_in_tree >= max_elements && flush())
DBUG_RETURN(1);
DBUG_RETURN(!tree_insert(&tree, ptr, 0, tree.custom_arg));
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index ac5b6ab29a2..d3ef245209d 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -314,13 +314,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
}
@@ -479,24 +475,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,
@@ -513,12 +501,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,
@@ -535,13 +520,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);
}
diff --git a/sql/sql_const.h b/sql/sql_const.h
index 3e23fc25bef..946cf13e2ae 100644
--- a/sql/sql_const.h
+++ b/sql/sql_const.h
@@ -45,7 +45,18 @@
#define MAX_MBWIDTH 3 /* Max multibyte sequence */
#define MAX_FILENAME_MBWIDTH 5
#define MAX_FIELD_CHARLENGTH 255
-#define MAX_FIELD_VARCHARLENGTH 65535
+/*
+ In MAX_FIELD_VARCHARLENGTH we reserve extra bytes for the overhead:
+ - 2 bytes for the length
+ - 1 byte for NULL bits
+ to avoid the "Row size too large" error for these three corner definitions:
+ CREATE TABLE t1 (c VARBINARY(65533));
+ CREATE TABLE t1 (c VARBINARY(65534));
+ CREATE TABLE t1 (c VARBINARY(65535));
+ Like VARCHAR(65536), they will be converted to BLOB automatically
+ in non-sctict mode.
+*/
+#define MAX_FIELD_VARCHARLENGTH (65535-2-1)
#define MAX_FIELD_BLOBLENGTH UINT_MAX32 /* cf field_blob::get_length() */
#define CONVERT_IF_BIGGER_TO_BLOB 512 /* Threshold *in characters* */
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index a8c5569ba4a..69781b5def3 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -211,7 +211,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.
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index c1011410970..bc067b667a6 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -766,7 +766,7 @@ send_nothing_and_leave:
DELETE_ACL, SELECT_ACL, TRUE))
DBUG_RETURN(TRUE);
if ((wild_num && setup_wild(thd, table_list, field_list, NULL, wild_num)) ||
- setup_fields(thd, NULL, field_list, MARK_COLUMNS_READ, NULL, 0) ||
+ setup_fields(thd, NULL, field_list, MARK_COLUMNS_READ, NULL, NULL, 0) ||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
setup_ftfuncs(select_lex))
DBUG_RETURN(TRUE);
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index d8386666de4..b29e676bfc7 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -362,9 +362,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 ? derived->alias : "<NULL>"),
+ derived->get_unit()));
if (derived->merged)
+ {
+
+ DBUG_PRINT("info", ("Irreversibly merged: exit"));
DBUG_RETURN(FALSE);
+ }
if (dt_select->uncacheable & UNCACHEABLE_RAND)
{
@@ -466,7 +473,8 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
// Update used tables cache according to new table map
if (derived->on_expr)
{
- derived->on_expr->fix_after_pullout(parent_lex, &derived->on_expr);
+ derived->on_expr->fix_after_pullout(parent_lex, &derived->on_expr,
+ TRUE);
fix_list_after_tbl_changes(parent_lex, &derived->nested_join->join_list);
}
}
@@ -509,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 ? derived->alias : "<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",
@@ -520,6 +530,8 @@ bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived)
derived->merge_underlying_list != 0));
if (derived->merged_for_insert)
DBUG_RETURN(FALSE);
+ if (derived->init_derived(thd, FALSE))
+ DBUG_RETURN(TRUE);
if (derived->is_materialized_derived())
DBUG_RETURN(mysql_derived_prepare(thd, lex, derived));
if ((thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
@@ -537,8 +549,6 @@ bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived)
DBUG_ASSERT(derived->table);
}
}
- else
- derived->table= derived->merge_underlying_list->table;
DBUG_RETURN(FALSE);
}
@@ -565,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 ? derived->alias : "<NULL>"),
+ derived->get_unit()));
// Skip already prepared views/DT
if (!unit || unit->prepared)
@@ -636,7 +648,9 @@ 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 0x%lx", (ulong) unit));
+ DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
+ (derived->alias ? derived->alias : "<NULL>"),
+ unit));
// Skip already prepared views/DT
if (!unit || unit->prepared ||
@@ -667,6 +681,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_union(thd)))
@@ -793,6 +818,14 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived)
bool res= FALSE;
DBUG_ENTER("mysql_derived_optimize");
+ DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
+ (derived->alias ? derived->alias : "<NULL>"),
+ derived->get_unit()));
+ if (derived->merged)
+ {
+ DBUG_PRINT("info", ("Irreversibly merged: exit"));
+ DBUG_RETURN(FALSE);
+ }
if (unit->optimized)
DBUG_RETURN(FALSE);
@@ -858,6 +891,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 ? derived->alias : "<NULL>"),
+ derived->get_unit()));
TABLE *table= derived->table;
SELECT_LEX_UNIT *unit= derived->get_unit();
@@ -907,9 +943,13 @@ bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived)
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 res= FALSE;
+ DBUG_ENTER("mysql_derived_fill");
+ DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
+ (derived->alias ? derived->alias : "<NULL>"),
+ derived->get_unit()));
if (unit->executed && !unit->uncacheable && !unit->describe)
DBUG_RETURN(FALSE);
@@ -949,7 +989,27 @@ 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);
+ }
+ }
}
+
if (res || !lex->describe)
unit->cleanup();
lex->current_select= save_current_select;
@@ -978,6 +1038,9 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
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 ? derived->alias : "<NULL>"),
+ derived->get_unit()));
st_select_lex_unit *unit= derived->get_unit();
derived->merged_for_insert= FALSE;
diff --git a/sql/sql_do.cc b/sql/sql_do.cc
index 9e58031f6a4..54850494ad0 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, 0, values, MARK_COLUMNS_NONE, 0, 0))
+ if (setup_fields(thd, 0, values, MARK_COLUMNS_NONE, 0, NULL, 0))
DBUG_RETURN(TRUE);
while ((value = li++))
(void) value->is_null();
diff --git a/sql/sql_explain.h b/sql/sql_explain.h
index 4d0ba38d810..caacf6b3a2f 100644
--- a/sql/sql_explain.h
+++ b/sql/sql_explain.h
@@ -208,6 +208,9 @@ public:
Explain_select(MEM_ROOT *root, bool is_analyze) :
Explain_basic_join(root),
+#ifndef DBUG_OFF
+ select_lex(NULL),
+#endif
message(NULL),
having(NULL), having_value(Item::COND_UNDEF),
using_temporary(false), using_filesort(false),
@@ -222,6 +225,9 @@ public:
void replace_table(uint idx, Explain_table_access *new_tab);
public:
+#ifndef DBUG_OFF
+ SELECT_LEX *select_lex;
+#endif
const char *select_type;
/*
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 721fff389e0..0a9ce00c950 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, 2016, 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
@@ -258,7 +258,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
if (table_list->is_view())
unfix_fields(fields);
- res= setup_fields(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0);
+ res= setup_fields(thd, 0, fields, MARK_COLUMNS_WRITE, 0, NULL, 0);
/* Restore the current context. */
ctx_state.restore_state(context, table_list);
@@ -372,7 +372,7 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
}
/* Check the fields we are going to modify */
- if (setup_fields(thd, 0, update_fields, MARK_COLUMNS_WRITE, 0, 0))
+ if (setup_fields(thd, 0, update_fields, MARK_COLUMNS_WRITE, 0, NULL, 0))
return -1;
if (insert_table_list->is_view() &&
@@ -794,7 +794,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter);
goto abort;
}
- if (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0))
+ if (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, NULL, 0))
goto abort;
switch_to_nullable_trigger_fields(*values, table);
}
@@ -1509,12 +1509,12 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
table_list->next_local= 0;
context->resolve_in_table_list_only(table_list);
- res= (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0) ||
+ res= (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, NULL, 0) ||
check_insert_fields(thd, context->table_list, fields, *values,
!insert_into_view, 0, &map));
if (!res)
- res= setup_fields(thd, 0, update_values, MARK_COLUMNS_READ, 0, 0);
+ res= setup_fields(thd, 0, update_values, MARK_COLUMNS_READ, 0, NULL, 0);
if (!res && duplic == DUP_UPDATE)
{
@@ -3478,7 +3478,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
*/
lex->current_select= &lex->select_lex;
- res= (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0) ||
+ res= (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, NULL, 0) ||
check_insert_fields(thd, table_list, *fields, values,
!insert_into_view, 1, &map));
@@ -3531,7 +3531,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
ctx_state.get_first_name_resolution_table();
res= res || setup_fields(thd, 0, *info.update_values,
- MARK_COLUMNS_READ, 0, 0);
+ MARK_COLUMNS_READ, 0, NULL, 0);
if (!res)
{
/*
diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc
index 1023aea4cd4..4b7667f1319 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);
@@ -3877,6 +3877,7 @@ int JOIN_TAB_SCAN_MRR::open()
/* Dynamic range access is never used with BKA */
DBUG_ASSERT(join_tab->use_quick != 2);
+ join_tab->tracker->r_scans++;
save_or_restore_used_tabs(join_tab, FALSE);
init_mrr_buff();
@@ -3920,6 +3921,8 @@ int JOIN_TAB_SCAN_MRR::next()
int rc= join_tab->table->file->multi_range_read_next((range_id_t*)ptr) ? -1 : 0;
if (!rc)
{
+ join_tab->tracker->r_rows++;
+ join_tab->tracker->r_rows_after_where++;
/*
If a record in in an incremental cache contains no fields then the
association for the last record in cache will be equal to cache->end_pos
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index b3a30c69a03..3fa5ec71aeb 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
@@ -657,6 +657,7 @@ void lex_start(THD *thd)
{
LEX *lex= thd->lex;
DBUG_ENTER("lex_start");
+ DBUG_PRINT("info", ("Lex %p stmt_lex: %p", thd->lex, thd->stmt_lex));
lex->thd= lex->unit.thd= thd;
@@ -668,6 +669,7 @@ void lex_start(THD *thd)
/* 'parent_lex' is used in init_query() so it must be before it. */
lex->select_lex.parent_lex= lex;
lex->select_lex.init_query();
+ lex->current_select_number= 1;
lex->value_list.empty();
lex->update_list.empty();
lex->set_var_list.empty();
@@ -800,6 +802,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;
}
@@ -2878,6 +2881,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);
}
@@ -4861,4 +4868,3 @@ void binlog_unsafe_map_init()
BINLOG_DIRECT_OFF & TRX_CACHE_NOT_EMPTY);
}
#endif
-
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 240eb2373eb..4fcd090e1f5 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, 2016, 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
@@ -502,7 +502,7 @@ public:
}
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.
@@ -727,7 +727,13 @@ public:
Item *prep_having;/* saved HAVING clause for prepared statement processing */
/* 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. */
@@ -743,6 +749,7 @@ public:
Group_list_ptrs *group_list_ptrs;
List<Item> item_list; /* list of fields & expressions */
+ List<Item> pre_fix; /* above list before fix_fields */
List<String> interval_list;
bool is_item_list_lookup;
/*
@@ -2451,7 +2458,7 @@ struct LEX: public Query_tables_list
/** SELECT of CREATE VIEW statement */
LEX_STRING create_view_select;
- uint number_of_selects; // valid only for view
+ 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;
@@ -2725,6 +2732,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)
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.h b/sql/sql_list.h
index 6f01b64df70..7fb9c19d2cf 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -41,12 +41,12 @@ public:
{ return 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, 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 */ }
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_load.cc b/sql/sql_load.cc
index 1ba9de297d4..45c5dc038fc 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -353,22 +353,22 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
Let us also prepare SET clause, altough it is probably empty
in this case.
*/
- if (setup_fields(thd, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) ||
- setup_fields(thd, 0, set_values, MARK_COLUMNS_READ, 0, 0))
+ if (setup_fields(thd, 0, set_fields, MARK_COLUMNS_WRITE, 0, NULL, 0) ||
+ setup_fields(thd, 0, set_values, MARK_COLUMNS_READ, 0, NULL, 0))
DBUG_RETURN(TRUE);
}
else
{ // Part field list
/* TODO: use this conds for 'WITH CHECK OPTIONS' */
- if (setup_fields(thd, 0, fields_vars, MARK_COLUMNS_WRITE, 0, 0) ||
- setup_fields(thd, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) ||
+ if (setup_fields(thd, 0, fields_vars, MARK_COLUMNS_WRITE, 0, NULL, 0) ||
+ setup_fields(thd, 0, set_fields, MARK_COLUMNS_WRITE, 0, NULL, 0) ||
check_that_all_fields_are_given_values(thd, table, table_list))
DBUG_RETURN(TRUE);
/* Add all fields with default functions to table->write_set. */
if (table->default_field)
table->mark_default_fields_for_write();
/* Fix the expressions in SET clause */
- if (setup_fields(thd, 0, set_values, MARK_COLUMNS_READ, 0, 0))
+ if (setup_fields(thd, 0, set_values, MARK_COLUMNS_READ, 0, NULL, 0))
DBUG_RETURN(TRUE);
}
switch_to_nullable_trigger_fields(fields_vars, table);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 6f9e4677c0b..4dd8d9e124e 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1160,8 +1160,7 @@ out:
@retval FALSE The statement isn't updating any relevant tables.
*/
-static my_bool deny_updates_if_read_only_option(THD *thd,
- TABLE_LIST *all_tables)
+static bool deny_updates_if_read_only_option(THD *thd, TABLE_LIST *all_tables)
{
DBUG_ENTER("deny_updates_if_read_only_option");
@@ -1170,11 +1169,7 @@ static my_bool deny_updates_if_read_only_option(THD *thd,
LEX *lex= thd->lex;
- const my_bool user_is_super=
- ((ulong)(thd->security_ctx->master_access & SUPER_ACL) ==
- (ulong)SUPER_ACL);
-
- if (user_is_super)
+ if (thd->security_ctx->master_access & SUPER_ACL)
DBUG_RETURN(FALSE);
if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA))
@@ -1184,28 +1179,26 @@ static my_bool deny_updates_if_read_only_option(THD *thd,
if (lex->sql_command == SQLCOM_UPDATE_MULTI)
DBUG_RETURN(FALSE);
+ if (lex->sql_command == SQLCOM_CREATE_DB ||
+ lex->sql_command == SQLCOM_DROP_DB)
+ DBUG_RETURN(TRUE);
+
/*
a table-to-be-created is not in the temp table list yet,
so CREATE TABLE needs a special treatment
*/
- const bool update_real_tables= lex->sql_command == SQLCOM_CREATE_TABLE ?
- !lex->tmp_table() : some_non_temp_table_to_be_updated(thd, all_tables);
-
- const bool create_or_drop_databases=
- (lex->sql_command == SQLCOM_CREATE_DB) ||
- (lex->sql_command == SQLCOM_DROP_DB);
-
- if (update_real_tables || create_or_drop_databases)
- {
- /*
- An attempt was made to modify one or more non-temporary tables.
- */
- DBUG_RETURN(TRUE);
- }
+ if (lex->sql_command == SQLCOM_CREATE_TABLE)
+ DBUG_RETURN(!lex->tmp_table());
+ /*
+ a table-to-be-dropped might not exist (DROP TEMPORARY TABLE IF EXISTS),
+ cannot use the temp table list either.
+ */
+ if (lex->sql_command == SQLCOM_DROP_TABLE && lex->tmp_table())
+ DBUG_RETURN(FALSE);
- /* Assuming that only temporary tables are modified. */
- DBUG_RETURN(FALSE);
+ /* Now, check thd->temporary_tables list */
+ DBUG_RETURN(some_non_temp_table_to_be_updated(thd, all_tables));
}
@@ -1964,11 +1957,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
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;
@@ -3310,7 +3304,7 @@ mysql_execute_command(THD *thd)
#ifdef WITH_PARTITION_STORAGE_ENGINE
{
partition_info *part_info= thd->lex->part_info;
- if (part_info && !(part_info= thd->lex->part_info->get_clone(thd)))
+ if (part_info && !(part_info= part_info->get_clone(thd)))
{
res= -1;
goto end_with_restore_list;
@@ -3780,7 +3774,7 @@ end_with_restore_list:
if (up_result != 2)
break;
}
- /* Fall through */
+ /* fall through */
case SQLCOM_UPDATE_MULTI:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
@@ -3891,7 +3885,7 @@ end_with_restore_list:
DBUG_PRINT("debug", ("Just after generate_incident()"));
}
#endif
- /* fall through */
+ /* fall through */
case SQLCOM_INSERT:
{
WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_INSERT_REPLACE);
@@ -4571,7 +4565,6 @@ end_with_restore_list:
if (res)
break;
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
switch (lex->sql_command) {
case SQLCOM_CREATE_EVENT:
{
@@ -4605,7 +4598,6 @@ end_with_restore_list:
lex->spname->m_name);
break;
case SQLCOM_DROP_EVENT:
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
if (!(res= Events::drop_event(thd,
lex->spname->m_db, lex->spname->m_name,
lex->if_exists())))
@@ -5048,14 +5040,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:
@@ -5092,13 +5089,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:
@@ -5503,7 +5503,6 @@ end_with_restore_list:
Note: SQLCOM_CREATE_VIEW also handles 'ALTER VIEW' commands
as specified through the thd->lex->create_view_mode flag.
*/
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
res= mysql_create_view(thd, first_table, thd->lex->create_view_mode);
break;
}
@@ -5519,7 +5518,6 @@ end_with_restore_list:
case SQLCOM_CREATE_TRIGGER:
{
/* Conditionally writes to binlog. */
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
res= mysql_create_or_drop_trigger(thd, all_tables, 1);
break;
@@ -5527,7 +5525,6 @@ end_with_restore_list:
case SQLCOM_DROP_TRIGGER:
{
/* Conditionally writes to binlog. */
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
res= mysql_create_or_drop_trigger(thd, all_tables, 0);
break;
}
@@ -5592,13 +5589,11 @@ end_with_restore_list:
my_ok(thd);
break;
case SQLCOM_INSTALL_PLUGIN:
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
if (! (res= mysql_install_plugin(thd, &thd->lex->comment,
&thd->lex->ident)))
my_ok(thd);
break;
case SQLCOM_UNINSTALL_PLUGIN:
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
if (! (res= mysql_uninstall_plugin(thd, &thd->lex->comment,
&thd->lex->ident)))
my_ok(thd);
@@ -5726,6 +5721,25 @@ finish:
}
if (thd->is_error() || (thd->variables.option_bits & OPTION_MASTER_SQL_ERROR))
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. */
@@ -6889,7 +6903,12 @@ void THD::reset_for_next_command(bool do_clear_error)
clear_error(1);
thd->free_list= 0;
- thd->select_number= 1;
+ /*
+ We also assign thd->stmt_lex in lex_start(), but during bootstrap this
+ code is executed first.
+ */
+ thd->stmt_lex= &main_lex; thd->stmt_lex->current_select_number= 1;
+ DBUG_PRINT("info", ("Lex %p stmt_lex: %p", thd->lex, thd->stmt_lex));
/*
Those two lines below are theoretically unneeded as
THD::cleanup_after_query() should take care of this already.
@@ -7007,7 +7026,7 @@ mysql_new_select(LEX *lex, bool move_down)
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();
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 78f8518650f..13e5f16685c 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2005, 2014, Oracle and/or its affiliates.
- Copyright (c) 2009, 2014, SkySQL Ab.
+/* Copyright (c) 2005, 2017, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2017, SkySQL Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -4652,10 +4652,6 @@ bool compare_partition_options(HA_CREATE_INFO *table_create_info,
option_diffs[errors++]= "MAX_ROWS";
if (part_elem->part_min_rows != table_create_info->min_rows)
option_diffs[errors++]= "MIN_ROWS";
- if (part_elem->data_file_name || table_create_info->data_file_name)
- option_diffs[errors++]= "DATA DIRECTORY";
- if (part_elem->index_file_name || table_create_info->index_file_name)
- option_diffs[errors++]= "INDEX DIRECTORY";
for (i= 0; i < errors; i++)
my_error(ER_PARTITION_EXCHANGE_DIFFERENT_OPTION, MYF(0),
@@ -4713,10 +4709,15 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
DBUG_RETURN(TRUE);
}
- thd->work_part_info= thd->lex->part_info;
+ /*
+ 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->lex->part_info->get_clone(thd)))
+ !(thd->work_part_info= thd->work_part_info->get_clone(thd)))
DBUG_RETURN(TRUE);
/* ALTER_ADMIN_PARTITION is handled in mysql_admin_table */
@@ -4886,16 +4887,11 @@ 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)
- {
- my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
- "RANGE", "LESS THAN");
- }
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;
}
@@ -6835,9 +6831,7 @@ 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_DYNAMIC)
- 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;
@@ -8312,6 +8306,7 @@ int create_partition_name(char *out, size_t outlen, const char *in1,
}
else
transl_part= in2;
+
if (name_variant == NORMAL_PART_NAME)
end= strxnmov(out, outlen-1, in1, "#P#", transl_part, NullS);
else if (name_variant == TEMP_PART_NAME)
@@ -8326,25 +8321,19 @@ int create_partition_name(char *out, size_t outlen, const char *in1,
return 0;
}
-
-/*
- Create subpartition name
-
- SYNOPSIS
- create_subpartition_name()
- out:out The buffer for the created partition name string
- must be *at least* of FN_REFLEN+1 bytes
- in1 First part
- in2 Second part
- in3 Third part
- name_variant Normal, temporary or renamed partition name
-
- RETURN VALUE
- 0 if ok, error if name too long
-
- DESCRIPTION
- This method is used to calculate the subpartition name, service routine to
- the del_ren_cre_table method.
+/**
+ Create subpartition name. This method is used to calculate the
+ subpartition name, service routine to the del_ren_cre_table method.
+ The output buffer size should be FN_REFLEN + 1(terminating '\0').
+
+ @param [out] out Created partition name string
+ @param in1 First part
+ @param in2 Second part
+ @param in3 Third part
+ @param name_variant Normal, temporary or renamed partition name
+
+ @retval true Error.
+ @retval false Success.
*/
int create_subpartition_name(char *out, size_t outlen,
@@ -8356,6 +8345,7 @@ int create_subpartition_name(char *out, size_t outlen,
tablename_to_filename(in2, transl_part_name, FN_REFLEN);
tablename_to_filename(in3, transl_subpart_name, FN_REFLEN);
+
if (name_variant == NORMAL_PART_NAME)
end= strxnmov(out, outlen-1, in1, "#P#", transl_part_name,
"#SP#", transl_subpart_name, NullS);
diff --git a/sql/sql_partition.h b/sql/sql_partition.h
index 76f162920f1..6629537b2ae 100644
--- a/sql/sql_partition.h
+++ b/sql/sql_partition.h
@@ -1,7 +1,8 @@
#ifndef SQL_PARTITION_INCLUDED
#define SQL_PARTITION_INCLUDED
-/* Copyright (c) 2006, 2013, Oracle and/or its affiliates.
+/* Copyright (c) 2006, 2017, Oracle and/or its affiliates.
+ Copyright (c) 2011, 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
diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc
index e7f5e3cb59e..e850677f8d9 100644
--- a/sql/sql_partition_admin.cc
+++ b/sql/sql_partition_admin.cc
@@ -171,7 +171,8 @@ static bool check_exchange_partition(TABLE *table, TABLE *part_table)
*/
static bool compare_table_with_partition(THD *thd, TABLE *table,
TABLE *part_table,
- partition_element *part_elem)
+ partition_element *part_elem,
+ uint part_id)
{
HA_CREATE_INFO table_create_info, part_create_info;
Alter_info part_alter_info;
@@ -196,6 +197,7 @@ static bool compare_table_with_partition(THD *thd, TABLE *table,
}
/* db_type is not set in prepare_alter_table */
part_create_info.db_type= part_table->part_info->default_engine_type;
+ ((ha_partition*)(part_table->file))->update_part_create_info(&part_create_info, part_id);
/*
Since we exchange the partition with the table, allow exchanging
auto_increment value as well.
@@ -606,7 +608,8 @@ bool Sql_cmd_alter_table_exchange_partition::
DBUG_RETURN(TRUE);
}
- if (compare_table_with_partition(thd, swap_table, part_table, part_elem))
+ if (compare_table_with_partition(thd, swap_table, part_table, part_elem,
+ swap_part_id))
DBUG_RETURN(TRUE);
/* Table and partition has same structure/options, OK to exchange */
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 5f503952828..d57137b30f6 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -228,7 +228,6 @@ static DYNAMIC_ARRAY plugin_array;
static HASH plugin_hash[MYSQL_MAX_PLUGIN_TYPE_NUM];
static MEM_ROOT plugin_mem_root;
static bool reap_needed= false;
-static int plugin_array_version=0;
static bool initialized= 0;
ulong dlopen_count;
@@ -322,7 +321,6 @@ static void unlock_variables(THD *thd, struct system_variables *vars);
static void cleanup_variables(struct system_variables *vars);
static void plugin_vars_free_values(sys_var *vars);
static void restore_ptr_backup(uint n, st_ptr_backup *backup);
-static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref plugin);
static void intern_plugin_unlock(LEX *lex, plugin_ref plugin);
static void reap_plugins(void);
@@ -489,6 +487,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 */
@@ -943,15 +946,17 @@ SHOW_COMP_OPTION plugin_status(const char *name, size_t len, int type)
}
-static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc)
+static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc,
+ uint state_mask= PLUGIN_IS_READY |
+ PLUGIN_IS_UNINITIALIZED |
+ PLUGIN_IS_DELETED)
{
st_plugin_int *pi= plugin_ref_to_int(rc);
DBUG_ENTER("intern_plugin_lock");
mysql_mutex_assert_owner(&LOCK_plugin);
- if (pi->state & (PLUGIN_IS_READY | PLUGIN_IS_UNINITIALIZED |
- PLUGIN_IS_DELETED))
+ if (pi->state & state_mask)
{
plugin_ref plugin;
#ifdef DBUG_OFF
@@ -1146,7 +1151,6 @@ static bool plugin_add(MEM_ROOT *tmp_root,
if (!(tmp_plugin_ptr= plugin_insert_or_reuse(&tmp)))
goto err;
- plugin_array_version++;
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));
@@ -1240,7 +1244,6 @@ static void plugin_del(struct st_plugin_int *plugin)
my_hash_delete(&plugin_hash[plugin->plugin->type], (uchar*)plugin);
plugin_dl_del(plugin->plugin_dl);
plugin->state= PLUGIN_IS_FREED;
- plugin_array_version++;
free_root(&plugin->mem_root, MYF(0));
}
else
@@ -1853,11 +1856,11 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, const char *list)
switch ((*(p++)= *(list++))) {
case '\0':
list= NULL; /* terminate the loop */
-#ifndef __WIN__
/* fall through */
+ case ';':
+#ifndef __WIN__
case ':': /* can't use this as delimiter as it may be drive letter */
#endif
- case ';':
str->str[str->length]= '\0';
if (str == &name) // load all plugins in named module
{
@@ -2110,12 +2113,16 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name,
bool error;
int argc=orig_argc;
char **argv=orig_argv;
+ unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] =
+ { MYSQL_AUDIT_GENERAL_CLASSMASK };
DBUG_ENTER("mysql_install_plugin");
tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_WRITE);
if (!opt_noacl && check_table_access(thd, INSERT_ACL, &tables, FALSE, 1, FALSE))
DBUG_RETURN(TRUE);
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
+
/* need to open before acquiring LOCK_plugin or it will deadlock */
if (! (table = open_ltable(thd, &tables, TL_WRITE,
MYSQL_LOCK_IGNORE_TIMEOUT)))
@@ -2148,8 +2155,6 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name,
See also mysql_uninstall_plugin() and initialize_audit_plugin()
*/
- unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] =
- { MYSQL_AUDIT_GENERAL_CLASSMASK };
mysql_audit_acquire_plugins(thd, event_class_mask);
mysql_mutex_lock(&LOCK_plugin);
@@ -2180,6 +2185,10 @@ err:
if (argv)
free_defaults(argv);
DBUG_RETURN(error);
+#ifdef WITH_WSREP
+error:
+ DBUG_RETURN(TRUE);
+#endif /* WITH_WSREP */
}
@@ -2246,6 +2255,8 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name,
TABLE_LIST tables;
LEX_STRING dl= *dl_arg;
bool error= false;
+ unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] =
+ { MYSQL_AUDIT_GENERAL_CLASSMASK };
DBUG_ENTER("mysql_uninstall_plugin");
tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_WRITE);
@@ -2253,6 +2264,8 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name,
if (!opt_noacl && check_table_access(thd, DELETE_ACL, &tables, FALSE, 1, FALSE))
DBUG_RETURN(TRUE);
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
+
/* need to open before acquiring LOCK_plugin or it will deadlock */
if (! (table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
DBUG_RETURN(TRUE);
@@ -2278,8 +2291,6 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name,
See also mysql_install_plugin() and initialize_audit_plugin()
*/
- unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] =
- { MYSQL_AUDIT_GENERAL_CLASSMASK };
mysql_audit_acquire_plugins(thd, event_class_mask);
mysql_mutex_lock(&LOCK_plugin);
@@ -2309,70 +2320,65 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name,
mysql_mutex_unlock(&LOCK_plugin);
DBUG_RETURN(error);
+#ifdef WITH_WSREP
+error:
+ DBUG_RETURN(TRUE);
+#endif /* WITH_WSREP */
}
bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func,
int type, uint state_mask, void *arg)
{
- uint idx, total;
- struct st_plugin_int *plugin, **plugins;
- int version=plugin_array_version;
+ uint idx, total= 0;
+ struct st_plugin_int *plugin;
+ plugin_ref *plugins;
+ my_bool res= FALSE;
DBUG_ENTER("plugin_foreach_with_mask");
if (!initialized)
DBUG_RETURN(FALSE);
- state_mask= ~state_mask; // do it only once
-
mysql_mutex_lock(&LOCK_plugin);
- total= type == MYSQL_ANY_PLUGIN ? plugin_array.elements
- : plugin_hash[type].records;
/*
Do the alloca out here in case we do have a working alloca:
- leaving the nested stack frame invalidates alloca allocation.
+ leaving the nested stack frame invalidates alloca allocation.
*/
- plugins=(struct st_plugin_int **)my_alloca(total*sizeof(plugin));
if (type == MYSQL_ANY_PLUGIN)
{
- for (idx= 0; idx < total; idx++)
+ plugins= (plugin_ref*) my_alloca(plugin_array.elements * sizeof(plugin_ref));
+ for (idx= 0; idx < plugin_array.elements; idx++)
{
plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
- plugins[idx]= !(plugin->state & state_mask) ? plugin : NULL;
+ if ((plugins[total]= intern_plugin_lock(0, plugin_int_to_ref(plugin),
+ state_mask)))
+ total++;
}
}
else
{
HASH *hash= plugin_hash + type;
- for (idx= 0; idx < total; idx++)
+ plugins= (plugin_ref*) my_alloca(hash->records * sizeof(plugin_ref));
+ for (idx= 0; idx < hash->records; idx++)
{
plugin= (struct st_plugin_int *) my_hash_element(hash, idx);
- plugins[idx]= !(plugin->state & state_mask) ? plugin : NULL;
+ if ((plugins[total]= intern_plugin_lock(0, plugin_int_to_ref(plugin),
+ state_mask)))
+ total++;
}
}
mysql_mutex_unlock(&LOCK_plugin);
for (idx= 0; idx < total; idx++)
{
- if (unlikely(version != plugin_array_version))
- {
- mysql_mutex_lock(&LOCK_plugin);
- for (uint i=idx; i < total; i++)
- if (plugins[i] && plugins[i]->state & state_mask)
- plugins[i]=0;
- mysql_mutex_unlock(&LOCK_plugin);
- }
- plugin= plugins[idx];
/* It will stop iterating on first engine error when "func" returns TRUE */
- if (plugin && func(thd, plugin_int_to_ref(plugin), arg))
- goto err;
+ if ((res= func(thd, plugins[idx], arg)))
+ break;
}
+ plugin_unlock_list(0, plugins, total);
my_afree(plugins);
- DBUG_RETURN(FALSE);
-err:
- my_afree(plugins);
- DBUG_RETURN(TRUE);
+ DBUG_RETURN(res);
}
@@ -3491,7 +3497,6 @@ bool sys_var_pluginvar::global_update(THD *thd, set_var *var)
options->max_value= getopt_double2ulonglong((opt)->max_val); \
options->block_size= (long) (opt)->blk_sz;
-
void plugin_opt_set_limits(struct my_option *options,
const struct st_mysql_sys_var *opt)
{
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index e0dd04b08f6..b515578eb05 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -164,20 +164,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];
#ifndef EMBEDDED_LIBRARY
bool (*set_params)(Prepared_statement *st, uchar *data, uchar *data_end,
@@ -1321,7 +1307,7 @@ static bool mysql_test_insert(Prepared_statement *stmt,
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter);
goto error;
}
- if (setup_fields(thd, 0, *values, MARK_COLUMNS_NONE, 0, 0))
+ if (setup_fields(thd, 0, *values, MARK_COLUMNS_NONE, 0, NULL, 0))
goto error;
}
}
@@ -1411,7 +1397,7 @@ static int mysql_test_update(Prepared_statement *stmt,
table_list->register_want_access(want_privilege);
#endif
thd->lex->select_lex.no_wrap_view_item= TRUE;
- res= setup_fields(thd, 0, select->item_list, MARK_COLUMNS_READ, 0, 0);
+ res= setup_fields(thd, 0, select->item_list, MARK_COLUMNS_READ, 0, NULL, 0);
thd->lex->select_lex.no_wrap_view_item= FALSE;
if (res)
goto error;
@@ -1422,7 +1408,8 @@ static int mysql_test_update(Prepared_statement *stmt,
(SELECT_ACL & ~table_list->table->grant.privilege);
table_list->register_want_access(SELECT_ACL);
#endif
- if (setup_fields(thd, 0, stmt->lex->value_list, MARK_COLUMNS_NONE, 0, 0) ||
+ if (setup_fields(thd, 0, stmt->lex->value_list, MARK_COLUMNS_NONE, 0, NULL,
+ 0) ||
check_unique_table(thd, table_list))
goto error;
/* TODO: here we should send types of placeholders to the client. */
@@ -1592,7 +1579,7 @@ static bool mysql_test_do_fields(Prepared_statement *stmt,
if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL,
DT_PREPARE | DT_CREATE))
DBUG_RETURN(TRUE);
- DBUG_RETURN(setup_fields(thd, 0, *values, MARK_COLUMNS_NONE, 0, 0));
+ DBUG_RETURN(setup_fields(thd, 0, *values, MARK_COLUMNS_NONE, 0, NULL, 0));
}
@@ -3562,9 +3549,9 @@ void Prepared_statement::cleanup_stmt()
DBUG_ENTER("Prepared_statement::cleanup_stmt");
DBUG_PRINT("enter",("stmt: 0x%lx", (long) this));
thd->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;
}
@@ -3648,6 +3635,7 @@ 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))
DBUG_RETURN(TRUE);
@@ -3753,8 +3741,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);
@@ -3890,7 +3876,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)
{
diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc
index d68ce96dc85..73dd9679ed7 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)
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 764047e4720..b5cca334891 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -30,7 +30,7 @@
#include <my_dir.h>
#include "rpl_handler.h"
#include "debug_sync.h"
-
+#include "log.h" // get_gtid_list_event
enum enum_gtid_until_state {
GTID_UNTIL_NOT_DONE,
@@ -875,72 +875,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)
diff --git a/sql/sql_repl.h b/sql/sql_repl.h
index e2000bbca73..37acff3141f 100644
--- a/sql/sql_repl.h
+++ b/sql/sql_repl.h
@@ -82,7 +82,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 f9da12aac29..067c71205d0 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 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
@@ -291,6 +291,11 @@ 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 *thd, Item **ref_pointer_array, TABLE_LIST *tables,
+ ORDER *order, List<Item> &fields, List<Item> &all_fields,
+ bool is_group_field, bool add_to_all_fields);
+
static double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
table_map rem_tables);
@@ -344,7 +349,6 @@ bool dbug_user_var_equals_int(THD *thd, const char *name, int value)
}
#endif
-
/**
This handles SELECT with and without UNION.
*/
@@ -708,6 +712,9 @@ JOIN::prepare(Item ***rref_pointer_array,
join_list= &select_lex->top_join_list;
union_part= unit_arg->is_union();
+ // simple check that we got usable conds
+ dbug_print_item(conds);
+
if (select_lex->handle_derived(thd->lex, DT_PREPARE))
DBUG_RETURN(1);
@@ -797,7 +804,7 @@ JOIN::prepare(Item ***rref_pointer_array,
wild_num)) ||
select_lex->setup_ref_array(thd, real_og_num) ||
setup_fields(thd, (*rref_pointer_array), fields_list, MARK_COLUMNS_READ,
- &all_fields, 1) ||
+ &all_fields, &select_lex->pre_fix, 1) ||
setup_without_group(thd, (*rref_pointer_array), tables_list,
select_lex->leaf_tables, fields_list,
all_fields, &conds, order, group_list,
@@ -810,9 +817,15 @@ JOIN::prepare(Item ***rref_pointer_array,
if (skip_order_by && select_lex !=
select_lex->master_unit()->global_parameters())
{
- if (setup_order(thd, (*rref_pointer_array), 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, *rref_pointer_array, tables_list, order,
+ fields_list, all_fields, false, false))
+ DBUG_RETURN(-1);
+ }
select_lex->order_list.empty();
}
@@ -2323,8 +2336,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)
@@ -2462,6 +2478,17 @@ void 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 &&
@@ -7874,9 +7901,11 @@ best_extension_by_limited_search(JOIN *join,
best_access_path(join, s, remaining_tables, idx, disable_jbuf,
record_count, join->positions + idx, &loose_scan_pos);
- /* Compute the cost of extending the plan with 's' */
-
- current_record_count= record_count * position->records_read;
+ /* Compute the cost of extending the plan with 's', avoid overflow */
+ if (position->records_read < DBL_MAX / record_count)
+ current_record_count= record_count * position->records_read;
+ else
+ current_record_count= DBL_MAX;
current_read_time=read_time + position->read_time +
current_record_count / (double) TIME_FOR_COMPARE;
@@ -10437,7 +10466,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;
@@ -12256,8 +12285,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 )
@@ -12632,7 +12661,7 @@ public:
}
static void operator delete(void *ptr __attribute__((unused)),
size_t size __attribute__((unused)))
- { TRASH(ptr, size); }
+ { TRASH_FREE(ptr, size); }
Item *and_level;
Item_bool_func2 *cmp_func;
@@ -14639,10 +14668,23 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top,
nested_join= table->nested_join;
if (table->sj_on_expr && !in_sj)
{
- /*
- If this is a semi-join that is not contained within another semi-join,
- leave it intact (otherwise it is flattened)
- */
+ /*
+ If this is a semi-join that is not contained within another semi-join
+ leave it intact (otherwise it is flattened)
+ */
+ /*
+ Make sure that any semi-join appear in
+ the join->select_lex->sj_nests list only once
+ */
+ List_iterator_fast<TABLE_LIST> sj_it(join->select_lex->sj_nests);
+ TABLE_LIST *sj_nest;
+ while ((sj_nest= sj_it++))
+ {
+ if (table == sj_nest)
+ break;
+ }
+ if (sj_nest)
+ continue;
join->select_lex->sj_nests.push_back(table, join->thd->mem_root);
/*
@@ -15618,9 +15660,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)) &&
@@ -16826,7 +16869,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());
}
}
@@ -22118,7 +22161,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.
@retval
FALSE if OK
@@ -22129,7 +22175,7 @@ cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref)
static bool
find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
ORDER *order, List<Item> &fields, List<Item> &all_fields,
- bool is_group_field)
+ bool is_group_field, bool add_to_all_fields)
{
Item *order_item= *order->item; /* The item from the GROUP/ORDER caluse. */
Item::Type order_item_type;
@@ -22253,6 +22299,9 @@ find_order_in_list(THD *thd, Item **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;
DBUG_ASSERT(all_fields.elements <=
thd->lex->current_select->ref_pointer_array_size);
@@ -22283,13 +22332,13 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
*/
int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
- List<Item> &fields, List<Item> &all_fields, ORDER *order)
+ List<Item> &fields, List<Item> &all_fields, ORDER *order)
{
thd->where="order clause";
for (; order; order=order->next)
{
if (find_order_in_list(thd, ref_pointer_array, tables, order, fields,
- all_fields, FALSE))
+ all_fields, FALSE, true))
return 1;
}
return 0;
@@ -22341,7 +22390,7 @@ setup_group(THD *thd, Item **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))
+ all_fields, TRUE, true))
return 1;
(*ord->item)->marker= UNDEF_POS; /* Mark found */
if ((*ord->item)->with_sum_func)
@@ -22660,6 +22709,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
@@ -24586,6 +24636,11 @@ int JOIN::save_explain_data_intern(Explain_query *output, bool need_tmp_table,
{
explain= new (output->mem_root) Explain_select(output->mem_root,
thd->lex->analyze_stmt);
+ if (!explain)
+ DBUG_RETURN(1); // EoM
+#ifndef DBUG_OFF
+ explain->select_lex= select_lex;
+#endif
join->select_lex->set_explain_type(true);
explain->select_id= join->select_lex->select_number;
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 7b9c03824eb..8c55528e120 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1839,7 +1839,7 @@ SORT_FIELD *make_unireg_sortorder(THD *thd, JOIN *join,
ORDER *order, uint *length,
SORT_FIELD *sortorder);
int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
- List<Item> &fields, List <Item> &all_fields, ORDER *order);
+ List<Item> &fields, List <Item> &all_fields, ORDER *order);
int setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
List<Item> &fields, List<Item> &all_fields, ORDER *order,
bool *hidden_group_fields);
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 953842e29d1..5a78a27a907 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -126,6 +126,12 @@ bool get_lookup_field_values(THD *, COND *, TABLE_LIST *, LOOKUP_FIELD_VALUES *)
** List all table types supported
***************************************************************************/
+
+static bool is_show_command(THD *thd)
+{
+ return sql_command_flags[thd->lex->sql_command] & CF_STATUS_COMMAND;
+}
+
static int make_version_string(char *buf, int buf_length, uint version)
{
return my_snprintf(buf, buf_length, "%d.%d", version>>8,version&0xff);
@@ -265,7 +271,7 @@ int fill_plugins(THD *thd, TABLE_LIST *tables, COND *cond)
TABLE *table= tables->table;
if (plugin_foreach_with_mask(thd, show_plugins, MYSQL_ANY_PLUGIN,
- ~PLUGIN_IS_FREED, table))
+ ~(PLUGIN_IS_FREED | PLUGIN_IS_DYING), table))
DBUG_RETURN(1);
DBUG_RETURN(0);
@@ -973,13 +979,20 @@ find_files(THD *thd, Dynamic_array<LEX_STRING*> *files, LEX_STRING *db,
if (tl.add_file(file->name))
goto err;
}
- tl.sort();
}
else
{
if (ha_discover_table_names(thd, db, dirp, &tl, false))
goto err;
}
+#if MYSQL_VERSION_ID < 100300
+ /* incomplete optimization, but a less drastic change in GA version */
+ if (!thd->lex->select_lex.order_list.elements &&
+ !thd->lex->select_lex.group_list.elements)
+#else
+ if (is_show_command(thd))
+#endif
+ tl.sort();
DBUG_PRINT("info",("found: %zu files", files->elements()));
my_dirend(dirp);
@@ -2401,7 +2414,7 @@ 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); }
ulong thread_id;
uint32 os_thread_id;
@@ -3640,6 +3653,15 @@ bool uses_only_table_name_fields(Item *item, TABLE_LIST *table)
return 0;
}
}
+ else if (item->type() == Item::ROW_ITEM)
+ {
+ Item_row *item_row= static_cast<Item_row*>(item);
+ for (uint i= 0; i < item_row->cols(); i++)
+ {
+ if (!uses_only_table_name_fields(item_row->element_index(i), table))
+ return 0;
+ }
+ }
else if (item->type() == Item::FIELD_ITEM)
{
Item_field *item_field= (Item_field*)item;
@@ -3659,6 +3681,11 @@ bool uses_only_table_name_fields(Item *item, TABLE_LIST *table)
strlen(item_field->field_name), 0)))
return 0;
}
+ else if (item->type() == Item::EXPR_CACHE_ITEM)
+ {
+ Item_cache_wrapper *tmp= static_cast<Item_cache_wrapper*>(item);
+ return uses_only_table_name_fields(tmp->get_orig_item(), table);
+ }
else if (item->type() == Item::REF_ITEM)
return uses_only_table_name_fields(item->real_item(), table);
@@ -4051,7 +4078,7 @@ make_table_name_list(THD *thd, Dynamic_array<LEX_STRING*> *table_names,
*/
if (res == FIND_FILES_DIR)
{
- if (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)
+ if (is_show_command(thd))
return 1;
thd->clear_error();
return 2;
@@ -5586,7 +5613,8 @@ int fill_schema_engines(THD *thd, TABLE_LIST *tables, COND *cond)
DBUG_ENTER("fill_schema_engines");
if (plugin_foreach_with_mask(thd, iter_schema_engines,
MYSQL_STORAGE_ENGINE_PLUGIN,
- ~PLUGIN_IS_FREED, tables->table))
+ ~(PLUGIN_IS_FREED | PLUGIN_IS_DYING),
+ tables->table))
DBUG_RETURN(1);
DBUG_RETURN(0);
}
@@ -5871,13 +5899,13 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
val_int() == TYPE_ENUM_PROCEDURE))
return 0;
- if ((lex->sql_command == SQLCOM_SHOW_STATUS_PROC &&
+ if (!is_show_command(thd) ||
+ (lex->sql_command == SQLCOM_SHOW_STATUS_PROC &&
proc_table->field[MYSQL_PROC_MYSQL_TYPE]->val_int() ==
TYPE_ENUM_PROCEDURE) ||
(lex->sql_command == SQLCOM_SHOW_STATUS_FUNC &&
proc_table->field[MYSQL_PROC_MYSQL_TYPE]->val_int() ==
- TYPE_ENUM_FUNCTION) ||
- (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0)
+ TYPE_ENUM_FUNCTION))
{
restore_record(table, s->default_values);
if (!wild || !wild[0] || !wild_case_compare(system_charset_info,
@@ -6009,6 +6037,10 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond)
DBUG_RETURN(1);
}
+ /* Disable padding temporarily so it doesn't break the query */
+ ulonglong sql_mode_was = thd->variables.sql_mode;
+ thd->variables.sql_mode &= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
+
if (proc_table->file->ha_index_init(0, 1))
{
res= 1;
@@ -6044,6 +6076,7 @@ err:
(void) proc_table->file->ha_index_end();
close_system_tables(thd, &open_tables_state_backup);
+ thd->variables.sql_mode = sql_mode_was;
DBUG_RETURN(res);
}
@@ -7626,7 +7659,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
tmp_table_param->field_count= field_count;
tmp_table_param->schema_table= 1;
SELECT_LEX *select_lex= thd->lex->current_select;
- bool keep_row_order= sql_command_flags[thd->lex->sql_command] & CF_STATUS_COMMAND;
+ bool keep_row_order= is_show_command(thd);
if (!(table= create_tmp_table(thd, tmp_table_param,
field_list, (ORDER*) 0, 0, 0,
(select_lex->options | thd->variables.option_bits |
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 51a11c7a4ff..b8979d397e6 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -149,7 +149,7 @@ public:
{
(void) ptr_arg;
(void) size;
- TRASH(ptr_arg, size);
+ TRASH_FREE(ptr_arg, size);
}
static void operator delete(void *, MEM_ROOT *)
{ /* never called */ }
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 2751c79a0a4..44df4bba767 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1829,7 +1829,8 @@ 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,
@@ -4161,7 +4162,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
if (!sql_field->def &&
!sql_field->has_default_function() &&
(sql_field->flags & NOT_NULL_FLAG) &&
- !is_timestamp_type(sql_field->sql_type))
+ (!is_timestamp_type(sql_field->sql_type) ||
+ opt_explicit_defaults_for_timestamp))
{
sql_field->flags|= NO_DEFAULT_VALUE_FLAG;
sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
@@ -4170,6 +4172,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
!sql_field->def && !sql_field->vcol_info &&
is_timestamp_type(sql_field->sql_type) &&
+ !opt_explicit_defaults_for_timestamp &&
(sql_field->flags & NOT_NULL_FLAG) &&
(type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
{
@@ -4412,10 +4415,7 @@ handler *mysql_create_frm_image(THD *thd,
set_table_default_charset(thd, create_info, (char*) 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)))
@@ -6038,6 +6038,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 */
@@ -6058,7 +6059,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;
}
}
@@ -6902,7 +6903,6 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
case Alter_info::LEAVE_AS_IS:
if (!indexes_were_disabled)
break;
- /* disabled indexes */
/* fall through */
case Alter_info::DISABLE:
error= table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
@@ -9681,11 +9681,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));
}
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 28e59319a50..70e9b36c56e 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -441,6 +441,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
my_error(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER, MYF(0));
DBUG_RETURN(TRUE);
}
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
if (!create)
{
@@ -606,6 +607,10 @@ end:
my_ok(thd);
DBUG_RETURN(result);
+#ifdef WITH_WSREP
+ error:
+ DBUG_RETURN(true);
+#endif /* WITH_WSREP */
}
/**
@@ -1368,12 +1373,13 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
List_iterator_fast<LEX_STRING> it_client_cs_name(triggers->client_cs_names);
List_iterator_fast<LEX_STRING> it_connection_cl_name(triggers->connection_cl_names);
List_iterator_fast<LEX_STRING> it_db_cl_name(triggers->db_cl_names);
- 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;
ulonglong save_sql_mode= thd->variables.sql_mode;
LEX_STRING *on_table_name;
- thd->lex= &lex;
+ thd->lex= thd->stmt_lex= &lex;
save_db.str= thd->db;
save_db.length= thd->db_length;
@@ -1572,6 +1578,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
}
thd->reset_db(save_db.str, save_db.length);
thd->lex= old_lex;
+ thd->stmt_lex= old_stmt_lex;
thd->spcont= save_spcont;
thd->variables.sql_mode= save_sql_mode;
@@ -1584,6 +1591,7 @@ err_with_lex_cleanup:
// QQ: anything else ?
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);
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 9d825f55fcb..e12cae0f80e 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -1093,22 +1093,6 @@ bool st_select_lex_unit::cleanup()
void st_select_lex_unit::reinit_exec_mechanism()
{
prepared= optimized= executed= 0;
-#ifndef DBUG_OFF
- if (is_union())
- {
- 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
}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index a87261aa34b..db9f9013188 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -359,7 +359,7 @@ int mysql_update(THD *thd,
table_list->grant.want_privilege= table->grant.want_privilege=
(SELECT_ACL & ~table->grant.privilege);
#endif
- if (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0))
+ if (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, NULL, 0))
{
free_underlaid_joins(thd, select_lex);
DBUG_RETURN(1); /* purecov: inspected */
@@ -701,6 +701,8 @@ int mysql_update(THD *thd,
if (reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
error=1; /* purecov: inspected */
select->file=tempfile; // Read row ptrs from this file
+ // select->file was copied, update self-references.
+ setup_io_cache(&select->file);
if (error >= 0)
goto err;
}
@@ -1711,7 +1713,7 @@ int multi_update::prepare(List<Item> &not_used_values,
reference tables
*/
- int error= setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0);
+ int error= setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, NULL, 0);
ti.rewind();
while ((table_ref= ti++))
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 90c94e6a503..1bdc76a66ea 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -429,6 +429,8 @@ 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)
+
/*
ignore lock specs for CREATE statement
*/
@@ -695,6 +697,10 @@ err:
lex->link_first_table_back(view, link_to_local);
unit->cleanup();
DBUG_RETURN(res || thd->is_error());
+#ifdef WITH_WSREP
+ error:
+ DBUG_RETURN(true);
+#endif /* WITH_WSREP */
}
@@ -1181,8 +1187,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);
}
@@ -1337,7 +1341,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;
ulonglong saved_mode= thd->variables.sql_mode;
/* switch off modes which can prevent normal parsing of VIEW
@@ -1371,9 +1375,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) ||
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index b4c0c4d45c3..1d380ce0c6b 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1182,6 +1182,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token DELAYED_SYM
%token DELAY_KEY_WRITE_SYM
%token DELETE_SYM /* SQL-2003-R */
+%token DELETE_DOMAIN_ID_SYM
%token DESC /* SQL-2003-N */
%token DESCRIBE /* SQL-2003-R */
%token DES_KEY_FILE
@@ -1951,6 +1952,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
parse_vcol_expr vcol_opt_specifier vcol_opt_attribute
vcol_opt_attribute_list vcol_attribute
explainable_command
+ opt_delete_gtid_domain
END_OF_INPUT
%type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
@@ -4678,17 +4680,11 @@ size_number:
switch (end_ptr[0])
{
case 'g':
- case 'G':
- text_shift_number+=10;
- /* fall through */
+ case 'G': text_shift_number+=30; break;
case 'm':
- case 'M':
- text_shift_number+=10;
- /* fall through */
+ case 'M': text_shift_number+=20; break;
case 'k':
- case 'K':
- text_shift_number+=10;
- break;
+ case 'K': text_shift_number+=10; break;
default:
my_yyabort_error((ER_WRONG_SIZE_NUMBER, MYF(0)));
}
@@ -5101,12 +5097,8 @@ 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;
}
else
part_info->part_type= HASH_PARTITION;
@@ -12768,7 +12760,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
{
@@ -12825,6 +12817,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; }
diff --git a/sql/structs.h b/sql/structs.h
index c1c832d07ec..2ab102d82f9 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -204,7 +204,7 @@ typedef int *(*update_var)(THD *, struct st_mysql_show_var *);
typedef struct st_lex_user {
LEX_STRING user, host, plugin, auth;
LEX_STRING pwtext, pwhash;
- bool is_role() { return user.str[0] && !host.str[0]; }
+ bool is_role() const { return user.str[0] && !host.str[0]; }
void set_lex_string(LEX_STRING *l, char *buf)
{
if (is_role())
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 8eb3d35a96e..303633939c3 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -4895,7 +4895,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 (
diff --git a/sql/table.cc b/sql/table.cc
index 3ab89897e07..ea0bc8f5c95 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1340,9 +1340,10 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
extra_rec_buf_length= uint2korr(frm_image+59);
rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length);
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);
@@ -2685,6 +2686,7 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
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);
if (records == 0)
{
@@ -2699,6 +2701,8 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
else
outparam->record[1]= outparam->record[0]; // Safety
}
+ MEM_UNDEFINED(outparam->record[0], share->reclength);
+ MEM_UNDEFINED(outparam->record[1], share->reclength);
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
(uint) ((share->fields+1)*
@@ -4260,6 +4264,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 ? alias : "<NULL>"),
+ get_unit()));
if (thd->stmt_arena->is_conventional() ||
thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
@@ -4715,20 +4722,29 @@ void TABLE_LIST::cleanup_items()
int TABLE_LIST::view_check_option(THD *thd, bool ignore_failure)
{
- if (check_option && check_option->val_int() == 0)
+ if (check_option)
{
- TABLE_LIST *main_view= top_table();
- if (ignore_failure)
+ Counting_error_handler ceh;
+ thd->push_internal_handler(&ceh);
+ bool res= check_option->val_int() == 0;
+ thd->pop_internal_handler();
+ if (ceh.errors)
+ return(VIEW_CHECK_ERROR);
+ if (res)
{
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_VIEW_CHECK_FAILED,
- ER_THD(thd, ER_VIEW_CHECK_FAILED),
- main_view->view_db.str, main_view->view_name.str);
- return(VIEW_CHECK_SKIP);
+ TABLE_LIST *main_view= top_table();
+ if (ignore_failure)
+ {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_VIEW_CHECK_FAILED,
+ ER_THD(thd, ER_VIEW_CHECK_FAILED),
+ main_view->view_db.str, main_view->view_name.str);
+ return(VIEW_CHECK_SKIP);
+ }
+ my_error(ER_VIEW_CHECK_FAILED, MYF(0), main_view->view_db.str,
+ main_view->view_name.str);
+ return(VIEW_CHECK_ERROR);
}
- my_error(ER_VIEW_CHECK_FAILED, MYF(0), main_view->view_db.str,
- main_view->view_name.str);
- return(VIEW_CHECK_ERROR);
}
return(VIEW_CHECK_OK);
}
@@ -5339,7 +5355,8 @@ Item *Field_iterator_table::create_item(THD *thd)
Item_field *item= new (thd->mem_root) Item_field(thd, &select->context, *ptr);
if (item && thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
- !thd->lex->in_sum_func && select->cur_pos_in_select_list != UNDEF_POS)
+ !thd->lex->in_sum_func && select->cur_pos_in_select_list != UNDEF_POS &&
+ select->join)
{
select->join->non_agg_fields.push_back(item);
item->marker= select->cur_pos_in_select_list;
@@ -6327,6 +6344,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 +
diff --git a/sql/table.h b/sql/table.h
index 876f496a312..5abb99cd0c7 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -35,6 +35,7 @@
/* Structs that defines the TABLE */
class Item; /* Needed by ORDER */
+typedef Item (*Item_ptr);
class Item_subselect;
class Item_field;
class GRANT_TABLE;
@@ -2286,6 +2287,9 @@ struct TABLE_LIST
inline void set_merged_derived()
{
DBUG_ENTER("set_merged_derived");
+ DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
+ (alias ? alias : "<NULL>"),
+ get_unit()));
derived_type= ((derived_type & DTYPE_MASK) |
DTYPE_TABLE | DTYPE_MERGE);
set_check_merged();
@@ -2298,6 +2302,9 @@ struct TABLE_LIST
void set_materialized_derived()
{
DBUG_ENTER("set_materialized_derived");
+ DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
+ (alias ? alias : "<NULL>"),
+ get_unit()));
derived_type= ((derived_type & (derived ? DTYPE_MASK : DTYPE_VIEW)) |
DTYPE_TABLE | DTYPE_MATERIALIZE);
set_check_materialized();
@@ -2528,7 +2535,7 @@ typedef struct st_nested_join
table_map sj_depends_on;
/* Outer non-trivially correlated tables */
table_map sj_corr_tables;
- List<Item> sj_outer_expr_list;
+ List<Item_ptr> sj_outer_expr_list;
/**
True if this join nest node is completely covered by the query execution
plan. This means two things.
diff --git a/sql/transaction.cc b/sql/transaction.cc
index f03cced7bc8..1744feea151 100644
--- a/sql/transaction.cc
+++ b/sql/transaction.cc
@@ -536,12 +536,8 @@ bool trans_savepoint(THD *thd, LEX_STRING 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);
@@ -616,12 +612,8 @@ bool trans_rollback_to_savepoint(THD *thd, LEX_STRING 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/uniques.cc b/sql/uniques.cc
index e88cd035549..1ce186b48e1 100644
--- a/sql/uniques.cc
+++ b/sql/uniques.cc
@@ -100,6 +100,9 @@ Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg,
*/
max_elements= (ulong) (max_in_memory_size /
ALIGN_SIZE(sizeof(TREE_ELEMENT)+size));
+ if (!max_elements)
+ max_elements= 1;
+
(void) open_cached_file(&file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE,
MYF(MY_WME));
}
@@ -643,11 +646,12 @@ bool Unique::walk(TABLE *table, tree_walk_action action, void *walk_action_arg)
if (flush_io_cache(&file) || reinit_io_cache(&file, READ_CACHE, 0L, 0, 0))
return 1;
/*
- merge_buffer must fit at least MERGEBUFF2 keys, because
- merge_index() can merge that many BUFFPEKs at once.
+ merge_buffer must fit at least MERGEBUFF2 + 1 keys, because
+ merge_index() can merge that many BUFFPEKs at once. The extra space for one key
+ is needed when a piece of merge buffer is re-read, see merge_walk()
*/
- size_t buff_sz= MY_MAX(MERGEBUFF2, max_in_memory_size/full_size+1) * full_size;
- if (!(merge_buffer = (uchar *)my_malloc(buff_sz, MYF(MY_THREAD_SPECIFIC|MY_WME))))
+ size_t buff_sz= MY_MAX(MERGEBUFF2+1, max_in_memory_size/full_size+1) * full_size;
+ if (!(merge_buffer = (uchar *)my_malloc(buff_sz, MYF(MY_WME))))
return 1;
if (buff_sz < full_size * (file_ptrs.elements + 1UL))
res= merge(table, merge_buffer, buff_sz >= full_size * MERGEBUFF2) ;
@@ -707,8 +711,8 @@ bool Unique::merge(TABLE *table, uchar *buff, bool without_last_merge)
full_size;
sort_param.min_dupl_count= min_dupl_count;
sort_param.res_length= 0;
- sort_param.max_keys_per_buffer=
- (uint) (max_in_memory_size / sort_param.sort_length);
+ sort_param.max_keys_per_buffer=
+ (uint) MY_MAX((max_in_memory_size / sort_param.sort_length), MERGEBUFF2);
sort_param.not_killable= 1;
sort_param.unique_buff= buff +(sort_param.max_keys_per_buffer *
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 66959f400d9..e41cca2dfcb 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
@@ -83,7 +83,7 @@ static uchar *extra2_write(uchar *pos, enum extra2_frm_value_type type,
return extra2_write(pos, type, reinterpret_cast<LEX_STRING *>(str));
}
-/**
+/*
Create a frm (table definition) file
@param thd Thread handler
@@ -160,7 +160,8 @@ 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))
DBUG_RETURN(frm);
/*
If table comment is longer than TABLE_COMMENT_INLINE_MAXLEN bytes,
@@ -263,6 +264,14 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
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);
+ goto err;
+ }
int2store(forminfo+2, frm.length - filepos);
int4store(fileinfo+10, frm.length);
diff --git a/sql/wsrep_binlog.cc b/sql/wsrep_binlog.cc
index b6aee3a74ab..998f4e72157 100644
--- a/sql/wsrep_binlog.cc
+++ b/sql/wsrep_binlog.cc
@@ -452,7 +452,7 @@ void wsrep_dump_rbr_buf_with_header(THD *thd, const void *rbr_buf,
File file;
IO_CACHE cache;
Log_event_writer writer(&cache);
- Format_description_log_event *ev;
+ Format_description_log_event *ev=NULL;
int len= my_snprintf(filename, PATH_MAX, "%s/GRA_%ld_%lld_v2.log",
wsrep_data_home_dir, thd->thread_id,
diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc
index a8a0d574362..75c1526cb15 100644
--- a/sql/wsrep_hton.cc
+++ b/sql/wsrep_hton.cc
@@ -505,6 +505,9 @@ wsrep_run_wsrep_commit(THD *thd, bool all)
}
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
+
+ DEBUG_SYNC(thd, "wsrep_after_replication");
+
switch(rcode) {
case 0:
/*
@@ -536,6 +539,7 @@ wsrep_run_wsrep_commit(THD *thd, bool all)
break;
case WSREP_BF_ABORT:
DBUG_ASSERT(thd->wsrep_trx_meta.gtid.seqno != WSREP_SEQNO_UNDEFINED);
+ /* fall through */
case WSREP_TRX_FAIL:
WSREP_DEBUG("commit failed for reason: %d", rcode);
DBUG_PRINT("wsrep", ("replicating commit fail"));
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index 67b64301ff9..285bb520b87 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -1227,6 +1227,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)
@@ -1363,64 +1373,6 @@ static int wsrep_create_sp(THD *thd, uchar** buf, size_t* buf_len);
static int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len);
/*
- Rewrite DROP TABLE for TOI. Temporary tables are eliminated from
- the query as they are visible only to client connection.
-
- TODO: See comments for sql_base.cc:drop_temporary_table() and refine
- the function to deal with transactional locked tables.
- */
-static int wsrep_drop_table_query(THD* thd, uchar** buf, size_t* buf_len)
-{
-
- LEX* lex= thd->lex;
- SELECT_LEX* select_lex= &lex->select_lex;
- TABLE_LIST* first_table= select_lex->table_list.first;
- String buff;
-
- bool found_temp_table= false;
- for (TABLE_LIST* table= first_table; table; table= table->next_global)
- {
- if (find_temporary_table(thd, table->db, table->table_name))
- {
- found_temp_table= true;
- break;
- }
- }
-
- if (found_temp_table)
- {
- buff.append("DROP TABLE ");
- if (lex->check_exists)
- buff.append("IF EXISTS ");
-
- for (TABLE_LIST* table= first_table; table; table= table->next_global)
- {
- if (!find_temporary_table(thd, table->db, table->table_name))
- {
- append_identifier(thd, &buff, table->db, strlen(table->db));
- buff.append(".");
- append_identifier(thd, &buff, table->table_name,
- strlen(table->table_name));
- buff.append(",");
- }
- }
-
- /* Chop the last comma */
- buff.chop();
- buff.append(" /* generated by wsrep */");
-
- WSREP_DEBUG("Rewrote '%s' as '%s'", thd->query(), buff.ptr());
-
- return wsrep_to_buf_helper(thd, buff.ptr(), buff.length(), buf, buf_len);
- }
- else
- {
- return wsrep_to_buf_helper(thd, thd->query(), thd->query_length(),
- buf, buf_len);
- }
-}
-
-/*
Decide if statement should run in TOI.
Look if table or table_list contain temporary tables. If the
@@ -2034,7 +1986,7 @@ static bool abort_replicated(THD *thd)
bool ret_code= false;
if (thd->wsrep_query_state== QUERY_COMMITTING)
{
- WSREP_DEBUG("aborting replicated trx: %lu", thd->real_id);
+ WSREP_DEBUG("aborting replicated trx: %llu", (ulonglong)(thd->real_id));
(void)wsrep_abort_thd(thd, thd, TRUE);
ret_code= true;
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index a187c75baa3..94804a6d3c7 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -30,9 +30,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};
const char* wsrep_sst_method = WSREP_SST_DEFAULT;
const char* wsrep_sst_receive_address = WSREP_SST_ADDRESS_AUTO;
@@ -75,7 +76,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);
}
}
@@ -385,7 +390,7 @@ static int generate_binlog_opt_val(char** ret)
{
assert(opt_bin_logname);
*ret= strcmp(opt_bin_logname, "0") ?
- my_strdup(opt_bin_logname, MYF(0)) : my_strdup("", MYF(0));
+ my_strdup(opt_bin_logname, MYF(0)) : my_strdup("", MYF(0));
}
else
{
@@ -581,8 +586,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)
@@ -864,7 +869,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 49dd5b39fad..dcf0ff22651 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_utils.cc b/sql/wsrep_utils.cc
index 580c8bbd55c..8a72d754a43 100644
--- a/sql/wsrep_utils.cc
+++ b/sql/wsrep_utils.cc
@@ -264,7 +264,6 @@ process::process (const char* cmd, const char* type, char** env)
err_ = posix_spawnattr_setflags (&attr, POSIX_SPAWN_SETSIGDEF |
POSIX_SPAWN_SETSIGMASK |
- /* start a new process group */ POSIX_SPAWN_SETPGROUP |
POSIX_SPAWN_USEVFORK);
if (err_)
{
diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc
index 1d117766db4..ad1f4ec0eac 100644
--- a/sql/wsrep_var.cc
+++ b/sql/wsrep_var.cc
@@ -52,12 +52,28 @@ int wsrep_init_vars()
return 0;
}
+extern ulong innodb_lock_schedule_algorithm;
+
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;
}
@@ -301,8 +317,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);
diff --git a/sql/wsrep_var.h b/sql/wsrep_var.h
index 7530fd98870..55eb2fbc501 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/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt
index 5541ca6c556..58d9ab1f1c3 100644
--- a/storage/connect/CMakeLists.txt
+++ b/storage/connect/CMakeLists.txt
@@ -45,34 +45,17 @@ add_definitions( -DHUGE_SUPPORT -DGZ_SUPPORT )
# OS specific C flags, definitions and source files.
#
IF(UNIX)
- if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
- # Bar: -Wfatal-errors removed (does not present in gcc on solaris10)
- if(WITH_WARNINGS)
- add_definitions(-Wall -Wextra -Wmissing-declarations)
- #message(STATUS "CONNECT: GCC: All warnings enabled")
- else()
- add_definitions(-Wall -Wmissing-declarations)
- add_definitions(-Wno-write-strings)
- add_definitions(-Wno-unused-variable)
- # Bar: -Wno-unused-but-set-variables commented (does not present on sol10)
- # add_definitions(-Wno-unused-but-set-variable)
- add_definitions(-Wno-unused-value)
- add_definitions(-Wno-unused-function)
- add_definitions(-Wno-parentheses)
- #add_definitions(-Wno-missing-declarations)
- # Bar: -Wno-int-to-pointer-cast commended (does not present in gcc on sol10)
- # add_definitions(-Wno-int-to-pointer-cast)
- # Bar: -Wno-narrowing commented (does not present in gcc on solaris10)
- # add_definitions(-Wno-narrowing)
-
-# This switch is for pure C only:
-# add_definitions(-Wno-implicit-function-declaration)
-# These switches are for C++ only
-# add_definitions(-Wno-reorder)
-
- #message(STATUS "CONNECT: GCC: Some warnings disabled")
- endif(WITH_WARNINGS)
- endif()
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wall -Wmissing-declarations")
+ if(NOT WITH_WARNINGS)
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-unused-function")
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-unused-variable")
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-unused-value")
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-parentheses")
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-strict-aliasing")
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-misleading-indentation")
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-format-truncation")
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-implicit-fallthrough")
+ endif(NOT WITH_WARNINGS)
add_definitions( -DUNIX -DLINUX -DUBUNTU )
@@ -247,7 +230,7 @@ ENDIF(CONNECT_WITH_ODBC)
#
# JDBC with MongoDB Java Driver included but disabled if without MONGO
#
-#OPTION(CONNECT_WITH_MONGO "Compile CONNECT storage engine with MONGO support" ON)
+OPTION(CONNECT_WITH_MONGO "Compile CONNECT storage engine with MONGO support" ON)
OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine with JDBC support" ON)
IF(CONNECT_WITH_JDBC)
@@ -302,7 +285,7 @@ IF(CONNECT_WITH_MONGO)
C:/mongo-c-driver/lib
D:/mongo-c-driver/lib)
ENDIF(WIN32)
- FIND_PACKAGE(libmongoc-1.0 1.7)
+ FIND_PACKAGE(libmongoc-1.0 1.7 QUIET)
IF (libmongoc-1.0_FOUND)
INCLUDE_DIRECTORIES(${MONGOC_INCLUDE_DIRS})
SET(MONGOC_LIBRARY ${MONGOC_LIBRARIES})
@@ -363,6 +346,23 @@ IF(WIN32)
DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
ENDIF(WIN32)
+IF(NOT TARGET connect)
+ RETURN()
+ENDIF()
+
+# Install some extra files that belong to connect engine
+IF(WIN32)
+ # install ha_connect.lib
+ GET_TARGET_PROPERTY(CONNECT_LOCATION connect LOCATION)
+ STRING(REPLACE "dll" "lib" CONNECT_LIB ${CONNECT_LOCATION})
+ IF(CMAKE_CONFIGURATION_TYPES)
+ STRING(REPLACE "${CMAKE_CFG_INTDIR}" "\${CMAKE_INSTALL_CONFIG_NAME}"
+ CONNECT_LIB ${CONNECT_LIB})
+ ENDIF()
+ INSTALL(FILES ${CONNECT_LIB}
+ DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
+ENDIF(WIN32)
+
IF(CONNECT_WITH_JDBC AND JAVA_FOUND AND JNI_FOUND)
# TODO: Find how to compile and install the java wrapper classes
# Find required libraries and include directories
@@ -373,4 +373,3 @@ IF(CONNECT_WITH_JDBC AND JAVA_FOUND AND JNI_FOUND)
${CMAKE_CURRENT_BINARY_DIR}/JdbcInterface.jar
DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
ENDIF()
-
diff --git a/storage/connect/array.cpp b/storage/connect/array.cpp
index c779fcef816..cd1785b48ac 100644
--- a/storage/connect/array.cpp
+++ b/storage/connect/array.cpp
@@ -520,7 +520,7 @@ bool ARRAY::FilTest(PGLOBAL g, PVAL valp, OPVAL opc, int opm)
} else if (opc != OP_EXIST) {
sprintf(g->Message, MSG(MISSING_ARG), opc);
- throw (int)TYPE_ARRAY;
+ throw (int)TYPE_ARRAY;
} else // OP_EXIST
return Nval > 0;
diff --git a/storage/connect/colblk.cpp b/storage/connect/colblk.cpp
index fa5c29aff74..a9cf43f3d96 100644
--- a/storage/connect/colblk.cpp
+++ b/storage/connect/colblk.cpp
@@ -412,4 +412,3 @@ void SIDBLK::ReadColumn(PGLOBAL)
// } // endif Sname
} // end of ReadColumn
-
diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc
index d731f7d9838..39123b18c59 100644
--- a/storage/connect/connect.cc
+++ b/storage/connect/connect.cc
@@ -1,4 +1,5 @@
-/* Copyright (C) MariaDB Corporation Ab
+/* Copyright (C) Olivier Bertrand 2004 - 2017
+ Copyright (C) MariaDB Corporation Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/connect/csort.cpp b/storage/connect/csort.cpp
index 13f325d8f3f..670131b8fd2 100644
--- a/storage/connect/csort.cpp
+++ b/storage/connect/csort.cpp
@@ -351,7 +351,7 @@ void CSORT::Qstx(int *base, int *max)
zlo = zhi = cnm = 0; // Avoid warning message
- lo = max - base; // Number of elements as longs
+ lo = (int)(max - base); // Number of elements as longs
if (Dup)
cnm = Cmpnum(lo);
@@ -472,7 +472,7 @@ void CSORT::Qstx(int *base, int *max)
i = him + 1;
if (Pof)
- Pof[him - Pex] = Pof[mid - Pex] = i - j;
+ Pof[him - Pex] = Pof[mid - Pex] = (int)(i - j);
/*******************************************************************/
/* Look at sizes of the two partitions, do the smaller one first */
@@ -481,8 +481,8 @@ void CSORT::Qstx(int *base, int *max)
/* But only repeat (recursively or by branching) if the partition */
/* is of at least size THRESH. */
/*******************************************************************/
- lo = j - base;
- hi = max - i;
+ lo = (int)(j - base);
+ hi = (int)(max - i);
if (Dup) { // Update progress information
zlo = Cmpnum(lo);
@@ -726,7 +726,7 @@ void CSORT::Qstc(int *base, int *max)
zlo = zhi = cnm = 0; // Avoid warning message
- lo = max - base; // Number of elements as longs
+ lo = (int)(max - base); // Number of elements as longs
if (Dup)
cnm = Cmpnum(lo);
@@ -853,7 +853,7 @@ void CSORT::Qstc(int *base, int *max)
/* the offset array values indicating break point and block size. */
/*******************************************************************/
if (Pof)
- Pof[lt - Pex] = Pof[(jj - 1) - Pex] = jj - lt;
+ Pof[lt - Pex] = Pof[(jj - 1) - Pex] = (int)(jj - lt);
/*******************************************************************/
/* Look at sizes of the two partitions, do the smaller one first */
@@ -862,8 +862,8 @@ void CSORT::Qstc(int *base, int *max)
/* But only repeat (recursively or by branching) if the partition */
/* is of at least size THRESH. */
/*******************************************************************/
- lo = lt - base;
- hi = gt - Swix;
+ lo = (int)(lt - base);
+ hi = (int)(gt - Swix);
if (Dup) { // Update progress information
zlo = Cmpnum(lo);
diff --git a/storage/connect/domdoc.cpp b/storage/connect/domdoc.cpp
index e24e10835c1..ba8eb829abd 100644
--- a/storage/connect/domdoc.cpp
+++ b/storage/connect/domdoc.cpp
@@ -13,6 +13,7 @@
#elif defined(MSX4)
#import "msxml4.dll" //Causes error C2872: DOMNodeType: ambiguous symbol ??
#elif defined(MSX6)
+#pragma warning(suppress : 4192)
#import "msxml6.dll" //Causes error C2872: DOMNodeType: ambiguous symbol ??
#else // MSX4
#error MSX? is not defined
@@ -540,7 +541,7 @@ PXNODE DOMNODE::AddChildNode(PGLOBAL g, PCSZ name, PXNODE np)
// If name has the format m[n] only m is taken as node name
if ((p = strchr(name, '[')))
- pn = BufAlloc(g, name, p - name);
+ pn = BufAlloc(g, name, (int)(p - name));
else
pn = name;
diff --git a/storage/connect/filamap.cpp b/storage/connect/filamap.cpp
index 956a70578f5..6e71e1bf2cd 100644
--- a/storage/connect/filamap.cpp
+++ b/storage/connect/filamap.cpp
@@ -247,7 +247,7 @@ int MAPFAM::GetRowID(void)
/***********************************************************************/
int MAPFAM::GetPos(void)
{
- return Fpos - Memory;
+ return (int)(Fpos - Memory);
} // end of GetPos
/***********************************************************************/
@@ -255,7 +255,7 @@ int MAPFAM::GetPos(void)
/***********************************************************************/
int MAPFAM::GetNextPos(void)
{
- return Mempos - Memory;
+ return (int)(Mempos - Memory);
} // end of GetNextPos
/***********************************************************************/
@@ -368,7 +368,7 @@ int MAPFAM::ReadBuffer(PGLOBAL g)
} // endif Mempos
// Set caller line buffer
- len = (Mempos - Fpos) - n;
+ len = (int)(Mempos - Fpos) - n;
// Don't rely on ENDING setting
if (len > 0 && *(Mempos - 2) == '\r')
@@ -428,7 +428,7 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
/* not required here, just setting of future Spos and Tpos. */
/*******************************************************************/
Tpos = Spos = Fpos;
- } else if ((n = Fpos - Spos) > 0) {
+ } else if ((n = (int)(Fpos - Spos)) > 0) {
/*******************************************************************/
/* Non consecutive line to delete. Move intermediate lines. */
/*******************************************************************/
@@ -461,7 +461,7 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
/*****************************************************************/
/* Remove extra records. */
/*****************************************************************/
- n = Tpos - Memory;
+ n = (int)(Tpos - Memory);
#if defined(__WIN__)
DWORD drc = SetFilePointer(fp->Handle, n, NULL, FILE_BEGIN);
@@ -627,7 +627,7 @@ int MBKFAM::ReadBuffer(PGLOBAL g)
break;
// Set caller line buffer
- len = (Mempos - Fpos) - Ending;
+ len = (int)(Mempos - Fpos) - Ending;
memcpy(Tdbp->GetLine(), Fpos, len);
Tdbp->GetLine()[len] = '\0';
return RC_OK;
diff --git a/storage/connect/filamgz.cpp b/storage/connect/filamgz.cpp
index fccda772fea..880db54c91d 100644
--- a/storage/connect/filamgz.cpp
+++ b/storage/connect/filamgz.cpp
@@ -537,7 +537,7 @@ int ZBKFAM::ReadBuffer(PGLOBAL g)
while (*NxtLine++ != '\n') ;
// Set caller line buffer
- n = NxtLine - CurLine - Ending;
+ n = (int)(NxtLine - CurLine - Ending);
memcpy(Tdbp->GetLine(), CurLine, n);
Tdbp->GetLine()[n] = '\0';
return RC_OK;
@@ -588,7 +588,7 @@ int ZBKFAM::ReadBuffer(PGLOBAL g)
for (NxtLine = CurLine; *NxtLine++ != '\n';) ;
// Set caller line buffer
- n = NxtLine - CurLine - Ending;
+ n = (int)(NxtLine - CurLine - Ending);
memcpy(Tdbp->GetLine(), CurLine, n);
Tdbp->GetLine()[n] = '\0';
Rbuf = (CurBlk == Block - 1) ? Last : Nrec;
@@ -1087,7 +1087,7 @@ bool ZLBFAM::SetPos(PGLOBAL g, int pos __attribute__((unused)))
/***********************************************************************/
int ZLBFAM::ReadBuffer(PGLOBAL g)
{
- int n;
+ size_t n;
void *rdbuf;
/*********************************************************************/
@@ -1299,7 +1299,7 @@ int ZLBFAM::WriteBuffer(PGLOBAL g)
else
NxtLine = CurLine + Lrecl;
- BlkLen = NxtLine - To_Buf;
+ BlkLen = (int)(NxtLine - To_Buf);
if (WriteCompressedBuffer(g)) {
Closing = TRUE; // To tell CloseDB about a Write error
diff --git a/storage/connect/filamtxt.cpp b/storage/connect/filamtxt.cpp
index e6c9a627df0..7c222eb3c80 100644
--- a/storage/connect/filamtxt.cpp
+++ b/storage/connect/filamtxt.cpp
@@ -1351,7 +1351,7 @@ int BLKFAM::GetPos(void)
/***********************************************************************/
int BLKFAM::GetNextPos(void)
{
- return Fpos + NxtLine - CurLine;
+ return (int)(Fpos + NxtLine - CurLine);
} // end of GetNextPos
/***********************************************************************/
@@ -1396,7 +1396,8 @@ int BLKFAM::SkipRecord(PGLOBAL, bool header)
/***********************************************************************/
int BLKFAM::ReadBuffer(PGLOBAL g)
{
- int i, n, rc = RC_OK;
+ int i, rc = RC_OK;
+ size_t n;
/*********************************************************************/
/* Sequential reading when Placed is not true. */
@@ -1458,7 +1459,7 @@ int BLKFAM::ReadBuffer(PGLOBAL g)
// Read the entire next block
n = fread(To_Buf, 1, (size_t)BlkLen, Stream);
- if (n == BlkLen) {
+ if ((size_t) n == (size_t) BlkLen) {
// ReadBlks++;
num_read++;
Rbuf = (CurBlk == Block - 1) ? Last : Nrec;
@@ -1497,7 +1498,7 @@ int BLKFAM::ReadBuffer(PGLOBAL g)
fin:
// Store the current record file position for Delete and Update
- Fpos = BlkPos[CurBlk] + CurLine - To_Buf;
+ Fpos = (int)(BlkPos[CurBlk] + CurLine - To_Buf);
return rc;
} // end of ReadBuffer
@@ -1524,7 +1525,7 @@ int BLKFAM::WriteBuffer(PGLOBAL g)
// Now start the writing process.
NxtLine = CurLine + strlen(CurLine);
- BlkLen = NxtLine - To_Buf;
+ BlkLen = (int)(NxtLine - To_Buf);
if (fwrite(To_Buf, 1, BlkLen, Stream) != (size_t)BlkLen) {
sprintf(g->Message, MSG(FWRITE_ERROR), strerror(errno));
diff --git a/storage/connect/filamzip.cpp b/storage/connect/filamzip.cpp
index 53e30d0fa02..e76dc496246 100644
--- a/storage/connect/filamzip.cpp
+++ b/storage/connect/filamzip.cpp
@@ -748,7 +748,7 @@ UNZFAM::UNZFAM(PUNZFAM txfp) : MAPFAM(txfp)
/***********************************************************************/
int UNZFAM::GetFileLength(PGLOBAL g)
{
- int len = (zutp && zutp->entryopen) ? Top - Memory
+ int len = (zutp && zutp->entryopen) ? (int)(Top - Memory)
: TXTFAM::GetFileLength(g) * 3;
if (trace(1))
@@ -1088,7 +1088,7 @@ int ZIPFAM::WriteBuffer(PGLOBAL g)
// Prepare to write the new line
strcat(strcpy(To_Buf, Tdbp->GetLine()), (Bin) ? CrLf : "\n");
- len = strchr(To_Buf, '\n') - To_Buf + 1;
+ len = (int)(strchr(To_Buf, '\n') - To_Buf + 1);
return zutp->writeEntry(g, To_Buf, len);
} // end of WriteBuffer
diff --git a/storage/connect/filter.cpp b/storage/connect/filter.cpp
index 47fead660fd..7082b082c67 100644
--- a/storage/connect/filter.cpp
+++ b/storage/connect/filter.cpp
@@ -84,7 +84,7 @@ BYTE OpBmp(PGLOBAL g, OPVAL opc)
case OP_EXIST: bt = 0x00; break;
default:
sprintf(g->Message, MSG(BAD_FILTER_OP), opc);
- throw (int)TYPE_ARRAY;
+ throw (int)TYPE_FILTER;
} // endswitch opc
return bt;
@@ -1707,7 +1707,7 @@ PFIL PrepareFilter(PGLOBAL g, PFIL fp, bool having)
break; // Remove eventual ending separator(s)
// if (fp->Convert(g, having))
-// (int)throw TYPE_ARRAY;
+// throw (int)TYPE_FILTER;
filp = fp;
fp = fp->Next;
diff --git a/storage/connect/fmdlex.c b/storage/connect/fmdlex.c
index 548a7ae5b7e..729b1b883c1 100644
--- a/storage/connect/fmdlex.c
+++ b/storage/connect/fmdlex.c
@@ -283,7 +283,7 @@ static void yy_fatal_error YY_PROTO(( const char msg[] ));
*/
#define YY_DO_BEFORE_ACTION \
yytext_ptr = yy_bp; \
- yyleng = yy_cp - yy_bp; \
+ yyleng = (int)(yy_cp - yy_bp); \
yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \
yy_c_buf_p = yy_cp;
@@ -417,10 +417,10 @@ static PDTP pp;
static void MakeParm(int n);
static void MakeMMDD(int n);
static void MakeAMPM(int n);
-static void MakeIn(char *);
-static void MakeOut(char *);
-static void Quotin(char *);
-static void Quotout(char *);
+static void MakeIn(const char *);
+static void MakeOut(const char *);
+static void Quotin(const char *);
+static void Quotout(const char *);
/* Macros after this point can all be overridden by user definitions in
* section 1.
@@ -529,7 +529,7 @@ YY_DECL
pp->Num = 0;
if (pp->InFmt) {*pp->InFmt = '\0'; pp->InFmt[pp->Outsize -1] = '\0'; }
if (pp->OutFmt) {*pp->OutFmt = '\0'; pp->OutFmt[pp->Outsize -1] = '\0'; }
- pp->Curp = pp->Format;
+ pp->Curp = (char*) pp->Format;
yy_init = 1; /* This is a new input */
@@ -695,7 +695,7 @@ case YY_STATE_EOF(dqt):
case YY_END_OF_BUFFER:
{
/* Amount of text matched not including the EOB char. */
- int yy_amount_of_matched_text = yy_cp - yytext_ptr - 1;
+ int yy_amount_of_matched_text = (int)(yy_cp - yytext_ptr - 1);
/* Undo the effects of YY_DO_BEFORE_ACTION. */
*yy_cp = yy_hold_char;
@@ -862,7 +862,7 @@ static int yy_get_next_buffer()
/* Try to read more data. */
/* First move last chars to start of buffer. */
- number_to_move = yy_c_buf_p - yytext_ptr;
+ number_to_move = (int)(yy_c_buf_p - yytext_ptr);
for ( i = 0; i < number_to_move; ++i )
*(dest++) = *(source++);
@@ -888,7 +888,7 @@ static int yy_get_next_buffer()
/* just a shorter name for the current buffer */
YY_BUFFER_STATE b = yy_current_buffer;
- int yy_c_buf_p_offset = yy_c_buf_p - b->yy_ch_buf;
+ int yy_c_buf_p_offset = (int)(yy_c_buf_p - b->yy_ch_buf);
b->yy_buf_size *= 2;
b->yy_ch_buf = (char *)
@@ -1492,7 +1492,7 @@ void MakeAMPM(int n)
} /* end of MakeAMPM */
-void MakeIn(char *text)
+void MakeIn(const char *text)
{
if (!pp->InFmt)
return;
@@ -1500,14 +1500,14 @@ void MakeIn(char *text)
strncat(pp->InFmt, text, (pp->Outsize - 1) - strlen(pp->InFmt));
} /* end of MakeIn */
-void MakeOut(char *text)
+void MakeOut(const char *text)
{
if (!pp->OutFmt) return;
strncat(pp->OutFmt, text, (pp->Outsize - 1) - strlen(pp->OutFmt));
} /* end of MakeOut */
-void Quotin(char *text)
+void Quotin(const char *text)
{
if (!pp->InFmt)
return;
@@ -1516,7 +1516,7 @@ void Quotin(char *text)
pp->InFmt[strlen(pp->InFmt)-1] = '\0';
} /* end of Quotin */
-void Quotout(char *text)
+void Quotout(const char *text)
{
if (!pp->OutFmt)
return;
diff --git a/storage/connect/global.h b/storage/connect/global.h
index 63d8782ee72..d8d03f606ba 100644
--- a/storage/connect/global.h
+++ b/storage/connect/global.h
@@ -220,7 +220,7 @@ DllExport BOOL PlugIsAbsolutePath(LPCSTR path);
DllExport bool AllocSarea(PGLOBAL, uint);
DllExport void FreeSarea(PGLOBAL);
DllExport BOOL PlugSubSet(PGLOBAL, void *, uint);
-DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t);
+ void *PlugSubAlloc(PGLOBAL, void *, size_t); // Does throw
DllExport char *PlugDup(PGLOBAL g, const char *str);
DllExport void *MakePtr(void *, OFFSET);
DllExport void htrc(char const *fmt, ...);
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 4c30938691f..2efed93ee2a 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -98,8 +98,8 @@
rnd_next signals that it has reached the end of its data. Calls to
ha_connect::extra() are hints as to what will be occuring to the request.
- Author Olivier Bertrand
-*/
+ Author Olivier Bertrand
+ */
#ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation
@@ -425,7 +425,7 @@ handlerton *connect_hton= NULL;
/* Function to export session variable values to other source files. */
/***********************************************************************/
uint GetTraceValue(void)
- {return connect_hton ? THDVAR(current_thd, xtrace) : 0;}
+ {return (uint)(connect_hton ? THDVAR(current_thd, xtrace) : 0);}
bool ExactInfo(void) {return THDVAR(current_thd, exact_info);}
USETEMP UseTemp(void) {return (USETEMP)THDVAR(current_thd, use_tempfile);}
int GetConvSize(void) {return THDVAR(current_thd, conv_size);}
@@ -1107,55 +1107,55 @@ PCSZ GetListOption(PGLOBAL g, PCSZ opname, PCSZ oplist, PCSZ def)
if (!oplist)
return (char*)def;
- char key[16], val[256];
- char *pv, *pn, *pk= (char*)oplist;
- PCSZ opval= def;
- int n;
+ char key[16], val[256];
+ char *pv, *pn, *pk = (char*)oplist;
+ PCSZ opval = def;
+ int n;
while (*pk == ' ')
pk++;
- for (; pk; pk= pn) {
- pn= strchr(pk, ',');
- pv= strchr(pk, '=');
+ for (; pk; pk = pn) {
+ pn = strchr(pk, ',');
+ pv = strchr(pk, '=');
- if (pv && (!pn || pv < pn)) {
+ if (pv && (!pn || pv < pn)) {
n = MY_MIN(static_cast<size_t>(pv - pk), sizeof(key) - 1);
memcpy(key, pk, n);
while (n && key[n - 1] == ' ')
n--;
- key[n]= 0;
+ key[n] = 0;
- while(*(++pv) == ' ') ;
+ while (*(++pv) == ' ');
- n= MY_MIN((pn ? pn - pv : strlen(pv)), sizeof(val) - 1);
- memcpy(val, pv, n);
+ n = MY_MIN((pn ? pn - pv : strlen(pv)), sizeof(val) - 1);
+ memcpy(val, pv, n);
while (n && val[n - 1] == ' ')
n--;
- val[n]= 0;
- } else {
- n= MY_MIN((pn ? pn - pk : strlen(pk)), sizeof(key) - 1);
- memcpy(key, pk, n);
+ val[n] = 0;
+ } else {
+ n = MY_MIN((pn ? pn - pk : strlen(pk)), sizeof(key) - 1);
+ memcpy(key, pk, n);
while (n && key[n - 1] == ' ')
n--;
- key[n]= 0;
- val[0]= 0;
- } // endif pv
+ key[n] = 0;
+ val[0] = 0;
+ } // endif pv
- if (!stricmp(opname, key)) {
- opval= PlugDup(g, val);
- break;
- } else if (!pn)
- break;
+ if (!stricmp(opname, key)) {
+ opval = PlugDup(g, val);
+ break;
+ } else if (!pn)
+ break;
- while (*(++pn) == ' ') ;
- } // endfor pk
+ while (*(++pn) == ' ');
+ } // endfor pk
return opval;
} // end of GetListOption
@@ -4391,53 +4391,59 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn, bool quick)
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
return true;
} // endif path
- }
+
+ } // endif !quick
+
} else
return false;
- /* Fall through to check FILE_ACL */
- case TAB_ODBC:
- case TAB_JDBC:
+ // Fall through
case TAB_MYSQL:
- case TAB_MONGO:
case TAB_DIR:
- case TAB_MAC:
- case TAB_WMI:
case TAB_ZIP:
case TAB_OEM:
#ifdef NO_EMBEDDED_ACCESS_CHECKS
- return false;
-#endif
- /*
- If table or table->mdl_ticket is NULL - it's a DLL, e.g. CREATE TABLE.
- if the table has an MDL_EXCLUSIVE lock - it's a DDL too, e.g. the
- insert step of CREATE ... SELECT.
-
- Otherwise it's a DML, the table was normally opened, locked,
- privilege were already checked, and table->grant.privilege is set.
- With SQL SECURITY DEFINER, table->grant.privilege has definer's privileges.
-
- Unless we're in prelocking mode, in this case table->grant.privilege
- is only checked in start_stmt(), not in external_lock().
- */
- if (!table || !table->mdl_ticket || table->mdl_ticket->get_type() == MDL_EXCLUSIVE)
- return check_access(thd, FILE_ACL, db, NULL, NULL, 0, 0);
- if ((!quick && thd->lex->requires_prelocking()) || table->grant.privilege & FILE_ACL)
- return false;
- status_var_increment(thd->status_var.access_denied_errors);
- my_error(access_denied_error_code(thd->password), MYF(0),
- thd->security_ctx->priv_user, thd->security_ctx->priv_host,
- (thd->password ? ER(ER_YES) : ER(ER_NO)));
- return true;
-
- // This is temporary until a solution is found
+ return false;
+ #endif
+
+ /*
+ Check FILE_ACL
+ If table or table->mdl_ticket is NULL - it's a DLL, e.g. CREATE TABLE.
+ if the table has an MDL_EXCLUSIVE lock - it's a DDL too, e.g. the
+ insert step of CREATE ... SELECT.
+
+ Otherwise it's a DML, the table was normally opened, locked,
+ privilege were already checked, and table->grant.privilege is set.
+ With SQL SECURITY DEFINER, table->grant.privilege has definer's privileges.
+
+ Unless we're in prelocking mode, in this case table->grant.privilege
+ is only checked in start_stmt(), not in external_lock().
+ */
+ if (!table || !table->mdl_ticket || table->mdl_ticket->get_type() == MDL_EXCLUSIVE)
+ return check_access(thd, FILE_ACL, db, NULL, NULL, 0, 0);
+
+ if ((!quick && thd->lex->requires_prelocking()) || table->grant.privilege & FILE_ACL)
+ return false;
+
+ status_var_increment(thd->status_var.access_denied_errors);
+ my_error(access_denied_error_code(thd->password), MYF(0),
+ thd->security_ctx->priv_user, thd->security_ctx->priv_host,
+ (thd->password ? ER(ER_YES) : ER(ER_NO)));
+ return true;
+ case TAB_ODBC:
+ case TAB_JDBC:
+ case TAB_MONGO:
+ case TAB_MAC:
+ case TAB_WMI:
+ return false;
case TAB_TBL:
case TAB_XCL:
case TAB_PRX:
case TAB_OCCUR:
case TAB_PIVOT:
case TAB_VIR:
- return false;
+ // This is temporary until a solution is found
+ return false;
} // endswitch type
my_printf_error(ER_UNKNOWN_ERROR, "check_privileges failed", MYF(0));
@@ -5629,7 +5635,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#endif // JAVA_SUPPORT
case TAB_DBF:
dbf = true;
- // Passthru
+ // fall through
case TAB_CSV:
if (!fn && fnc != FNC_NO)
sprintf(g->Message, "Missing %s file name", topt->type);
diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp
index 4e0cf401ed4..ff84c75b67f 100644
--- a/storage/connect/jdbconn.cpp
+++ b/storage/connect/jdbconn.cpp
@@ -154,38 +154,38 @@ int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v)
case 91: // DATE, YEAR
type = TYPE_DATE;
- if (!tn || toupper(tn[0]) != 'Y') {
- len = 10;
- v = 'D';
- } else {
- len = 4;
- v = 'Y';
- } // endif len
+ if (!tn || toupper(tn[0]) != 'Y') {
+ len = 10;
+ v = 'D';
+ } else {
+ len = 4;
+ v = 'Y';
+ } // endif len
- break;
- case 92: // TIME
- type = TYPE_DATE;
- len = 8 + ((prec) ? (prec+1) : 0);
- v = 'T';
- break;
- case -5: // BIGINT
- type = TYPE_BIGINT;
- break;
- case 0: // NULL
- case -2: // BINARY
- case -4: // LONGVARBINARY
- case 70: // DATALINK
- case 2000: // JAVA_OBJECT
- case 2001: // DISTINCT
- case 2002: // STRUCT
- case 2003: // ARRAY
- case 2004: // BLOB
- case 2005: // CLOB
- case 2006: // REF
- case 2009: // SQLXML
- case 2011: // NCLOB
- default:
- type = TYPE_ERROR;
+ break;
+ case 92: // TIME
+ type = TYPE_DATE;
+ len = 8 + ((prec) ? (prec + 1) : 0);
+ v = 'T';
+ break;
+ case -5: // BIGINT
+ type = TYPE_BIGINT;
+ break;
+ case 0: // NULL
+ case -2: // BINARY
+ case -4: // LONGVARBINARY
+ case 70: // DATALINK
+ case 2000: // JAVA_OBJECT
+ case 2001: // DISTINCT
+ case 2002: // STRUCT
+ case 2003: // ARRAY
+ case 2004: // BLOB
+ case 2005: // CLOB
+ case 2006: // REF
+ case 2009: // SQLXML
+ case 2011: // NCLOB
+ default:
+ type = TYPE_ERROR;
len = 0;
} // endswitch type
diff --git a/storage/connect/json.cpp b/storage/connect/json.cpp
index f6ed48c4d06..98a4659cea8 100644
--- a/storage/connect/json.cpp
+++ b/storage/connect/json.cpp
@@ -165,7 +165,7 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma)
}; // endswitch s[i]
if (!jsp)
- sprintf(g->Message, "Invalid Json string '%.*s'", 50, s);
+ sprintf(g->Message, "Invalid Json string '%.*s'", MY_MIN(len, 50), s);
else if (ptyp && pretty == 3) {
*ptyp = 3; // Not recognized pretty
@@ -1016,6 +1016,20 @@ PJAR JOBJECT::GetKeyList(PGLOBAL g)
} // end of GetKeyList
/***********************************************************************/
+/* Return all values as an array. */
+/***********************************************************************/
+PJAR JOBJECT::GetValList(PGLOBAL g)
+{
+ PJAR jarp = new(g) JARRAY();
+
+ for (PJPR jpp = First; jpp; jpp = jpp->Next)
+ jarp->AddValue(g, jpp->GetVal());
+
+ jarp->InitArray(g);
+ return jarp;
+} // end of GetValList
+
+/***********************************************************************/
/* Get the value corresponding to the given key. */
/***********************************************************************/
PJVAL JOBJECT::GetValue(const char* key)
@@ -1224,6 +1238,7 @@ PJVAL JARRAY::AddValue(PGLOBAL g, PJVAL jvp, int *x)
Last->Next = jvp;
Last = jvp;
+ Last->Next = NULL;
} // endif x
return jvp;
@@ -1319,6 +1334,24 @@ bool JARRAY::IsNull(void)
/* -------------------------- Class JVALUE- -------------------------- */
/***********************************************************************/
+/* Constructor for a JSON. */
+/***********************************************************************/
+JVALUE::JVALUE(PJSON jsp) : JSON()
+{
+ if (jsp->GetType() == TYPE_JVAL) {
+ Jsp = jsp->GetJsp();
+ Value = jsp->GetValue();
+ } else {
+ Jsp = jsp;
+ Value = NULL;
+ } // endif Type
+
+ Next = NULL;
+ Del = false;
+ Size = 1;
+} // end of JVALUE constructor
+
+/***********************************************************************/
/* Constructor for a Value with a given string or numeric value. */
/***********************************************************************/
JVALUE::JVALUE(PGLOBAL g, PVAL valp) : JSON()
diff --git a/storage/connect/json.h b/storage/connect/json.h
index 375532212c4..dcc97287420 100644
--- a/storage/connect/json.h
+++ b/storage/connect/json.h
@@ -20,7 +20,8 @@ enum JTYP {TYPE_NULL = TYPE_VOID,
TYPE_BINT = TYPE_BIGINT,
TYPE_DTM = TYPE_DATE,
TYPE_INTG = TYPE_INT,
- TYPE_JSON = 12,
+ TYPE_VAL = 12,
+ TYPE_JSON,
TYPE_JAR,
TYPE_JOB,
TYPE_JVAL};
@@ -157,6 +158,7 @@ class JSON : public BLOCK {
//virtual PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL, int *x = NULL) {X return NULL;}
virtual PJPR AddPair(PGLOBAL g, PCSZ key) {X return NULL;}
virtual PJAR GetKeyList(PGLOBAL g) {X return NULL;}
+ virtual PJAR GetValList(PGLOBAL g) {X return NULL;}
virtual PJVAL GetValue(const char *key) {X return NULL;}
virtual PJOB GetObject(void) {return NULL;}
virtual PJAR GetArray(void) {return NULL;}
@@ -205,6 +207,7 @@ class JOBJECT : public JSON {
virtual PJOB GetObject(void) {return this;}
virtual PJVAL GetValue(const char* key);
virtual PJAR GetKeyList(PGLOBAL g);
+ virtual PJAR GetValList(PGLOBAL g);
virtual PSZ GetText(PGLOBAL g, PSZ text);
virtual bool Merge(PGLOBAL g, PJSON jsp);
virtual void SetValue(PGLOBAL g, PJVAL jvp, PCSZ key);
@@ -258,8 +261,7 @@ class JVALUE : public JSON {
friend bool SerializeValue(JOUT *, PJVAL);
public:
JVALUE(void) : JSON() {Clear();}
- JVALUE(PJSON jsp) : JSON()
- {Jsp = jsp; Value = NULL; Next = NULL; Del = false; Size = 1;}
+ JVALUE(PJSON jsp);
JVALUE(PGLOBAL g, PVAL valp);
JVALUE(PGLOBAL g, PCSZ strp);
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index 952cd76ef8d..e45846ea23b 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -1,6 +1,6 @@
/****************** jsonudf C++ Program Source Code File (.CPP) ******************/
-/* PROGRAM NAME: jsonudf Version 1.6 */
-/* (C) Copyright to the author Olivier BERTRAND 2015-2017 */
+/* PROGRAM NAME: jsonudf Version 1.7 */
+/* (C) Copyright to the author Olivier BERTRAND 2015-2018 */
/* This program are the JSON User Defined Functions . */
/*********************************************************************************/
@@ -31,16 +31,39 @@ bool IsNum(PSZ s);
char *NextChr(PSZ s, char sep);
char *GetJsonNull(void);
uint GetJsonGrpSize(void);
-static int IsJson(UDF_ARGS *args, uint i);
+static int IsJson(UDF_ARGS *args, uint i, bool b = false);
static PSZ MakePSZ(PGLOBAL g, UDF_ARGS *args, int i);
static char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error);
static char *bin_handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error);
+static PJSON JsonNew(PGLOBAL g, JTYP type);
+static PJVAL JvalNew(PGLOBAL g, JTYP type, void *vp = NULL);
+static PJSNX JsnxNew(PGLOBAL g, PJSON jsp, int type, int len = 64);
static uint JsonGrpSize = 10;
-/* ----------------------------------- JSNX ------------------------------------ */
+/*********************************************************************************/
+/* SubAlloc a new JSNX class with protection against memory exhaustion. */
+/*********************************************************************************/
+static PJSNX JsnxNew(PGLOBAL g, PJSON jsp, int type, int len)
+{
+ PJSNX jsx;
+
+ try {
+ jsx = new(g) JSNX(g, jsp, type, len);
+ } catch (...) {
+ if (trace(1023))
+ htrc("%s\n", g->Message);
+
+ PUSH_WARNING(g->Message);
+ jsx = NULL;
+ } // end try/catch
+
+ return jsx;
+} /* end of JsnxNew */
+
+ /* ----------------------------------- JSNX ------------------------------------ */
/*********************************************************************************/
/* JSNX public constructor. */
@@ -81,21 +104,7 @@ my_bool JSNX::SetJpath(PGLOBAL g, char *path, my_bool jb)
return true;
Value->SetNullable(true);
-
-#if 0
- if (jb) {
- // Path must return a Json item
- size_t n = strlen(path);
-
- if (!n || path[n - 1] != '*') {
- Jpath = (char*)PlugSubAlloc(g, NULL, n + 3);
- strcat(strcpy(Jpath, path), (n) ? ":*" : "*");
- } else
- Jpath = path;
-
- } else
-#endif // 0
- Jpath = path;
+ Jpath = path;
// Parse the json path
Parsed = false;
@@ -753,6 +762,7 @@ my_bool JSNX::WriteValue(PGLOBAL g, PJVAL jvalp)
/*********************************************************************************/
PSZ JSNX::Locate(PGLOBAL g, PJSON jsp, PJVAL jvp, int k)
{
+ PSZ str = NULL;
my_bool b = false, err = true;
g->Message[0] = 0;
@@ -762,37 +772,47 @@ PSZ JSNX::Locate(PGLOBAL g, PJSON jsp, PJVAL jvp, int k)
return NULL;
} // endif jsp
- // Write to the path string
- Jp = new(g) JOUTSTR(g);
- Jp->WriteChr('$');
- Jvalp = jvp;
- K = k;
+ try {
+ // Write to the path string
+ Jp = new(g) JOUTSTR(g);
+ Jp->WriteChr('$');
+ Jvalp = jvp;
+ K = k;
- switch (jsp->GetType()) {
- case TYPE_JAR:
- err = LocateArray((PJAR)jsp);
- break;
- case TYPE_JOB:
- err = LocateObject((PJOB)jsp);
- break;
- case TYPE_JVAL:
- err = LocateValue((PJVAL)jsp);
- break;
- default:
- err = true;
+ switch (jsp->GetType()) {
+ case TYPE_JAR:
+ err = LocateArray((PJAR)jsp);
+ break;
+ case TYPE_JOB:
+ err = LocateObject((PJOB)jsp);
+ break;
+ case TYPE_JVAL:
+ err = LocateValue((PJVAL)jsp);
+ break;
+ default:
+ err = true;
} // endswitch Type
- if (err) {
- if (!g->Message[0])
- strcpy(g->Message, "Invalid json tree");
+ if (err) {
+ if (!g->Message[0])
+ strcpy(g->Message, "Invalid json tree");
- } else if (Found) {
- Jp->WriteChr('\0');
- PlugSubAlloc(g, NULL, Jp->N);
- return Jp->Strp;
- } // endif's
+ } else if (Found) {
+ Jp->WriteChr('\0');
+ PlugSubAlloc(g, NULL, Jp->N);
+ str = Jp->Strp;
+ } // endif's
- return NULL;
+ } catch (int n) {
+ if (trace(1))
+ htrc("Exception %d: %s\n", n, g->Message);
+
+ PUSH_WARNING(g->Message);
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ } // end catch
+
+ return str;
} // end of Locate
/*********************************************************************************/
@@ -864,53 +884,62 @@ my_bool JSNX::LocateValue(PJVAL jvp)
/*********************************************************************************/
PSZ JSNX::LocateAll(PGLOBAL g, PJSON jsp, PJVAL jvp, int mx)
{
+ PSZ str = NULL;
my_bool b = false, err = true;
- PJPN jnp = (PJPN)PlugSubAlloc(g, NULL, sizeof(JPN) * mx);
-
- memset(jnp, 0, sizeof(JPN) * mx);
- g->Message[0] = 0;
-
+ PJPN jnp;
+
if (!jsp) {
strcpy(g->Message, "Null json tree");
return NULL;
} // endif jsp
- // Write to the path string
- Jp = new(g)JOUTSTR(g);
- Jvalp = jvp;
- Imax = mx - 1;
- Jpnp = jnp;
- Jp->WriteChr('[');
+ try {
+ jnp = (PJPN)PlugSubAlloc(g, NULL, sizeof(JPN) * mx);
+ memset(jnp, 0, sizeof(JPN) * mx);
+ g->Message[0] = 0;
+
+ // Write to the path string
+ Jp = new(g)JOUTSTR(g);
+ Jvalp = jvp;
+ Imax = mx - 1;
+ Jpnp = jnp;
+ Jp->WriteChr('[');
+
+ switch (jsp->GetType()) {
+ case TYPE_JAR:
+ err = LocateArrayAll((PJAR)jsp);
+ break;
+ case TYPE_JOB:
+ err = LocateObjectAll((PJOB)jsp);
+ break;
+ case TYPE_JVAL:
+ err = LocateValueAll((PJVAL)jsp);
+ break;
+ default:
+ err = true;
+ } // endswitch Type
- switch (jsp->GetType()) {
- case TYPE_JAR:
- err = LocateArrayAll((PJAR)jsp);
- break;
- case TYPE_JOB:
- err = LocateObjectAll((PJOB)jsp);
- break;
- case TYPE_JVAL:
- err = LocateValueAll((PJVAL)jsp);
- break;
- default:
- err = true;
- } // endswitch Type
+ if (!err) {
+ if (Jp->N > 1)
+ Jp->N--;
- if (err) {
- if (!g->Message[0])
+ Jp->WriteChr(']');
+ Jp->WriteChr('\0');
+ PlugSubAlloc(g, NULL, Jp->N);
+ str = Jp->Strp;
+ } else if (!g->Message[0])
strcpy(g->Message, "Invalid json tree");
- return NULL;
- } else {
- if (Jp->N > 1)
- Jp->N--;
+ } catch (int n) {
+ if (trace(1))
+ htrc("Exception %d: %s\n", n, g->Message);
- Jp->WriteChr(']');
- Jp->WriteChr('\0');
- PlugSubAlloc(g, NULL, Jp->N);
- return Jp->Strp;
- } // endif's
+ PUSH_WARNING(g->Message);
+ } catch (const char *msg) {
+ strcpy(g->Message, msg);
+ } // end catch
+ return str;
} // end of LocateAll
/*********************************************************************************/
@@ -1138,6 +1167,72 @@ inline void JsonFreeMem(PGLOBAL g)
} /* end of JsonFreeMem */
/*********************************************************************************/
+/* SubAlloc a new JSON item with protection against memory exhaustion. */
+/*********************************************************************************/
+static PJSON JsonNew(PGLOBAL g, JTYP type)
+{
+ PJSON jsp = NULL;
+
+ try {
+ switch (type) {
+ case TYPE_JAR:
+ jsp = new(g) JARRAY;
+ break;
+ case TYPE_JOB:
+ jsp = new(g) JOBJECT;
+ break;
+ default:
+ break;
+ } // endswitch type
+
+ } catch (...) {
+ if (trace(1023))
+ htrc("%s\n", g->Message);
+
+ PUSH_WARNING(g->Message);
+ } // end try/catch
+
+ return jsp;
+} /* end of JsonNew */
+
+/*********************************************************************************/
+/* SubAlloc a new JValue with protection against memory exhaustion. */
+/*********************************************************************************/
+static PJVAL JvalNew(PGLOBAL g, JTYP type, void *vp)
+{
+ PJVAL jvp = NULL;
+
+ try {
+ if (!vp)
+ jvp = new (g) JVALUE;
+ else switch (type) {
+ case TYPE_JSON:
+ case TYPE_JVAL:
+ case TYPE_JAR:
+ case TYPE_JOB:
+ jvp = new(g) JVALUE((PJSON)vp);
+ break;
+ case TYPE_VAL:
+ jvp = new(g) JVALUE(g, (PVAL)vp);
+ break;
+ case TYPE_STRG:
+ jvp = new(g) JVALUE(g, (PCSZ)vp);
+ break;
+ default:
+ break;
+ } // endswitch type
+
+ } catch (...) {
+ if (trace(1023))
+ htrc("%s\n", g->Message);
+
+ PUSH_WARNING(g->Message);
+ } // end try/catch
+
+ return jvp;
+} /* end of JsonNew */
+
+/*********************************************************************************/
/* Allocate and initialise the memory area. */
/*********************************************************************************/
static my_bool JsonInit(UDF_INIT *initid, UDF_ARGS *args,
@@ -1289,8 +1384,11 @@ static int *GetIntArgPtr(PGLOBAL g, UDF_ARGS *args, uint& n)
for (uint i = n; i < args->arg_count; i++)
if (args->arg_type[i] == INT_RESULT) {
if (args->args[i]) {
- x = (int*)PlugSubAlloc(g, NULL, sizeof(int));
- *x = (int)*(longlong*)args->args[i];
+ if ((x = (int*)PlgDBSubAlloc(g, NULL, sizeof(int))))
+ *x = (int)*(longlong*)args->args[i];
+ else
+ PUSH_WARNING(g->Message);
+
} // endif args
n = i + 1;
@@ -1303,7 +1401,7 @@ static int *GetIntArgPtr(PGLOBAL g, UDF_ARGS *args, uint& n)
/*********************************************************************************/
/* Returns not 0 if the argument is a JSON item or file name. */
/*********************************************************************************/
-static int IsJson(UDF_ARGS *args, uint i)
+static int IsJson(UDF_ARGS *args, uint i, bool b)
{
int n = 0;
@@ -1320,8 +1418,20 @@ static int IsJson(UDF_ARGS *args, uint i)
else
n = 2; // A file name may have been returned
- } else if (!strnicmp(args->attributes[i], "Jfile_", 6))
+ } else if (!strnicmp(args->attributes[i], "Jfile_", 6)) {
n = 2; // arg is a json file name
+ } else if (b) {
+ char *sap;
+ PGLOBAL g = PlugInit(NULL, args->lengths[i] * M + 1024);
+
+ JsonSubSet(g);
+ sap = MakePSZ(g, args, i);
+
+ if (ParseJson(g, sap, strlen(sap)))
+ n = 4;
+
+ JsonFreeMem(g);
+ } // endif's
return n;
} // end of IsJson
@@ -1534,10 +1644,14 @@ static PSZ MakePSZ(PGLOBAL g, UDF_ARGS *args, int i)
{
if (args->arg_count > (unsigned)i && args->args[i]) {
int n = args->lengths[i];
- PSZ s = (PSZ)PlugSubAlloc(g, NULL, n + 1);
+ PSZ s = (PSZ)PlgDBSubAlloc(g, NULL, n + 1);
+
+ if (s) {
+ memcpy(s, args->args[i], n);
+ s[n] = 0;
+ } else
+ PUSH_WARNING(g->Message);
- memcpy(s, args->args[i], n);
- s[n] = 0;
return s;
} else
return NULL;
@@ -1574,9 +1688,12 @@ static PCSZ MakeKey(PGLOBAL g, UDF_ARGS *args, int i)
return "Key";
if (!b) {
- p = (PSZ)PlugSubAlloc(g, NULL, n + 1);
- memcpy(p, s, n);
- p[n] = 0;
+ if ((p = (PSZ)PlgDBSubAlloc(g, NULL, n + 1))) {
+ memcpy(p, s, n);
+ p[n] = 0;
+ } else
+ PUSH_WARNING(g->Message);
+
s = p;
} // endif b
@@ -1665,15 +1782,16 @@ static char *GetJsonFile(PGLOBAL g, char *fn)
return NULL;
} // endif len
- str = (char*)PlugSubAlloc(g, NULL, len + 1);
-
- if ((n = read(h, str, len)) < 0) {
- sprintf(g->Message, "Error %d reading %d bytes from %s", errno, len, fn);
- return NULL;
- } // endif n
+ if ((str = (char*)PlgDBSubAlloc(g, NULL, len + 1))) {
+ if ((n = read(h, str, len)) < 0) {
+ sprintf(g->Message, "Error %d reading %d bytes from %s", errno, len, fn);
+ return NULL;
+ } // endif n
- str[n] = 0;
- close(h);
+ str[n] = 0;
+ close(h);
+ } // endif str
+
return str;
} // end of GetJsonFile
@@ -1760,6 +1878,41 @@ static PJVAL MakeValue(PGLOBAL g, UDF_ARGS *args, uint i, PJSON *top = NULL)
} // end of MakeValue
/*********************************************************************************/
+/* Try making a JSON value of the passed type from the passed argument. */
+/*********************************************************************************/
+static PJVAL MakeTypedValue(PGLOBAL g, UDF_ARGS *args, uint i,
+ JTYP type, PJSON *top = NULL)
+{
+ char *sap;
+ PJSON jsp;
+ PJVAL jvp = MakeValue(g, args, i, top);
+
+ //if (type == TYPE_JSON) {
+ // if (jvp->GetValType() >= TYPE_JSON)
+ // return jvp;
+
+ //} else if (jvp->GetValType() == type)
+ // return jvp;
+
+ if (jvp->GetValType() == TYPE_STRG) {
+ sap = jvp->GetString(g);
+
+ if ((jsp = ParseJson(g, sap, strlen(sap)))) {
+ if ((type == TYPE_JSON && jsp->GetType() != TYPE_JVAL) || jsp->GetType() == type) {
+ if (top)
+ *top = jsp;
+
+ jvp->SetValue(jsp);
+ } // endif Type
+
+ } // endif jsp
+
+ } // endif Type
+
+ return jvp;
+} // end of MakeTypedValue
+
+/*********************************************************************************/
/* Make a Json value containing the parameter. */
/*********************************************************************************/
my_bool jsonvalue_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
@@ -1861,9 +2014,9 @@ my_bool json_array_add_values_init(UDF_INIT *initid, UDF_ARGS *args, char *messa
if (args->arg_count < 2) {
strcpy(message, "This function must have at least 2 arguments");
return true;
- } else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
- strcpy(message, "First argument must be a json string or item");
- return true;
+ //} else if (!IsJson(args, 0, true)) {
+ // strcpy(message, "First argument must be a valid json string or item");
+ // return true;
} else
CalcLen(args, false, reslen, memlen);
@@ -1891,23 +2044,14 @@ char *json_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!g->Xchk) {
if (!CheckMemory(g, initid, args, args->arg_count, true)) {
- char *p;
PJSON top;
PJAR arp;
- PJVAL jvp = MakeValue(g, args, 0, &top);
+ PJVAL jvp = MakeTypedValue(g, args, 0, TYPE_JAR, &top);
- if ((p = jvp->GetString(g))) {
- if (!(top = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- return NULL;
- } // endif jsp
-
- jvp->SetValue(top);
- } // endif p
-
if (jvp->GetValType() != TYPE_JAR) {
arp = new(g)JARRAY;
arp->AddValue(g, jvp);
+ top = arp;
} else
arp = jvp->GetArray();
@@ -1915,7 +2059,6 @@ char *json_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
arp->AddValue(g, MakeValue(g, args, i));
arp->InitArray(g);
-// str = Serialize(g, arp, NULL, 0);
str = MakeResult(g, args, top, args->arg_count);
} // endif CheckMemory
@@ -1952,10 +2095,10 @@ my_bool json_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
if (args->arg_count < 2) {
strcpy(message, "This function must have at least 2 arguments");
- return true;
- } else if (!IsJson(args, 0)) {
- strcpy(message, "First argument must be a json item");
- return true;
+ return true;
+ //} else if (!IsJson(args, 0, true)) {
+ // strcpy(message, "First argument is not a valid Json item");
+ // return true;
} else
CalcLen(args, false, reslen, memlen, true);
@@ -1994,22 +2137,38 @@ char *json_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
PJVAL jvp;
PJAR arp;
- jvp = MakeValue(g, args, 0, &top);
+ jvp = MakeTypedValue(g, args, 0, TYPE_JSON, &top);
jsp = jvp->GetJson();
x = GetIntArgPtr(g, args, n);
if (CheckPath(g, args, jsp, jvp, 2))
PUSH_WARNING(g->Message);
- else if (jvp && jvp->GetValType() == TYPE_JAR) {
+ else if (jvp) {
PGLOBAL gb = GetMemPtr(g, args, 0);
- arp = jvp->GetArray();
- arp->AddValue(gb, MakeValue(gb, args, 1), x);
- arp->InitArray(gb);
- str = MakeResult(g, args, top, n);
+ if (jvp->GetValType() != TYPE_JAR) {
+ if ((arp = (PJAR)JsonNew(gb, TYPE_JAR))) {
+ arp->AddValue(gb, JvalNew(gb, TYPE_JVAL, jvp));
+ jvp->SetValue(arp);
+
+ if (!top)
+ top = arp;
+
+ } // endif arp
+
+ } else
+ arp = jvp->GetArray();
+
+ if (arp) {
+ arp->AddValue(gb, MakeValue(gb, args, 1), x);
+ arp->InitArray(gb);
+ str = MakeResult(g, args, top, n);
+ } else
+ PUSH_WARNING(gb->Message);
+
} else {
- PUSH_WARNING("First argument target is not an array");
-// if (g->Mrr) *error = 1; (only if no path)
+ PUSH_WARNING("Target is not an array");
+ // if (g->Mrr) *error = 1; (only if no path)
} // endif jvp
} // endif CheckMemory
@@ -2048,9 +2207,6 @@ my_bool json_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
if (args->arg_count < 2) {
strcpy(message, "This function must have at least 2 arguments");
return true;
- } else if (!IsJson(args, 0)) {
- strcpy(message, "First argument must be a json item");
- return true;
} else
CalcLen(args, false, reslen, memlen, true);
@@ -2087,7 +2243,7 @@ char *json_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
uint n = 1;
PJSON top;
PJAR arp;
- PJVAL jvp = MakeValue(g, args, 0, &top);
+ PJVAL jvp = MakeTypedValue(g, args, 0, TYPE_JSON, &top);
if (!(x = GetIntArgPtr(g, args, n)))
PUSH_WARNING("Missing or null array index");
@@ -2186,9 +2342,14 @@ long long jsonsum_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *err
if (g->N) {
// Keep result of constant function
- long long *np = (long long*)PlugSubAlloc(g, NULL, sizeof(long long));
- *np = n;
- g->Activityp = (PACTIVITY)np;
+ long long *np;
+
+ if ((np = (long long*)PlgDBSubAlloc(g, NULL, sizeof(long long)))) {
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } else
+ PUSH_WARNING(g->Message);
+
} // endif const_item
return n;
@@ -2252,13 +2413,21 @@ double jsonsum_real(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error
} else {
*error = 1;
n = -1.0;
- } // end of CheckMemory
+ } // endif CheckMemory
if (g->N) {
// Keep result of constant function
- double *np = (double*)PlugSubAlloc(g, NULL, sizeof(double));
- *np = n;
- g->Activityp = (PACTIVITY)np;
+ double *np;
+
+ if ((np = (double*)PlgDBSubAlloc(g, NULL, sizeof(double)))) {
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } else {
+ PUSH_WARNING(g->Message);
+ *error = 1;
+ n = -1.0;
+ } // endif np
+
} // endif const_item
return n;
@@ -2312,13 +2481,20 @@ double jsonavg_real(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error
} else {
*error = 1;
n = -1.0;
- } // end of CheckMemory
+ } // endif CheckMemory
if (g->N) {
// Keep result of constant function
- double *np = (double*)PlugSubAlloc(g, NULL, sizeof(double));
- *np = n;
- g->Activityp = (PACTIVITY)np;
+ double *np;
+
+ if ((np = (double*)PlgDBSubAlloc(g, NULL, sizeof(double)))) {
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } else {
+ *error = 1;
+ n = -1.0;
+ } // endif np
+
} // endif const_item
return n;
@@ -2348,12 +2524,15 @@ char *json_make_object(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!g->Xchk) {
if (!CheckMemory(g, initid, args, args->arg_count, false, false, true)) {
- PJOB objp = new(g)JOBJECT;
+ PJOB objp;
+
+ if ((objp = (PJOB)JsonNew(g, TYPE_JOB))) {
+ for (uint i = 0; i < args->arg_count; i++)
+ objp->SetValue(g, MakeValue(g, args, i), MakeKey(g, args, i));
- for (uint i = 0; i < args->arg_count; i++)
- objp->SetValue(g, MakeValue(g, args, i), MakeKey(g, args, i));
+ str = Serialize(g, objp, NULL, 0);
+ } // endif objp
- str = Serialize(g, objp, NULL, 0);
} // endif CheckMemory
if (!str)
@@ -2394,13 +2573,16 @@ char *json_object_nonull(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!g->Xchk) {
if (!CheckMemory(g, initid, args, args->arg_count, false, true)) {
PJVAL jvp;
- PJOB objp = new(g)JOBJECT;
+ PJOB objp;
+
+ if ((objp = (PJOB)JsonNew(g, TYPE_JOB))) {
+ for (uint i = 0; i < args->arg_count; i++)
+ if (!(jvp = MakeValue(g, args, i))->IsNull())
+ objp->SetValue(g, jvp, MakeKey(g, args, i));
- for (uint i = 0; i < args->arg_count; i++)
- if (!(jvp = MakeValue(g, args, i))->IsNull())
- objp->SetValue(g, jvp, MakeKey(g, args, i));
+ str = Serialize(g, objp, NULL, 0);
+ } // endif objp
- str = Serialize(g, objp, NULL, 0);
} // endif CheckMemory
if (!str)
@@ -2444,12 +2626,15 @@ char *json_object_key(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!g->Xchk) {
if (!CheckMemory(g, initid, args, args->arg_count, false, true)) {
- PJOB objp = new(g)JOBJECT;
+ PJOB objp;
- for (uint i = 0; i < args->arg_count; i += 2)
- objp->SetValue(g, MakeValue(g, args, i+1), MakePSZ(g, args, i));
+ if ((objp = (PJOB)JsonNew(g, TYPE_JOB))) {
+ for (uint i = 0; i < args->arg_count; i += 2)
+ objp->SetValue(g, MakeValue(g, args, i + 1), MakePSZ(g, args, i));
+
+ str = Serialize(g, objp, NULL, 0);
+ } // endif objp
- str = Serialize(g, objp, NULL, 0);
} // endif CheckMemory
if (!str)
@@ -2732,6 +2917,82 @@ void json_object_list_deinit(UDF_INIT* initid)
} // end of json_object_list_deinit
/*********************************************************************************/
+/* Returns an array of the Json object values. */
+/*********************************************************************************/
+my_bool json_object_values_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+{
+ unsigned long reslen, memlen;
+
+ if (args->arg_count != 1) {
+ strcpy(message, "This function must have 1 argument");
+ return true;
+ } else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
+ strcpy(message, "Argument must be a json object");
+ return true;
+ } else
+ CalcLen(args, false, reslen, memlen);
+
+ return JsonInit(initid, args, message, true, reslen, memlen);
+} // end of json_object_list_init
+
+char *json_object_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
+ unsigned long *res_length, char *is_null, char *error)
+{
+ char *str = NULL;
+ PGLOBAL g = (PGLOBAL)initid->ptr;
+
+ if (!g->N) {
+ if (!CheckMemory(g, initid, args, 1, true, true)) {
+ char *p;
+ PJSON jsp;
+ PJVAL jvp = MakeValue(g, args, 0);
+
+ if ((p = jvp->GetString(g))) {
+ if (!(jsp = ParseJson(g, p, strlen(p)))) {
+ PUSH_WARNING(g->Message);
+ return NULL;
+ } // endif jsp
+
+ } else
+ jsp = jvp->GetJson();
+
+ if (jsp->GetType() == TYPE_JOB) {
+ PJAR jarp = ((PJOB)jsp)->GetValList(g);
+
+ if (!(str = Serialize(g, jarp, NULL, 0)))
+ PUSH_WARNING(g->Message);
+
+ } else {
+ PUSH_WARNING("First argument is not an object");
+ if (g->Mrr) *error = 1;
+ } // endif jvp
+
+ } // endif CheckMemory
+
+ if (initid->const_item) {
+ // Keep result of constant function
+ g->Xchk = str;
+ g->N = 1; // str can be NULL
+ } // endif const_item
+
+ } else
+ str = (char*)g->Xchk;
+
+ if (!str) {
+ *is_null = 1;
+ *res_length = 0;
+ } else
+ *res_length = strlen(str);
+
+ return str;
+} // end of json_object_values
+
+void json_object_values_deinit(UDF_INIT* initid)
+{
+ JsonFreeMem((PGLOBAL)initid->ptr);
+} // end of json_object_values_deinit
+
+/*********************************************************************************/
/* Set the value of JsonGrpSize. */
/*********************************************************************************/
my_bool jsonset_grp_size_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
@@ -2795,7 +3056,7 @@ my_bool json_array_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
PGLOBAL g = (PGLOBAL)initid->ptr;
PlugSubSet(g, g->Sarea, g->Sarea_Size);
- g->Activityp = (PACTIVITY)new(g) JARRAY;
+ g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JAR);
g->N = (int)n;
return false;
} // end of json_array_grp_init
@@ -2805,7 +3066,7 @@ void json_array_grp_add(UDF_INIT *initid, UDF_ARGS *args, char*, char*)
PGLOBAL g = (PGLOBAL)initid->ptr;
PJAR arp = (PJAR)g->Activityp;
- if (g->N-- > 0)
+ if (arp && g->N-- > 0)
arp->AddValue(g, MakeValue(g, args, 0));
} // end of json_array_grp_add
@@ -2820,12 +3081,16 @@ char *json_array_grp(UDF_INIT *initid, UDF_ARGS *, char *result,
if (g->N < 0)
PUSH_WARNING("Result truncated to json_grp_size values");
- arp->InitArray(g);
+ if (arp) {
+ arp->InitArray(g);
+ str = Serialize(g, arp, NULL, 0);
+ } else
+ str = NULL;
- if (!(str = Serialize(g, arp, NULL, 0)))
- str = strcpy(result, g->Message);
+ if (!str)
+ str = strcpy(result, g->Message);
- *res_length = strlen(str);
+ *res_length = strlen(str);
return str;
} // end of json_array_grp
@@ -2834,8 +3099,8 @@ void json_array_grp_clear(UDF_INIT *initid, char*, char*)
PGLOBAL g = (PGLOBAL)initid->ptr;
PlugSubSet(g, g->Sarea, g->Sarea_Size);
- g->Activityp = (PACTIVITY)new(g) JARRAY;
- g->N = GetJsonGroupSize();
+ g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JAR);
+ g->N = GetJsonGroupSize();
} // end of json_array_grp_clear
void json_array_grp_deinit(UDF_INIT* initid)
@@ -2868,7 +3133,7 @@ my_bool json_object_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
PGLOBAL g = (PGLOBAL)initid->ptr;
PlugSubSet(g, g->Sarea, g->Sarea_Size);
- g->Activityp = (PACTIVITY)new(g) JOBJECT;
+ g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JOB);
g->N = (int)n;
return false;
} // end of json_object_grp_init
@@ -2893,7 +3158,7 @@ char *json_object_grp(UDF_INIT *initid, UDF_ARGS *, char *result,
if (g->N < 0)
PUSH_WARNING("Result truncated to json_grp_size values");
- if (!(str = Serialize(g, objp, NULL, 0)))
+ if (!objp || !(str = Serialize(g, objp, NULL, 0)))
str = strcpy(result, g->Message);
*res_length = strlen(str);
@@ -2905,8 +3170,8 @@ void json_object_grp_clear(UDF_INIT *initid, char*, char*)
PGLOBAL g = (PGLOBAL)initid->ptr;
PlugSubSet(g, g->Sarea, g->Sarea_Size);
- g->Activityp = (PACTIVITY)new(g) JOBJECT;
- g->N = GetJsonGroupSize();
+ g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JOB);
+ g->N = GetJsonGroupSize();
} // end of json_object_grp_clear
void json_object_grp_deinit(UDF_INIT* initid)
@@ -3051,7 +3316,7 @@ my_bool json_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
char *json_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *)
{
- char *p, *path, *str = NULL;
+ char *path, *str = NULL;
PJSON jsp;
PJVAL jvp;
PJSNX jsx;
@@ -3067,17 +3332,10 @@ char *json_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (CheckMemory(g, initid, args, 1, true, true)) {
PUSH_WARNING("CheckMemory error");
goto fin;
- } else
- jvp = MakeValue(g, args, 0);
-
- if ((p = jvp->GetString(g))) {
- if (!(jsp = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- return NULL;
- } // endif jsp
+ } // endif CheckMemory
- } else
- jsp = jvp->GetJson();
+ jvp = MakeTypedValue(g, args, 0, TYPE_JSON);
+ jsp = jvp->GetJson();
if (g->Mrr) { // First argument is a constant
g->Xchk = jsp;
@@ -3088,9 +3346,9 @@ char *json_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
jsp = (PJSON)g->Xchk;
path = MakePSZ(g, args, 1);
- jsx = new(g) JSNX(g, jsp, TYPE_STRING, initid->max_length);
+ jsx = JsnxNew(g, jsp, TYPE_STRING, initid->max_length);
- if (jsx->SetJpath(g, path, true)) {
+ if (!jsx || jsx->SetJpath(g, path, true)) {
PUSH_WARNING(g->Message);
*is_null = 1;
return NULL;
@@ -3203,9 +3461,9 @@ char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result,
jsp = (PJSON)g->Xchk;
path = MakePSZ(g, args, 1);
- jsx = new(g) JSNX(g, jsp, TYPE_STRING, initid->max_length);
+ jsx = JsnxNew(g, jsp, TYPE_STRING, initid->max_length);
- if (jsx->SetJpath(g, path)) {
+ if (!jsx || jsx->SetJpath(g, path)) {
PUSH_WARNING(g->Message);
goto err;
} // endif SetJpath
@@ -3320,9 +3578,9 @@ long long jsonget_int(UDF_INIT *initid, UDF_ARGS *args,
jsp = (PJSON)g->Xchk;
path = MakePSZ(g, args, 1);
- jsx = new(g) JSNX(g, jsp, TYPE_BIGINT);
+ jsx = JsnxNew(g, jsp, TYPE_BIGINT);
- if (jsx->SetJpath(g, path)) {
+ if (!jsx || jsx->SetJpath(g, path)) {
PUSH_WARNING(g->Message);
*is_null = 1;
return 0;
@@ -3339,9 +3597,14 @@ long long jsonget_int(UDF_INIT *initid, UDF_ARGS *args,
if (initid->const_item) {
// Keep result of constant function
- long long *np = (long long*)PlugSubAlloc(g, NULL, sizeof(long long));
- *np = n;
- g->Activityp = (PACTIVITY)np;
+ long long *np = (long long*)PlgDBSubAlloc(g, NULL, sizeof(long long));
+
+ if (np) {
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } else
+ PUSH_WARNING(g->Message);
+
} // endif const_item
return n;
@@ -3434,9 +3697,9 @@ double jsonget_real(UDF_INIT *initid, UDF_ARGS *args,
jsp = (PJSON)g->Xchk;
path = MakePSZ(g, args, 1);
- jsx = new(g) JSNX(g, jsp, TYPE_DOUBLE);
+ jsx = JsnxNew(g, jsp, TYPE_DOUBLE);
- if (jsx->SetJpath(g, path)) {
+ if (!jsx || jsx->SetJpath(g, path)) {
PUSH_WARNING(g->Message);
*is_null = 1;
return 0.0;
@@ -3453,9 +3716,17 @@ double jsonget_real(UDF_INIT *initid, UDF_ARGS *args,
if (initid->const_item) {
// Keep result of constant function
- double *dp = (double*)PlugSubAlloc(g, NULL, sizeof(double));
- *dp = d;
- g->Activityp = (PACTIVITY)dp;
+ double *dp;
+
+ if ((dp = (double*)PlgDBSubAlloc(g, NULL, sizeof(double)))) {
+ *dp = d;
+ g->Activityp = (PACTIVITY)dp;
+ } else {
+ PUSH_WARNING(g->Message);
+ *is_null = 1;
+ return 0.0;
+ } // endif dp
+
} // endif const_item
return d;
@@ -3501,7 +3772,7 @@ my_bool jsonlocate_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
{
- char *p, *path = NULL;
+ char *path = NULL;
int k;
PJVAL jvp, jvp2;
PJSON jsp;
@@ -3529,16 +3800,20 @@ char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result,
*error = 1;
goto err;
} else
- jvp = MakeValue(g, args, 0);
-
- if ((p = jvp->GetString(g))) {
- if (!(jsp = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- goto err;
- } // endif jsp
-
- } else
- jsp = jvp->GetJson();
+ jvp = MakeTypedValue(g, args, 0, TYPE_JSON);
+
+ //if ((p = jvp->GetString(g))) {
+ // if (!(jsp = ParseJson(g, p, strlen(p)))) {
+ // PUSH_WARNING(g->Message);
+ // goto err;
+ // } // endif jsp
+ //} else
+ // jsp = jvp->GetJson();
+
+ if (!(jsp = jvp->GetJson())) {
+ PUSH_WARNING("First argument is not a valid JSON item");
+ goto err;
+ } // endif jsp
if (g->Mrr) { // First argument is a constant
g->Xchk = jsp;
@@ -3845,9 +4120,9 @@ long long jsoncontains_path(UDF_INIT *initid, UDF_ARGS *args, char *result,
jsp = (PJSON)g->Xchk;
path = MakePSZ(g, args, 1);
- jsx = new(g)JSNX(g, jsp, TYPE_BIGINT);
+ jsx = JsnxNew(g, jsp, TYPE_BIGINT);
- if (jsx->SetJpath(g, path)) {
+ if (!jsx || jsx->SetJpath(g, path)) {
PUSH_WARNING(g->Message);
goto err;
} // endif SetJpath
@@ -3856,9 +4131,14 @@ long long jsoncontains_path(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (initid->const_item) {
// Keep result of constant function
- long long *np = (long long*)PlugSubAlloc(g, NULL, sizeof(long long));
- *np = n;
- g->Activityp = (PACTIVITY)np;
+ long long *np = (long long*)PlgDBSubAlloc(g, NULL, sizeof(long long));
+
+ if (np) {
+ *np = n;
+ g->Activityp = (PACTIVITY)np;
+ } else
+ PUSH_WARNING(g->Message);
+
} // endif const_item
return n;
@@ -4335,18 +4615,23 @@ char *jbin_array(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!bsp || bsp->Changed) {
if (!CheckMemory(g, initid, args, args->arg_count, false)) {
- PJAR arp = new(g) JARRAY;
+ PJAR arp;
- bsp = JbinAlloc(g, args, initid->max_length, arp);
- strcat(bsp->Msg, " array");
+ if ((arp = (PJAR)JsonNew(g, TYPE_JAR)) &&
+ (bsp = JbinAlloc(g, args, initid->max_length, arp))) {
+ strcat(bsp->Msg, " array");
- for (uint i = 0; i < args->arg_count; i++)
- arp->AddValue(g, MakeValue(g, args, i));
+ for (uint i = 0; i < args->arg_count; i++)
+ arp->AddValue(g, MakeValue(g, args, i));
+
+ arp->InitArray(g);
+ } // endif arp && bsp
- arp->InitArray(g);
} else
- if ((bsp = JbinAlloc(g, args, initid->max_length, NULL)))
- strncpy(bsp->Msg, g->Message, 139);
+ bsp = NULL;
+
+ if (!bsp && (bsp = JbinAlloc(g, args, initid->max_length, NULL)))
+ strncpy(bsp->Msg, g->Message, 139);
// Keep result of constant function
g->Xchk = (initid->const_item) ? bsp : NULL;
@@ -4377,9 +4662,6 @@ my_bool jbin_array_add_values_init(UDF_INIT *initid, UDF_ARGS *args, char *messa
if (args->arg_count < 2) {
strcpy(message, "This function must have at least 2 arguments");
return true;
- } else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
- strcpy(message, "First argument must be a json string or item");
- return true;
} else
CalcLen(args, false, reslen, memlen);
@@ -4394,24 +4676,17 @@ char *jbin_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!bsp || bsp->Changed) {
if (!CheckMemory(g, initid, args, args->arg_count, true)) {
- char *p;
PJSON top;
PJAR arp;
- PJVAL jvp = MakeValue(g, args, 0, &top);
+ PJVAL jvp = MakeTypedValue(g, args, 0, TYPE_JAR, &top);
PGLOBAL gb = GetMemPtr(g, args, 0);
- if ((p = jvp->GetString(g))) {
- if (!(top = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- return NULL;
- } // endif jsp
-
- jvp->SetValue(top);
- } // endif p
-
if (jvp->GetValType() != TYPE_JAR) {
- arp = new(gb)JARRAY;
- arp->AddValue(gb, jvp);
+ if ((arp = (PJAR)JsonNew(gb, TYPE_JAR))) {
+ arp->AddValue(gb, jvp);
+ top = arp;
+ } // endif arp
+
} else
arp = jvp->GetArray();
@@ -4458,9 +4733,9 @@ my_bool jbin_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
if (args->arg_count < 2) {
strcpy(message, "This function must have at least 2 arguments");
return true;
- } else if (!IsJson(args, 0)) {
- strcpy(message, "First argument must be a json item");
- return true;
+ //} else if (!IsJson(args, 0)) {
+ // strcpy(message, "First argument must be a json item");
+ // return true;
} else
CalcLen(args, false, reslen, memlen, true);
@@ -4488,20 +4763,32 @@ char *jbin_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result,
PJVAL jvp;
PJAR arp;
- jvp = MakeValue(g, args, 0, &top);
-// jsp = jvp->GetJson();
+ jvp = MakeTypedValue(g, args, 0, TYPE_JSON, &top);
+ // jsp = jvp->GetJson();
x = GetIntArgPtr(g, args, n);
if (CheckPath(g, args, top, jvp, n))
PUSH_WARNING(g->Message);
- else if (jvp && jvp->GetValType() == TYPE_JAR) {
+ else if (jvp) {
PGLOBAL gb = GetMemPtr(g, args, 0);
- arp = jvp->GetArray();
+ if (jvp->GetValType() != TYPE_JAR) {
+ if ((arp = (PJAR)JsonNew(gb, TYPE_JAR))) {
+ arp->AddValue(gb, (PJVAL)JvalNew(gb, TYPE_JVAL, jvp));
+ jvp->SetValue(arp);
+
+ if (!top)
+ top = arp;
+
+ } // endif arp
+
+ } else
+ arp = jvp->GetArray();
+
arp->AddValue(gb, MakeValue(gb, args, 1), x);
arp->InitArray(gb);
} else {
- PUSH_WARNING("First argument is not an array");
+ PUSH_WARNING("First argument target is not an array");
// if (g->Mrr) *error = 1; (only if no path)
} // endif jvp
@@ -4539,9 +4826,6 @@ my_bool jbin_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
if (args->arg_count < 2) {
strcpy(message, "This function must have at least 2 arguments");
return true;
- } else if (!IsJson(args, 0)) {
- strcpy(message, "First argument must be a json item");
- return true;
} else
CalcLen(args, false, reslen, memlen, true);
@@ -4565,7 +4849,7 @@ char *jbin_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
int *x;
uint n = 1;
PJAR arp;
- PJVAL jvp = MakeValue(g, args, 0, &top);
+ PJVAL jvp = MakeTypedValue(g, args, 0, TYPE_JSON, &top);
if (CheckPath(g, args, top, jvp, 1))
PUSH_WARNING(g->Message);
@@ -4578,8 +4862,8 @@ char *jbin_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result,
PUSH_WARNING("Missing or null array index");
} else {
- PUSH_WARNING("First argument is not an array");
- if (g->Mrr) *error = 1;
+ PUSH_WARNING("First argument target is not an array");
+// if (g->Mrr) *error = 1;
} // endif jvp
} // endif CheckMemory
@@ -4625,13 +4909,18 @@ char *jbin_object(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!bsp || bsp->Changed) {
if (!CheckMemory(g, initid, args, args->arg_count, true)) {
- PJOB objp = new(g)JOBJECT;
+ PJOB objp;
- for (uint i = 0; i < args->arg_count; i++)
- objp->SetValue(g, MakeValue(g, args, i), MakeKey(g, args, i));
+ if ((objp = (PJOB)JsonNew(g, TYPE_JOB))) {
+ for (uint i = 0; i < args->arg_count; i++)
+ objp->SetValue(g, MakeValue(g, args, i), MakeKey(g, args, i));
+
+
+ if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
+ strcat(bsp->Msg, " object");
- if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
- strcat(bsp->Msg, " object");
+ } else
+ bsp = NULL;
} else
if ((bsp = JbinAlloc(g, args, initid->max_length, NULL)))
@@ -4676,14 +4965,18 @@ char *jbin_object_nonull(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!bsp || bsp->Changed) {
if (!CheckMemory(g, initid, args, args->arg_count, false, true)) {
PJVAL jvp;
- PJOB objp = new(g)JOBJECT;
+ PJOB objp;
- for (uint i = 0; i < args->arg_count; i++)
- if (!(jvp = MakeValue(g, args, i))->IsNull())
- objp->SetValue(g, jvp, MakeKey(g, args, i));
+ if ((objp = (PJOB)JsonNew(g, TYPE_JOB))) {
+ for (uint i = 0; i < args->arg_count; i++)
+ if (!(jvp = MakeValue(g, args, i))->IsNull())
+ objp->SetValue(g, jvp, MakeKey(g, args, i));
- if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
- strcat(bsp->Msg, " object");
+ if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
+ strcat(bsp->Msg, " object");
+
+ } else
+ bsp = NULL;
} else
if ((bsp = JbinAlloc(g, args, initid->max_length, NULL)))
@@ -4732,13 +5025,17 @@ char *jbin_object_key(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (!bsp || bsp->Changed) {
if (!CheckMemory(g, initid, args, args->arg_count, false, true)) {
- PJOB objp = new(g)JOBJECT;
+ PJOB objp;
+
+ if ((objp = (PJOB)JsonNew(g, TYPE_JOB))) {
+ for (uint i = 0; i < args->arg_count; i += 2)
+ objp->SetValue(g, MakeValue(g, args, i + 1), MakePSZ(g, args, i));
- for (uint i = 0; i < args->arg_count; i += 2)
- objp->SetValue(g, MakeValue(g, args, i+1), MakePSZ(g, args, i));
+ if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
+ strcat(bsp->Msg, " object");
- if ((bsp = JbinAlloc(g, args, initid->max_length, objp)))
- strcat(bsp->Msg, " object");
+ } else
+ bsp = NULL;
} else
if ((bsp = JbinAlloc(g, args, initid->max_length, NULL)))
@@ -4989,7 +5286,7 @@ my_bool jbin_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
char *jbin_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *res_length, char *is_null, char *error)
{
- char *p, *path;
+ char *path;
PJSON jsp;
PJSNX jsx;
PJVAL jvp;
@@ -5006,17 +5303,10 @@ char *jbin_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (CheckMemory(g, initid, args, 1, true, true)) {
PUSH_WARNING("CheckMemory error");
goto fin;
- } else
- jvp = MakeValue(g, args, 0);
-
- if ((p = jvp->GetString(g))) {
- if (!(jsp = ParseJson(g, p, strlen(p)))) {
- PUSH_WARNING(g->Message);
- goto fin;
- } // endif jsp
+ } // endif CheckMemory
- } else
- jsp = jvp->GetJson();
+ jvp = MakeTypedValue(g, args, 0, TYPE_JSON);
+ jsp = jvp->GetJson();
if (g->Mrr) { // First argument is a constant
g->Xchk = jsp;
@@ -5027,16 +5317,16 @@ char *jbin_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
jsp = (PJSON)g->Xchk;
path = MakePSZ(g, args, 1);
- jsx = new(g) JSNX(g, jsp, TYPE_STRING, initid->max_length);
+ jsx = JsnxNew(g, jsp, TYPE_STRING, initid->max_length);
- if (jsx->SetJpath(g, path, false)) {
+ if (!jsx || jsx->SetJpath(g, path, false)) {
PUSH_WARNING(g->Message);
goto fin;
} // endif SetJpath
// Get the json tree
if ((jvp = jsx->GetRowValue(g, jsp, 0, false))) {
- jsp = (jvp->GetJsp()) ? jvp->GetJsp() : new(g) JVALUE(g, jvp->GetValue());
+ jsp = (jvp->GetJsp()) ? jvp->GetJsp() : JvalNew(g, TYPE_VAL, jvp->GetValue());
if ((bsp = JbinAlloc(g, args, initid->max_length, jsp)))
strcat(bsp->Msg, " item");
diff --git a/storage/connect/jsonudf.h b/storage/connect/jsonudf.h
index cd3b9768f7a..23e8c0e1aed 100644
--- a/storage/connect/jsonudf.h
+++ b/storage/connect/jsonudf.h
@@ -89,6 +89,10 @@ extern "C" {
DllExport char *json_object_list(UDF_EXEC_ARGS);
DllExport void json_object_list_deinit(UDF_INIT*);
+ DllExport my_bool json_object_values_init(UDF_INIT*, UDF_ARGS*, char*);
+ DllExport char *json_object_values(UDF_EXEC_ARGS);
+ DllExport void json_object_values_deinit(UDF_INIT*);
+
DllExport my_bool jsonset_grp_size_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport long long jsonset_grp_size(UDF_INIT*, UDF_ARGS*, char*, char*);
diff --git a/storage/connect/macutil.cpp b/storage/connect/macutil.cpp
index b9600bdac2e..f95f3adcc6e 100644
--- a/storage/connect/macutil.cpp
+++ b/storage/connect/macutil.cpp
@@ -230,13 +230,13 @@ bool MACINFO::GetOneInfo(PGLOBAL g, int flag, void *v, int lv)
case 11: // Description
if ((p = strstr(Curp->Description, " - Packet Scheduler Miniport"))) {
strncpy(buf, Curp->Description, p - Curp->Description);
- i = p - Curp->Description;
+ i = (int)(p - Curp->Description);
strncpy(buf, Curp->Description, i);
buf[i] = 0;
p = buf;
} else if ((p = strstr(Curp->Description,
" - Miniport d'ordonnancement de paquets"))) {
- i = p - Curp->Description;
+ i = (int)(p - Curp->Description);
strncpy(buf, Curp->Description, i);
buf[i] = 0;
p = buf;
diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp
index 9da9c268c3d..253c42bb002 100644
--- a/storage/connect/myconn.cpp
+++ b/storage/connect/myconn.cpp
@@ -248,7 +248,7 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
while (true) {
p2 = strchr(p1, '\'');
- len = MY_MAX(len, p2 - p1);
+ len = MY_MAX(len, (int)(p2 - p1));
if (*++p2 != ',') break;
p1 = p2 + 2;
} // endwhile
@@ -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 0dcf030613d..7273e13dc4f 100644
--- a/storage/connect/mysql-test/connect/disabled.def
+++ b/storage/connect/mysql-test/connect/disabled.def
@@ -20,3 +20,4 @@ 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
+vcol : Different error code on different versions
diff --git a/storage/connect/mysql-test/connect/r/json_udf.result b/storage/connect/mysql-test/connect/r/json_udf.result
index 7d81ca5e73d..09544bb1ecb 100644
--- a/storage/connect/mysql-test/connect/r/json_udf.result
+++ b/storage/connect/mysql-test/connect/r/json_udf.result
@@ -50,17 +50,19 @@ SELECT Json_Array_Add(Json_Make_Array(56, 3.1416, 'foo', NULL), 'One more') Arra
Array
[56,3.141600,"foo",null,"One more"]
SELECT Json_Array_Add(JsonValue('one value'), 'One more');
-ERROR HY000: Can't initialize function 'json_array_add'; First argument must be a json item
+Json_Array_Add(JsonValue('one value'), 'One more')
+["\"one value\"","One more"]
SELECT Json_Array_Add('one value', 'One more');
-ERROR HY000: Can't initialize function 'json_array_add'; First argument must be a json item
+Json_Array_Add('one value', 'One more')
+["one value","One more"]
SELECT Json_Array_Add('one value' json_, 'One more');
Json_Array_Add('one value' json_, 'One more')
one value
Warnings:
Warning 1105 Error 2 opening one value
-Warning 1105 First argument target is not an array
SELECT Json_Array_Add(5 json_, 'One more');
-ERROR HY000: Can't initialize function 'json_array_add'; First argument must be a json item
+Json_Array_Add(5 json_, 'One more')
+[5,"One more"]
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 0);
Json_Array_Add('[5,3,8,7,9]' json_, 4, 0)
[4,5,3,8,7,9]
diff --git a/storage/connect/mysql-test/connect/r/json_udf_bin.result b/storage/connect/mysql-test/connect/r/json_udf_bin.result
index 0c009d612fe..d0819619c33 100644
--- a/storage/connect/mysql-test/connect/r/json_udf_bin.result
+++ b/storage/connect/mysql-test/connect/r/json_udf_bin.result
@@ -272,10 +272,9 @@ Json_Serialize(Jbin_Array('a','b','c'))
["a","b","c"]
SELECT Json_Serialize(Jbin_Array_Add(Jbin_File('not_exist.json'), 'd'));
Json_Serialize(Jbin_Array_Add(Jbin_File('not_exist.json'), 'd'))
-Null json tree
+[null,"d"]
Warnings:
Warning 1105 Open(map) error 2 on not_exist.json
-Warning 1105 First argument is not an array
# This does not modify the file
SELECT Json_Serialize(Jbin_Array_Add(Jbin_File('bt1.json'), 'd'));
Json_Serialize(Jbin_Array_Add(Jbin_File('bt1.json'), 'd'))
diff --git a/storage/connect/mysql-test/connect/r/vcol.result b/storage/connect/mysql-test/connect/r/vcol.result
new file mode 100644
index 00000000000..e0fd37203e4
--- /dev/null
+++ b/storage/connect/mysql-test/connect/r/vcol.result
@@ -0,0 +1,29 @@
+create table t1 (
+#linenum int(6) not null default 0 special=rowid,
+name char(12) not null,
+city char(11) not null,
+birth date not null date_format='DD/MM/YYYY',
+hired date not null date_format='DD/MM/YYYY' flag=36,
+agehired int(3) as (floor(datediff(hired,birth)/365.25))
+)
+engine=CONNECT table_type=FIX file_name='boys.txt' mapped=YES lrecl=47 ending=1;
+select * from t1;
+name city birth hired agehired
+John Boston 1986-01-25 2010-06-02 24
+Henry Boston 1987-06-07 2008-04-01 20
+George San Jose 1981-08-10 2010-06-02 28
+Sam Chicago 1979-11-22 2007-10-10 27
+James Dallas 1992-05-13 2009-12-14 17
+Bill Boston 1986-09-11 2008-02-10 21
+drop table t1;
+create table t1 (
+#linenum int(6) not null default 0 special=rowid,
+name char(12) not null,
+city char(11) not null,
+birth date not null date_format='DD/MM/YYYY',
+hired date not null date_format='DD/MM/YYYY' flag=36,
+agehired int(3) as (floor(datediff(hired,birth)/365.25)),
+index (agehired)
+)
+engine=CONNECT table_type=FIX file_name='boys.txt' mapped=YES lrecl=47 ending=1;
+ERROR 42000: Table handler doesn't support NULL in given index. Please change column 'agehired' to be NOT NULL or use another handler
diff --git a/storage/connect/mysql-test/connect/std_data/Mongo2.jar b/storage/connect/mysql-test/connect/std_data/Mongo2.jar
index d019bf6906b..9be654bd4c8 100644
--- a/storage/connect/mysql-test/connect/std_data/Mongo2.jar
+++ b/storage/connect/mysql-test/connect/std_data/Mongo2.jar
Binary files differ
diff --git a/storage/connect/mysql-test/connect/std_data/Mongo3.jar b/storage/connect/mysql-test/connect/std_data/Mongo3.jar
index 21c6c2d10bd..2850177a668 100644
--- a/storage/connect/mysql-test/connect/std_data/Mongo3.jar
+++ b/storage/connect/mysql-test/connect/std_data/Mongo3.jar
Binary files differ
diff --git a/storage/connect/mysql-test/connect/t/json_udf.test b/storage/connect/mysql-test/connect/t/json_udf.test
index 35dbbfed706..d45131f32ba 100644
--- a/storage/connect/mysql-test/connect/t/json_udf.test
+++ b/storage/connect/mysql-test/connect/t/json_udf.test
@@ -29,12 +29,12 @@ SELECT Json_Make_Array(Json_Make_Array(56, 3.1416, 'foo'), TRUE);
--error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Add(Json_Make_Array(56, 3.1416, 'foo', NULL)) Array;
SELECT Json_Array_Add(Json_Make_Array(56, 3.1416, 'foo', NULL), 'One more') Array;
---error ER_CANT_INITIALIZE_UDF
+#--error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Add(JsonValue('one value'), 'One more');
---error ER_CANT_INITIALIZE_UDF
+#--error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Add('one value', 'One more');
SELECT Json_Array_Add('one value' json_, 'One more');
---error ER_CANT_INITIALIZE_UDF
+#--error ER_CANT_INITIALIZE_UDF
SELECT Json_Array_Add(5 json_, 'One more');
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 0);
SELECT Json_Array_Add('[5,3,8,7,9]' json_, 4, 2) Array;
diff --git a/storage/connect/mysql-test/connect/t/vcol.test b/storage/connect/mysql-test/connect/t/vcol.test
new file mode 100644
index 00000000000..cdf37175f41
--- /dev/null
+++ b/storage/connect/mysql-test/connect/t/vcol.test
@@ -0,0 +1,31 @@
+let datadir= `select @@datadir`;
+--copy_file $MTR_SUITE_DIR/std_data/boys.txt $datadir/test/boys.txt
+
+create table t1 (
+ #linenum int(6) not null default 0 special=rowid,
+ name char(12) not null,
+ city char(11) not null,
+ birth date not null date_format='DD/MM/YYYY',
+ hired date not null date_format='DD/MM/YYYY' flag=36,
+ agehired int(3) as (floor(datediff(hired,birth)/365.25))
+ )
+engine=CONNECT table_type=FIX file_name='boys.txt' mapped=YES lrecl=47 ending=1;
+select * from t1;
+drop table t1;
+
+--error ER_NULL_COLUMN_IN_INDEX
+create table t1 (
+ #linenum int(6) not null default 0 special=rowid,
+ name char(12) not null,
+ city char(11) not null,
+ birth date not null date_format='DD/MM/YYYY',
+ hired date not null date_format='DD/MM/YYYY' flag=36,
+ agehired int(3) as (floor(datediff(hired,birth)/365.25)),
+ index (agehired)
+ )
+engine=CONNECT table_type=FIX file_name='boys.txt' mapped=YES lrecl=47 ending=1;
+
+#
+# Clean up
+#
+--remove_file $datadir/test/boys.txt
diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp
index cfd7546524e..f7b1a43a95d 100644
--- a/storage/connect/odbconn.cpp
+++ b/storage/connect/odbconn.cpp
@@ -2261,10 +2261,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
@@ -2438,7 +2438,7 @@ int ODBConn::GetCatInfo(CATPARM *cap)
else if (vlen[n] == SQL_NULL_DATA)
pval[n]->SetNull(true);
else if (crp->Type == TYPE_STRING/* && vlen[n] != SQL_NULL_DATA*/)
- pval[n]->SetValue_char(pbuf[n], vlen[n]);
+ pval[n]->SetValue_char(pbuf[n], (int)vlen[n]);
else
pval[n]->SetNull(false);
diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp
index f248e72be12..e296553d8e2 100644
--- a/storage/connect/plgdbutl.cpp
+++ b/storage/connect/plgdbutl.cpp
@@ -519,7 +519,7 @@ bool EvalLikePattern(LPCSTR sp, LPCSTR tp)
{
LPSTR p;
char c;
- int n;
+ ssize_t n;
bool b, t = false;
if (trace(2))
diff --git a/storage/connect/plugutil.cpp b/storage/connect/plugutil.cpp
index 0e6caa953b1..887527e38ab 100644
--- a/storage/connect/plugutil.cpp
+++ b/storage/connect/plugutil.cpp
@@ -162,7 +162,7 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
/*******************************************************************/
if (worksize && AllocSarea(g, worksize)) {
char errmsg[MAX_STR];
- sprintf(errmsg, MSG(WORK_AREA), g->Message);
+ snprintf(errmsg, sizeof(errmsg) - 1, MSG(WORK_AREA), g->Message);
strcpy(g->Message, errmsg);
} // endif Sarea
@@ -559,7 +559,7 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
if (trace(1))
htrc("PlugSubAlloc: %s\n", g->Message);
- throw 1234;
+ throw 1234;
} /* endif size OS32 code */
/*********************************************************************/
diff --git a/storage/connect/preparse.h b/storage/connect/preparse.h
index f16624548fb..3db7a2af1cd 100644
--- a/storage/connect/preparse.h
+++ b/storage/connect/preparse.h
@@ -8,7 +8,7 @@
/***********************************************************************/
typedef struct _datpar {
const char *Format; // Points to format to decode
- char *Curp; // Points to current parsing position
+ const char *Curp; // Points to current parsing position
char *InFmt; // Start of input format
char *OutFmt; // Start of output format
int Index[8]; // Indexes of date values
diff --git a/storage/connect/rcmsg.c b/storage/connect/rcmsg.c
index 75759e03314..895f8f5862b 100644
--- a/storage/connect/rcmsg.c
+++ b/storage/connect/rcmsg.c
@@ -27,9 +27,9 @@
char *msglang(void);
-char *GetMsgid(int id)
+const char *GetMsgid(int id)
{
- char *p = NULL;
+ const char *p = NULL;
// This conditional until a real fix is found for MDEV-7304
#if defined(FRENCH)
@@ -55,7 +55,8 @@ char *GetMsgid(int id)
int GetRcString(int id, char *buf, int bufsize)
{
- char *p = NULL, msg[32];
+ const char *p = NULL;
+ char msg[32];
if (!(p = GetMsgid(id))) {
sprintf(msg, "ID=%d unknown", id);
diff --git a/storage/connect/rcmsg.h b/storage/connect/rcmsg.h
index b22e77f5175..499ca3b2dd4 100644
--- a/storage/connect/rcmsg.h
+++ b/storage/connect/rcmsg.h
@@ -5,7 +5,7 @@
extern "C" {
#endif
-char *GetMsgid(int id);
+const char *GetMsgid(int id);
int GetRcString(int id, char *buf, int bufsize);
#ifdef __cplusplus
diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp
index 072bd25c5a7..e4f169575f8 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/tabdos.cpp b/storage/connect/tabdos.cpp
index 6ead8e40cd9..29cbbb35765 100644
--- a/storage/connect/tabdos.cpp
+++ b/storage/connect/tabdos.cpp
@@ -1647,8 +1647,8 @@ int TDBDOS::TestBlock(PGLOBAL g)
/***********************************************************************/
int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
{
- int k, n, rc = RC_OK;
- bool fixed, doit, sep, b = (pxdf != NULL);
+ int k, n, rc = RC_OK;
+ bool fixed, doit, sep, b = (pxdf != NULL);
PCOL *keycols, colp;
PIXDEF xdp, sxp = NULL;
PKPDEF kdp;
@@ -1694,8 +1694,8 @@ int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
try {
// Allocate all columns that will be used by indexes.
- // This must be done before opening the table so specific
- // column initialization can be done (in particular by TDBVCT)
+ // This must be done before opening the table so specific
+ // column initialization can be done (in particular by TDBVCT)
for (n = 0, xdp = pxdf; xdp; xdp = xdp->GetNext())
for (kdp = xdp->GetToKeyParts(); kdp; kdp = kdp->GetNext()) {
if (!(colp = ColDB(g, kdp->GetName(), 0))) {
@@ -2881,4 +2881,3 @@ bool DOSCOL::AddDistinctValue(PGLOBAL g)
} // end of AddDistinctValue
/* ------------------------------------------------------------------- */
-
diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp
index 66339a49de2..63fa2a63668 100644
--- a/storage/connect/tabfmt.cpp
+++ b/storage/connect/tabfmt.cpp
@@ -934,7 +934,7 @@ int TDBCSV::ReadBuffer(PGLOBAL g)
if (p) {
//len = p++ - p2;
- len = p - p2 - 1;;
+ len = (int)(p - p2 - 1);
// if (Sep != ' ')
// for (; *p == ' '; p++) ; // Skip blanks
@@ -978,7 +978,7 @@ int TDBCSV::ReadBuffer(PGLOBAL g)
return RC_NF;
} else if ((p = strchr(p2, Sep)))
- len = p - p2;
+ len = (int)(p - p2);
else if (i == Fields - 1)
len = strlen(p2);
else if (Accept && Maxerr == 0) {
@@ -996,7 +996,7 @@ int TDBCSV::ReadBuffer(PGLOBAL g)
} else
len = 0;
- Offset[i] = p2 - To_Line;
+ Offset[i] = (int)(p2 - To_Line);
if (Mode != MODE_UPDATE)
Fldlen[i] = len;
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp
index 3acc2389975..b66682e0190 100644
--- a/storage/connect/tabjson.cpp
+++ b/storage/connect/tabjson.cpp
@@ -94,7 +94,7 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
return NULL;
} // endif Multiple
- pjdc = new(g) JSONDISC(g, (int*)length);
+ pjdc = new(g) JSONDISC(g, length);
if (!(n = pjdc->GetColumns(g, db, dsn, topt)))
return NULL;
@@ -157,7 +157,7 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
/***********************************************************************/
/* Class used to get the columns of a JSON table. */
/***********************************************************************/
-JSONDISC::JSONDISC(PGLOBAL g, int *lg)
+JSONDISC::JSONDISC(PGLOBAL g, uint *lg)
{
length = lg;
jcp = fjcp = pjcp = NULL;
diff --git a/storage/connect/tabjson.h b/storage/connect/tabjson.h
index fb0ee786f74..0341c0f8aa0 100644
--- a/storage/connect/tabjson.h
+++ b/storage/connect/tabjson.h
@@ -47,7 +47,7 @@ typedef struct _jncol {
class JSONDISC : public BLOCK {
public:
// Constructor
- JSONDISC(PGLOBAL g, int *lg);
+ JSONDISC(PGLOBAL g, uint *lg);
// Functions
int GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt);
@@ -66,7 +66,7 @@ public:
PJOB row;
PCSZ sep;
char colname[65], fmt[129], buf[16];
- int *length;
+ uint *length;
int i, n, bf, ncol, lvl;
bool all;
}; // end of JSONDISC
diff --git a/storage/connect/tabmac.cpp b/storage/connect/tabmac.cpp
index a28b5d7108c..8260ab65391 100644
--- a/storage/connect/tabmac.cpp
+++ b/storage/connect/tabmac.cpp
@@ -367,13 +367,13 @@ void MACCOL::ReadColumn(PGLOBAL g)
case 11: // Description
if ((p = strstr(adp->Description, " - Packet Scheduler Miniport"))) {
strncpy(buf, adp->Description, p - adp->Description);
- i = p - adp->Description;
+ i = (int)(p - adp->Description);
strncpy(buf, adp->Description, i);
buf[i] = 0;
p = buf;
} else if ((p = strstr(adp->Description,
" - Miniport d'ordonnancement de paquets"))) {
- i = p - adp->Description;
+ i = (int)(p - adp->Description);
strncpy(buf, adp->Description, i);
buf[i] = 0;
p = buf;
diff --git a/storage/connect/tabmul.cpp b/storage/connect/tabmul.cpp
index 1afd21db452..649fc6706c6 100644
--- a/storage/connect/tabmul.cpp
+++ b/storage/connect/tabmul.cpp
@@ -203,12 +203,12 @@ bool TDBMUL::InitFileNames(PGLOBAL g)
// Data files can be imported from Windows (having CRLF)
if (*p == '\n' || *p == '\r') {
// is this enough for Unix ???
- *p--; // Eliminate ending CR or LF character
+ p--; // Eliminate ending CR or LF character
if (p >= filename)
// is this enough for Unix ???
if (*p == '\n' || *p == '\r')
- *p--; // Eliminate ending CR or LF character
+ p--; // Eliminate ending CR or LF character
} // endif p
diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp
index a80abcdd19f..605b3822430 100644
--- a/storage/connect/tabmysql.cpp
+++ b/storage/connect/tabmysql.cpp
@@ -124,8 +124,8 @@ bool MYSQLDEF::GetServerInfo(PGLOBAL g, const char *server_name)
DBUG_RETURN(true);
} // endif server
- DBUG_PRINT("info", ("get_server_by_name returned server at %lx",
- (size_t) server));
+ DBUG_PRINT("info", ("get_server_by_name returned server at %p",
+ server));
// TODO: We need to examine which of these can really be NULL
Hostname = PlugDup(g, server->host);
@@ -681,7 +681,7 @@ bool TDBMYSQL::MakeCommand(PGLOBAL g)
strlwr(strcpy(name, Name)); // Not a keyword
if ((p = strstr(qrystr, name))) {
- Query->Set(Qrystr, p - qrystr);
+ Query->Set(Qrystr, (uint)(p - qrystr));
if (qtd && *(p-1) == ' ') {
Query->Append('`');
diff --git a/storage/connect/tabmysql.h b/storage/connect/tabmysql.h
index 39fba87bcc9..4b61c7eb762 100644
--- a/storage/connect/tabmysql.h
+++ b/storage/connect/tabmysql.h
@@ -135,7 +135,7 @@ class TDBMYSQL : public TDBEXT {
int m_Rc; // Return code from command
//int AftRows; // The number of affected rows
int N; // The current table index
- int Port; // MySQL port number (0 = default)
+ unsigned Port; // MySQL port number (0 = default)
//int Nparm; // The number of statement parameters
//int Quoted; // The identifier quoting level
}; // end of class TDBMYSQL
diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp
index 1f89fd7af9c..f7bc3934fbd 100644
--- a/storage/connect/tabodbc.cpp
+++ b/storage/connect/tabodbc.cpp
@@ -289,7 +289,7 @@ void TDBODBC::SetFile(PGLOBAL g, PCSZ fn)
sprintf(Connect, MulConn, fn);
} // endif MultConn
- DBQ = (PSZ)fn;
+ DBQ = PlugDup(g, fn);
} // end of SetFile
/***********************************************************************/
diff --git a/storage/connect/tabtbl.cpp b/storage/connect/tabtbl.cpp
index 53af28354e7..e194568ccf8 100644
--- a/storage/connect/tabtbl.cpp
+++ b/storage/connect/tabtbl.cpp
@@ -656,7 +656,7 @@ bool TDBTBM::IsLocal(PTABLE tbp)
return ((!stricmp(tdbp->Host, "localhost") ||
!strcmp(tdbp->Host, "127.0.0.1")) &&
- tdbp->Port == (int)GetDefaultPort());
+ (int) tdbp->Port == (int)GetDefaultPort());
} // end of IsLocal
/***********************************************************************/
diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp
index 759bb370b43..c96e0844497 100644
--- a/storage/connect/tabxml.cpp
+++ b/storage/connect/tabxml.cpp
@@ -1319,7 +1319,7 @@ void TDBXML::CloseDB(PGLOBAL g)
Docp->CloseDoc(g, To_Xb);
// This causes a crash in Diagnostics_area::set_error_status
-// throw (int)TYPE_AM_XML;
+// throw (int)TYPE_AM_XML;
} // endif DumpDoc
} // endif Changed
diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp
index 90c01f72b35..e159efaa989 100644
--- a/storage/connect/value.cpp
+++ b/storage/connect/value.cpp
@@ -1374,7 +1374,7 @@ bool TYPVAL<PSZ>::SetValue_char(const char *cp, int n)
} else if (cp != Strp) {
const char *p = cp + n - 1;
- for (p; p >= cp; p--, n--)
+ for (; p >= cp; p--, n--)
if (*p && *p != ' ')
break;
@@ -1747,7 +1747,7 @@ DECVAL::DECVAL(PSZ s) : TYPVAL<PSZ>(s)
if (s) {
char *p = strchr(Strp, '.');
- Prec = (p) ? Len - (p - Strp) : 0;
+ Prec = (p) ? (int)(Len - (p - Strp)) : 0;
} // endif s
Type = TYPE_DECIM;
@@ -2656,7 +2656,7 @@ bool DTVAL::SetValue_char(const char *p, int n)
// Trim trailing blanks
for (p2 = p + n -1; p < p2 && *p2 == ' '; p2--);
- if ((rc = (n = p2 - p + 1) > Len))
+ if ((rc = (n = (int)(p2 - p + 1)) > Len))
n = Len;
memcpy(Sdate, p, n);
diff --git a/storage/connect/xobject.cpp b/storage/connect/xobject.cpp
index 02d3e974dcc..c595ce5d6c4 100644
--- a/storage/connect/xobject.cpp
+++ b/storage/connect/xobject.cpp
@@ -204,7 +204,7 @@ STRING::STRING(PGLOBAL g, uint n, PCSZ str)
*Strp = 0;
Next = GetNext();
- Size = Next - Strp;
+ Size = (int)(Next - Strp);
Trc = false;
} else {
// This should normally never happen
@@ -239,7 +239,7 @@ char *STRING::Realloc(uint len)
p = Strp;
Next = GetNext();
- Size = Next - p;
+ Size = (int)(Next - p);
return p;
} // end of Realloc
@@ -439,4 +439,3 @@ bool STRING::Resize(uint newsize)
return newsize > Size;
} // end of Resize
-
diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc
index 85e41554efc..0e84546764d 100644
--- a/storage/federated/ha_federated.cc
+++ b/storage/federated/ha_federated.cc
@@ -2982,6 +2982,9 @@ int ha_federated::reset(void)
}
reset_dynamic(&results);
+ if (mysql)
+ mysql->net.thd= NULL;
+
return 0;
}
@@ -3202,12 +3205,14 @@ int ha_federated::real_query(const char *query, size_t length)
int rc= 0;
DBUG_ENTER("ha_federated::real_query");
- if (!mysql && (rc= real_connect()))
+ if (!query || !length)
goto end;
- if (!query || !length)
+ if (!mysql && (rc= real_connect()))
goto end;
+ mysql->net.thd= table->in_use;
+
rc= mysql_real_query(mysql, query, (uint) length);
end:
diff --git a/storage/federatedx/federatedx_io_mysql.cc b/storage/federatedx/federatedx_io_mysql.cc
index 54059c0ecff..2068716eeba 100644
--- a/storage/federatedx/federatedx_io_mysql.cc
+++ b/storage/federatedx/federatedx_io_mysql.cc
@@ -265,9 +265,8 @@ ulong federatedx_io_mysql::savepoint_release(ulong sp)
savept= dynamic_element(&savepoints, savepoints.elements - 1, SAVEPT *);
if (savept->level < sp)
break;
- if ((savept->flags & (SAVEPOINT_REALIZED |
- SAVEPOINT_RESTRICT)) == SAVEPOINT_REALIZED)
- last= savept;
+ if ((savept->flags & (SAVEPOINT_REALIZED | SAVEPOINT_RESTRICT)) == SAVEPOINT_REALIZED)
+ last= savept;
savepoints.elements--;
}
@@ -293,8 +292,8 @@ ulong federatedx_io_mysql::savepoint_rollback(ulong sp)
while (savepoints.elements)
{
savept= dynamic_element(&savepoints, savepoints.elements - 1, SAVEPT *);
- if (savept->level <= sp)
- break;
+ if (savept->level <= sp)
+ break;
savepoints.elements--;
}
diff --git a/storage/federatedx/ha_federatedx.h b/storage/federatedx/ha_federatedx.h
index abf25abe0c5..f3af7258623 100644
--- a/storage/federatedx/ha_federatedx.h
+++ b/storage/federatedx/ha_federatedx.h
@@ -169,7 +169,7 @@ 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); }
virtual int query(const char *buffer, uint length)=0;
virtual FEDERATEDX_IO_RESULT *store_result()=0;
diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc
index 970c503497f..3513ddb4c2f 100644
--- a/storage/heap/ha_heap.cc
+++ b/storage/heap/ha_heap.cc
@@ -91,6 +91,15 @@ ha_heap::ha_heap(handlerton *hton, TABLE_SHARE *table_arg)
int ha_heap::open(const char *name, int mode, uint test_if_locked)
{
+ if (table->s->reclength < sizeof (char*))
+ {
+ MEM_UNDEFINED(table->s->default_values + table->s->reclength,
+ sizeof(char*) - table->s->reclength);
+ table->s->reclength= sizeof(char*);
+ MEM_UNDEFINED(table->record[0], table->s->reclength);
+ MEM_UNDEFINED(table->record[1], table->s->reclength);
+ }
+
internal_table= MY_TEST(test_if_locked & HA_OPEN_INTERNAL_TABLE);
if (internal_table || (!(file= heap_open(name, mode)) && my_errno == ENOENT))
{
diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
index 86032ff207d..7eecefc90fd 100644
--- a/storage/innobase/CMakeLists.txt
+++ b/storage/innobase/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -85,6 +85,12 @@ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DUNIV_DEBUG -DUNIV_SYNC_DEB
CHECK_FUNCTION_EXISTS(sched_getcpu HAVE_SCHED_GETCPU)
IF(NOT MSVC)
+
+ CHECK_FUNCTION_EXISTS(posix_memalign HAVE_POSIX_MEMALIGN)
+ IF(HAVE_POSIX_MEMALIGN)
+ ADD_DEFINITIONS(-DHAVE_POSIX_MEMALIGN)
+ ENDIF()
+
# either define HAVE_IB_GCC_ATOMIC_BUILTINS or not
# workaround for old gcc on x86, gcc atomic ops only work under -march=i686
IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "i686" AND CMAKE_COMPILER_IS_GNUCC AND
@@ -514,3 +520,4 @@ MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE
MODULE_OUTPUT_NAME ha_innodb
LINK_LIBRARIES ${ZLIB_LIBRARY} ${LIBSYSTEMD} ${LINKER_SCRIPT})
+ADD_DEPENDENCIES(innobase GenError)
diff --git a/storage/innobase/api/api0api.cc b/storage/innobase/api/api0api.cc
index bc83e98374f..fd14fdefd18 100644
--- a/storage/innobase/api/api0api.cc
+++ b/storage/innobase/api/api0api.cc
@@ -398,7 +398,7 @@ ib_read_tuple(
data = btr_rec_copy_externally_stored_field(
copy, offsets, zip_size, i, &len,
- tuple->heap, NULL);
+ tuple->heap);
ut_a(len != UNIV_SQL_NULL);
}
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc
index c519baef58c..841b14e76f4 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -77,10 +77,9 @@ btr_corruption_report(
index->name, index->table_name);
if (block->page.zip.data) {
buf_page_print(block->page.zip.data,
- buf_block_get_zip_size(block),
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_block_get_zip_size(block));
}
- buf_page_print(buf_block_get_frame(block), 0, 0);
+ buf_page_print(buf_block_get_frame(block), 0);
}
#ifndef UNIV_HOTBACKUP
@@ -1582,11 +1581,9 @@ btr_page_get_father_node_ptr_func(
if (btr_node_ptr_get_child_page_no(node_ptr, offsets) != page_no) {
rec_t* print_rec;
fputs("InnoDB: Dump of the child page:\n", stderr);
- buf_page_print(page_align(user_rec), 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page_align(user_rec), 0);
fputs("InnoDB: Dump of the parent page:\n", stderr);
- buf_page_print(page_align(node_ptr), 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page_align(node_ptr), 0);
fputs("InnoDB: Corruption of an index tree: table ", stderr);
ut_print_name(stderr, NULL, TRUE, index->table_name);
@@ -2046,8 +2043,8 @@ btr_page_reorganize_low(
max_ins_size2 = page_get_max_insert_size_after_reorganize(page, 1);
if (data_size1 != data_size2 || max_ins_size1 != max_ins_size2) {
- buf_page_print(page, 0, BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(temp_page, 0, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page, 0);
+ buf_page_print(temp_page, 0);
fprintf(stderr,
"InnoDB: Error: page old data size %lu"
@@ -2055,7 +2052,7 @@ btr_page_reorganize_low(
"InnoDB: Error: page old max ins size %lu"
" new max ins size %lu\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n",
+ " to https://jira.mariadb.org/\n",
(unsigned long) data_size1, (unsigned long) data_size2,
(unsigned long) max_ins_size1,
(unsigned long) max_ins_size2);
@@ -4575,7 +4572,7 @@ btr_index_rec_validate(
(ulong) rec_get_n_fields_old(rec), (ulong) n);
if (dump_on_error) {
- buf_page_print(page, 0, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page, 0);
fputs("InnoDB: corrupt record ", stderr);
rec_print_old(stderr, rec);
@@ -4613,8 +4610,7 @@ btr_index_rec_validate(
(ulong) i, (ulong) len, (ulong) fixed_size);
if (dump_on_error) {
- buf_page_print(page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page, 0);
fputs("InnoDB: corrupt record ", stderr);
rec_print_new(stderr, rec, offsets);
@@ -4891,8 +4887,8 @@ loop:
btr_validate_report2(index, level, block, right_block);
fputs("InnoDB: broken FIL_PAGE_NEXT"
" or FIL_PAGE_PREV links\n", stderr);
- buf_page_print(page, 0, BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(right_page, 0, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page, 0);
+ buf_page_print(right_page, 0);
ret = false;
}
@@ -4900,8 +4896,8 @@ loop:
if (page_is_comp(right_page) != page_is_comp(page)) {
btr_validate_report2(index, level, block, right_block);
fputs("InnoDB: 'compact' flag mismatch\n", stderr);
- buf_page_print(page, 0, BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(right_page, 0, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page, 0);
+ buf_page_print(right_page, 0);
ret = false;
@@ -4923,8 +4919,8 @@ loop:
fputs("InnoDB: records in wrong order"
" on adjacent pages\n", stderr);
- buf_page_print(page, 0, BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(right_page, 0, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page, 0);
+ buf_page_print(right_page, 0);
fputs("InnoDB: record ", stderr);
rec = page_rec_get_prev(page_get_supremum_rec(page));
@@ -4972,8 +4968,8 @@ loop:
fputs("InnoDB: node pointer to the page is wrong\n",
stderr);
- buf_page_print(father_page, 0, BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(page, 0, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(father_page, 0);
+ buf_page_print(page, 0);
fputs("InnoDB: node ptr ", stderr);
rec_print(stderr, node_ptr, index);
@@ -5005,10 +5001,8 @@ loop:
btr_validate_report1(index, level, block);
- buf_page_print(father_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(father_page, 0);
+ buf_page_print(page, 0);
fputs("InnoDB: Error: node ptrs differ"
" on levels > 0\n"
@@ -5053,15 +5047,9 @@ loop:
btr_validate_report1(index, level,
block);
- buf_page_print(
- father_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(
- page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(
- right_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(father_page, 0);
+ buf_page_print(page, 0);
+ buf_page_print(right_page, 0);
}
} else {
page_t* right_father_page
@@ -5079,18 +5067,10 @@ loop:
btr_validate_report1(index, level,
block);
- buf_page_print(
- father_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(
- right_father_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(
- page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(
- right_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(father_page, 0);
+ buf_page_print(right_father_page, 0);
+ buf_page_print(page, 0);
+ buf_page_print(right_page, 0);
}
if (page_get_page_no(right_father_page)
@@ -5104,18 +5084,10 @@ loop:
btr_validate_report1(index, level,
block);
- buf_page_print(
- father_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(
- right_father_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(
- page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(
- right_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(father_page, 0);
+ buf_page_print(right_father_page, 0);
+ buf_page_print(page, 0);
+ buf_page_print(right_page, 0);
}
}
}
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index d848ee538c6..09d84d1ecbc 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -3433,7 +3433,6 @@ btr_cur_pessimistic_delete(
ulint n_reserved = 0;
ibool success;
ibool ret = FALSE;
- ulint level;
mem_heap_t* heap;
ulint* offsets;
@@ -3484,6 +3483,10 @@ btr_cur_pessimistic_delete(
#endif /* UNIV_ZIP_DEBUG */
}
+ if (flags == 0) {
+ lock_update_delete(block, rec);
+ }
+
if (UNIV_UNLIKELY(page_get_n_recs(page) < 2)
&& UNIV_UNLIKELY(dict_index_get_page(index)
!= buf_block_get_page_no(block))) {
@@ -3498,13 +3501,7 @@ btr_cur_pessimistic_delete(
goto return_after_reservations;
}
- if (flags == 0) {
- lock_update_delete(block, rec);
- }
-
- level = btr_page_get_level(page, mtr);
-
- if (level > 0
+ if (!page_is_leaf(page)
&& UNIV_UNLIKELY(rec == page_rec_get_next(
page_get_infimum_rec(page)))) {
@@ -3527,6 +3524,7 @@ btr_cur_pessimistic_delete(
on a page, we have to change the father node pointer
so that it is equal to the new leftmost node pointer
on the page */
+ ulint level = btr_page_get_level(page, mtr);
btr_node_ptr_delete(index, block, mtr);
@@ -3794,8 +3792,7 @@ btr_estimate_n_rows_in_range(
const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
ulint mode1, /*!< in: search mode for range start */
const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
- ulint mode2, /*!< in: search mode for range end */
- trx_t* trx) /*!< in: trx */
+ ulint mode2) /*!< in: search mode for range end */
{
btr_path_t path1[BTR_PATH_ARRAY_N_SLOTS];
btr_path_t path2[BTR_PATH_ARRAY_N_SLOTS];
@@ -3813,7 +3810,7 @@ btr_estimate_n_rows_in_range(
table_n_rows = dict_table_get_n_rows(index->table);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
cursor.path_arr = path1;
@@ -3835,7 +3832,7 @@ btr_estimate_n_rows_in_range(
return (0);
}
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
cursor.path_arr = path2;
@@ -4106,7 +4103,7 @@ btr_estimate_number_of_different_key_vals(
if (index->stat_index_size > 1) {
n_sample_pages = (srv_stats_transient_sample_pages < index->stat_index_size) ?
ut_min(index->stat_index_size,
- log2(index->stat_index_size)*srv_stats_transient_sample_pages)
+ ulint(log2(index->stat_index_size)*srv_stats_transient_sample_pages))
: index->stat_index_size;
}
@@ -5468,8 +5465,7 @@ btr_copy_blob_prefix(
ulint len, /*!< in: length of buf, in bytes */
ulint space_id,/*!< in: space id of the BLOB pages */
ulint page_no,/*!< in: page number of the first BLOB page */
- ulint offset, /*!< in: offset on the first BLOB page */
- trx_t* trx) /*!< in: transaction handle */
+ ulint offset) /*!< in: offset on the first BLOB page */
{
ulint copied_len = 0;
@@ -5481,7 +5477,7 @@ btr_copy_blob_prefix(
ulint part_len;
ulint copy_len;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
block = buf_page_get(space_id, 0, page_no, RW_S_LATCH, &mtr);
buf_block_dbg_add_level(block, SYNC_EXTERN_STORAGE);
@@ -5684,8 +5680,7 @@ btr_copy_externally_stored_field_prefix_low(
zero for uncompressed BLOBs */
ulint space_id,/*!< in: space id of the first BLOB page */
ulint page_no,/*!< in: page number of the first BLOB page */
- ulint offset, /*!< in: offset on the first BLOB page */
- trx_t* trx) /*!< in: transaction handle */
+ ulint offset) /*!< in: offset on the first BLOB page */
{
if (UNIV_UNLIKELY(len == 0)) {
return(0);
@@ -5696,7 +5691,7 @@ btr_copy_externally_stored_field_prefix_low(
space_id, page_no, offset));
} else {
return(btr_copy_blob_prefix(buf, len, space_id,
- page_no, offset, trx));
+ page_no, offset));
}
}
@@ -5717,8 +5712,7 @@ btr_copy_externally_stored_field_prefix(
field containing also the reference to
the external part; must be protected by
a lock or a page latch */
- ulint local_len,/*!< in: length of data, in bytes */
- trx_t* trx) /*!< in: transaction handle */
+ ulint local_len)/*!< in: length of data, in bytes */
{
ulint space_id;
ulint page_no;
@@ -5757,7 +5751,7 @@ btr_copy_externally_stored_field_prefix(
len - local_len,
zip_size,
space_id, page_no,
- offset, trx));
+ offset));
}
/*******************************************************************//**
@@ -5776,8 +5770,7 @@ btr_copy_externally_stored_field(
ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
ulint local_len,/*!< in: length of data */
- mem_heap_t* heap, /*!< in: mem heap */
- trx_t* trx) /*!< in: transaction handle */
+ mem_heap_t* heap) /*!< in: mem heap */
{
ulint space_id;
ulint page_no;
@@ -5808,8 +5801,7 @@ btr_copy_externally_stored_field(
extern_len,
zip_size,
space_id,
- page_no, offset,
- trx);
+ page_no, offset);
return(buf);
}
@@ -5828,8 +5820,7 @@ btr_rec_copy_externally_stored_field(
zero for uncompressed BLOBs */
ulint no, /*!< in: field number */
ulint* len, /*!< out: length of the field */
- mem_heap_t* heap, /*!< in: mem heap */
- trx_t* trx) /*!< in: transaction handle */
+ mem_heap_t* heap) /*!< in: mem heap */
{
ulint local_len;
const byte* data;
@@ -5860,7 +5851,6 @@ btr_rec_copy_externally_stored_field(
}
return(btr_copy_externally_stored_field(len, data,
- zip_size, local_len, heap,
- trx));
+ zip_size, local_len, heap));
}
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc
index ff80cfb29ad..5ba9409a7b1 100644
--- a/storage/innobase/btr/btr0pcur.cc
+++ b/storage/innobase/btr/btr0pcur.cc
@@ -496,7 +496,7 @@ btr_pcur_move_backward_from_page(
mtr_commit(mtr);
- mtr_start_trx(mtr, mtr->trx);
+ mtr_start(mtr);
btr_pcur_restore_position(latch_mode2, cursor, mtr);
diff --git a/storage/innobase/btr/btr0scrub.cc b/storage/innobase/btr/btr0scrub.cc
index 24c84ed301b..1b10b79838d 100644
--- a/storage/innobase/btr/btr0scrub.cc
+++ b/storage/innobase/btr/btr0scrub.cc
@@ -886,17 +886,15 @@ btr_scrub_update_total_stat(btr_scrub_t *scrub_data)
memset(&scrub_data->scrub_stat, 0, sizeof(scrub_data->scrub_stat));
}
-/**************************************************************//**
-Complete iterating a space */
+/** Complete iterating a space.
+@param[in,out] scrub_data scrub data */
UNIV_INTERN
-bool
-btr_scrub_complete_space(
-/*=====================*/
- btr_scrub_t* scrub_data) /*!< in/out: scrub data */
+void
+btr_scrub_complete_space(btr_scrub_t* scrub_data)
{
+ ut_ad(scrub_data->scrubbing);
btr_scrub_table_close_for_thread(scrub_data);
btr_scrub_update_total_stat(scrub_data);
- return scrub_data->scrubbing;
}
/*********************************************************************
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index 70f2cbc10e2..e36e6d6194c 100644
--- a/storage/innobase/btr/btr0sea.cc
+++ b/storage/innobase/btr/btr0sea.cc
@@ -1982,9 +1982,7 @@ btr_search_validate(void)
(ulong) block->curr_left_side);
if (n_page_dumps < 20) {
- buf_page_print(
- page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page, 0);
n_page_dumps++;
}
}
diff --git a/storage/innobase/buf/buf0buddy.cc b/storage/innobase/buf/buf0buddy.cc
index f2ab73217e0..7a441b4239a 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
@@ -649,7 +650,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 85d7485678e..e3c2337659e 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -86,10 +86,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;
}
@@ -731,6 +734,7 @@ buf_page_is_corrupted(
const void* space)
#endif
{
+ DBUG_EXECUTE_IF("buf_page_import_corrupt_failure", return(TRUE); );
ulint checksum_field1 = 0;
ulint checksum_field2 = 0;
#ifndef UNIV_INNOCHECKSUM
@@ -844,8 +848,6 @@ buf_page_is_corrupted(
return(false);
}
- DBUG_EXECUTE_IF("buf_page_is_corrupt_failure", return(true); );
-
#ifndef UNIV_INNOCHECKSUM
ulint page_no = mach_read_from_4(read_buf + FIL_PAGE_OFFSET);
#endif
@@ -1034,19 +1036,12 @@ buf_page_is_corrupted(
}
#ifndef UNIV_INNOCHECKSUM
-/********************************************************************//**
-Prints a page to stderr. */
+/** Dump a page to stderr.
+@param[in] read_buf database page
+@param[in] zip_size compressed page size, or 0 for uncompressed */
UNIV_INTERN
void
-buf_page_print(
-/*===========*/
- const byte* read_buf, /*!< in: a database page */
- ulint zip_size, /*!< in: compressed page size, or
- 0 for uncompressed pages */
- ulint flags) /*!< in: 0 or
- BUF_PAGE_PRINT_NO_CRASH or
- BUF_PAGE_PRINT_NO_FULL */
-
+buf_page_print(const byte* read_buf, ulint zip_size)
{
#ifndef UNIV_HOTBACKUP
dict_index_t* index;
@@ -1057,14 +1052,12 @@ buf_page_print(
size = UNIV_PAGE_SIZE;
}
- if (!(flags & BUF_PAGE_PRINT_NO_FULL)) {
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Page dump in ascii and hex (" ULINTPF " bytes):\n",
- size);
- ut_print_buf(stderr, read_buf, size);
- fputs("\nInnoDB: End of page dump\n", stderr);
- }
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Page dump in ascii and hex (" ULINTPF " bytes):\n",
+ size);
+ ut_print_buf(stderr, read_buf, size);
+ fputs("\nInnoDB: End of page dump\n", stderr);
if (zip_size) {
/* Print compressed page. */
@@ -1219,8 +1212,6 @@ buf_page_print(
stderr);
break;
}
-
- ut_ad(flags & BUF_PAGE_PRINT_NO_CRASH);
}
#ifndef UNIV_HOTBACKUP
@@ -3071,8 +3062,8 @@ buf_page_get_gen(
ib_mutex_t* fix_mutex = NULL;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
- ut_ad(mtr);
- ut_ad(mtr->state == MTR_ACTIVE);
+ ut_ad((mtr == NULL) == (mode == BUF_EVICT_IF_IN_POOL));
+ ut_ad(!mtr || mtr->state == MTR_ACTIVE);
ut_ad((rw_latch == RW_S_LATCH)
|| (rw_latch == RW_X_LATCH)
|| (rw_latch == RW_NO_LATCH));
@@ -3083,23 +3074,29 @@ buf_page_get_gen(
#ifdef UNIV_DEBUG
switch (mode) {
+ case BUF_EVICT_IF_IN_POOL:
+ /* After DISCARD TABLESPACE, the tablespace would not exist,
+ but in IMPORT TABLESPACE, PageConverter::operator() must
+ replace any old pages, which were not evicted during DISCARD.
+ Skip the assertion on zip_size. */
+ break;
case BUF_GET_NO_LATCH:
ut_ad(rw_latch == RW_NO_LATCH);
- break;
+ /* fall through */
case BUF_GET:
case BUF_GET_IF_IN_POOL:
case BUF_PEEK_IF_IN_POOL:
case BUF_GET_IF_IN_POOL_OR_WATCH:
case BUF_GET_POSSIBLY_FREED:
+ ut_ad(zip_size == fil_space_get_zip_size(space));
break;
default:
ut_error;
}
#endif /* UNIV_DEBUG */
- ut_ad(zip_size == fil_space_get_zip_size(space));
ut_ad(ut_is_2pow(zip_size));
#ifndef UNIV_LOG_DEBUG
- ut_ad(!ibuf_inside(mtr)
+ ut_ad(!mtr || !ibuf_inside(mtr)
|| ibuf_page_low(space, zip_size, offset,
FALSE, file, line, NULL));
#endif
@@ -3164,9 +3161,11 @@ loop:
rw_lock_x_unlock(hash_lock);
}
- if (mode == BUF_GET_IF_IN_POOL
- || mode == BUF_PEEK_IF_IN_POOL
- || mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
+ switch (mode) {
+ case BUF_GET_IF_IN_POOL:
+ 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_EX));
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_SHARED));
@@ -3255,8 +3254,10 @@ got_block:
ut_ad(page_zip_get_size(&block->page.zip) == zip_size);
- if (mode == BUF_GET_IF_IN_POOL || mode == BUF_PEEK_IF_IN_POOL) {
-
+ switch (mode) {
+ case BUF_GET_IF_IN_POOL:
+ case BUF_PEEK_IF_IN_POOL:
+ case BUF_EVICT_IF_IN_POOL:
bool must_read;
{
@@ -3285,6 +3286,19 @@ got_block:
buf_page_t* bpage;
case BUF_BLOCK_FILE_PAGE:
+ if (UNIV_UNLIKELY(mode == BUF_EVICT_IF_IN_POOL)) {
+evict_from_pool:
+ ut_ad(!fix_block->page.oldest_modification);
+ buf_pool_mutex_enter(buf_pool);
+ buf_block_unfix(fix_block);
+
+ if (!buf_LRU_free_page(&fix_block->page, true)) {
+ ut_ad(0);
+ }
+
+ buf_pool_mutex_exit(buf_pool);
+ return(NULL);
+ }
break;
case BUF_BLOCK_ZIP_PAGE:
@@ -3317,6 +3331,10 @@ got_block:
goto loop;
}
+ if (UNIV_UNLIKELY(mode == BUF_EVICT_IF_IN_POOL)) {
+ goto evict_from_pool;
+ }
+
/* Buffer-fix the block so that it cannot be evicted
or relocated while we are attempting to allocate an
uncompressed page. */
@@ -3435,6 +3453,8 @@ got_block:
buf_block_unfix(fix_block);
buf_pool_mutex_exit(buf_pool);
rw_lock_x_unlock(&fix_block->lock);
+
+ *err = DB_PAGE_CORRUPTED;
return NULL;
}
}
@@ -4860,7 +4880,7 @@ database_corrupted:
if (err != DB_SUCCESS) {
/* Not a real corruption if it was triggered by
error injection */
- DBUG_EXECUTE_IF("buf_page_is_corrupt_failure",
+ DBUG_EXECUTE_IF("buf_page_import_corrupt_failure",
if (bpage->space > TRX_SYS_SPACE) {
buf_mark_space_corrupt(bpage);
ib_logf(IB_LOG_LEVEL_INFO,
@@ -4883,8 +4903,8 @@ database_corrupted:
space->name,
bpage->space, bpage->offset);
- buf_page_print(frame, buf_page_get_zip_size(bpage),
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(frame,
+ buf_page_get_zip_size(bpage));
ib_logf(IB_LOG_LEVEL_INFO,
"It is also possible that your"
@@ -4916,7 +4936,7 @@ database_corrupted:
}
}
- DBUG_EXECUTE_IF("buf_page_is_corrupt_failure",
+ DBUG_EXECUTE_IF("buf_page_import_corrupt_failure",
page_not_corrupt: bpage = bpage; );
if (recv_recovery_is_on()) {
diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc
index f35a34e5e98..70422671190 100644
--- a/storage/innobase/buf/buf0dblwr.cc
+++ b/storage/innobase/buf/buf0dblwr.cc
@@ -800,7 +800,7 @@ buf_dblwr_assert_on_corrupt_block(
/*==============================*/
const buf_block_t* block) /*!< in: block to check */
{
- buf_page_print(block->frame, 0, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(block->frame, 0);
ut_print_timestamp(stderr);
fprintf(stderr,
diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc
index 33a39aaed8a..793d6cdd68e 100644
--- a/storage/innobase/buf/buf0dump.cc
+++ b/storage/innobase/buf/buf0dump.cc
@@ -41,9 +41,7 @@ Created April 08, 2011 Vasil Dimov
#include "sync0rw.h" /* rw_lock_s_lock() */
#include "ut0byte.h" /* ut_ull_create() */
#include "ut0sort.h" /* UT_SORT_FUNCTION_BODY */
-#ifdef WITH_WSREP
-extern my_bool wsrep_recovery;
-#endif /* WITH_WSREP */
+#include "mysql/service_wsrep.h" /* wsrep_recovery */
enum status_severity {
STATUS_INFO,
@@ -615,6 +613,7 @@ buf_load()
if (dump_n == 0) {
ut_free(dump);
+ ut_free(dump_tmp);
ut_sprintf_timestamp(now);
buf_load_status(STATUS_NOTICE,
"Buffer pool(s) load completed at %s "
@@ -695,12 +694,13 @@ DECLARE_THREAD(buf_dump_thread)(void*)
buf_load_status(STATUS_INFO, "Loading buffer pool(s) not yet started");
if (srv_buffer_pool_load_at_startup) {
+
#ifdef WITH_WSREP
if (!wsrep_recovery) {
#endif /* WITH_WSREP */
- buf_load();
+ buf_load();
#ifdef WITH_WSREP
- }
+ }
#endif /* WITH_WSREP */
}
@@ -728,6 +728,7 @@ DECLARE_THREAD(buf_dump_thread)(void*)
#ifdef WITH_WSREP
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
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index 31feb322826..dacddfca385 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -715,7 +715,6 @@ buf_flush_update_zip_checksum(
srv_checksum_algorithm)));
mach_write_to_8(page + FIL_PAGE_LSN, lsn);
- memset(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8);
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum);
}
@@ -894,8 +893,6 @@ buf_flush_write_block_low(
bpage->newest_modification);
ut_a(page_zip_verify_checksum(frame, zip_size));
-
- memset(frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8);
break;
case BUF_BLOCK_FILE_PAGE:
frame = bpage->zip.data;
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index 8c2b5df4bce..9e89a291c80 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
@@ -90,6 +90,10 @@ during LRU eviction. */
frames in the buffer pool, we set this to TRUE */
static ibool 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,
@@ -528,26 +532,20 @@ 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.
+@param[in,out] buf_pool buffer pool
+@param[in] id tablespace identifier
+@param[in] trx transaction (to check for interrupt),
+ or NULL if the files should not be written to
@retval DB_SUCCESS if all freed
@retval DB_FAIL if not all freed
@retval DB_INTERRUPTED if the transaction was interrupted */
static MY_ATTRIBUTE((nonnull(1), warn_unused_result))
dberr_t
-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 */
- 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_flush_or_remove_pages(buf_pool_t* buf_pool, ulint id, const trx_t* trx)
{
buf_page_t* prev;
buf_page_t* bpage;
@@ -574,7 +572,7 @@ rescan:
/* Skip this block, as it does not belong to
the target space. */
- } else if (!buf_flush_or_remove_page(buf_pool, bpage, flush)) {
+ } else if (!buf_flush_or_remove_page(buf_pool, bpage, trx)) {
/* Remove was unsuccessful, we have to try again
by scanning the entire list from the end.
@@ -597,7 +595,7 @@ rescan:
iteration. */
all_freed = false;
- } else if (flush) {
+ } else if (trx) {
/* The processing was successful. And during the
processing we have released the buf_pool mutex
@@ -616,19 +614,17 @@ rescan:
processed = 0;
}
-#ifdef DBUG_OFF
- if (flush) {
+ if (trx) {
DBUG_EXECUTE_IF("ib_export_flush_crash",
static ulint n_pages;
if (++n_pages == 4) {DBUG_SUICIDE();});
- }
-#endif /* DBUG_OFF */
- /* The check for trx is interrupted is expensive, we want
- to check every N iterations. */
- if (!processed && trx && trx_is_interrupted(trx)) {
- buf_flush_list_mutex_exit(buf_pool);
- return(DB_INTERRUPTED);
+ /* The check for trx is interrupted is
+ expensive, we want to check every N iterations. */
+ if (!processed && trx_is_interrupted(trx)) {
+ buf_flush_list_mutex_exit(buf_pool);
+ return(DB_INTERRUPTED);
+ }
}
}
@@ -637,28 +633,25 @@ rescan:
return(all_freed ? DB_SUCCESS : DB_FAIL);
}
-/******************************************************************//**
-Remove or flush all the dirty pages that belong to a given tablespace
+/** Remove or flush all the dirty pages that belong to a given tablespace
inside a specific buffer pool instance. The pages will remain in the LRU
list and will be evicted from the LRU list as they age and move towards
-the tail of the LRU list. */
+the tail of the LRU list.
+@param[in,out] buf_pool buffer pool
+@param[in] id tablespace identifier
+@param[in] trx transaction (to check for interrupt),
+ or NULL if the files should not be written to
+*/
static MY_ATTRIBUTE((nonnull(1)))
void
-buf_flush_dirty_pages(
-/*==================*/
- buf_pool_t* buf_pool, /*!< buffer pool instance */
- ulint id, /*!< in: space id */
- bool flush, /*!< in: flush to disk if true otherwise
- remove the pages without flushing */
- const trx_t* trx) /*!< to check if the operation must
- be interrupted */
+buf_flush_dirty_pages(buf_pool_t* buf_pool, ulint id, const trx_t* trx)
{
dberr_t err;
do {
buf_pool_mutex_enter(buf_pool);
- err = buf_flush_or_remove_pages(buf_pool, id, flush, trx);
+ err = buf_flush_or_remove_pages(buf_pool, id, trx);
buf_pool_mutex_exit(buf_pool);
@@ -679,231 +672,27 @@ buf_flush_dirty_pages(
|| buf_pool_get_dirty_pages_count(buf_pool, id) == 0);
}
-/******************************************************************//**
-Remove all pages that belong to a given tablespace inside a specific
-buffer pool instance when we are DISCARDing the tablespace. */
-static MY_ATTRIBUTE((nonnull))
+/** 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
void
-buf_LRU_remove_all_pages(
-/*=====================*/
- buf_pool_t* buf_pool, /*!< buffer pool instance */
- ulint id) /*!< in: space id */
+buf_LRU_flush_or_remove_pages(ulint id, const trx_t* trx, bool drop_ahi)
{
- buf_page_t* bpage;
- ibool all_freed;
-
-scan_again:
- buf_pool_mutex_enter(buf_pool);
-
- all_freed = TRUE;
-
- for (bpage = UT_LIST_GET_LAST(buf_pool->LRU);
- bpage != NULL;
- /* No op */) {
-
- rw_lock_t* hash_lock;
- buf_page_t* prev_bpage;
- ib_mutex_t* block_mutex = NULL;
-
- ut_a(buf_page_in_file(bpage));
- ut_ad(bpage->in_LRU_list);
-
- prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
-
- /* bpage->space and bpage->io_fix are protected by
- buf_pool->mutex and the block_mutex. It is safe to check
- them while holding buf_pool->mutex only. */
-
- if (buf_page_get_space(bpage) != id) {
- /* Skip this block, as it does not belong to
- the space that is being invalidated. */
- goto next_page;
- } else if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
- /* We cannot remove this page during this scan
- yet; maybe the system is currently reading it
- in, or flushing the modifications to the file */
-
- all_freed = FALSE;
- goto next_page;
- } else {
- ulint fold = buf_page_address_fold(
- bpage->space, bpage->offset);
-
- hash_lock = buf_page_hash_lock_get(buf_pool, fold);
-
- rw_lock_x_lock(hash_lock);
-
- block_mutex = buf_page_get_mutex(bpage);
- mutex_enter(block_mutex);
-
- if (bpage->buf_fix_count > 0) {
-
- mutex_exit(block_mutex);
-
- rw_lock_x_unlock(hash_lock);
-
- /* We cannot remove this page during
- this scan yet; maybe the system is
- currently reading it in, or flushing
- the modifications to the file */
-
- all_freed = FALSE;
-
- goto next_page;
- }
- }
-
- ut_ad(mutex_own(block_mutex));
-
-#ifdef UNIV_DEBUG
- if (buf_debug_prints) {
- fprintf(stderr,
- "Dropping space %lu page %lu\n",
- (ulong) buf_page_get_space(bpage),
- (ulong) buf_page_get_page_no(bpage));
- }
-#endif
- if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
- /* Do nothing, because the adaptive hash index
- covers uncompressed pages only. */
- } else if (((buf_block_t*) bpage)->index) {
- ulint page_no;
- ulint zip_size;
-
- buf_pool_mutex_exit(buf_pool);
-
- zip_size = buf_page_get_zip_size(bpage);
- page_no = buf_page_get_page_no(bpage);
-
- rw_lock_x_unlock(hash_lock);
-
- mutex_exit(block_mutex);
-
- /* Note that the following call will acquire
- and release block->lock X-latch. */
-
- btr_search_drop_page_hash_when_freed(
- id, zip_size, page_no);
-
- goto scan_again;
- }
-
- if (bpage->oldest_modification != 0) {
-
- buf_flush_remove(bpage);
- }
-
- ut_ad(!bpage->in_flush_list);
-
- /* Remove from the LRU list. */
-
- if (buf_LRU_block_remove_hashed(bpage, true)) {
- buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
- } else {
- ut_ad(block_mutex == &buf_pool->zip_mutex);
+ for (ulint i = 0; i < srv_buf_pool_instances; i++) {
+ buf_pool_t* buf_pool = buf_pool_from_array(i);
+ if (drop_ahi) {
+ buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
}
-
- ut_ad(!mutex_own(block_mutex));
-
-#ifdef UNIV_SYNC_DEBUG
- /* buf_LRU_block_remove_hashed() releases the hash_lock */
- ut_ad(!rw_lock_own(hash_lock, RW_LOCK_EX));
- ut_ad(!rw_lock_own(hash_lock, RW_LOCK_SHARED));
-#endif /* UNIV_SYNC_DEBUG */
-
-next_page:
- bpage = prev_bpage;
+ buf_flush_dirty_pages(buf_pool, id, trx);
}
- buf_pool_mutex_exit(buf_pool);
-
- if (!all_freed) {
- os_thread_sleep(20000);
-
- goto scan_again;
- }
-}
-
-/******************************************************************//**
-Remove 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 only if buf_remove
-is BUF_REMOVE_FLUSH_NO_WRITE. */
-static MY_ATTRIBUTE((nonnull(1)))
-void
-buf_LRU_remove_pages(
-/*=================*/
- buf_pool_t* buf_pool, /*!< buffer pool instance */
- ulint id, /*!< in: space id */
- buf_remove_t buf_remove, /*!< in: remove or flush strategy */
- const trx_t* trx) /*!< to check if the operation must
- be interrupted */
-{
- switch (buf_remove) {
- case BUF_REMOVE_ALL_NO_WRITE:
- buf_LRU_remove_all_pages(buf_pool, id);
- break;
-
- case BUF_REMOVE_FLUSH_NO_WRITE:
- ut_a(trx == 0);
- buf_flush_dirty_pages(buf_pool, id, false, NULL);
- break;
-
- case BUF_REMOVE_FLUSH_WRITE:
- ut_a(trx != 0);
- buf_flush_dirty_pages(buf_pool, id, true, trx);
+ if (trx && !trx_is_interrupted(trx)) {
/* Ensure that all asynchronous IO is completed. */
os_aio_wait_until_no_pending_writes();
fil_flush(id);
- break;
- }
-}
-
-/******************************************************************//**
-Flushes all dirty pages or removes all pages belonging
-to a given tablespace. A PROBLEM: if readahead is being started, what
-guarantees that it will not try to read in pages after this operation
-has completed? */
-UNIV_INTERN
-void
-buf_LRU_flush_or_remove_pages(
-/*==========================*/
- ulint id, /*!< in: space id */
- buf_remove_t buf_remove, /*!< in: remove or flush strategy */
- const trx_t* trx) /*!< to check if the operation must
- be interrupted */
-{
- ulint i;
-
- /* Before we attempt to drop pages one by one we first
- attempt to drop page hash index entries in batches to make
- it more efficient. The batching attempt is a best effort
- attempt and does not guarantee that all pages hash entries
- will be dropped. We get rid of remaining page hash entries
- one by one below. */
- for (i = 0; i < srv_buf_pool_instances; i++) {
- buf_pool_t* buf_pool;
-
- buf_pool = buf_pool_from_array(i);
-
- switch (buf_remove) {
- case BUF_REMOVE_ALL_NO_WRITE:
- buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
- break;
-
- case BUF_REMOVE_FLUSH_NO_WRITE:
- /* It is a DROP TABLE for a single table
- tablespace. No AHI entries exist because
- we already dealt with them when freeing up
- extents. */
- case BUF_REMOVE_FLUSH_WRITE:
- /* We allow read-only queries against the
- table, there is no need to drop the AHI entries. */
- break;
- }
-
- buf_LRU_remove_pages(buf_pool, id, buf_remove, trx);
}
}
@@ -1260,8 +1049,6 @@ buf_LRU_get_free_block(
ibool freed = FALSE;
ulint n_iterations = 0;
ulint flush_failures = 0;
- ibool mon_value_was = FALSE;
- ibool started_monitor = FALSE;
MONITOR_INC(MONITOR_LRU_GET_FREE_SEARCH);
loop:
@@ -1269,6 +1056,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);
@@ -1277,16 +1069,11 @@ loop:
buf_pool_mutex_exit(buf_pool);
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);
- }
-
return(block);
}
freed = FALSE;
+
if (buf_pool->try_LRU_scan || n_iterations > 0) {
/* If no block was in the free list, search from the
end of the LRU list and try to free a block there.
@@ -1309,6 +1096,10 @@ loop:
}
}
+#ifndef DBUG_OFF
+not_found:
+#endif
+
buf_pool_mutex_exit(buf_pool);
if (freed) {
@@ -1316,40 +1107,26 @@ loop:
}
- if (n_iterations > 20) {
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Warning: difficult to find free blocks in\n"
- "InnoDB: the buffer pool (%lu search iterations)!\n"
- "InnoDB: %lu failed attempts to flush a page!"
- " Consider\n"
- "InnoDB: increasing the buffer pool size.\n"
- "InnoDB: It is also possible that"
- " in your Unix version\n"
- "InnoDB: fsync is very slow, or"
- " completely frozen inside\n"
- "InnoDB: the OS kernel. Then upgrading to"
- " a newer version\n"
- "InnoDB: of your operating system may help."
- " Look at the\n"
- "InnoDB: number of fsyncs in diagnostic info below.\n"
- "InnoDB: Pending flushes (fsync) log: %lu;"
- " buffer pool: %lu\n"
- "InnoDB: %lu OS file reads, %lu OS file writes,"
- " %lu OS fsyncs\n"
- "InnoDB: Starting InnoDB Monitor to print further\n"
- "InnoDB: diagnostics to the standard output.\n",
- (ulong) n_iterations,
- (ulong) flush_failures,
- (ulong) fil_n_pending_log_flushes,
- (ulong) fil_n_pending_tablespace_flushes,
- (ulong) os_n_file_reads, (ulong) os_n_file_writes,
- (ulong) os_n_fsyncs);
-
- mon_value_was = srv_print_innodb_monitor;
- started_monitor = TRUE;
- srv_print_innodb_monitor = TRUE;
- os_event_set(srv_monitor_event);
+ if (n_iterations > 20 && !buf_lru_free_blocks_error_printed) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Difficult to find free blocks in"
+ " the buffer pool (" ULINTPF " search iterations)! "
+ ULINTPF " failed attempts to flush a page!",
+ n_iterations, flush_failures);
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Consider increasing the buffer pool size.");
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Pending flushes (fsync) log: " ULINTPF
+ " buffer pool: " ULINTPF
+ " OS file reads: " ULINTPF " OS file writes: "
+ ULINTPF " OS fsyncs: " ULINTPF "",
+ fil_n_pending_log_flushes,
+ fil_n_pending_tablespace_flushes,
+ os_n_file_reads,
+ os_n_file_writes,
+ os_n_fsyncs);
+
+ buf_lru_free_blocks_error_printed = true;
}
/* If we have scanned the whole LRU and still are unable to
@@ -2131,8 +1908,7 @@ buf_LRU_block_free_non_file_page(
UT_LIST_ADD_FIRST(list, buf_pool->free, (&block->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 0b9e08544a5..34ca399f9b2 100644
--- a/storage/innobase/data/data0type.cc
+++ b/storage/innobase/data/data0type.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2011, 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
@@ -49,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) */
@@ -58,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(data_len != UNIV_SQL_NULL);
ut_ad(!mbmaxlen || !(prefix_len % mbmaxlen));
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 1a3923047b0..7ec4364becc 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -570,15 +570,14 @@ dict_table_close(
ut_ad(mutex_own(&dict_sys->mutex));
ut_a(table->n_ref_count > 0);
- --table->n_ref_count;
+ const bool last_handle = !--table->n_ref_count;
/* Force persistent stats re-read upon next open of the table
so that FLUSH TABLE can be used to forcibly fetch stats from disk
if they have been manually modified. We reset table->stat_initialized
only if table reference count is 0 because we do not want too frequent
stats re-reads (e.g. in other cases than FLUSH TABLE). */
- if (strchr(table->name, '/') != NULL
- && table->n_ref_count == 0
+ if (last_handle && strchr(table->name, '/') != NULL
&& dict_stats_is_persistent_enabled(table)) {
dict_stats_deinit(table);
@@ -598,11 +597,8 @@ dict_table_close(
if (!dict_locked) {
table_id_t table_id = table->id;
- ibool drop_aborted;
-
- drop_aborted = try_drop
+ const bool drop_aborted = last_handle && try_drop
&& table->drop_aborted
- && table->n_ref_count == 1
&& dict_table_get_first_index(table);
mutex_exit(&dict_sys->mutex);
@@ -642,40 +638,6 @@ dict_table_get_col_name(
return(s);
}
-/**********************************************************************//**
-Returns a column's name.
-@return column name. NOTE: not guaranteed to stay valid if table is
-modified in any way (columns added, etc.). */
-UNIV_INTERN
-const char*
-dict_table_get_col_name_for_mysql(
-/*==============================*/
- const dict_table_t* table, /*!< in: table */
- const char* col_name)/*! in: MySQL table column name */
-{
- ulint i;
- const char* s;
-
- ut_ad(table);
- ut_ad(col_name);
- ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
-
- s = table->col_names;
- if (s) {
- /* If we have many virtual columns MySQL key_part->fieldnr
- could be larger than number of columns in InnoDB table
- when creating new indexes. */
- for (i = 0; i < table->n_def; i++) {
-
- if (!innobase_strcasecmp(s, col_name)) {
- break; /* Found */
- }
- s += strlen(s) + 1;
- }
- }
-
- return(s);
-}
#ifndef UNIV_HOTBACKUP
/** Allocate and init the autoinc latch of a given table.
This function must not be called concurrently on the same table object.
@@ -1711,7 +1673,7 @@ dict_table_rename_in_cache(
filepath = fil_make_ibd_name(table->name, false);
}
- fil_delete_tablespace(table->space, BUF_REMOVE_ALL_NO_WRITE);
+ fil_delete_tablespace(table->space, true);
/* Delete any temp file hanging around. */
if (os_file_status(filepath, &exists, &ftype)
@@ -2145,8 +2107,9 @@ dict_table_remove_from_cache_low(
}
if (lru_evict && table->drop_aborted) {
- /* Do as dict_table_try_drop_aborted() does. */
-
+ /* When evicting the table definition,
+ drop the orphan indexes from the data dictionary
+ and free the index pages. */
trx_t* trx = trx_allocate_for_background();
ut_ad(mutex_own(&dict_sys->mutex));
@@ -2157,12 +2120,7 @@ dict_table_remove_from_cache_low(
trx->dict_operation_lock_mode = RW_X_LATCH;
trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
-
- /* Silence a debug assertion in row_merge_drop_indexes(). */
- ut_d(table->n_ref_count++);
- row_merge_drop_indexes(trx, table, TRUE);
- ut_d(table->n_ref_count--);
- ut_ad(table->n_ref_count == 0);
+ row_merge_drop_indexes_dict(trx, table->id);
trx_commit_for_mysql(trx);
trx->dict_operation_lock_mode = 0;
trx_free_for_background(trx);
@@ -3440,6 +3398,7 @@ dict_foreign_find_index(
if (types_idx != index
&& !(index->type & DICT_FTS)
&& !index->to_be_dropped
+ && !dict_index_is_online_ddl(index)
&& dict_foreign_qualify_index(
table, col_names, columns, n_cols,
index, types_idx,
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc
index 0e5e9f65b04..dd8155c09eb 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
@@ -319,8 +319,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
@@ -532,7 +532,8 @@ dict_mem_fill_column_struct(
column->len = (unsigned int) col_len;
#ifndef UNIV_HOTBACKUP
dtype_get_mblen(mtype, prtype, &mbminlen, &mbmaxlen);
- dict_col_set_mbminmaxlen(column, mbminlen, mbmaxlen);
+ column->mbminlen = mbminlen;
+ column->mbmaxlen = mbmaxlen;
#endif /* !UNIV_HOTBACKUP */
}
diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc
index 57a5912941e..6f2f96c452e 100644
--- a/storage/innobase/dict/dict0stats_bg.cc
+++ b/storage/innobase/dict/dict0stats_bg.cc
@@ -336,7 +336,7 @@ dict_stats_wait_bg_to_stop_using_table(
unlocking/locking the data dict */
{
while (!dict_stats_stop_bg(table)) {
- DICT_STATS_BG_YIELD(trx);
+ DICT_BG_YIELD(trx);
}
}
@@ -478,7 +478,6 @@ 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;
@@ -500,31 +499,19 @@ 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;
- }
+ mutex_exit(&dict_sys->mutex);
dict_stats_save_defrag_stats(index);
dict_table_close(table, FALSE, FALSE);
}
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index a388ce4b604..3095503cfc5 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -742,11 +742,12 @@ fil_space_encrypt(
fprintf(stderr, "ok %d corrupted %d corrupted1 %d err %d different %d\n",
ok , corrupted, corrupted1, err, different);
fprintf(stderr, "src_frame\n");
- buf_page_print(src_frame, zip_size, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(src_frame, zip_size);
fprintf(stderr, "encrypted_frame\n");
- buf_page_print(tmp, zip_size, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(tmp, zip_size);
fprintf(stderr, "decrypted_frame\n");
- buf_page_print(tmp_mem, zip_size, 0);
+ buf_page_print(tmp_mem, zip_size);
+ ut_ad(0);
}
free(tmp_mem);
@@ -2127,7 +2128,8 @@ fil_crypt_complete_rotate_space(
mutex_exit(&crypt_data->mutex);
/* all threads must call btr_scrub_complete_space wo/ mutex held */
- if (btr_scrub_complete_space(&state->scrub_data) == true) {
+ if (state->scrub_data.scrubbing) {
+ btr_scrub_complete_space(&state->scrub_data);
if (should_flush) {
/* only last thread updates last_scrub_completed */
ut_ad(crypt_data);
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 7200c3c32e2..b4102e48628 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -1037,155 +1037,26 @@ fil_space_extend_must_retry(
page_size = UNIV_PAGE_SIZE;
}
-#ifdef _WIN32
- const ulint io_completion_type = OS_FILE_READ;
- /* Logically or physically extend the file with zero bytes,
- depending on whether it is sparse. */
+ /* fil_read_first_page() expects UNIV_PAGE_SIZE bytes.
+ fil_node_open_file() expects at least 4 * UNIV_PAGE_SIZE bytes.*/
- /* FIXME: Call DeviceIoControl(node->handle, FSCTL_SET_SPARSE, ...)
- when opening a file when FSP_FLAGS_HAS_PAGE_COMPRESSION(). */
- {
- FILE_END_OF_FILE_INFO feof;
- /* fil_read_first_page() expects UNIV_PAGE_SIZE bytes.
- fil_node_open_file() expects at least 4 * UNIV_PAGE_SIZE bytes.
- Do not shrink short ROW_FORMAT=COMPRESSED files. */
- feof.EndOfFile.QuadPart = std::max(
- os_offset_t(size - file_start_page_no) * page_size,
- os_offset_t(FIL_IBD_FILE_INITIAL_SIZE
- * UNIV_PAGE_SIZE));
- *success = SetFileInformationByHandle(node->handle,
- FileEndOfFileInfo,
- &feof, sizeof feof);
- if (!*success) {
- ib_logf(IB_LOG_LEVEL_ERROR, "extending file %s"
- " from " INT64PF
- " to " INT64PF " bytes failed with %u",
- node->name,
- os_offset_t(node->size) * page_size,
- feof.EndOfFile.QuadPart, GetLastError());
- } else {
- start_page_no = size;
- }
- }
-#else
- /* We will logically extend the file with ftruncate() if
- page_compression is enabled, because the file is expected to
- be sparse in that case. Make sure that ftruncate() can deal
- with large files. */
- const bool is_sparse = sizeof(off_t) >= 8
- && FSP_FLAGS_HAS_PAGE_COMPRESSION(space->flags);
-
-# ifdef HAVE_POSIX_FALLOCATE
- /* We must complete the I/O request after invoking
- posix_fallocate() to avoid an assertion failure at shutdown.
- Because no actual writes were dispatched, a read operation
- will suffice. */
- const ulint io_completion_type = srv_use_posix_fallocate
- || is_sparse ? OS_FILE_READ : OS_FILE_WRITE;
-
- if (srv_use_posix_fallocate && !is_sparse) {
- const os_offset_t start_offset
- = os_offset_t(start_page_no - file_start_page_no)
- * page_size;
- const ulint n_pages = size - start_page_no;
- const os_offset_t len = os_offset_t(n_pages) * page_size;
-
- int err;
- do {
- err = posix_fallocate(node->handle, start_offset, len);
- } while (err == EINTR
- && srv_shutdown_state == SRV_SHUTDOWN_NONE);
-
- *success = !err;
- if (!*success) {
- ib_logf(IB_LOG_LEVEL_ERROR, "extending file %s"
- " from " INT64PF " to " INT64PF " bytes"
- " failed with error %d",
- node->name, start_offset, len + start_offset,
- err);
- }
-
- DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28",
- *success = FALSE;
- os_has_said_disk_full = TRUE;);
-
- if (*success) {
- os_has_said_disk_full = FALSE;
- start_page_no = size;
- }
- } else
-# else
- const ulint io_completion_type = is_sparse
- ? OS_FILE_READ : OS_FILE_WRITE;
-# endif
- if (is_sparse) {
- /* fil_read_first_page() expects UNIV_PAGE_SIZE bytes.
- fil_node_open_file() expects at least 4 * UNIV_PAGE_SIZE bytes.
- Do not shrink short ROW_FORMAT=COMPRESSED files. */
- off_t s = std::max(off_t(size - file_start_page_no)
- * off_t(page_size),
- off_t(FIL_IBD_FILE_INITIAL_SIZE
- * UNIV_PAGE_SIZE));
- *success = !ftruncate(node->handle, s);
- if (!*success) {
- ib_logf(IB_LOG_LEVEL_ERROR, "ftruncate of file %s"
- " from " INT64PF " to " INT64PF " bytes"
- " failed with error %d",
- node->name,
- os_offset_t(start_page_no - file_start_page_no)
- * page_size, os_offset_t(s), errno);
- } else {
- start_page_no = size;
- }
- } else {
- /* Extend at most 64 pages at a time */
- ulint buf_size = ut_min(64, size - start_page_no)
- * page_size;
- byte* buf2 = static_cast<byte*>(
- calloc(1, buf_size + page_size));
- *success = buf2 != NULL;
- if (!buf2) {
- ib_logf(IB_LOG_LEVEL_ERROR, "Cannot allocate " ULINTPF
- " bytes to extend file",
- buf_size + page_size);
- }
- byte* const buf = static_cast<byte*>(
- ut_align(buf2, page_size));
-
- while (*success && start_page_no < size) {
- ulint n_pages
- = ut_min(buf_size / page_size,
- size - start_page_no);
-
- os_offset_t offset = static_cast<os_offset_t>(
- start_page_no - file_start_page_no)
- * page_size;
-
- *success = os_aio(OS_FILE_WRITE, 0, OS_AIO_SYNC,
- node->name, node->handle, buf,
- offset, page_size * n_pages,
- page_size, node, NULL, 0);
-
- DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28",
- *success = FALSE;
- os_has_said_disk_full = TRUE;);
-
- if (*success) {
- os_has_said_disk_full = FALSE;
- }
- /* Let us measure the size of the file
- to determine how much we were able to
- extend it */
- os_offset_t fsize = os_file_get_size(node->handle);
- ut_a(fsize != os_offset_t(-1));
+ os_offset_t new_size = std::max(
+ os_offset_t(size - file_start_page_no) * page_size,
+ os_offset_t(FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE));
- start_page_no = ulint(fsize / page_size)
- + file_start_page_no;
- }
+ *success = os_file_set_size(node->name, node->handle, new_size,
+ FSP_FLAGS_HAS_PAGE_COMPRESSION(space->flags));
+
+
+ DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28",
+ *success = FALSE;
+ os_has_said_disk_full = TRUE;);
- free(buf2);
+ if (*success) {
+ os_has_said_disk_full = FALSE;
+ start_page_no = size;
}
-#endif
+
mutex_enter(&fil_system->mutex);
ut_a(node->being_extended);
@@ -1195,7 +1066,7 @@ fil_space_extend_must_retry(
space->size += file_size - node->size;
node->size = file_size;
- fil_node_complete_io(node, fil_system, io_completion_type);
+ fil_node_complete_io(node, fil_system, OS_FILE_READ);
node->being_extended = FALSE;
@@ -2203,7 +2074,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(2 * UNIV_PAGE_SIZE));
buf = static_cast<byte*>(ut_align(buf1, UNIV_PAGE_SIZE));
@@ -2214,7 +2085,9 @@ fil_write_flushed_lsn(
/* If tablespace is not encrypted, stamp flush_lsn to
first page of all system tablespace datafiles to avoid
unnecessary error messages on possible downgrade. */
- if (!space->crypt_data || space->crypt_data->min_key_version == 0) {
+ if (!space->crypt_data
+ || !space->crypt_data->should_encrypt()) {
+
fil_node_t* node;
ulint sum_of_sizes = 0;
@@ -2655,8 +2528,7 @@ fil_op_log_parse_or_replay(
switch (type) {
case MLOG_FILE_DELETE:
if (fil_tablespace_exists_in_mem(space_id)) {
- dberr_t err = fil_delete_tablespace(
- space_id, BUF_REMOVE_FLUSH_NO_WRITE);
+ dberr_t err = fil_delete_tablespace(space_id);
ut_a(err == DB_SUCCESS);
}
@@ -2934,7 +2806,7 @@ 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, BUF_REMOVE_FLUSH_WRITE, trx);
+ buf_LRU_flush_or_remove_pages(id, trx);
#endif
mutex_enter(&fil_system->mutex);
@@ -2961,18 +2833,13 @@ fil_close_tablespace(
return(err);
}
-/*******************************************************************//**
-Deletes a single-table tablespace. The tablespace must be cached in the
-memory cache.
+/** 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 */
UNIV_INTERN
dberr_t
-fil_delete_tablespace(
-/*==================*/
- ulint id, /*!< in: space id */
- buf_remove_t buf_remove) /*!< in: specify the action to take
- on the tables pages in the buffer
- pool */
+fil_delete_tablespace(ulint id, bool drop_ahi)
{
char* path = 0;
fil_space_t* space = 0;
@@ -3028,7 +2895,7 @@ fil_delete_tablespace(
To deal with potential read requests by checking the
::stop_new_ops flag in fil_io() */
- buf_LRU_flush_or_remove_pages(id, buf_remove, 0);
+ buf_LRU_flush_or_remove_pages(id, NULL, drop_ahi);
#endif /* !UNIV_HOTBACKUP */
@@ -3139,7 +3006,7 @@ fil_discard_tablespace(
{
dberr_t err;
- switch (err = fil_delete_tablespace(id, BUF_REMOVE_ALL_NO_WRITE)) {
+ switch (err = fil_delete_tablespace(id, true)) {
case DB_SUCCESS:
break;
diff --git a/storage/innobase/fil/fil0pagecompress.cc b/storage/innobase/fil/fil0pagecompress.cc
index 2b6ae95640f..edc932f36f5 100644
--- a/storage/innobase/fil/fil0pagecompress.cc
+++ b/storage/innobase/fil/fil0pagecompress.cc
@@ -106,6 +106,9 @@ fil_compress_page(
int comp_level = level;
ulint header_len = FIL_PAGE_DATA + FIL_PAGE_COMPRESSED_SIZE;
ulint write_size = 0;
+#if HAVE_LZO
+ lzo_uint write_size_lzo = write_size;
+#endif
/* Cache to avoid change during function execution */
ulint comp_method = innodb_compression_algorithm;
bool allocated = false;
@@ -207,7 +210,9 @@ fil_compress_page(
#ifdef HAVE_LZO
case PAGE_LZO_ALGORITHM:
err = lzo1x_1_15_compress(
- buf, len, out_buf+header_len, &write_size, out_buf+UNIV_PAGE_SIZE);
+ buf, len, out_buf+header_len, &write_size_lzo, out_buf+UNIV_PAGE_SIZE);
+
+ write_size = write_size_lzo;
if (err != LZO_E_OK || write_size > UNIV_PAGE_SIZE-header_len) {
if (space && !space->printed_compression_failure) {
@@ -397,7 +402,8 @@ fil_compress_page(
fil_decompress_page(uncomp_page, comp_page, ulong(len), NULL);
if (buf_page_is_corrupted(false, uncomp_page, 0, space)) {
- buf_page_print(uncomp_page, 0, 0);
+ buf_page_print(uncomp_page, 0);
+ ut_ad(0);
}
ut_free(comp_page);
@@ -603,8 +609,11 @@ fil_decompress_page(
#ifdef HAVE_LZO
case PAGE_LZO_ALGORITHM: {
ulint olen = 0;
+ lzo_uint olen_lzo = olen;
err = lzo1x_decompress((const unsigned char *)buf+header_len,
- actual_size,(unsigned char *)in_buf, &olen, NULL);
+ actual_size,(unsigned char *)in_buf, &olen_lzo, NULL);
+
+ olen = olen_lzo;
if (err != LZO_E_OK || (olen == 0 || olen > UNIV_PAGE_SIZE)) {
ib_logf(IB_LOG_LEVEL_ERROR,
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index bfe32e2aec4..dc121083c6e 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, MariaDB Corporation. All Rights reserved.
+Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2016, 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
@@ -26,6 +26,7 @@ Full Text Search interface
#include "row0mysql.h"
#include "row0upd.h"
#include "dict0types.h"
+#include "dict0stats_bg.h"
#include "row0sel.h"
#include "fts0fts.h"
@@ -868,18 +869,37 @@ fts_drop_index(
err = fts_drop_index_tables(trx, index);
- fts_free(table);
-
+ for(;;) {
+ bool retry = false;
+ if (index->index_fts_syncing) {
+ retry = true;
+ }
+ if (!retry){
+ fts_free(table);
+ break;
+ }
+ DICT_BG_YIELD(trx);
+ }
return(err);
}
- current_doc_id = table->fts->cache->next_doc_id;
- first_doc_id = table->fts->cache->first_doc_id;
- fts_cache_clear(table->fts->cache);
- fts_cache_destroy(table->fts->cache);
- table->fts->cache = fts_cache_create(table);
- table->fts->cache->next_doc_id = current_doc_id;
- table->fts->cache->first_doc_id = first_doc_id;
+ for(;;) {
+ bool retry = false;
+ if (index->index_fts_syncing) {
+ retry = true;
+ }
+ if (!retry){
+ current_doc_id = table->fts->cache->next_doc_id;
+ first_doc_id = table->fts->cache->first_doc_id;
+ fts_cache_clear(table->fts->cache);
+ fts_cache_destroy(table->fts->cache);
+ table->fts->cache = fts_cache_create(table);
+ table->fts->cache->next_doc_id = current_doc_id;
+ table->fts->cache->first_doc_id = first_doc_id;
+ break;
+ }
+ DICT_BG_YIELD(trx);
+ }
} else {
fts_cache_t* cache = table->fts->cache;
fts_index_cache_t* index_cache;
@@ -889,9 +909,17 @@ fts_drop_index(
index_cache = fts_find_index_cache(cache, index);
if (index_cache != NULL) {
- if (index_cache->words) {
- fts_words_free(index_cache->words);
- rbt_free(index_cache->words);
+ for(;;) {
+ bool retry = false;
+ if (index->index_fts_syncing) {
+ retry = true;
+ }
+ if (!retry && index_cache->words) {
+ fts_words_free(index_cache->words);
+ rbt_free(index_cache->words);
+ break;
+ }
+ DICT_BG_YIELD(trx);
}
ib_vector_remove(cache->indexes, *(void**) index_cache);
@@ -1973,7 +2001,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,
@@ -2645,22 +2673,23 @@ fts_get_next_doc_id(
will consult the CONFIG table and user table to re-establish
the initial value of the Doc ID */
- if (cache->first_doc_id != 0 || !fts_init_doc_id(table)) {
- if (!DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID)) {
- *doc_id = FTS_NULL_DOC_ID;
- return(DB_SUCCESS);
+ if (!DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID)) {
+ if (cache->first_doc_id == FTS_NULL_DOC_ID) {
+ fts_init_doc_id(table);
}
+ *doc_id = FTS_NULL_DOC_ID;
+ return(DB_SUCCESS);
+ }
- /* Otherwise, simply increment the value in cache */
- mutex_enter(&cache->doc_id_lock);
- *doc_id = ++cache->next_doc_id;
- mutex_exit(&cache->doc_id_lock);
- } else {
- mutex_enter(&cache->doc_id_lock);
- *doc_id = cache->next_doc_id;
- mutex_exit(&cache->doc_id_lock);
+ if (cache->first_doc_id == FTS_NULL_DOC_ID) {
+ fts_init_doc_id(table);
}
+ DEBUG_SYNC_C("get_next_FTS_DOC_ID");
+ mutex_enter(&cache->doc_id_lock);
+ *doc_id = cache->next_doc_id++;
+ mutex_exit(&cache->doc_id_lock);
+
return(DB_SUCCESS);
}
@@ -3034,53 +3063,6 @@ fts_modify(
}
/*********************************************************************//**
-Create a new document id.
-@return DB_SUCCESS if all went well else error */
-UNIV_INTERN
-dberr_t
-fts_create_doc_id(
-/*==============*/
- dict_table_t* table, /*!< in: row is of this table. */
- dtuple_t* row, /* in/out: add doc id value to this
- row. This is the current row that is
- being inserted. */
- mem_heap_t* heap) /*!< in: heap */
-{
- doc_id_t doc_id;
- dberr_t error = DB_SUCCESS;
-
- ut_a(table->fts->doc_col != ULINT_UNDEFINED);
-
- if (!DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID)) {
- if (table->fts->cache->first_doc_id == FTS_NULL_DOC_ID) {
- error = fts_get_next_doc_id(table, &doc_id);
- }
- return(error);
- }
-
- error = fts_get_next_doc_id(table, &doc_id);
-
- if (error == DB_SUCCESS) {
- dfield_t* dfield;
- doc_id_t* write_doc_id;
-
- ut_a(doc_id > 0);
-
- dfield = dtuple_get_nth_field(row, table->fts->doc_col);
- write_doc_id = static_cast<doc_id_t*>(
- mem_heap_alloc(heap, sizeof(*write_doc_id)));
-
- ut_a(doc_id != FTS_NULL_DOC_ID);
- ut_a(sizeof(doc_id) == dfield->type.len);
- fts_write_doc_id((byte*) write_doc_id, doc_id);
-
- dfield_set_data(dfield, write_doc_id, sizeof(*write_doc_id));
- }
-
- return(error);
-}
-
-/*********************************************************************//**
The given transaction is about to be committed; do whatever is necessary
from the FTS system's POV.
@return DB_SUCCESS or error code */
@@ -3380,8 +3362,7 @@ fts_fetch_doc_from_rec(
dict_table_zip_size(table),
clust_pos, &doc->text.f_len,
static_cast<mem_heap_t*>(
- doc->self_heap->arg),
- NULL);
+ doc->self_heap->arg));
} else {
doc->text.f_str = (byte*) rec_get_nth_field(
clust_rec, offsets, clust_pos,
@@ -4615,10 +4596,16 @@ begin_sync:
index_cache = static_cast<fts_index_cache_t*>(
ib_vector_get(cache->indexes, i));
- if (index_cache->index->to_be_dropped) {
+ if (index_cache->index->to_be_dropped
+ || index_cache->index->table->to_be_dropped) {
continue;
}
+ index_cache->index->index_fts_syncing = true;
+ DBUG_EXECUTE_IF("fts_instrument_sync_sleep_drop_waits",
+ os_thread_sleep(10000000);
+ );
+
error = fts_sync_index(sync, index_cache);
if (error != DB_SUCCESS && !sync->interrupted) {
@@ -4651,11 +4638,33 @@ begin_sync:
end_sync:
if (error == DB_SUCCESS && !sync->interrupted) {
error = fts_sync_commit(sync);
+ if (error == DB_SUCCESS) {
+ for (i = 0; i < ib_vector_size(cache->indexes); ++i) {
+ fts_index_cache_t* index_cache;
+ index_cache = static_cast<fts_index_cache_t*>(
+ ib_vector_get(cache->indexes, i));
+ if (index_cache->index->index_fts_syncing) {
+ index_cache->index->index_fts_syncing
+ = false;
+ }
+ }
+ }
} else {
fts_sync_rollback(sync);
}
rw_lock_x_lock(&cache->lock);
+ /* Clear fts syncing flags of any indexes incase sync is
+ interrupeted */
+ for (i = 0; i < ib_vector_size(cache->indexes); ++i) {
+ fts_index_cache_t* index_cache;
+ index_cache = static_cast<fts_index_cache_t*>(
+ ib_vector_get(cache->indexes, i));
+ if (index_cache->index->index_fts_syncing == true) {
+ index_cache->index->index_fts_syncing = false;
+ }
+ }
+
sync->interrupted = false;
sync->in_progress = false;
os_event_set(sync->event);
@@ -4752,9 +4761,17 @@ fts_process_token(
t_str.f_str = static_cast<byte*>(
mem_heap_alloc(heap, t_str.f_len));
- newlen = innobase_fts_casedn_str(
- doc->charset, (char*) str.f_str, str.f_len,
- (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(
+ 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;
@@ -7582,8 +7599,7 @@ fts_init_recover_doc(
&doc.text.f_len,
static_cast<byte*>(dfield_get_data(dfield)),
zip_size, len,
- static_cast<mem_heap_t*>(doc.self_heap->arg),
- NULL);
+ 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 cb30122adcb..d9f96948000 100644
--- a/storage/innobase/fts/fts0opt.cc
+++ b/storage/innobase/fts/fts0opt.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2007, 2017, 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
@@ -2971,13 +2971,6 @@ fts_optimize_sync_table(
{
dict_table_t* table = NULL;
- /* Prevent DROP INDEX etc. from running when we are syncing
- cache in background. */
- if (!rw_lock_s_lock_nowait(&dict_operation_lock, __FILE__, __LINE__)) {
- /* Exit when fail to get dict operation lock. */
- return;
- }
-
table = dict_table_open_on_id(table_id, FALSE, DICT_TABLE_OP_NORMAL);
if (table) {
@@ -2987,8 +2980,6 @@ fts_optimize_sync_table(
dict_table_close(table, FALSE, FALSE);
}
-
- rw_lock_s_unlock(&dict_operation_lock);
}
/**********************************************************************//**
diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc
index 26bd0378aed..3a543836837 100644
--- a/storage/innobase/fts/fts0que.cc
+++ b/storage/innobase/fts/fts0que.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
-Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2007, 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
the terms of the GNU General Public License as published by the Free Software
@@ -1916,8 +1917,7 @@ fts_query_fetch_document(
if (dfield_is_ext(dfield)) {
data = btr_copy_externally_stored_field(
&cur_len, data, phrase->zip_size,
- dfield_get_len(dfield), phrase->heap,
- NULL);
+ dfield_get_len(dfield), phrase->heap);
} else {
cur_len = dfield_get_len(dfield);
}
@@ -3633,6 +3633,10 @@ fts_query_free(
fts_doc_ids_free(query->deleted);
}
+ if (query->intersection) {
+ fts_query_free_doc_ids(query, query->intersection);
+ }
+
if (query->doc_ids) {
fts_query_free_doc_ids(query, query->doc_ids);
}
@@ -3657,8 +3661,6 @@ fts_query_free(
rbt_free(query->word_freqs);
}
- ut_a(!query->intersection);
-
if (query->word_map) {
rbt_free(query->word_map);
}
@@ -3760,10 +3762,19 @@ fts_query_str_preprocess(
str_len = query_len * charset->casedn_multiply + 1;
str_ptr = static_cast<byte*>(ut_malloc(str_len));
- *result_len = innobase_fts_casedn_str(
- charset, const_cast<char*>(reinterpret_cast<const char*>(
- query_str)), query_len,
- reinterpret_cast<char*>(str_ptr), str_len);
+ /* For binary collations, a case sensitive search is
+ performed. Hence don't convert to lower case. */
+ if (my_binary_compare(charset)) {
+ memcpy(str_ptr, query_str, query_len);
+ str_ptr[query_len]= 0;
+ *result_len= query_len;
+ } else {
+ *result_len = innobase_fts_casedn_str(
+ charset, const_cast<char*>
+ (reinterpret_cast<const char*>( query_str)),
+ query_len,
+ reinterpret_cast<char*>(str_ptr), str_len);
+ }
ut_ad(*result_len < str_len);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 4c6e13291e0..b66f74873a9 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -1087,6 +1087,18 @@ static SHOW_VAR innodb_status_variables[]= {
{"encryption_key_rotation_list_length",
(char*)&export_vars.innodb_key_rotation_list_length,
SHOW_LONGLONG},
+ {"encryption_n_merge_blocks_encrypted",
+ (char*)&export_vars.innodb_n_merge_blocks_encrypted,
+ SHOW_LONGLONG},
+ {"encryption_n_merge_blocks_decrypted",
+ (char*)&export_vars.innodb_n_merge_blocks_decrypted,
+ SHOW_LONGLONG},
+ {"encryption_n_rowlog_blocks_encrypted",
+ (char*)&export_vars.innodb_n_rowlog_blocks_encrypted,
+ SHOW_LONGLONG},
+ {"encryption_n_rowlog_blocks_decrypted",
+ (char*)&export_vars.innodb_n_rowlog_blocks_decrypted,
+ SHOW_LONGLONG},
/* scrubing */
{"scrub_background_page_reorganizations",
@@ -3082,13 +3094,13 @@ innobase_convert_identifier(
ibool file_id)/*!< in: TRUE=id is a table or database name;
FALSE=id is an UTF-8 string */
{
+ char nz2[MAX_TABLE_NAME_LEN + 1];
const char* s = id;
int q;
if (file_id) {
char nz[MAX_TABLE_NAME_LEN + 1];
- char nz2[MAX_TABLE_NAME_LEN + 1];
/* Decode the table name. The MySQL function expects
a NUL-terminated string. The input and output strings
@@ -3466,6 +3478,17 @@ 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) {
+ /* Do not allow InnoDB startup with VATS and Galera */
+ sql_print_error("In Galera, innodb_lock_schedule_algorithm=vats"
+ " is not supported.");
+ goto error;
+ }
+#endif /* WITH_WSREP */
+
#ifndef HAVE_LZ4
if (innodb_compression_algorithm == PAGE_LZ4_ALGORITHM) {
sql_print_error("InnoDB: innodb_compression_algorithm = %lu unsupported.\n"
@@ -4110,7 +4133,7 @@ innobase_commit_low(
trx_commit_for_mysql(trx);
}
#ifdef WITH_WSREP
- if (wsrep_on(thd)) { thd_proc_info(thd, tmp); }
+ if (thd && wsrep_on(thd)) { thd_proc_info(thd, tmp); }
#endif /* WITH_WSREP */
}
@@ -4870,8 +4893,8 @@ innobase_kill_query(
wsrep_thd_is_BF(current_thd, FALSE),
lock_get_info(trx->lock.wait_lock).c_str());
- if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
- trx->abort_type == TRX_SERVER_ABORT) {
+ if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE)
+ && trx->abort_type == TRX_SERVER_ABORT) {
ut_ad(!lock_mutex_own());
lock_mutex_enter();
}
@@ -5415,8 +5438,6 @@ innobase_match_index_columns(
if (innodb_idx_fld >= innodb_idx_fld_end) {
DBUG_RETURN(FALSE);
}
-
- mtype = innodb_idx_fld->col->mtype;
}
// MariaDB-5.5 compatibility
@@ -8276,7 +8297,7 @@ no_commit:
table->next_number_field);
/* Get the value that MySQL attempted to store in the table.*/
- auto_inc = table->next_number_field->val_int();
+ auto_inc = table->next_number_field->val_uint();
switch (error) {
case DB_DUPLICATE_KEY:
@@ -8870,7 +8891,7 @@ ha_innobase::update_row(
ulonglong auto_inc;
ulonglong col_max_value;
- auto_inc = table->next_number_field->val_int();
+ auto_inc = table->next_number_field->val_uint();
/* We need the upper limit of the col type to check for
whether we update the table autoinc counter or not. */
@@ -10408,7 +10429,7 @@ wsrep_append_foreign_key(
shared ? WSREP_KEY_SHARED : WSREP_KEY_EXCLUSIVE,
copy);
if (rcode) {
- DBUG_PRINT("wsrep", ("row key failed: %lu", rcode));
+ DBUG_PRINT("wsrep", ("row key failed: %zu", rcode));
WSREP_ERROR("Appending cascaded fk row key failed: %s, %lu",
(wsrep_thd_query(thd)) ?
wsrep_thd_query(thd) : "void", rcode);
@@ -13088,7 +13109,7 @@ ha_innobase::records_in_range(
n_rows = btr_estimate_n_rows_in_range(index, range_start,
mode1, range_end,
- mode2, prebuilt->trx);
+ mode2);
} else {
n_rows = HA_POS_ERROR;
@@ -16429,6 +16450,10 @@ innobase_commit_by_xid(
DBUG_ASSERT(hton == innodb_hton_ptr);
+ if (high_level_read_only) {
+ return(XAER_RMFAIL);
+ }
+
trx = trx_get_trx_by_xid(xid);
if (trx) {
@@ -16456,8 +16481,11 @@ innobase_rollback_by_xid(
DBUG_ASSERT(hton == innodb_hton_ptr);
- trx = trx_get_trx_by_xid(xid);
+ if (high_level_read_only) {
+ return(XAER_RMFAIL);
+ }
+ trx = trx_get_trx_by_xid(xid);
if (trx) {
int ret = innobase_rollback_trx(trx);
trx_free_for_background(trx);
@@ -18397,7 +18425,7 @@ buffer_pool_load_now(
const void* save) /*!< in: immediate result from
check function */
{
- if (*(my_bool*) save) {
+ if (*(my_bool*) save && !srv_read_only_mode) {
buf_load_start();
}
}
@@ -18420,7 +18448,7 @@ buffer_pool_load_abort(
const void* save) /*!< in: immediate result from
check function */
{
- if (*(my_bool*) save) {
+ if (*(my_bool*) save && !srv_read_only_mode) {
buf_load_abort();
}
}
@@ -18692,7 +18720,7 @@ wsrep_innobase_kill_one_trx(
wsrep_thd_awake(thd, signal);
} else {
/* abort currently executing query */
- DBUG_PRINT("wsrep",("sending KILL_QUERY to: %ld",
+ DBUG_PRINT("wsrep",("sending KILL_QUERY to: %lu",
thd_get_thread_id(thd)));
WSREP_DEBUG("kill query for: %ld",
thd_get_thread_id(thd));
@@ -18823,7 +18851,8 @@ wsrep_fake_trx_id(
mutex_enter(&trx_sys->mutex);
trx_id_t trx_id = trx_sys_get_new_trx_id();
mutex_exit(&trx_sys->mutex);
- WSREP_DEBUG("innodb fake trx id: %lu thd: %s", trx_id, wsrep_thd_query(thd));
+ 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);
}
@@ -19216,7 +19245,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"
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 2a74ac489c9..f8e61631dfe 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved.
+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
@@ -208,60 +208,44 @@ innobase_fulltext_exist(
return(false);
}
-/*******************************************************************//**
-Determine if ALTER TABLE needs to rebuild the table.
-@param ha_alter_info the DDL operation
-@param altered_table MySQL original table
+/** Determine if ALTER TABLE needs to rebuild the table.
+@param ha_alter_info the DDL operation
+@param table metadata before ALTER TABLE
@return whether it is necessary to rebuild the table */
static MY_ATTRIBUTE((nonnull, warn_unused_result))
bool
innobase_need_rebuild(
-/*==================*/
const Alter_inplace_info* ha_alter_info,
- const TABLE* altered_table)
+ const TABLE* table)
{
Alter_inplace_info::HA_ALTER_FLAGS alter_inplace_flags =
- ha_alter_info->handler_flags & ~(INNOBASE_INPLACE_IGNORE);
+ ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE;
+
+ if (alter_inplace_flags & Alter_inplace_info::CHANGE_CREATE_OPTION) {
+ const ha_table_option_struct& alt_opt=
+ *ha_alter_info->create_info->option_struct;
+ const ha_table_option_struct& opt= *table->s->option_struct;
+
+ if (alt_opt.page_compressed != opt.page_compressed
+ || alt_opt.page_compression_level
+ != opt.page_compression_level
+ || alt_opt.encryption != opt.encryption
+ || alt_opt.encryption_key_id != opt.encryption_key_id) {
+ return(true);
+ }
+ }
- if (alter_inplace_flags
- == Alter_inplace_info::CHANGE_CREATE_OPTION
+ if (alter_inplace_flags == Alter_inplace_info::CHANGE_CREATE_OPTION
&& !(ha_alter_info->create_info->used_fields
& (HA_CREATE_USED_ROW_FORMAT
| HA_CREATE_USED_KEY_BLOCK_SIZE))) {
/* Any other CHANGE_CREATE_OPTION than changing
- ROW_FORMAT or KEY_BLOCK_SIZE is ignored. */
+ ROW_FORMAT or KEY_BLOCK_SIZE can be done without
+ rebuilding the table. */
return(false);
}
- /* If alter table changes column name and adds a new
- index, we need to check is this new index created
- to new column name. This is because column name
- changes are done normally after creating indexes. */
- if ((ha_alter_info->handler_flags
- & Alter_inplace_info::ALTER_COLUMN_NAME) &&
- ((ha_alter_info->handler_flags
- & Alter_inplace_info::ADD_INDEX) ||
- (ha_alter_info->handler_flags
- & Alter_inplace_info::ADD_FOREIGN_KEY))) {
- for (ulint i = 0; i < ha_alter_info->index_add_count; i++) {
- const KEY* key = &ha_alter_info->key_info_buffer[
- ha_alter_info->index_add_buffer[i]];
-
- for (ulint j = 0; j < key->user_defined_key_parts; j++) {
- const KEY_PART_INFO* key_part = &(key->key_part[j]);
- const Field* field = altered_table->field[key_part->fieldnr];
-
- /* Field used on added index is renamed on
- this same alter table. We need table
- rebuild. */
- if (field && field->flags & FIELD_IS_RENAMED) {
- return (true);
- }
- }
- }
- }
-
- return(!!(ha_alter_info->handler_flags & INNOBASE_ALTER_REBUILD));
+ return(!!(alter_inplace_flags & INNOBASE_ALTER_REBUILD));
}
/** Check if InnoDB supports a particular alter table in-place
@@ -311,29 +295,6 @@ ha_innobase::check_if_supported_inplace_alter(
update_thd();
trx_search_latch_release_if_reserved(prebuilt->trx);
- /* Change on engine specific table options require rebuild of the
- table */
- if (ha_alter_info->handler_flags
- & Alter_inplace_info::CHANGE_CREATE_OPTION) {
- ha_table_option_struct *new_options= ha_alter_info->create_info->option_struct;
- ha_table_option_struct *old_options= table->s->option_struct;
-
- if (new_options->page_compressed != old_options->page_compressed ||
- new_options->page_compression_level != old_options->page_compression_level ||
- new_options->atomic_writes != old_options->atomic_writes) {
- ha_alter_info->unsupported_reason = innobase_get_err_msg(
- ER_ALTER_OPERATION_NOT_SUPPORTED_REASON);
- DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
- }
-
- if (new_options->encryption != old_options->encryption ||
- new_options->encryption_key_id != old_options->encryption_key_id) {
- ha_alter_info->unsupported_reason = innobase_get_err_msg(
- ER_ALTER_OPERATION_NOT_SUPPORTED_REASON);
- DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
- }
- }
-
if (ha_alter_info->handler_flags
& ~(INNOBASE_INPLACE_IGNORE
| INNOBASE_ALTER_NOREBUILD
@@ -612,7 +573,7 @@ ha_innobase::check_if_supported_inplace_alter(
operation is possible. */
} else if (((ha_alter_info->handler_flags
& Alter_inplace_info::ADD_PK_INDEX)
- || innobase_need_rebuild(ha_alter_info, table))
+ || innobase_need_rebuild(ha_alter_info, table))
&& (innobase_fulltext_exist(altered_table))) {
/* Refuse to rebuild the table online, if
fulltext indexes are to survive the rebuild. */
@@ -1236,8 +1197,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;
@@ -1548,38 +1508,49 @@ name_ok:
return(0);
}
-/*******************************************************************//**
-Create index field definition for key part */
+/** Create index field definition for key part
+@param[in] new_clustered true if alter is generating a new clustered
+index
+@param[in] altered_table MySQL table that is being altered
+@param[in] key_part MySQL key definition
+@param[out] index_field index field defition for key_part */
static MY_ATTRIBUTE((nonnull(2,3)))
void
innobase_create_index_field_def(
-/*============================*/
- const TABLE* altered_table, /*!< in: MySQL table that is
- being altered, or NULL
- if a new clustered index is
- not being created */
- const KEY_PART_INFO* key_part, /*!< in: MySQL key definition */
- index_field_t* index_field, /*!< out: index field
- definition for key_part */
- const Field** fields) /*!< in: MySQL table fields */
+ bool new_clustered,
+ const TABLE* altered_table,
+ const KEY_PART_INFO* key_part,
+ index_field_t* index_field)
{
const Field* field;
ibool is_unsigned;
ulint col_type;
+ ulint innodb_fieldnr=0;
DBUG_ENTER("innobase_create_index_field_def");
ut_ad(key_part);
ut_ad(index_field);
+ ut_ad(altered_table);
+
+ /* Virtual columns are not stored in InnoDB data dictionary, thus
+ if there is virtual columns we need to skip them to find the
+ correct field. */
+ for(ulint i = 0; i < key_part->fieldnr; i++) {
+ const Field* table_field = altered_table->field[i];
+ if (!table_field->stored_in_db) {
+ continue;
+ }
+ innodb_fieldnr++;
+ }
- field = altered_table
- ? altered_table->field[key_part->fieldnr]
+ field = new_clustered ?
+ altered_table->field[key_part->fieldnr]
: key_part->field;
- ut_a(field);
- index_field->col_no = key_part->fieldnr;
- index_field->col_name = altered_table ? field->field_name : fields[key_part->fieldnr]->field_name;
+ ut_a(field);
+ index_field->col_no = innodb_fieldnr;
col_type = get_innobase_type_from_mysql_type(&is_unsigned, field);
if (DATA_BLOB == col_type
@@ -1613,10 +1584,8 @@ innobase_create_index_def(
bool key_clustered, /*!< in: true if this is
the new clustered index */
index_def_t* index, /*!< out: index definition */
- mem_heap_t* heap, /*!< in: heap where memory
+ mem_heap_t* heap) /*!< in: heap where memory
is allocated */
- const Field** fields) /*!< in: MySQL table fields
- */
{
const KEY* key = &keys[key_number];
ulint i;
@@ -1627,10 +1596,10 @@ innobase_create_index_def(
DBUG_ENTER("innobase_create_index_def");
DBUG_ASSERT(!key_clustered || new_clustered);
+ ut_ad(altered_table);
+
index->fields = static_cast<index_field_t*>(
mem_heap_alloc(heap, n_fields * sizeof *index->fields));
- memset(index->fields, 0, n_fields * sizeof *index->fields);
-
index->ind_type = 0;
index->key_number = key_number;
index->n_fields = n_fields;
@@ -1661,13 +1630,12 @@ innobase_create_index_def(
index->ind_type |= DICT_FTS;
}
- if (!new_clustered) {
- altered_table = NULL;
- }
-
for (i = 0; i < n_fields; i++) {
innobase_create_index_field_def(
- altered_table, &key->key_part[i], &index->fields[i], fields);
+ new_clustered,
+ altered_table,
+ &key->key_part[i],
+ &index->fields[i]);
}
DBUG_VOID_RETURN;
@@ -1993,7 +1961,7 @@ innobase_create_key_defs(
/* Create the PRIMARY key index definition */
innobase_create_index_def(
altered_table, key_info, primary_key_number,
- TRUE, TRUE, indexdef++, heap, (const Field **)altered_table->field);
+ TRUE, TRUE, indexdef++, heap);
created_clustered:
n_add = 1;
@@ -2005,7 +1973,7 @@ created_clustered:
/* Copy the index definitions. */
innobase_create_index_def(
altered_table, key_info, i, TRUE, FALSE,
- indexdef, heap, (const Field **)altered_table->field);
+ indexdef, heap);
if (indexdef->ind_type & DICT_FTS) {
n_fts_add++;
@@ -2050,7 +2018,7 @@ created_clustered:
for (ulint i = 0; i < n_add; i++) {
innobase_create_index_def(
altered_table, key_info, add[i], FALSE, FALSE,
- indexdef, heap, (const Field **)altered_table->field);
+ indexdef, heap);
if (indexdef->ind_type & DICT_FTS) {
n_fts_add++;
@@ -2067,7 +2035,6 @@ created_clustered:
index->fields = static_cast<index_field_t*>(
mem_heap_alloc(heap, sizeof *index->fields));
- memset(index->fields, 0, sizeof *index->fields);
index->n_fields = 1;
index->fields->col_no = fts_doc_id_col;
index->fields->prefix_len = 0;
@@ -2157,7 +2124,7 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
/** mapping of old column numbers to new ones, or NULL */
const ulint* col_map;
/** new column names, or NULL if nothing was renamed */
- const char** col_names;
+ const char** col_names;
/** added AUTO_INCREMENT column position, or ULINT_UNDEFINED */
const ulint add_autoinc;
/** default values of ADD COLUMN, or NULL */
@@ -2884,7 +2851,6 @@ prepare_inplace_alter_table_dict(
to rebuild the table with a temporary name. */
if (new_clustered) {
- fil_space_crypt_t* crypt_data;
const char* new_table_name
= dict_mem_create_temporary_tablename(
ctx->heap,
@@ -2895,13 +2861,29 @@ prepare_inplace_alter_table_dict(
ulint key_id = FIL_DEFAULT_ENCRYPTION_KEY;
fil_encryption_t mode = FIL_ENCRYPTION_DEFAULT;
- fil_space_t* space = fil_space_acquire(ctx->prebuilt->table->space);
- crypt_data = space->crypt_data;
- fil_space_release(space);
+ if (fil_space_t* space
+ = fil_space_acquire(ctx->prebuilt->table->space)) {
+ if (const fil_space_crypt_t* crypt_data
+ = space->crypt_data) {
+ key_id = crypt_data->key_id;
+ mode = crypt_data->encryption;
+ }
- if (crypt_data) {
- key_id = crypt_data->key_id;
- mode = crypt_data->encryption;
+ fil_space_release(space);
+ }
+
+ if (ha_alter_info->handler_flags
+ & Alter_inplace_info::CHANGE_CREATE_OPTION) {
+ const ha_table_option_struct& alt_opt=
+ *ha_alter_info->create_info->option_struct;
+ const ha_table_option_struct& opt=
+ *old_table->s->option_struct;
+ if (alt_opt.encryption != opt.encryption
+ || alt_opt.encryption_key_id
+ != opt.encryption_key_id) {
+ key_id = alt_opt.encryption_key_id;
+ mode = fil_encryption_t(alt_opt.encryption);
+ }
}
if (innobase_check_foreigns(
@@ -3114,8 +3096,7 @@ prepare_inplace_alter_table_dict(
for (ulint a = 0; a < ctx->num_to_add_index; a++) {
ctx->add_index[a] = row_merge_create_index(
- ctx->trx, ctx->new_table,
- &index_defs[a], ctx->col_names);
+ ctx->trx, ctx->new_table, &index_defs[a]);
add_key_nums[a] = index_defs[a].key_number;
@@ -5917,7 +5898,47 @@ ha_innobase::commit_inplace_alter_table(
break;
}
- DICT_STATS_BG_YIELD(trx);
+ DICT_BG_YIELD(trx);
+ }
+
+ /* Make a concurrent Drop fts Index to wait until sync of that
+ fts index is happening in the background */
+ for (;;) {
+ bool retry = false;
+
+ for (inplace_alter_handler_ctx** pctx = ctx_array;
+ *pctx; pctx++) {
+ int count =0;
+ ha_innobase_inplace_ctx* ctx
+ = static_cast<ha_innobase_inplace_ctx*>(*pctx);
+ DBUG_ASSERT(new_clustered == ctx->need_rebuild());
+
+ if (dict_fts_index_syncing(ctx->old_table)) {
+ count++;
+ if (count == 100) {
+ fprintf(stderr,
+ "Drop index waiting for background sync"
+ "to finish\n");
+ }
+ retry = true;
+ }
+
+ if (new_clustered && dict_fts_index_syncing(ctx->new_table)) {
+ count++;
+ if (count == 100) {
+ fprintf(stderr,
+ "Drop index waiting for background sync"
+ "to finish\n");
+ }
+ retry = true;
+ }
+ }
+
+ if (!retry) {
+ break;
+ }
+
+ DICT_BG_YIELD(trx);
}
/* Apply the changes to the data dictionary tables, for all
@@ -6233,8 +6254,13 @@ foreign_fail:
ut_d(dict_table_check_for_dup_indexes(
ctx->new_table, CHECK_ABORTED_OK));
- ut_a(fts_check_cached_index(ctx->new_table));
+#ifdef UNIV_DEBUG
+ if (!(ctx->new_table->fts != NULL
+ && ctx->new_table->fts->cache->sync->in_progress)) {
+ ut_a(fts_check_cached_index(ctx->new_table));
+ }
+#endif
if (new_clustered) {
/* Since the table has been rebuilt, we remove
all persistent statistics corresponding to the
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index 145100c8838..2c82c1b4931 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -6383,6 +6383,7 @@ i_s_sys_tables_fill_table_stats(
}
heap = mem_heap_create(1000);
+ rw_lock_s_lock(&dict_operation_lock);
mutex_enter(&dict_sys->mutex);
mtr_start(&mtr);
@@ -6409,9 +6410,11 @@ i_s_sys_tables_fill_table_stats(
err_msg);
}
+ rw_lock_s_unlock(&dict_operation_lock);
mem_heap_empty(heap);
/* Get the next record */
+ rw_lock_s_lock(&dict_operation_lock);
mutex_enter(&dict_sys->mutex);
mtr_start(&mtr);
rec = dict_getnext_system(&pcur, &mtr);
@@ -6419,6 +6422,7 @@ i_s_sys_tables_fill_table_stats(
mtr_commit(&mtr);
mutex_exit(&dict_sys->mutex);
+ rw_lock_s_unlock(&dict_operation_lock);
mem_heap_free(heap);
DBUG_RETURN(0);
@@ -7722,8 +7726,6 @@ i_s_dict_fill_sys_tablespaces(
{
Field** fields;
ulint atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(flags);
- ulint page_size = fsp_flags_get_page_size(flags);
- ulint zip_size = fsp_flags_get_zip_size(flags);
const char* file_format;
const char* row_format;
@@ -7740,13 +7742,11 @@ i_s_dict_fill_sys_tablespaces(
fields = table_to_fill->field;
- OK(fields[SYS_TABLESPACES_SPACE]->store(
- static_cast<double>(space)));
+ OK(fields[SYS_TABLESPACES_SPACE]->store(space, true));
OK(field_store_string(fields[SYS_TABLESPACES_NAME], name));
- OK(fields[SYS_TABLESPACES_FLAGS]->store(
- static_cast<double>(flags)));
+ OK(fields[SYS_TABLESPACES_FLAGS]->store(flags, true));
OK(field_store_string(fields[SYS_TABLESPACES_FILE_FORMAT],
file_format));
@@ -7754,11 +7754,18 @@ i_s_dict_fill_sys_tablespaces(
OK(field_store_string(fields[SYS_TABLESPACES_ROW_FORMAT],
row_format));
- OK(fields[SYS_TABLESPACES_PAGE_SIZE]->store(
- static_cast<double>(page_size)));
+ ulint cflags = fsp_flags_is_valid(flags, space)
+ ? flags : fsp_flags_convert_from_101(flags);
+ if (cflags != ULINT_UNDEFINED) {
+ OK(fields[SYS_TABLESPACES_PAGE_SIZE]->store(
+ fsp_flags_get_page_size(cflags), true));
- OK(fields[SYS_TABLESPACES_ZIP_PAGE_SIZE]->store(
- static_cast<double>(zip_size)));
+ OK(fields[SYS_TABLESPACES_ZIP_PAGE_SIZE]->store(
+ fsp_flags_get_zip_size(cflags), true));
+ } else {
+ fields[SYS_TABLESPACES_PAGE_SIZE]->set_null();
+ fields[SYS_TABLESPACES_ZIP_PAGE_SIZE]->set_null();
+ }
OK(schema_table_store_record(thd, table_to_fill));
diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc
index 3c4955b5c9e..2b406e116b0 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
@@ -4000,7 +4000,7 @@ ibuf_insert_to_index_page_low(
(ulong) zip_size, (ulong) old_bits);
fputs("InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n", stderr);
+ " to https://jira.mariadb.org/\n", stderr);
ut_ad(0);
DBUG_RETURN(NULL);
}
@@ -4062,7 +4062,7 @@ ibuf_insert_to_index_page(
"InnoDB: but the number of fields does not match!\n",
stderr);
dump:
- buf_page_print(page, 0, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page, 0);
dtuple_print(stderr, entry);
ut_ad(0);
@@ -4073,7 +4073,7 @@ dump:
" Please run CHECK TABLE on\n"
"InnoDB: your tables.\n"
"InnoDB: Submit a detailed bug report to"
- " http://bugs.mysql.com!\n", stderr);
+ " https://jira.mariadb.org/\n", stderr);
DBUG_VOID_RETURN;
}
@@ -4249,7 +4249,7 @@ ibuf_set_del_mark(
fprintf(stderr, "\nspace %u offset %u"
" (%u records, index id %llu)\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n",
+ " to https://jira.mariadb.org/\n",
(unsigned) buf_block_get_space(block),
(unsigned) buf_block_get_page_no(block),
(unsigned) page_get_n_recs(page),
@@ -4313,7 +4313,7 @@ ibuf_delete(
fprintf(stderr, "\nspace %u offset %u"
" (%u records, index id %llu)\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n",
+ " to https://jira.mariadb.org/\n",
(unsigned) buf_block_get_space(block),
(unsigned) buf_block_get_page_no(block),
(unsigned) page_get_n_recs(page),
@@ -4384,7 +4384,7 @@ ibuf_restore_pos(
} else {
fprintf(stderr,
"InnoDB: ERROR: Submit the output to"
- " http://bugs.mysql.com\n"
+ " https://jira.mariadb.org/\n"
"InnoDB: ibuf cursor restoration fails!\n"
"InnoDB: ibuf record inserted to page %lu:%lu\n",
(ulong) space, (ulong) page_no);
@@ -4603,7 +4603,7 @@ ibuf_merge_or_delete_for_page(
function. When the counter is > 0, that prevents tablespace
from being dropped. */
- space = fil_space_acquire(space_id);
+ space = fil_space_acquire_silent(space_id);
if (UNIV_UNLIKELY(!space)) {
/* Do not try to read the bitmap page from space;
@@ -4681,15 +4681,13 @@ ibuf_merge_or_delete_for_page(
fputs("InnoDB: cannot retrieve bitmap page\n",
stderr);
} else {
- buf_page_print(bitmap_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(bitmap_page, 0);
}
ibuf_mtr_commit(&mtr);
fputs("\nInnoDB: Dump of the page:\n", stderr);
- buf_page_print(block->frame, 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(block->frame, 0);
fprintf(stderr,
"InnoDB: Error: corruption in the tablespace."
@@ -4705,7 +4703,7 @@ ibuf_merge_or_delete_for_page(
"InnoDB: to determine if they are corrupt"
" after this.\n\n"
"InnoDB: Please submit a detailed bug report"
- " to http://bugs.mysql.com\n\n",
+ " to https://jira.mariadb.org/\n\n",
(ulong) page_no,
(ulong)
fil_page_get_type(block->frame));
@@ -5138,7 +5136,20 @@ ibuf_check_bitmap_on_import(
return(DB_TABLE_NOT_FOUND);
}
- size = fil_space_get_size(space_id);
+ mtr_t mtr;
+ mtr_start(&mtr);
+ {
+ buf_block_t* sp = buf_page_get(space_id, zip_size, 0,
+ RW_S_LATCH, &mtr);
+ if (sp) {
+ size = mach_read_from_4(
+ FSP_HEADER_OFFSET + FSP_FREE_LIMIT
+ + sp->frame);
+ } else {
+ size = 0;
+ }
+ }
+ mtr_commit(&mtr);
if (size == 0) {
return(DB_TABLE_NOT_FOUND);
@@ -5149,7 +5160,6 @@ ibuf_check_bitmap_on_import(
page_size = zip_size ? zip_size : UNIV_PAGE_SIZE;
for (page_no = 0; page_no < size; page_no += page_size) {
- mtr_t mtr;
page_t* bitmap_page;
ulint i;
diff --git a/storage/innobase/include/btr0btr.ic b/storage/innobase/include/btr0btr.ic
index 98fa765c0b5..57fccede952 100644
--- a/storage/innobase/include/btr0btr.ic
+++ b/storage/innobase/include/btr0btr.ic
@@ -306,7 +306,7 @@ btr_node_ptr_get_child_page_no(
"InnoDB: a nonsensical page number 0"
" in a node ptr record at offset %lu\n",
(ulong) page_offset(rec));
- buf_page_print(page_align(rec), 0, 0);
+ buf_page_print(page_align(rec), 0);
ut_ad(0);
}
diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h
index 30010da9d8f..51ff300fa1f 100644
--- a/storage/innobase/include/btr0cur.h
+++ b/storage/innobase/include/btr0cur.h
@@ -566,8 +566,7 @@ btr_estimate_n_rows_in_range(
const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
ulint mode1, /*!< in: search mode for range start */
const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
- ulint mode2, /*!< in: search mode for range end */
- trx_t* trx); /*!< in: trx */
+ ulint mode2); /*!< in: search mode for range end */
/*******************************************************************//**
Estimates the number of different key values in a given index, for
each n-column prefix of the index where 1 <= n <= dict_index_get_n_unique(index).
@@ -703,8 +702,7 @@ btr_copy_externally_stored_field_prefix(
field containing also the reference to
the external part; must be protected by
a lock or a page latch */
- ulint local_len,/*!< in: length of data, in bytes */
- trx_t* trx); /*!< in: transaction handle */
+ ulint local_len);/*!< in: length of data, in bytes */
/*******************************************************************//**
Copies an externally stored field of a record to mem heap. The
clustered index record must be protected by a lock or a page latch.
@@ -721,8 +719,7 @@ btr_copy_externally_stored_field(
ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
ulint local_len,/*!< in: length of data */
- mem_heap_t* heap, /*!< in: mem heap */
- trx_t* trx); /*!< in: transaction handle */
+ mem_heap_t* heap); /*!< in: mem heap */
/*******************************************************************//**
Copies an externally stored field of a record to mem heap.
@return the field copied to heap, or NULL if the field is incomplete */
@@ -737,8 +734,7 @@ btr_rec_copy_externally_stored_field(
zero for uncompressed BLOBs */
ulint no, /*!< in: field number */
ulint* len, /*!< out: length of the field */
- mem_heap_t* heap, /*!< in: mem heap */
- trx_t* trx); /*!< in: transaction handle */
+ mem_heap_t* heap); /*!< in: mem heap */
/*******************************************************************//**
Flags the data tuple fields that are marked as extern storage in the
update vector. We use this function to remember which fields we must
diff --git a/storage/innobase/include/btr0scrub.h b/storage/innobase/include/btr0scrub.h
index 608266c206d..8029cc91005 100644
--- a/storage/innobase/include/btr0scrub.h
+++ b/storage/innobase/include/btr0scrub.h
@@ -154,13 +154,10 @@ btr_scrub_start_space(
ulint space, /*!< in: space */
btr_scrub_t* scrub_data); /*!< in/out: scrub data */
-/****************************************************************
-Complete iterating a space
-* @return true if space was scrubbed */
+/** Complete iterating a space.
+@param[in,out] scrub_data scrub data */
UNIV_INTERN
-bool
-btr_scrub_complete_space(
-/*=====================*/
- btr_scrub_t* scrub_data); /*!< in/out: scrub data */
+void
+btr_scrub_complete_space(btr_scrub_t* scrub_data);
#endif
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index 5fd3e05370f..857bdf9d2be 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -59,6 +59,7 @@ Created 11/5/1995 Heikki Tuuri
#define BUF_GET_POSSIBLY_FREED 16
/*!< Like BUF_GET, but do not mind
if the file page has been freed. */
+#define BUF_EVICT_IF_IN_POOL 20 /*!< evict a clean block if found */
/* @} */
/** @name Modes for buf_page_get_known_nowait */
/* @{ */
@@ -773,25 +774,13 @@ buf_print(void);
/*============*/
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
#endif /* !UNIV_HOTBACKUP */
-enum buf_page_print_flags {
- /** Do not crash at the end of buf_page_print(). */
- BUF_PAGE_PRINT_NO_CRASH = 1,
- /** Do not print the full page dump. */
- BUF_PAGE_PRINT_NO_FULL = 2
-};
-/********************************************************************//**
-Prints a page to stderr. */
+/** Dump a page to stderr.
+@param[in] read_buf database page
+@param[in] zip_size compressed page size, or 0 for uncompressed */
UNIV_INTERN
void
-buf_page_print(
-/*===========*/
- const byte* read_buf, /*!< in: a database page */
- ulint zip_size, /*!< in: compressed page size, or
- 0 for uncompressed pages */
- ulint flags) /*!< in: 0 or
- BUF_PAGE_PRINT_NO_CRASH or
- BUF_PAGE_PRINT_NO_FULL */
+buf_page_print(const byte* read_buf, ulint zip_size)
UNIV_COLD MY_ATTRIBUTE((nonnull));
/********************************************************************//**
Decompress a block.
diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h
index a7a65df33aa..308bda20c7b 100644
--- a/storage/innobase/include/buf0lru.h
+++ b/storage/innobase/include/buf0lru.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 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
@@ -51,19 +52,14 @@ These are low-level functions
/** Minimum LRU list length for which the LRU_old pointer is defined */
#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
-/******************************************************************//**
-Flushes all dirty pages or removes all pages belonging
-to a given tablespace. A PROBLEM: if readahead is being started, what
-guarantees that it will not try to read in pages after this operation
-has completed? */
+/** 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
void
-buf_LRU_flush_or_remove_pages(
-/*==========================*/
- ulint id, /*!< in: space id */
- buf_remove_t buf_remove, /*!< in: remove or flush strategy */
- const trx_t* trx); /*!< to check if the operation must
- be interrupted */
+buf_LRU_flush_or_remove_pages(ulint id, const trx_t* trx, bool drop_ahi=false);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/********************************************************************//**
diff --git a/storage/innobase/include/buf0types.h b/storage/innobase/include/buf0types.h
index 11bbc9b5c8a..511240d669d 100644
--- a/storage/innobase/include/buf0types.h
+++ b/storage/innobase/include/buf0types.h
@@ -58,17 +58,6 @@ enum buf_flush_t {
BUF_FLUSH_N_TYPES /*!< index of last element + 1 */
};
-/** Algorithm to remove the pages for a tablespace from the buffer pool.
-See buf_LRU_flush_or_remove_pages(). */
-enum buf_remove_t {
- BUF_REMOVE_ALL_NO_WRITE, /*!< Remove all pages from the buffer
- pool, don't write or sync to disk */
- BUF_REMOVE_FLUSH_NO_WRITE, /*!< Remove only, from the flush list,
- don't write or sync to disk */
- BUF_REMOVE_FLUSH_WRITE /*!< Flush dirty pages to disk only
- don't remove from the buffer pool */
-};
-
/** Flags for io_fix types */
enum buf_io_fix {
BUF_IO_NONE = 0, /**< no pending I/O */
diff --git a/storage/innobase/include/data0type.h b/storage/innobase/include/data0type.h
index 111664b0b52..28182782105 100644
--- a/storage/innobase/include/data0type.h
+++ b/storage/innobase/include/data0type.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2012, 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
@@ -181,18 +182,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) \
- ((mbmaxlen) * DATA_MBMAX + (mbminlen))
-/* Get mbminlen from mbminmaxlen. Cast the result of UNIV_EXPECT to ulint
-because in GCC it returns a long. */
-#define DATA_MBMINLEN(mbminmaxlen) ((ulint) \
- UNIV_EXPECT(((mbminmaxlen) % DATA_MBMAX), \
- 1))
-/* Get mbmaxlen from mbminmaxlen. */
-#define DATA_MBMAXLEN(mbminmaxlen) ((ulint) ((mbminmaxlen) / DATA_MBMAX))
+#define DATA_MBMAX 8
/* We now support 15 bits (up to 32767) collation number */
#define MAX_CHAR_COLL_NUM 32767
@@ -219,8 +209,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) */
@@ -365,19 +357,6 @@ 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 */
-/*********************************************************************//**
Gets the padding character code for the type.
@return padding character code, or ULINT_UNDEFINED if no padding specified */
UNIV_INLINE
@@ -397,7 +376,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 */
#ifndef UNIV_HOTBACKUP
@@ -411,8 +392,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.
@@ -529,11 +510,10 @@ struct dtype_t{
the string, MySQL uses 1 or 2
bytes to store the string length) */
#ifndef UNIV_HOTBACKUP
- 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 */
#endif /* !UNIV_HOTBACKUP */
};
diff --git a/storage/innobase/include/data0type.ic b/storage/innobase/include/data0type.ic
index b4dbf4b1213..eaa90f6d33a 100644
--- a/storage/innobase/include/data0type.ic
+++ b/storage/innobase/include/data0type.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2012, 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
@@ -104,27 +104,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
@@ -136,7 +115,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));
}
@@ -232,8 +212,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.
@@ -245,8 +224,7 @@ dtype_get_mbmaxlen(
/*===============*/
const dtype_t* type) /*!< in: type */
{
- ut_ad(type);
- return(DATA_MBMAXLEN(type->mbminmaxlen));
+ return type->mbmaxlen;
}
/*********************************************************************//**
@@ -522,8 +500,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) {
@@ -564,11 +544,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);
}
}
@@ -576,7 +555,7 @@ dtype_get_fixed_size_low(
return(len);
#endif /* !UNIV_HOTBACKUP */
/* Treat as variable-length. */
- /* Fall through */
+ /* fall through */
case DATA_VARCHAR:
case DATA_BINARY:
case DATA_DECIMAL:
@@ -601,8 +580,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:
@@ -632,9 +611,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);
}
@@ -705,9 +681,9 @@ dtype_get_sql_null_size(
{
#ifndef UNIV_HOTBACKUP
return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
- type->mbminmaxlen, comp));
+ type->mbminlen, type->mbmaxlen, comp));
#else /* !UNIV_HOTBACKUP */
return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
- 0, 0));
+ 0, 0, 0));
#endif /* !UNIV_HOTBACKUP */
}
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 6e88c91557a..7011f4a9226 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, 2015, 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
@@ -197,18 +197,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
@@ -620,17 +608,6 @@ dict_table_get_col_name(
ulint col_nr) /*!< in: column number */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/**********************************************************************//**
-Returns a column's name.
-@return column name. NOTE: not guaranteed to stay valid if table is
-modified in any way (columns added, etc.). */
-UNIV_INTERN
-const char*
-dict_table_get_col_name_for_mysql(
-/*==============================*/
- const dict_table_t* table, /*!< in: table */
- const char* col_name)/*!< in: MySQL table column name */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-/**********************************************************************//**
Prints a table data. */
UNIV_INTERN
void
diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
index 147968a343a..bc72d441081 100644
--- a/storage/innobase/include/dict0dict.ic
+++ b/storage/innobase/include/dict0dict.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
+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;
}
#endif /* !UNIV_HOTBACKUP */
@@ -109,7 +92,8 @@ dict_col_type_assert_equal(
ut_ad(col->prtype == type->prtype);
//ut_ad(col->len == type->len);
# ifndef UNIV_HOTBACKUP
- ut_ad(col->mbminmaxlen == type->mbminmaxlen);
+ ut_ad(col->mbminlen == type->mbminlen);
+ ut_ad(col->mbmaxlen == type->mbmaxlen);
# endif /* !UNIV_HOTBACKUP */
return(TRUE);
@@ -127,7 +111,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.
@@ -152,7 +136,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.
@@ -1077,6 +1061,27 @@ dict_table_x_lock_indexes(
}
/*********************************************************************//**
+Returns true if the particular FTS index in the table is still syncing
+in the background, false otherwise.
+@param [in] table Table containing FTS index
+@return True if sync of fts index is still going in the background */
+UNIV_INLINE
+bool
+dict_fts_index_syncing(
+ dict_table_t* table)
+{
+ dict_index_t* index;
+
+ for (index = dict_table_get_first_index(table);
+ index != NULL;
+ index = dict_table_get_next_index(index)) {
+ if (index->index_fts_syncing) {
+ return(true);
+ }
+ }
+ return(false);
+}
+/*********************************************************************//**
Release the exclusive locks on all index tree. */
UNIV_INLINE
void
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 1c0f4d73006..3c9bd80431e 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -1,8 +1,8 @@
/*****************************************************************************
-Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+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
@@ -526,11 +526,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 */
/* @} */
@@ -704,6 +703,8 @@ struct dict_index_t{
dict_sys->mutex. Other changes are
protected by index->lock. */
dict_field_t* fields; /*!< array of field descriptions */
+ bool index_fts_syncing;/*!< Whether the fts index is
+ still syncing in the background */
#ifndef UNIV_HOTBACKUP
UT_LIST_NODE_T(dict_index_t)
indexes;/*!< list of indexes of the table */
diff --git a/storage/innobase/include/dict0stats_bg.h b/storage/innobase/include/dict0stats_bg.h
index 8f3385eb22b..66fcf7a0998 100644
--- a/storage/innobase/include/dict0stats_bg.h
+++ b/storage/innobase/include/dict0stats_bg.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2012, 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
@@ -83,7 +83,7 @@ dict_stats_defrag_pool_del(
/** Yield the data dictionary latch when waiting
for the background thread to stop accessing a table.
@param trx transaction holding the data dictionary locks */
-#define DICT_STATS_BG_YIELD(trx) do { \
+#define DICT_BG_YIELD(trx) do { \
row_mysql_unlock_data_dictionary(trx); \
os_thread_sleep(250000); \
row_mysql_lock_data_dictionary(trx); \
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 38250949380..312b09e1f2d 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
@@ -851,18 +851,13 @@ fil_op_log_parse_or_replay(
only be parsed but not replayed */
ulint log_flags); /*!< in: redo log flags
(stored in the page number parameter) */
-/*******************************************************************//**
-Deletes a single-table tablespace. The tablespace must be cached in the
-memory cache.
-@return TRUE if success */
+/** 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 */
UNIV_INTERN
dberr_t
-fil_delete_tablespace(
-/*==================*/
- ulint id, /*!< in: space id */
- buf_remove_t buf_remove); /*!< in: specify the action to take
- on the tables pages in the buffer
- pool */
+fil_delete_tablespace(ulint id, bool drop_ahi = false);
/*******************************************************************//**
Closes a single-table tablespace. The tablespace must be cached in the
memory cache. Free all pages used by the tablespace.
diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h
index 7aa7055640c..cd94956dc55 100644
--- a/storage/innobase/include/fts0fts.h
+++ b/storage/innobase/include/fts0fts.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, MariaDB Corporation. All Rights reserved.
+Copyright (c) 2016, 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
@@ -429,21 +429,6 @@ fts_update_next_doc_id(
MY_ATTRIBUTE((nonnull(2)));
/******************************************************************//**
-Create a new document id .
-@return DB_SUCCESS if all went well else error */
-UNIV_INTERN
-dberr_t
-fts_create_doc_id(
-/*==============*/
- dict_table_t* table, /*!< in: row is of this
- table. */
- dtuple_t* row, /*!< in/out: add doc id
- value to this row. This is the
- current row that is being
- inserted. */
- mem_heap_t* heap) /*!< in: heap */
- MY_ATTRIBUTE((nonnull));
-/******************************************************************//**
Create a new fts_doc_ids_t.
@return new fts_doc_ids_t. */
UNIV_INTERN
diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
index 8c63157ea8e..b4259cd4851 100644
--- a/storage/innobase/include/lock0lock.h
+++ b/storage/innobase/include/lock0lock.h
@@ -1024,6 +1024,10 @@ std::string
lock_get_info(
const lock_t*);
+/*******************************************************************//**
+@return whether wsrep_on is true on trx->mysql_thd*/
+#define wsrep_on_trx(trx) ((trx)->mysql_thd && wsrep_on((trx)->mysql_thd))
+
#endif /* WITH_WSREP */
#ifndef UNIV_NONINL
#include "lock0lock.ic"
diff --git a/storage/innobase/include/log0crypt.h b/storage/innobase/include/log0crypt.h
index 6b164e90d6e..b7a221e0a81 100644
--- a/storage/innobase/include/log0crypt.h
+++ b/storage/innobase/include/log0crypt.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
-Copyright (C) 2014, 2016, MariaDB Corporation. 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
@@ -29,6 +29,7 @@ Modified Jan Lindström jan.lindstrom@mariadb.com
#include "univ.i"
#include "ut0byte.h"
#include "my_crypt.h"
+#include "os0file.h"
typedef int Crypt_result;
@@ -72,6 +73,8 @@ log_encrypt_before_write(
/*=====================*/
ib_uint64_t next_checkpoint_no, /*!< in: log group to be flushed */
byte* block, /*!< in/out: pointer to a log block */
+ lsn_t lsn, /*!< in: log sequence number of
+ the start of the buffer */
const ulint size); /*!< in: size of log blocks */
/********************************************************
@@ -82,6 +85,8 @@ void
log_decrypt_after_read(
/*===================*/
byte* frame, /*!< in/out: log segment */
+ lsn_t lsn, /*!< in: log sequence number of the start
+ of the buffer */
const ulint size); /*!< in: log segment size */
/* Error codes for crypt info */
@@ -125,4 +130,45 @@ log_crypt_print_checkpoint_keys(
/*============================*/
const byte* log_block);
+/** Encrypt temporary log block.
+@param[in] src_block block to encrypt or decrypt
+@param[in] size size of the block
+@param[out] dst_block destination block
+@param[in] offs offset to block
+@param[in] space_id tablespace id
+@return true if successfull, false in case of failure
+*/
+UNIV_INTERN
+bool
+log_tmp_block_encrypt(
+ const byte* src_block,
+ ulint size,
+ byte* dst_block,
+ os_offset_t offs,
+ ulint space_id)
+ MY_ATTRIBUTE((warn_unused_result));
+
+/** Decrypt temporary log block.
+@param[in] src_block block to encrypt or decrypt
+@param[in] size size of the block
+@param[out] dst_block destination block
+@param[in] offs offset to block
+@param[in] space_id tablespace id
+@return true if successfull, false in case of failure
+*/
+UNIV_INTERN
+bool
+log_tmp_block_decrypt(
+ const byte* src_block,
+ ulint size,
+ byte* dst_block,
+ os_offset_t offs,
+ ulint space_id)
+ MY_ATTRIBUTE((warn_unused_result));
+
+/** Find out is temporary log files encrypted.
+@return true if temporary log file should be encrypted, false if not */
+UNIV_INTERN
+bool
+log_tmp_is_encrypted() MY_ATTRIBUTE((warn_unused_result));
#endif // log0crypt.h
diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic
index 63e68150b61..2b4638718fd 100644
--- a/storage/innobase/include/mem0mem.ic
+++ b/storage/innobase/include/mem0mem.ic
@@ -305,8 +305,8 @@ 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);
#if defined UNIV_MEM_DEBUG
+ UNIV_MEM_ALLOC(old_top, (byte*)block + block->len - old_top);
/* In the debug version erase block from top up */
mem_erase_buf(old_top, (byte*) block + block->len - old_top);
@@ -315,7 +315,7 @@ mem_heap_free_heap_top(
mem_current_allocated_memory -= (total_size - size);
mutex_exit(&mem_hash_mutex);
#endif /* UNIV_MEM_DEBUG */
- 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 */
@@ -396,11 +396,11 @@ 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);
#ifdef UNIV_MEM_DEBUG
ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
+ UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n);
/* In the debug version check the consistency, and erase field */
mem_field_erase((byte*) block + mem_block_get_free(block), n);
#endif
@@ -412,11 +412,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/mtr0log.ic b/storage/innobase/include/mtr0log.ic
index 6457e02d455..bdfd98709d1 100644
--- a/storage/innobase/include/mtr0log.ic
+++ b/storage/innobase/include/mtr0log.ic
@@ -215,7 +215,7 @@ mlog_write_initial_log_record_fast(
"%d on page %lu of space %lu in the "
"doublewrite buffer, continuing anyway.\n"
"Please post a bug report to "
- "bugs.mysql.com.\n",
+ "https://jira.mariadb.org/\n",
type, offset, space);
ut_ad(0);
}
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index c3307985532..1df9fba5e9e 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -36,7 +36,6 @@ Created 11/26/1995 Heikki Tuuri
#include "ut0byte.h"
#include "mtr0types.h"
#include "page0types.h"
-#include "trx0types.h"
/* Logging modes for a mini-transaction */
#define MTR_LOG_ALL 21 /* default mode: log all operations
@@ -214,22 +213,10 @@ functions). The page number parameter was originally written as 0. @{ */
Starts a mini-transaction. */
UNIV_INLINE
void
-mtr_start_trx(
-/*======*/
- mtr_t* mtr, /*!< out: mini-transaction */
- trx_t* trx) /*!< in: transaction */
- MY_ATTRIBUTE((nonnull (1)));
-/***************************************************************//**
-Starts a mini-transaction. */
-UNIV_INLINE
-void
mtr_start(
/*======*/
mtr_t* mtr) /*!< out: mini-transaction */
-{
- mtr_start_trx(mtr, NULL);
-}
- MY_ATTRIBUTE((nonnull))
+ MY_ATTRIBUTE((nonnull));
/***************************************************************//**
Commits a mini-transaction. */
UNIV_INTERN
@@ -437,7 +424,6 @@ struct mtr_t{
#ifdef UNIV_DEBUG
ulint magic_n;
#endif /* UNIV_DEBUG */
- trx_t* trx; /*!< transaction */
};
#ifdef UNIV_DEBUG
diff --git a/storage/innobase/include/mtr0mtr.ic b/storage/innobase/include/mtr0mtr.ic
index 37cea34d4eb..3f897ae1d10 100644
--- a/storage/innobase/include/mtr0mtr.ic
+++ b/storage/innobase/include/mtr0mtr.ic
@@ -43,10 +43,9 @@ mtr_block_dirtied(
Starts a mini-transaction. */
UNIV_INLINE
void
-mtr_start_trx(
+mtr_start(
/*======*/
- mtr_t* mtr, /*!< out: mini-transaction */
- trx_t* trx) /*!< in: transaction */
+ mtr_t* mtr) /*!< out: mini-transaction */
{
UNIV_MEM_INVALID(mtr, sizeof *mtr);
@@ -59,7 +58,6 @@ mtr_start_trx(
mtr->made_dirty = FALSE;
mtr->n_log_recs = 0;
mtr->n_freed_pages = 0;
- mtr->trx = trx;
ut_d(mtr->state = MTR_ACTIVE);
ut_d(mtr->magic_n = MTR_MAGIC_N);
diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
index e2e88eee560..55e41f6ebb5 100644
--- a/storage/innobase/include/os0file.h
+++ b/storage/innobase/include/os0file.h
@@ -405,10 +405,10 @@ to original un-instrumented file I/O APIs */
os_file_read_no_error_handling_func(file, buf, offset, n)
# define os_file_read_no_error_handling_int_fd( \
file, buf, offset, n) \
- os_file_read_no_error_handling_func(file, buf, offset, n)
+ os_file_read_no_error_handling_func(OS_FILE_FROM_FD(file), buf, offset, n)
# define os_file_write_int_fd(name, file, buf, offset, n) \
- os_file_write_func(name, file, buf, offset, n)
+ os_file_write_func(name, OS_FILE_FROM_FD(file), buf, offset, n)
# define os_file_write(name, file, buf, offset, n) \
os_file_write_func(name, file, buf, offset, n)
diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic
index c5775188bcf..7a1a3be91ec 100644
--- a/storage/innobase/include/page0page.ic
+++ b/storage/innobase/include/page0page.ic
@@ -772,7 +772,7 @@ page_rec_get_next_low(
(void*) rec,
(ulong) page_get_space_id(page),
(ulong) page_get_page_no(page));
- buf_page_print(page, 0, 0);
+ buf_page_print(page, 0);
ut_error;
} else if (offs == 0) {
diff --git a/storage/innobase/include/page0zip.ic b/storage/innobase/include/page0zip.ic
index bee35a48cc2..3fa8a08c4f9 100644
--- a/storage/innobase/include/page0zip.ic
+++ b/storage/innobase/include/page0zip.ic
@@ -174,7 +174,7 @@ page_zip_rec_needs_ext(
ulint zip_size) /*!< in: compressed page size in bytes, or 0 */
{
ut_ad(rec_size
- > (comp ? REC_N_NEW_EXTRA_BYTES : REC_N_OLD_EXTRA_BYTES));
+ > ulint(comp ? REC_N_NEW_EXTRA_BYTES : REC_N_OLD_EXTRA_BYTES));
ut_ad(ut_is_2pow(zip_size));
ut_ad(comp || !zip_size);
diff --git a/storage/innobase/include/que0que.h b/storage/innobase/include/que0que.h
index ba8828623af..f37581cbf8f 100644
--- a/storage/innobase/include/que0que.h
+++ b/storage/innobase/include/que0que.h
@@ -384,9 +384,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
diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic
index 5811a77a48b..89f6902059d 100644
--- a/storage/innobase/include/rem0rec.ic
+++ b/storage/innobase/include/rem0rec.ic
@@ -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
@@ -922,7 +923,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/row0ftsort.h b/storage/innobase/include/row0ftsort.h
index 00bd3317de3..e784fae78b9 100644
--- a/storage/innobase/include/row0ftsort.h
+++ b/storage/innobase/include/row0ftsort.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2016, MariaDB Corporation.
+Copyright (c) 2015, 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
@@ -72,7 +72,6 @@ struct fts_psort_common_t {
store Doc ID during sort, if
Doc ID will not be big enough
to use 8 bytes value */
- fil_space_crypt_t* crypt_data; /*!< crypt data or NULL */
};
struct fts_psort_t {
diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h
index 04d4010ad48..6129d03fa09 100644
--- a/storage/innobase/include/row0merge.h
+++ b/storage/innobase/include/row0merge.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2016, MariaDB Corporation.
+Copyright (c) 2015, 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
@@ -41,9 +41,6 @@ Created 13/06/2005 Jan Lindstrom
#include "lock0types.h"
#include "srv0srv.h"
-/* Reserve free space from every block for key_version */
-#define ROW_MERGE_RESERVE_SIZE 4
-
/* Cluster index read task is mandatory */
#define COST_READ_CLUSTERED_INDEX 1.0
@@ -111,7 +108,6 @@ struct index_field_t {
ulint col_no; /*!< column offset */
ulint prefix_len; /*!< column prefix length, or 0
if indexing the whole column */
- const char* col_name; /*!< column name or NULL */
};
/** Definition of an index being created */
@@ -268,11 +264,7 @@ row_merge_create_index(
/*===================*/
trx_t* trx, /*!< in/out: trx (sets error_state) */
dict_table_t* table, /*!< in: the index is on this table */
- const index_def_t* index_def,
- /*!< in: the index definition */
- const char** col_names);
- /*! in: column names if columns are
- renamed or NULL */
+ const index_def_t* index_def); /*!< in: the index definition */
/*********************************************************************//**
Check if a transaction can use an index.
@return TRUE if index can be used by the transaction else FALSE */
@@ -352,17 +344,16 @@ row_merge_buf_sort(
Write a merge block to the file system.
@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
-ibool
+bool
row_merge_write(
/*============*/
int fd, /*!< in: file descriptor */
ulint offset, /*!< in: offset where to write,
in number of row_merge_block_t elements */
const void* buf, /*!< in: data */
- fil_space_crypt_t* crypt_data, /*!< in: table crypt data */
void* crypt_buf, /*!< in: crypt buf or NULL */
- ulint space); /*!< in: space id */
-
+ ulint space) /*!< in: space id */
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Empty a sort buffer.
@return sort buffer */
@@ -400,10 +391,10 @@ row_merge_sort(
const bool update_progress, /*!< in: update progress status variable or not */
const float pct_progress, /*!< in: total progress percent until now */
const float pct_cost, /*!< in: current progress percent */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
ulint space) /*!< in: space id */
- __attribute__((nonnull(1,2,3,4,5)));
+ MY_ATTRIBUTE((warn_unused_result));
+
/*********************************************************************//**
Allocate a sort buffer.
@return own: sort buffer */
@@ -433,7 +424,7 @@ row_merge_file_destroy(
Read a merge block from the file system.
@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
-ibool
+bool
row_merge_read(
/*===========*/
int fd, /*!< in: file descriptor */
@@ -441,9 +432,9 @@ row_merge_read(
in number of row_merge_block_t
elements */
row_merge_block_t* buf, /*!< out: data */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_buf, /*!< in: crypt buf or NULL */
- ulint space); /*!< in: space id */
+ ulint space) /*!< in: space id */
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Read a merge record.
@@ -462,8 +453,8 @@ row_merge_read_rec(
or NULL on end of list
(non-NULL on I/O error) */
ulint* offsets,/*!< out: offsets of mrec */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
ulint space) /*!< in: space id */
- __attribute__((nonnull(1,2,3,4,6,7,8), warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
+
#endif /* row0merge.h */
diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h
index 71e3b9bb19e..a38e9b6b3d5 100644
--- a/storage/innobase/include/row0mysql.h
+++ b/storage/innobase/include/row0mysql.h
@@ -589,18 +589,6 @@ void
row_mysql_close(void);
/*=================*/
-/*********************************************************************//**
-Reassigns the table identifier of a table.
-@return error code or DB_SUCCESS */
-UNIV_INTERN
-dberr_t
-row_mysql_table_id_reassign(
-/*========================*/
- dict_table_t* table, /*!< in/out: table */
- trx_t* trx, /*!< in/out: transaction */
- table_id_t* new_id) /*!< out: new table id */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-
/* A struct describing a place for an individual column in the MySQL
row format which is presented to the table handler in ha_innobase.
This template struct is used to speed up row transformations between
diff --git a/storage/innobase/include/row0upd.h b/storage/innobase/include/row0upd.h
index e59ec58b63c..0a99e0ebd56 100644
--- a/storage/innobase/include/row0upd.h
+++ b/storage/innobase/include/row0upd.h
@@ -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
@@ -119,8 +120,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. */
UNIV_INTERN
diff --git a/storage/innobase/include/row0upd.ic b/storage/innobase/include/row0upd.ic
index 618a77fa4bf..efc6c1be4b5 100644
--- a/storage/innobase/include/row0upd.ic
+++ b/storage/innobase/include/row0upd.ic
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2012, 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
@@ -153,8 +154,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/srv0srv.h b/storage/innobase/include/srv0srv.h
index 79cf9cdd2ab..09af0b2cdd2 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -137,6 +137,14 @@ struct srv_stats_t {
ulint_ctr_64_t pages_encrypted;
/* Number of pages decrypted */
ulint_ctr_64_t pages_decrypted;
+ /* Number of merge blocks encrypted */
+ ulint_ctr_64_t n_merge_blocks_encrypted;
+ /* Number of merge blocks decrypted */
+ ulint_ctr_64_t n_merge_blocks_decrypted;
+ /* Number of row log blocks encrypted */
+ ulint_ctr_64_t n_rowlog_blocks_encrypted;
+ /* Number of row log blocks decrypted */
+ ulint_ctr_64_t n_rowlog_blocks_decrypted;
/** Number of data read in total (in bytes) */
ulint_ctr_1_t data_read;
@@ -1033,6 +1041,15 @@ struct export_var_t{
ib_int64_t innodb_pages_decrypted; /*!< Number of pages
decrypted */
+ /*!< Number of merge blocks encrypted */
+ ib_int64_t innodb_n_merge_blocks_encrypted;
+ /*!< Number of merge blocks decrypted */
+ ib_int64_t innodb_n_merge_blocks_decrypted;
+ /*!< Number of row log blocks encrypted */
+ ib_int64_t innodb_n_rowlog_blocks_encrypted;
+ /*!< Number of row log blocks decrypted */
+ ib_int64_t innodb_n_rowlog_blocks_decrypted;
+
ulint innodb_sec_rec_cluster_reads; /*!< srv_sec_rec_cluster_reads */
ulint innodb_sec_rec_cluster_reads_avoided;/*!< srv_sec_rec_cluster_reads_avoided */
diff --git a/storage/innobase/include/trx0rec.h b/storage/innobase/include/trx0rec.h
index a6e202d04e4..ec15250ec7b 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
@@ -196,6 +196,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
@@ -226,10 +227,8 @@ trx_undo_report_row_operation(
marking, the record in the clustered
index, otherwise NULL */
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));
/******************************************************************//**
Copies an undo record to heap. This function can be called if we know that
diff --git a/storage/innobase/include/trx0roll.h b/storage/innobase/include/trx0roll.h
index 98a667b2ec1..274a3b038ba 100644
--- a/storage/innobase/include/trx0roll.h
+++ b/storage/innobase/include/trx0roll.h
@@ -1,6 +1,7 @@
/*****************************************************************************
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
@@ -32,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_or_clean_is_active;
+extern const trx_t* trx_roll_crash_recv_trx;
/*******************************************************************//**
Determines if this transaction is rolling back an incomplete transaction
@@ -103,6 +105,11 @@ trx_undo_rec_release(
/*=================*/
trx_t* trx, /*!< in/out: transaction */
undo_no_t undo_no);/*!< in: undo number */
+/** Report progress when rolling back a row of a recovered transaction.
+@return whether the rollback should be aborted due to pending shutdown */
+UNIV_INTERN
+bool
+trx_roll_must_shutdown();
/*******************************************************************//**
Rollback or clean up any incomplete transactions which were
encountered in crash recovery. If the transaction already was
diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h
index 83814d088f3..f70c53b57e6 100644
--- a/storage/innobase/include/trx0sys.h
+++ b/storage/innobase/include/trx0sys.h
@@ -315,6 +315,7 @@ trx_sys_print_mysql_binlog_offset(void);
@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,
@@ -322,8 +323,10 @@ trx_sys_update_wsrep_checkpoint(
mtr_t* mtr);
/** Read WSREP XID from sys_header of TRX_SYS_PAGE_NO = 5.
-@param[out] xid Transaction XID */
-void
+@param[out] xid Transaction XID
+@return true on success, false on error. */
+UNIV_INTERN
+bool
trx_sys_read_wsrep_checkpoint(XID* xid);
#endif /* WITH_WSREP */
diff --git a/storage/innobase/include/trx0sys.ic b/storage/innobase/include/trx0sys.ic
index 7265a97ae25..e097e29b551 100644
--- a/storage/innobase/include/trx0sys.ic
+++ b/storage/innobase/include/trx0sys.ic
@@ -445,10 +445,7 @@ trx_id_t
trx_sys_get_new_trx_id(void)
/*========================*/
{
-#ifndef WITH_WSREP
- /* wsrep_fake_trx_id violates this assert */
ut_ad(mutex_own(&trx_sys->mutex));
-#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
diff --git a/storage/innobase/include/trx0undo.h b/storage/innobase/include/trx0undo.h
index 42ac62916e0..266ca32548c 100644
--- a/storage/innobase/include/trx0undo.h
+++ b/storage/innobase/include/trx0undo.h
@@ -246,13 +246,22 @@ Truncates an undo log from the end. This function is used during a rollback
to free space from an undo log. */
UNIV_INTERN
void
-trx_undo_truncate_end(
+trx_undo_truncate_end_func(
/*=======================*/
- trx_t* trx, /*!< in: transaction whose undo log it is */
+#ifdef UNIV_DEBUG
+ const trx_t* trx, /*!< in: transaction whose undo log it is */
+#endif /* UNIV_DEBUG */
trx_undo_t* undo, /*!< in/out: undo log */
undo_no_t limit) /*!< in: all undo records with undo number
>= this value should be truncated */
MY_ATTRIBUTE((nonnull));
+#ifdef UNIV_DEBUG
+# define trx_undo_truncate_end(trx,undo,limit) \
+ trx_undo_truncate_end_func(trx,undo,limit)
+#else /* UNIV_DEBUG */
+# define trx_undo_truncate_end(trx,undo,limit) \
+ trx_undo_truncate_end_func(undo,limit)
+#endif /* UNIV_DEBUG */
/***********************************************************************//**
Truncates an undo log from the start. This function is used during a purge
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index f00cb179f56..24bcab56870 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -677,14 +677,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/ut0timer.ic b/storage/innobase/include/ut0timer.ic
index 027e89c6279..46dcd0cb718 100644
--- a/storage/innobase/include/ut0timer.ic
+++ b/storage/innobase/include/ut0timer.ic
@@ -106,7 +106,7 @@ ut_microseconds_to_timer(
/*=====================*/
ulonglong when) /*!< in: time where to calculate */
{
- double ret = when;
+ double ret = (double)when;
ret *= (double)(ut_timer.frequency);
ret /= 1000000.0;
return (ulonglong)ret;
diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h
index cdf517ce176..ffdb13ddf43 100644
--- a/storage/innobase/include/ut0ut.h
+++ b/storage/innobase/include/ut0ut.h
@@ -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.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -291,6 +291,7 @@ UNIV_INTERN
ulint
ut_time_ms(void);
/*============*/
+
#endif /* !UNIV_HOTBACKUP */
/**********************************************************//**
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 6f198b7aad9..eb3d260e78a 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) 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
@@ -925,15 +925,21 @@ lock_reset_lock_and_trx_wait(
ib_logf(IB_LOG_LEVEL_INFO,
"Trx id " TRX_ID_FMT
- " is waiting a lock in statement %s"
+ " is waiting a lock "
" for this trx id " TRX_ID_FMT
- " and statement %s wait_lock %p",
+ " wait_lock %p",
lock->trx->id,
- stmt ? stmt : "NULL",
trx_id,
- stmt2 ? stmt2 : "NULL",
lock->trx->lock.wait_lock);
+ if (stmt) {
+ ib_logf(IB_LOG_LEVEL_INFO, " SQL1: %s\n", stmt);
+ }
+
+ if (stmt2) {
+ ib_logf(IB_LOG_LEVEL_INFO, " SQL2: %s\n", stmt2);
+ }
+
ut_ad(lock->trx->lock.wait_lock == lock);
}
@@ -1151,7 +1157,7 @@ lock_rec_has_to_wait(
type_mode, lock_is_on_supremum);
fprintf(stderr,
"conflicts states: my %d locked %d\n",
- wsrep_thd_conflict_state(trx->mysql_thd, FALSE),
+ wsrep_thd_conflict_state(trx->mysql_thd, FALSE),
wsrep_thd_conflict_state(lock2->trx->mysql_thd, FALSE) );
lock_rec_print(stderr, lock2);
if (for_locking) return FALSE;
@@ -1687,7 +1693,7 @@ lock_rec_discard(lock_t* in_lock);
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(
/*========================*/
enum lock_mode mode, /*!< in: LOCK_S or LOCK_X */
@@ -1704,7 +1710,7 @@ lock_rec_other_has_expl_req(
requests by all transactions
are taken into account */
{
- const lock_t* lock;
+ lock_t* lock;
ut_ad(lock_mutex_own());
ut_ad(mode == LOCK_X || mode == LOCK_S);
@@ -1713,7 +1719,7 @@ lock_rec_other_has_expl_req(
for (lock = lock_rec_get_first(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
&& (gap
@@ -1800,7 +1806,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(
/*===========================*/
enum lock_mode mode, /*!< in: LOCK_S or LOCK_X,
@@ -1812,7 +1818,7 @@ 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;
ibool is_supremum;
ut_ad(lock_mutex_own());
@@ -1821,13 +1827,16 @@ lock_rec_other_has_conflicting(
for (lock = lock_rec_get_first(block, heap_no);
lock != NULL;
- lock = lock_rec_get_next_const(heap_no, lock)) {
+ lock = lock_rec_get_next(heap_no, lock)) {
#ifdef WITH_WSREP
if (lock_rec_has_to_wait(TRUE, trx, mode, lock, is_supremum)) {
- if (wsrep_on(trx->mysql_thd)) {
+ if (wsrep_on_trx(trx)) {
trx_mutex_enter(lock->trx);
- wsrep_kill_victim(trx, 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);
}
#else
@@ -1911,7 +1920,7 @@ lock_sec_rec_some_has_impl(
} else if (!lock_check_trx_id_sanity(max_trx_id, rec, index, offsets)) {
- buf_page_print(page, 0, 0);
+ buf_page_print(page, 0);
/* The page is corrupt: try to avoid a crash by returning 0 */
trx_id = 0;
@@ -2023,15 +2032,17 @@ wsrep_print_wait_locks(
{
if (wsrep_debug && c_lock->trx->lock.wait_lock != c_lock) {
fprintf(stderr, "WSREP: c_lock != wait lock\n");
- if (lock_get_type_low(c_lock) & LOCK_TABLE)
+ if (lock_get_type_low(c_lock) & LOCK_TABLE) {
lock_table_print(stderr, c_lock);
- else
+ } else {
lock_rec_print(stderr, c_lock);
+ }
- if (lock_get_type_low(c_lock->trx->lock.wait_lock) & LOCK_TABLE)
+ if (lock_get_type_low(c_lock->trx->lock.wait_lock) & LOCK_TABLE) {
lock_table_print(stderr, c_lock->trx->lock.wait_lock);
- else
+ } else {
lock_rec_print(stderr, c_lock->trx->lock.wait_lock);
+ }
}
}
#endif /* WITH_WSREP */
@@ -2151,7 +2162,7 @@ lock_rec_create(
#ifdef WITH_WSREP
if (c_lock &&
- wsrep_on(trx->mysql_thd) &&
+ wsrep_on_trx(trx) &&
wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
lock_t *hash = (lock_t *)c_lock->hash;
lock_t *prev = NULL;
@@ -2217,8 +2228,8 @@ lock_rec_create(
if (wsrep_debug) {
fprintf(
stderr,
- "WSREP: c_lock canceled %llu\n",
- (ulonglong) c_lock->trx->id);
+ "WSREP: c_lock canceled " TRX_ID_FMT "\n",
+ c_lock->trx->id);
}
/* have to bail out here to avoid lock_set_lock... */
@@ -2351,6 +2362,7 @@ lock_rec_insert_by_trx_age(
return DB_SUCCESS;
}
+#ifdef UNIV_DEBUG
static
bool
lock_queue_validate(
@@ -2384,6 +2396,7 @@ lock_queue_validate(
}
return true;
}
+#endif /* UNIV_DEBUG */
/*********************************************************************//**
Enqueues a waiting request for a lock which cannot be granted immediately.
@@ -2451,7 +2464,7 @@ lock_rec_enqueue_waiting(
dict_index_name_print(stderr, trx, index);
fputs(".\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n",
+ " to https://jira.mariadb.org/\n",
stderr);
ut_ad(0);
}
@@ -2517,6 +2530,16 @@ lock_rec_enqueue_waiting(
err = DB_LOCK_WAIT;
}
+#ifdef WITH_WSREP
+ if (!lock_get_wait(lock) && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
+ if (wsrep_debug) {
+ fprintf(stderr, "WSREP: BF thread got lock granted early, ID " TRX_ID_FMT
+ "\n",
+ lock->trx->id);
+ }
+ return(DB_SUCCESS);
+ }
+#endif /* WITH_WSREP */
// Move it only when it does not cause a deadlock.
if (err != DB_DEADLOCK
&& innodb_lock_schedule_algorithm
@@ -2812,7 +2835,7 @@ lock_rec_lock_slow(
/* The trx already has a strong enough lock on rec: do
nothing */
#ifdef WITH_WSREP
- } else if ((c_lock = (ib_lock_t*)lock_rec_other_has_conflicting(
+ } else if ((c_lock = lock_rec_other_has_conflicting(
static_cast<enum lock_mode>(mode),
block, heap_no, trx))) {
#else
@@ -2944,6 +2967,15 @@ 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) {
+ fprintf(stderr,
+ "BF-BF lock conflict " TRX_ID_FMT
+ " : " TRX_ID_FMT "\n",
+ wait_lock->trx->id,
+ lock->trx->id);
+ lock_rec_print(stderr, wait_lock);
+ lock_rec_print(stderr, lock);
+ }
/* don't wait for another BF lock */
continue;
}
@@ -3102,7 +3134,7 @@ lock_grant_and_move_on_page(
&& !lock_rec_has_to_wait_in_queue(lock)) {
lock_grant(lock, false);
-
+
if (previous != NULL) {
/* Move the lock to the head of the list. */
HASH_GET_NEXT(hash, previous) = HASH_GET_NEXT(hash, lock);
@@ -4976,8 +5008,8 @@ lock_table_create(
}
if (wsrep_debug) {
- fprintf(stderr, "WSREP: c_lock canceled %llu\n",
- (ulonglong) c_lock->trx->id);
+ fprintf(stderr, "WSREP: c_lock canceled " TRX_ID_FMT "\n",
+ c_lock->trx->id);
}
}
if (c_lock) {
@@ -5185,7 +5217,7 @@ lock_table_enqueue_waiting(
ut_print_name(stderr, trx, TRUE, table->name);
fputs(".\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n",
+ " to https://jira.mariadb.org/\n",
stderr);
ut_ad(0);
}
@@ -5249,7 +5281,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
@@ -5260,7 +5292,7 @@ lock_table_other_has_incompatible(
const dict_table_t* table, /*!< in: table */
enum lock_mode mode) /*!< in: lock mode */
{
- const lock_t* lock;
+ lock_t* lock;
ut_ad(lock_mutex_own());
@@ -5313,7 +5345,7 @@ lock_table(
#endif
trx_t* trx;
dberr_t err;
- const lock_t* wait_for;
+ lock_t* wait_for;
ut_ad(table != NULL);
ut_ad(thr != NULL);
@@ -5360,13 +5392,13 @@ lock_table(
if (wait_for != NULL) {
#ifdef WITH_WSREP
- err = lock_table_enqueue_waiting((ib_lock_t*)wait_for, mode | flags, table, thr);
+ err = lock_table_enqueue_waiting(wait_for, mode | flags, table, thr);
#else
err = lock_table_enqueue_waiting(mode | flags, table, thr);
#endif
} else {
#ifdef WITH_WSREP
- lock_table_create(c_lock, table, mode | flags, trx);
+ lock_table_create(c_lock, table, mode | flags, trx);
#else
lock_table_create(table, mode | flags, trx);
#endif
@@ -6878,7 +6910,7 @@ lock_rec_block_validate(
/* Make sure that the tablespace is not deleted while we are
trying to access the page. */
- if (fil_space_t* space = fil_space_acquire(space_id)) {
+ if (fil_space_t* space = fil_space_acquire_silent(space_id)) {
mtr_start(&mtr);
block = buf_page_get_gen(
@@ -7034,10 +7066,10 @@ lock_rec_insert_check_and_lock(
on the successor, which produced an unnecessary deadlock. */
#ifdef WITH_WSREP
- if ((c_lock = (ib_lock_t*)lock_rec_other_has_conflicting(
- static_cast<enum lock_mode>(
- LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION),
- block, next_rec_heap_no, trx))) {
+ if ((c_lock = lock_rec_other_has_conflicting(
+ static_cast<enum lock_mode>(
+ LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION),
+ block, next_rec_heap_no, trx))) {
#else
if (lock_rec_other_has_conflicting(
static_cast<enum lock_mode>(
@@ -7050,7 +7082,7 @@ lock_rec_insert_check_and_lock(
#ifdef WITH_WSREP
err = lock_rec_enqueue_waiting(c_lock,
- LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION,
+ LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION,
block, next_rec_heap_no, index, thr);
#else
err = lock_rec_enqueue_waiting(
@@ -7908,7 +7940,10 @@ lock_trx_release_locks(
}
mutex_exit(&trx_sys->mutex);
} else {
- ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE));
+ ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE)
+ || (trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY)
+ && trx->is_recovered
+ && !UT_LIST_GET_LEN(trx->lock.trx_locks)));
}
/* The transition of trx->state to TRX_STATE_COMMITTED_IN_MEMORY
diff --git a/storage/innobase/lock/lock0wait.cc b/storage/innobase/lock/lock0wait.cc
index a447027e336..a0f557e18e5 100644
--- a/storage/innobase/lock/lock0wait.cc
+++ b/storage/innobase/lock/lock0wait.cc
@@ -191,22 +191,25 @@ 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->mysql_thd) &&
- wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
- fprintf(stderr, "WSREP: BF lock wait long\n");
- srv_print_innodb_monitor = TRUE;
- srv_print_innodb_lock_monitor = TRUE;
- os_event_set(srv_monitor_event);
- return TRUE;
- }
- return FALSE;
- }
+ if (wsrep_on_trx(trx)
+ && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
+ fprintf(stderr, "WSREP: BF lock wait long for trx " TRX_ID_FMT "\n", trx->id);
+ srv_print_innodb_monitor = TRUE;
+ srv_print_innodb_lock_monitor = TRUE;
+ os_event_set(srv_monitor_event);
+ return true;
+ }
+ return false;
+}
#endif /* WITH_WSREP */
/***************************************************************//**
@@ -402,15 +405,15 @@ lock_wait_suspend_thread(
if (lock_wait_timeout < 100000000
&& wait_time > (double) lock_wait_timeout) {
#ifdef WITH_WSREP
- if (!wsrep_on(trx->mysql_thd) ||
- (!wsrep_is_BF_lock_timeout(trx) &&
- trx->error_state != DB_DEADLOCK)) {
+ if (!wsrep_on_trx(trx) ||
+ (!wsrep_is_BF_lock_timeout(trx) &&
+ trx->error_state != DB_DEADLOCK)) {
#endif /* WITH_WSREP */
- trx->error_state = DB_LOCK_WAIT_TIMEOUT;
+ trx->error_state = DB_LOCK_WAIT_TIMEOUT;
#ifdef WITH_WSREP
- }
+ }
#endif /* WITH_WSREP */
MONITOR_INC(MONITOR_TIMEOUT);
}
diff --git a/storage/innobase/log/log0crypt.cc b/storage/innobase/log/log0crypt.cc
index af9b2349187..ec3c72cab43 100644
--- a/storage/innobase/log/log0crypt.cc
+++ b/storage/innobase/log/log0crypt.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
-Copyright (C) 2014, 2016, MariaDB Corporation. 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
@@ -71,22 +71,6 @@ struct crypt_info_t {
static std::deque<crypt_info_t> crypt_info;
/*********************************************************************//**
-Get a log block's start lsn.
-@return a log block's start lsn */
-static inline
-lsn_t
-log_block_get_start_lsn(
-/*====================*/
- lsn_t lsn, /*!< in: checkpoint lsn */
- ulint log_block_no) /*!< in: log block number */
-{
- lsn_t start_lsn =
- (lsn & (lsn_t)0xffffffff00000000ULL) |
- (((log_block_no - 1) & (lsn_t)0x3fffffff) << 9);
- return start_lsn;
-}
-
-/*********************************************************************//**
Get crypt info from checkpoint.
@return a crypt info or NULL if not present. */
static
@@ -162,6 +146,8 @@ Crypt_result
log_blocks_crypt(
/*=============*/
const byte* block, /*!< in: blocks before encrypt/decrypt*/
+ lsn_t lsn, /*!< in: log sequence number of the start
+ of the buffer */
ulint size, /*!< in: size of block */
byte* dst_block, /*!< out: blocks after encrypt/decrypt */
int what, /*!< in: encrypt or decrypt*/
@@ -171,21 +157,18 @@ log_blocks_crypt(
Crypt_result rc = MY_AES_OK;
uint dst_len;
byte aes_ctr_counter[MY_AES_BLOCK_SIZE];
- byte is_encrypt= what == ENCRYPTION_FLAG_ENCRYPT;
- lsn_t lsn = is_encrypt ? log_sys->lsn : srv_start_lsn;
const uint src_len = OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_HDR_SIZE;
- for (ulint i = 0; i < size ; i += OS_FILE_LOG_BLOCK_SIZE) {
+ for (ulint i = 0; i < size ; i += OS_FILE_LOG_BLOCK_SIZE,
+ lsn += OS_FILE_LOG_BLOCK_SIZE) {
ulint log_block_no = log_block_get_hdr_no(log_block);
- lsn_t log_block_start_lsn = log_block_get_start_lsn(
- lsn, log_block_no);
const crypt_info_t* info = crypt_info == NULL ? get_crypt_info(log_block) :
crypt_info;
#ifdef DEBUG_CRYPT
fprintf(stderr,
"%s %lu chkpt: %lu key: %u lsn: %lu\n",
- is_encrypt ? "crypt" : "decrypt",
+ what == ENCRYPTION_FLAG_ENCRYPT ? "crypt" : "decrypt",
log_block_no,
log_block_get_checkpoint_no(log_block),
info ? info->key_version : 0,
@@ -214,7 +197,7 @@ log_blocks_crypt(
// (1-byte, only 5 bits are used). "+" means concatenate.
bzero(aes_ctr_counter, MY_AES_BLOCK_SIZE);
memcpy(aes_ctr_counter, info->crypt_nonce, 3);
- mach_write_to_8(aes_ctr_counter + 3, log_block_start_lsn);
+ mach_write_to_8(aes_ctr_counter + 3, lsn);
mach_write_to_4(aes_ctr_counter + 11, log_block_no);
bzero(aes_ctr_counter + 15, 1);
@@ -237,6 +220,129 @@ next:
return rc;
}
+/** Encrypt/decrypt temporary log blocks.
+
+@param[in] src_block block to encrypt or decrypt
+@param[in] size size of the block
+@param[out] dst_block destination block
+@param[in] what ENCRYPTION_FLAG_ENCRYPT or
+ ENCRYPTION_FLAG_DECRYPT
+@param[in] offs offset to block
+@param[in] space_id tablespace id
+@return true if successful, false in case of failure
+*/
+static
+bool
+log_tmp_blocks_crypt(
+ const byte* src_block,
+ ulint size,
+ byte* dst_block,
+ int what,
+ os_offset_t offs,
+ ulint space_id)
+{
+ Crypt_result rc = MY_AES_OK;
+ uint dst_len;
+ byte aes_ctr_counter[MY_AES_BLOCK_SIZE];
+ byte is_encrypt= what == ENCRYPTION_FLAG_ENCRYPT;
+ const crypt_info_t* info = static_cast<const crypt_info_t*>(&crypt_info[0]);
+
+ // AES_CTR_COUNTER = space_id + offs
+
+ bzero(aes_ctr_counter, MY_AES_BLOCK_SIZE);
+ mach_write_to_8(aes_ctr_counter, space_id);
+ mach_write_to_8(aes_ctr_counter + 8, offs);
+
+ rc = encryption_crypt(src_block, size,
+ dst_block, &dst_len,
+ (unsigned char*)(info->crypt_key), 16,
+ aes_ctr_counter, MY_AES_BLOCK_SIZE,
+ what | ENCRYPTION_FLAG_NOPAD,
+ LOG_DEFAULT_ENCRYPTION_KEY,
+ info->key_version);
+
+ if (rc != MY_AES_OK) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "%s failed for temporary log file with rc = %d",
+ is_encrypt ? "Encryption" : "Decryption",
+ rc);
+ return false;
+ }
+
+ return true;
+}
+
+/** Get crypt info
+@return pointer to log crypt info or NULL
+*/
+inline
+const crypt_info_t*
+get_crypt_info()
+{
+ mutex_enter(&log_sys->mutex);
+ const crypt_info_t* info = get_crypt_info(log_sys->next_checkpoint_no);
+ mutex_exit(&log_sys->mutex);
+
+ return info;
+}
+
+/** Find out is temporary log files encrypted.
+@return true if temporary log file should be encrypted, false if not */
+UNIV_INTERN
+bool
+log_tmp_is_encrypted()
+{
+ const crypt_info_t* info = get_crypt_info();
+
+ if (info == NULL || info->key_version == UNENCRYPTED_KEY_VER) {
+ return false;
+ }
+
+ return true;
+}
+
+/** Encrypt temporary log block.
+@param[in] src_block block to encrypt or decrypt
+@param[in] size size of the block
+@param[out] dst_block destination block
+@param[in] offs offset to block
+@param[in] space_id tablespace id
+@return true if successfull, false in case of failure
+*/
+UNIV_INTERN
+bool
+log_tmp_block_encrypt(
+ const byte* src_block,
+ ulint size,
+ byte* dst_block,
+ os_offset_t offs,
+ ulint space_id)
+{
+ return (log_tmp_blocks_crypt(src_block, size, dst_block,
+ ENCRYPTION_FLAG_ENCRYPT, offs, space_id));
+}
+
+/** Decrypt temporary log block.
+@param[in] src_block block to encrypt or decrypt
+@param[in] size size of the block
+@param[out] dst_block destination block
+@param[in] offs offset to block
+@param[in] space_id tablespace id
+@return true if successfull, false in case of failure
+*/
+UNIV_INTERN
+bool
+log_tmp_block_decrypt(
+ const byte* src_block,
+ ulint size,
+ byte* dst_block,
+ os_offset_t offs,
+ ulint space_id)
+{
+ return (log_tmp_blocks_crypt(src_block, size, dst_block,
+ ENCRYPTION_FLAG_DECRYPT, offs, space_id));
+}
+
/*********************************************************************//**
Generate crypt key from crypt msg.
@return true if successfull, false if not. */
@@ -337,19 +443,6 @@ add_crypt_info(
}
/*********************************************************************//**
-Encrypt log blocks. */
-UNIV_INTERN
-Crypt_result
-log_blocks_encrypt(
-/*===============*/
- const byte* block, /*!< in: blocks before encryption */
- const ulint size, /*!< in: size of blocks, must be multiple of a log block */
- byte* dst_block) /*!< out: blocks after encryption */
-{
- return log_blocks_crypt(block, size, dst_block, ENCRYPTION_FLAG_ENCRYPT, NULL);
-}
-
-/*********************************************************************//**
Set next checkpoint's key version to latest one, and generate current
key. Key version 0 means no encryption. */
UNIV_INTERN
@@ -400,6 +493,8 @@ log_encrypt_before_write(
/*=====================*/
ib_uint64_t next_checkpoint_no, /*!< in: log group to be flushed */
byte* block, /*!< in/out: pointer to a log block */
+ lsn_t lsn, /*!< in: log sequence number of
+ the start of the buffer */
const ulint size) /*!< in: size of log blocks */
{
ut_ad(size % OS_FILE_LOG_BLOCK_SIZE == 0);
@@ -418,7 +513,8 @@ log_encrypt_before_write(
byte* dst_frame = (byte*)malloc(size);
//encrypt log blocks content
- Crypt_result result = log_blocks_crypt(block, size, dst_frame, ENCRYPTION_FLAG_ENCRYPT, NULL);
+ Crypt_result result = log_blocks_crypt(
+ block, lsn, size, dst_frame, ENCRYPTION_FLAG_ENCRYPT, NULL);
if (result == MY_AES_OK) {
ut_ad(block[0] == dst_frame[0]);
@@ -438,13 +534,16 @@ void
log_decrypt_after_read(
/*===================*/
byte* frame, /*!< in/out: log segment */
+ lsn_t lsn, /*!< in: log sequence number of the start
+ of the buffer */
const ulint size) /*!< in: log segment size */
{
ut_ad(size % OS_FILE_LOG_BLOCK_SIZE == 0);
byte* dst_frame = (byte*)malloc(size);
// decrypt log blocks content
- Crypt_result result = log_blocks_crypt(frame, size, dst_frame, ENCRYPTION_FLAG_DECRYPT, NULL);
+ Crypt_result result = log_blocks_crypt(
+ frame, lsn, size, dst_frame, ENCRYPTION_FLAG_DECRYPT, NULL);
if (result == MY_AES_OK) {
memcpy(frame, dst_frame, size);
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 1c9cbc3a219..7a242b76e85 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -1380,7 +1380,7 @@ loop:
ut_a(next_offset / UNIV_PAGE_SIZE <= ULINT_MAX);
log_encrypt_before_write(log_sys->next_checkpoint_no,
- buf, write_len);
+ buf, start_lsn, write_len);
fil_io(OS_FILE_WRITE | OS_FILE_LOG, true, group->space_id, 0,
(ulint) (next_offset / UNIV_PAGE_SIZE),
@@ -2335,7 +2335,7 @@ loop:
log_block_get_checksum(buf), source_offset);
#endif
- log_decrypt_after_read(buf, len);
+ log_decrypt_after_read(buf, start_lsn, len);
#ifdef DEBUG_CRYPT
fprintf(stderr, "AFTER DECRYPT: block: %lu checkpoint: %lu %.8lx %.8lx\n",
@@ -2576,7 +2576,8 @@ loop:
MONITOR_INC(MONITOR_LOG_IO);
//TODO (jonaso): This must be dead code??
- log_encrypt_before_write(log_sys->next_checkpoint_no, buf, len);
+ log_encrypt_before_write(log_sys->next_checkpoint_no,
+ buf, start_lsn, len);
fil_io(OS_FILE_WRITE | OS_FILE_LOG, false, group->archive_space_id,
(ulint) (next_offset / UNIV_PAGE_SIZE),
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 4e6e66e808e..6e6d8aae25e 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -819,10 +819,8 @@ not_consistent:
fprintf(stderr,
"InnoDB: No valid checkpoint found.\n"
- "InnoDB: If you are attempting downgrade"
- " from MySQL 5.7.9 or later,\n"
- "InnoDB: please refer to " REFMAN
- "upgrading-downgrading.html\n"
+ "InnoDB: A downgrade from MariaDB 10.2.2"
+ " or later is not supported.\n"
"InnoDB: If this error appears when you are"
" creating an InnoDB database,\n"
"InnoDB: the problem may be that during"
@@ -3463,6 +3461,7 @@ recv_reset_logs(
log_sys->archived_lsn = log_sys->lsn;
#endif /* UNIV_LOG_ARCHIVE */
+ memset(log_sys->buf, 0, log_sys->buf_size);
log_block_init(log_sys->buf, log_sys->lsn);
log_block_set_first_rec_group(log_sys->buf, LOG_BLOCK_HDR_SIZE);
diff --git a/storage/innobase/mem/mem0mem.cc b/storage/innobase/mem/mem0mem.cc
index e066aff5b30..b9f190509ee 100644
--- a/storage/innobase/mem/mem0mem.cc
+++ b/storage/innobase/mem/mem0mem.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2011, 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
@@ -506,13 +507,13 @@ mem_heap_block_free(
#ifndef UNIV_HOTBACKUP
if (!srv_use_sys_malloc) {
#ifdef UNIV_MEM_DEBUG
+ UNIV_MEM_ALLOC(block, len);
/* In the debug version we set the memory to a random
combination of hex 0xDE and 0xAD. */
- mem_erase_buf((byte*) block, len);
-#else /* UNIV_MEM_DEBUG */
- UNIV_MEM_ASSERT_AND_FREE(block, len);
+ mem_erase_buf((byte*)block, len);
#endif /* UNIV_MEM_DEBUG */
+ UNIV_MEM_FREE(block, len);
}
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
@@ -526,13 +527,13 @@ mem_heap_block_free(
}
#else /* !UNIV_HOTBACKUP */
#ifdef UNIV_MEM_DEBUG
+ UNIV_MEM_ALLOC(block, len);
/* In the debug version we set the memory to a random
combination of hex 0xDE and 0xAD. */
- mem_erase_buf((byte*) block, len);
-#else /* UNIV_MEM_DEBUG */
- UNIV_MEM_ASSERT_AND_FREE(block, len);
+ mem_erase_buf((byte*)block, len);
#endif /* UNIV_MEM_DEBUG */
+ UNIV_MEM_FREE(block, len);
ut_free(block);
#endif /* !UNIV_HOTBACKUP */
}
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index 5a945aae7bc..e9abdc91ff8 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -569,10 +569,9 @@ os_file_get_last_error_low(
REFMAN
"operating-system-error-codes.html\n");
}
+ fflush(stderr);
}
- fflush(stderr);
-
if (err == ERROR_FILE_NOT_FOUND) {
return(OS_FILE_NOT_FOUND);
} else if (err == ERROR_DISK_FULL) {
@@ -2336,12 +2335,21 @@ os_file_get_size(
return(offset);
#else
- return((os_offset_t) lseek(file, 0, SEEK_END));
-
+ struct stat statbuf;
+ return fstat(file, &statbuf) ? os_offset_t(-1) : statbuf.st_size;
#endif /* __WIN__ */
}
-/** Set the size of a newly created file.
+/** Extend a file.
+
+On Windows, extending a file allocates blocks for the file,
+unless the file is sparse.
+
+On Unix, we will extend the file with ftruncate(), if
+file needs to be sparse. Otherwise posix_fallocate() is used
+when available, and if not, binary zeroes are added to the end
+of file.
+
@param[in] name file name
@param[in] file file handle
@param[in] size desired file size
@@ -2382,25 +2390,41 @@ os_file_set_size(
if (srv_use_posix_fallocate) {
int err;
do {
- err = posix_fallocate(file, 0, size);
+ os_offset_t current_size = os_file_get_size(file);
+ err = current_size >= size
+ ? 0 : posix_fallocate(file, current_size,
+ size - current_size);
} while (err == EINTR
&& srv_shutdown_state == SRV_SHUTDOWN_NONE);
- if (err) {
+ switch (err) {
+ case 0:
+ return true;
+ default:
ib_logf(IB_LOG_LEVEL_ERROR,
"preallocating " INT64PF " bytes for"
"file %s failed with error %d",
size, name, err);
+ /* fall through */
+ case EINTR:
+ errno = err;
+ return false;
+ case EINVAL:
+ /* fall back to the code below */
+ break;
}
- return(!err);
}
# endif
+ os_offset_t current_size = os_file_get_size(file);
+
+ if (current_size >= size) {
+ return true;
+ }
+
/* Write up to 1 megabyte at a time. */
ulint buf_size = ut_min(64, (ulint) (size / UNIV_PAGE_SIZE))
* UNIV_PAGE_SIZE;
- os_offset_t current_size = 0;
-
byte* buf2 = static_cast<byte*>(calloc(1, buf_size + UNIV_PAGE_SIZE));
if (!buf2) {
@@ -2430,11 +2454,12 @@ os_file_set_size(
}
current_size += n_bytes;
- } while (current_size < size);
+ } while (current_size < size
+ && srv_shutdown_state == SRV_SHUTDOWN_NONE);
free(buf2);
- return(ret && os_file_flush(file));
+ return(ret && current_size >= size && os_file_flush(file));
#endif
}
diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc
index 76e4c2aed9b..692cb393afd 100644
--- a/storage/innobase/page/page0cur.cc
+++ b/storage/innobase/page/page0cur.cc
@@ -903,7 +903,7 @@ page_cur_parse_insert_rec(
ut_print_buf(stderr, ptr2, 300);
putc('\n', stderr);
- buf_page_print(page, 0, 0);
+ buf_page_print(page, 0);
ut_error;
}
diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc
index 41f56fd4559..231c0101266 100644
--- a/storage/innobase/page/page0page.cc
+++ b/storage/innobase/page/page0page.cc
@@ -149,7 +149,7 @@ page_dir_find_owner_slot(
fputs("\n"
"InnoDB: on that page!\n", stderr);
- buf_page_print(page, 0, 0);
+ buf_page_print(page, 0);
ut_error;
}
@@ -613,10 +613,8 @@ page_copy_rec_list_end_no_locks(
/* Track an assertion failure reported on the mailing
list on June 18th, 2003 */
- buf_page_print(new_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(page_align(rec), 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(new_page, 0);
+ buf_page_print(page_align(rec), 0);
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -1948,7 +1946,8 @@ page_check_dir(
fprintf(stderr,
"InnoDB: Page directory corruption:"
" infimum not pointed to\n");
- buf_page_print(page, 0, 0);
+ buf_page_print(page, 0);
+ ut_ad(0);
}
if (UNIV_UNLIKELY(!page_rec_is_supremum_low(supremum_offs))) {
@@ -1956,7 +1955,8 @@ page_check_dir(
fprintf(stderr,
"InnoDB: Page directory corruption:"
" supremum not pointed to\n");
- buf_page_print(page, 0, 0);
+ buf_page_print(page, 0);
+ ut_ad(0);
}
}
#endif /* !UNIV_HOTBACKUP */
@@ -2674,7 +2674,8 @@ func_exit2:
(ulong) page_get_space_id(page),
(ulong) page_get_page_no(page),
index->name);
- buf_page_print(page, 0, 0);
+ buf_page_print(page, 0);
+ ut_ad(0);
}
return(ret);
diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc
index b6bbe3347bd..af32d0519e2 100644
--- a/storage/innobase/rem/rem0rec.cc
+++ b/storage/innobase/rem/rem0rec.cc
@@ -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
@@ -861,13 +862,10 @@ 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);
- 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 */
ut_ad(!field->prefix_len
@@ -1254,14 +1252,10 @@ rec_convert_dtuple_to_rec_comp(
it is 128 or more, or when the field is stored externally. */
if (fixed_len) {
#ifdef UNIV_DEBUG
- ulint mbminlen = DATA_MBMINLEN(
- ifield->col->mbminmaxlen);
- ulint mbmaxlen = DATA_MBMAXLEN(
- ifield->col->mbminmaxlen);
-
ut_ad(len <= fixed_len);
- ut_ad(!mbmaxlen || len >= mbminlen
- * (fixed_len / mbmaxlen));
+ ut_ad(!ifield->col->mbmaxlen
+ || len >= ifield->col->mbminlen
+ * (fixed_len / ifield->col->mbmaxlen));
ut_ad(!dfield_is_ext(field));
#endif /* UNIV_DEBUG */
} else if (dfield_is_ext(field)) {
diff --git a/storage/innobase/row/row0ext.cc b/storage/innobase/row/row0ext.cc
index ad852577ad2..32b78391d6a 100644
--- a/storage/innobase/row/row0ext.cc
+++ b/storage/innobase/row/row0ext.cc
@@ -78,8 +78,7 @@ row_ext_cache_fill(
crashed during the execution of
btr_free_externally_stored_field(). */
ext->len[i] = btr_copy_externally_stored_field_prefix(
- buf, ext->max_len, zip_size, field, f_len,
- NULL);
+ buf, ext->max_len, zip_size, field, f_len);
}
}
}
diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc
index 62271e766cf..5ab577ce020 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
@@ -39,7 +39,7 @@ Created 10/13/2010 Jimmy Yang
b[N] = row_merge_read_rec( \
block[N], buf[N], b[N], index, \
fd[N], &foffs[N], &mrec[N], offsets[N], \
- crypt_data, crypt_block[N], space); \
+ crypt_block[N], space); \
if (UNIV_UNLIKELY(!b[N])) { \
if (mrec[N]) { \
goto exit; \
@@ -103,8 +103,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;
@@ -147,7 +148,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);
@@ -159,7 +161,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);
}
@@ -191,7 +194,6 @@ row_fts_psort_info_init(
fts_psort_t* merge_info = NULL;
ulint block_size;
ibool ret = TRUE;
- fil_space_crypt_t* crypt_data = NULL;
bool encrypted = false;
block_size = 3 * srv_sort_buf_size;
@@ -222,21 +224,8 @@ row_fts_psort_info_init(
common_info->merge_event = os_event_create();
common_info->opt_doc_id_size = opt_doc_id_size;
- /* Theoretically the tablespace can be dropped straight away.
- In practice, the DDL completion will wait for this thread to
- finish. */
- if (fil_space_t* space = fil_space_acquire(new_table->space)) {
- crypt_data = space->crypt_data;
- fil_space_release(space);
- }
-
- if (crypt_data && crypt_data->should_encrypt()) {
- common_info->crypt_data = crypt_data;
+ if (log_tmp_is_encrypted()) {
encrypted = true;
- } else {
- /* Not needed */
- common_info->crypt_data = NULL;
- crypt_data = NULL;
}
ut_ad(trx->mysql_thd != NULL);
@@ -551,7 +540,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);
@@ -570,15 +560,14 @@ 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);
- /* Reserve one byte for the end marker of row_merge_block_t
- and we have reserved ROW_MERGE_RESERVE_SIZE (= 4) for
- encryption key_version in the beginning of the buffer. */
+ /* Reserve one byte for the end marker of row_merge_block_t */
if (buf->total_size + data_size[idx] + cur_len
- >= (srv_sort_buf_size - 1 - ROW_MERGE_RESERVE_SIZE)) {
+ >= (srv_sort_buf_size - 1)) {
buf_full = TRUE;
break;
@@ -672,7 +661,6 @@ fts_parallel_tokenization(
fts_tokenize_ctx_t t_ctx;
ulint retried = 0;
dberr_t error = DB_SUCCESS;
- fil_space_crypt_t* crypt_data = NULL;
ut_ad(psort_info->psort_common->trx->mysql_thd != NULL);
@@ -693,7 +681,6 @@ fts_parallel_tokenization(
block = psort_info->merge_block;
crypt_block = psort_info->crypt_block;
- crypt_data = psort_info->psort_common->crypt_data;
zip_size = dict_table_zip_size(table);
row_merge_fts_get_next_doc_item(psort_info, &doc_item);
@@ -724,8 +711,7 @@ loop:
doc.text.f_str =
btr_copy_externally_stored_field(
&doc.text.f_len, data,
- zip_size, data_len, blob_heap,
- NULL);
+ zip_size, data_len, blob_heap);
} else {
doc.text.f_str = data;
doc.text.f_len = data_len;
@@ -788,7 +774,6 @@ loop:
if (!row_merge_write(merge_file[t_ctx.buf_used]->fd,
merge_file[t_ctx.buf_used]->offset++,
block[t_ctx.buf_used],
- crypt_data,
crypt_block[t_ctx.buf_used],
table->space)) {
error = DB_TEMP_FILE_WRITE_FAILURE;
@@ -884,7 +869,6 @@ exit:
if (!row_merge_write(merge_file[i]->fd,
merge_file[i]->offset++,
block[i],
- crypt_data,
crypt_block[i],
table->space)) {
error = DB_TEMP_FILE_WRITE_FAILURE;
@@ -924,7 +908,7 @@ exit:
psort_info->psort_common->dup,
merge_file[i], block[i], &tmpfd[i],
false, 0.0/* pct_progress */, 0.0/* pct_cost */,
- crypt_data, crypt_block[i], table->space);
+ crypt_block[i], table->space);
if (error != DB_SUCCESS) {
close(tmpfd[i]);
@@ -1436,7 +1420,6 @@ row_fts_merge_insert(
ulint start;
fts_psort_insert_t ins_ctx;
ulint count_diag = 0;
- fil_space_crypt_t* crypt_data = NULL;
ulint space;
ut_ad(index);
@@ -1450,7 +1433,6 @@ row_fts_merge_insert(
ins_ctx.trx->op_info = "inserting index entries";
ins_ctx.opt_doc_id_size = psort_info[0].psort_common->opt_doc_id_size;
- crypt_data = psort_info[0].psort_common->crypt_data;
heap = mem_heap_create(500 + sizeof(mrec_buf_t));
@@ -1544,7 +1526,6 @@ row_fts_merge_insert(
&& (!row_merge_read(
fd[i], foffs[i],
(row_merge_block_t*) block[i],
- crypt_data,
(row_merge_block_t*) crypt_block[i],
space))) {
error = DB_CORRUPTION;
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 4375d491ba7..020a814c4eb 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
@@ -1258,7 +1258,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,
@@ -1601,18 +1602,16 @@ PageConverter::PageConverter(
:
AbstractCallback(trx),
m_cfg(cfg),
+ m_index(cfg->m_indexes),
+ m_current_lsn(log_get_lsn()),
m_page_zip_ptr(0),
- m_heap(0) UNIV_NOTHROW
+ m_rec_iter(),
+ m_offsets_(), m_offsets(m_offsets_),
+ m_heap(0),
+ m_cluster_index(dict_table_get_first_index(cfg->m_table)) UNIV_NOTHROW
{
- m_index = m_cfg->m_indexes;
-
- m_current_lsn = log_get_lsn();
ut_a(m_current_lsn > 0);
-
- m_offsets = m_offsets_;
rec_offs_init(m_offsets_);
-
- m_cluster_index = dict_table_get_first_index(m_cfg->m_table);
}
/**
@@ -1770,7 +1769,7 @@ PageConverter::adjust_cluster_record(
row_upd_rec_sys_fields(
rec, m_page_zip_ptr, m_cluster_index, m_offsets,
- m_trx, 0);
+ m_trx, roll_ptr_t(1) << 55);
}
return(err);
@@ -1792,16 +1791,12 @@ PageConverter::update_records(
m_rec_iter.open(block);
- while (!m_rec_iter.end()) {
+ if (!page_is_leaf(block->frame)) {
+ return DB_SUCCESS;
+ }
+ while (!m_rec_iter.end()) {
rec_t* rec = m_rec_iter.current();
-
- /* FIXME: Move out of the loop */
-
- if (rec_get_status(rec) == REC_STATUS_NODE_PTR) {
- break;
- }
-
ibool deleted = rec_get_deleted_flag(rec, comp);
/* For the clustered index we have to adjust the BLOB
@@ -2107,7 +2102,7 @@ PageConverter::operator() (
we can work on them */
if ((err = update_page(block, page_type)) != DB_SUCCESS) {
- return(err);
+ break;
}
/* Note: For compressed pages this function will write to the
@@ -2144,9 +2139,15 @@ PageConverter::operator() (
"%s: Page %lu at offset " UINT64PF " looks corrupted.",
m_filepath, (ulong) (offset / m_page_size), offset);
- return(DB_CORRUPTION);
+ err = DB_CORRUPTION;
}
+ /* If we already had and old page with matching number
+ in the buffer pool, evict it now, because
+ we no longer evict the pages on DISCARD TABLESPACE. */
+ buf_page_get_gen(get_space_id(), get_zip_size(), block->page.offset,
+ RW_NO_LATCH, NULL, BUF_EVICT_IF_IN_POOL,
+ __FILE__, __LINE__, NULL);
return(err);
}
@@ -2876,7 +2877,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);
@@ -3720,8 +3723,7 @@ 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, BUF_REMOVE_FLUSH_WRITE, trx);
+ buf_LRU_flush_or_remove_pages(prebuilt->table->space, trx);
if (trx_is_interrupted(trx)) {
ib_logf(IB_LOG_LEVEL_INFO, "Phase III - Flush interrupted");
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index cbbb584d6b6..c50eaa2a653 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 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
@@ -565,7 +565,8 @@ 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*>(
@@ -1137,7 +1138,7 @@ row_ins_foreign_check_on_constraint(
rec_print(stderr, clust_rec, clust_index);
fputs("\n"
"InnoDB: Submit a detailed bug report to"
- " http://bugs.mysql.com\n", stderr);
+ " https://jira.mariadb.org/\n", stderr);
ut_ad(0);
err = DB_SUCCESS;
@@ -1291,12 +1292,11 @@ row_ins_foreign_check_on_constraint(
#ifdef WITH_WSREP
err = wsrep_append_foreign_key(
- thr_get_trx(thr),
- foreign,
- clust_rec,
- clust_index,
- FALSE,
- (node) ? TRUE : FALSE);
+ thr_get_trx(thr),
+ foreign,
+ clust_rec,
+ clust_index,
+ FALSE, FALSE);
if (err != DB_SUCCESS) {
fprintf(stderr,
"WSREP: foreign key append failed: %d\n", err);
@@ -1325,7 +1325,7 @@ row_ins_foreign_check_on_constraint(
row_mysql_freeze_data_dictionary(thr_get_trx(thr));
- mtr_start_trx(mtr, trx);
+ mtr_start(mtr);
/* Restore pcur position */
@@ -1353,7 +1353,7 @@ nonstandard_exit_func:
btr_pcur_store_position(pcur, mtr);
mtr_commit(mtr);
- mtr_start_trx(mtr, trx);
+ mtr_start(mtr);
btr_pcur_restore_position(BTR_SEARCH_LEAF, pcur, mtr);
@@ -1566,7 +1566,7 @@ run_again:
}
}
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* Store old value on n_fields_cmp */
@@ -2361,7 +2361,7 @@ row_ins_clust_index_entry_low(
|| n_uniq == dict_index_get_n_unique(index));
ut_ad(!n_uniq || n_uniq == dict_index_get_n_unique(index));
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
if (mode == BTR_MODIFY_LEAF && dict_index_is_online_ddl(index)) {
mode = BTR_MODIFY_LEAF | BTR_ALREADY_S_LATCHED;
@@ -2580,10 +2580,9 @@ Starts a mini-transaction and checks if the index will be dropped.
@return true if the index is to be dropped */
static MY_ATTRIBUTE((nonnull, warn_unused_result))
bool
-row_ins_sec_mtr_start_trx_and_check_if_aborted(
+row_ins_sec_mtr_start_and_check_if_aborted(
/*=======================================*/
mtr_t* mtr, /*!< out: mini-transaction */
- trx_t* trx, /*!< in: transaction handle */
dict_index_t* index, /*!< in/out: secondary index */
bool check, /*!< in: whether to check */
ulint search_mode)
@@ -2591,7 +2590,7 @@ row_ins_sec_mtr_start_trx_and_check_if_aborted(
{
ut_ad(!dict_index_is_clust(index));
- mtr_start_trx(mtr, trx);
+ mtr_start(mtr);
if (!check) {
return(false);
@@ -2649,14 +2648,13 @@ row_ins_sec_index_entry_low(
ulint n_unique;
mtr_t mtr;
ulint* offsets = NULL;
- trx_t* trx = thr_get_trx(thr);
ut_ad(!dict_index_is_clust(index));
ut_ad(mode == BTR_MODIFY_LEAF || mode == BTR_MODIFY_TREE);
cursor.thr = thr;
ut_ad(thr_get_trx(thr)->id);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* Ensure that we acquire index->lock when inserting into an
index with index->online_status == ONLINE_INDEX_COMPLETE, but
@@ -2694,7 +2692,7 @@ row_ins_sec_index_entry_low(
if (err != DB_SUCCESS) {
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. "
@@ -2730,8 +2728,8 @@ row_ins_sec_index_entry_low(
DEBUG_SYNC_C("row_ins_sec_index_unique");
- if (row_ins_sec_mtr_start_trx_and_check_if_aborted(
- &mtr, trx, index, check, search_mode)) {
+ if (row_ins_sec_mtr_start_and_check_if_aborted(
+ &mtr, index, check, search_mode)) {
goto func_exit;
}
@@ -2765,8 +2763,8 @@ row_ins_sec_index_entry_low(
return(err);
}
- if (row_ins_sec_mtr_start_trx_and_check_if_aborted(
- &mtr, trx, index, check, search_mode)) {
+ if (row_ins_sec_mtr_start_and_check_if_aborted(
+ &mtr, index, check, search_mode)) {
goto func_exit;
}
@@ -2969,6 +2967,10 @@ row_ins_sec_index_entry(
mem_heap_t* offsets_heap;
mem_heap_t* heap;
+ DBUG_EXECUTE_IF("row_ins_sec_index_entry_timeout", {
+ DBUG_SET("-d,row_ins_sec_index_entry_timeout");
+ return(DB_LOCK_WAIT);});
+
if (!index->table->foreign_set.empty()) {
err = row_ins_check_foreign_constraints(index->table, index,
entry, thr);
@@ -3071,7 +3073,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*>(
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc
index 88398c20342..fd5a13bbaab 100644
--- a/storage/innobase/row/row0log.cc
+++ b/storage/innobase/row/row0log.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 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
@@ -197,8 +197,14 @@ struct row_log_t {
row_log_buf_t tail; /*!< writer context;
protected by mutex and index->lock S-latch,
or by index->lock X-latch only */
+ byte* crypt_tail; /*!< writer context;
+ temporary buffer used in encryption,
+ decryption or NULL*/
row_log_buf_t head; /*!< reader context; protected by MDL only;
modifiable by row_log_apply_ops() */
+ byte* crypt_head; /*!< reader context;
+ temporary buffer used in encryption,
+ decryption or NULL */
const char* path; /*!< where to create temporary file during
log operation */
};
@@ -349,6 +355,7 @@ row_log_online_op(
= (os_offset_t) log->tail.blocks
* srv_sort_buf_size;
ibool ret;
+ byte * buf = log->tail.block;
if (byte_offset + srv_sort_buf_size >= srv_online_max_size) {
goto write_failed;
@@ -368,11 +375,29 @@ row_log_online_op(
goto err_exit;
}
+ /* If encryption is enabled encrypt buffer before writing it
+ to file system. */
+ if (log_tmp_is_encrypted()) {
+ if (!log_tmp_block_encrypt(log->tail.block,
+ srv_sort_buf_size,
+ log->crypt_tail,
+ byte_offset,
+ index->table->space)) {
+ log->error = DB_DECRYPTION_FAILED;
+ goto write_failed;
+ }
+
+ srv_stats.n_rowlog_blocks_encrypted.inc();
+ buf = log->crypt_tail;
+ }
+
ret = os_file_write_int_fd(
"(modification log)",
log->fd,
- log->tail.block, byte_offset, srv_sort_buf_size);
+ buf, byte_offset, srv_sort_buf_size);
+
log->tail.blocks++;
+
if (!ret) {
write_failed:
/* We set the flag directly instead of invoking
@@ -380,7 +405,9 @@ write_failed:
because the index is not "public" yet. */
index->type |= DICT_CORRUPT;
}
+
UNIV_MEM_INVALID(log->tail.block, srv_sort_buf_size);
+
memcpy(log->tail.block, log->tail.buf + avail_size,
mrec_size - avail_size);
log->tail.bytes = mrec_size - avail_size;
@@ -451,13 +478,15 @@ static MY_ATTRIBUTE((nonnull))
void
row_log_table_close_func(
/*=====================*/
- row_log_t* log, /*!< in/out: online rebuild log */
+ dict_index_t* index, /*!< in/out: online rebuilt index */
#ifdef UNIV_DEBUG
const byte* b, /*!< in: end of log record */
#endif /* UNIV_DEBUG */
ulint size, /*!< in: size of log record */
ulint avail) /*!< in: available size for log record */
{
+ row_log_t* log = index->online_log;
+
ut_ad(mutex_own(&log->mutex));
if (size >= avail) {
@@ -465,6 +494,7 @@ row_log_table_close_func(
= (os_offset_t) log->tail.blocks
* srv_sort_buf_size;
ibool ret;
+ byte * buf = log->tail.block;
if (byte_offset + srv_sort_buf_size >= srv_online_max_size) {
goto write_failed;
@@ -484,11 +514,29 @@ row_log_table_close_func(
goto err_exit;
}
+ /* If encryption is enabled encrypt buffer before writing it
+ to file system. */
+ if (log_tmp_is_encrypted()) {
+ if (!log_tmp_block_encrypt(log->tail.block,
+ srv_sort_buf_size,
+ log->crypt_tail,
+ byte_offset,
+ index->table->space)) {
+ log->error = DB_DECRYPTION_FAILED;
+ goto err_exit;
+ }
+
+ srv_stats.n_rowlog_blocks_encrypted.inc();
+ buf = log->crypt_tail;
+ }
+
ret = os_file_write_int_fd(
"(modification log)",
log->fd,
- log->tail.block, byte_offset, srv_sort_buf_size);
+ buf, byte_offset, srv_sort_buf_size);
+
log->tail.blocks++;
+
if (!ret) {
write_failed:
log->error = DB_ONLINE_LOG_TOO_BIG;
@@ -512,11 +560,11 @@ err_exit:
}
#ifdef UNIV_DEBUG
-# define row_log_table_close(log, b, size, avail) \
- row_log_table_close_func(log, b, size, avail)
+# define row_log_table_close(index, b, size, avail) \
+ row_log_table_close_func(index, b, size, avail)
#else /* UNIV_DEBUG */
# define row_log_table_close(log, b, size, avail) \
- row_log_table_close_func(log, size, avail)
+ row_log_table_close_func(index, size, avail)
#endif /* UNIV_DEBUG */
/******************************************************//**
@@ -688,8 +736,7 @@ row_log_table_delete(
b += ext_size;
}
- row_log_table_close(
- index->online_log, b, mrec_size, avail_size);
+ row_log_table_close(index, b, mrec_size, avail_size);
}
func_exit:
@@ -812,8 +859,7 @@ row_log_table_low_redundant(
b + extra_size, index, tuple->fields, tuple->n_fields);
b += size;
- row_log_table_close(
- index->online_log, b, mrec_size, avail_size);
+ row_log_table_close(index, b, mrec_size, avail_size);
}
mem_heap_free(heap);
@@ -922,8 +968,7 @@ row_log_table_low(
memcpy(b, rec, rec_offs_data_size(offsets));
b += rec_offs_data_size(offsets);
- row_log_table_close(
- index->online_log, b, mrec_size, avail_size);
+ row_log_table_close(index, b, mrec_size, avail_size);
}
}
@@ -1019,7 +1064,7 @@ row_log_table_get_pk_col(
mem_heap_alloc(heap, field_len));
len = btr_copy_externally_stored_field_prefix(
- blob_field, field_len, zip_size, field, len, NULL);
+ blob_field, field_len, zip_size, field, len);
if (len >= max_len + 1) {
return(DB_TOO_BIG_INDEX_COL);
}
@@ -1138,7 +1183,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);
@@ -1167,7 +1212,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
@@ -1177,7 +1223,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;
}
@@ -1186,7 +1233,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*>(
@@ -1410,7 +1457,7 @@ row_log_table_apply_convert_mrec(
data = btr_rec_copy_externally_stored_field(
mrec, offsets,
dict_table_zip_size(index->table),
- i, &len, heap, NULL);
+ i, &len, heap);
ut_a(data);
dfield_set_data(dfield, data, len);
blob_done:
@@ -1528,13 +1575,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;
}
@@ -1544,12 +1588,13 @@ row_log_table_apply_insert_low(
flags, BTR_MODIFY_TREE,
index, offsets_heap, heap, entry, trx_id, thr);
- /* 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);
}
@@ -2128,17 +2173,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;
@@ -2622,10 +2666,29 @@ all_done:
goto func_exit;
}
+ byte * buf = index->online_log->head.block;
+
success = os_file_read_no_error_handling_int_fd(
index->online_log->fd,
- index->online_log->head.block, ofs,
+ buf, ofs,
srv_sort_buf_size);
+
+ /* If encryption is enabled decrypt buffer after reading it
+ from file system. */
+ if (success && log_tmp_is_encrypted()) {
+ if (!log_tmp_block_decrypt(buf,
+ srv_sort_buf_size,
+ index->online_log->crypt_head,
+ ofs,
+ index->table->space)) {
+ error = DB_DECRYPTION_FAILED;
+ goto func_exit;
+ }
+
+ srv_stats.n_rowlog_blocks_decrypted.inc();
+ memcpy(buf, index->online_log->crypt_head, srv_sort_buf_size);
+ }
+
if (!success) {
fprintf(stderr, "InnoDB: unable to read temporary file"
" for table %s\n", index->table_name);
@@ -2932,9 +2995,21 @@ row_log_allocate(
log->head.blocks = log->head.bytes = 0;
log->head.total = 0;
log->path = path;
+ log->crypt_tail = log->crypt_head = NULL;
dict_index_set_online_status(index, ONLINE_INDEX_CREATION);
index->online_log = log;
+ if (log_tmp_is_encrypted()) {
+ ulint size = srv_sort_buf_size;
+ log->crypt_head = static_cast<byte *>(os_mem_alloc_large(&size));
+ log->crypt_tail = static_cast<byte *>(os_mem_alloc_large(&size));
+
+ if (!log->crypt_head || !log->crypt_tail) {
+ row_log_free(log);
+ DBUG_RETURN(false);
+ }
+ }
+
/* While we might be holding an exclusive data dictionary lock
here, in row_log_abort_sec() we will not always be holding it. Use
atomic operations in both cases. */
@@ -2957,6 +3032,15 @@ row_log_free(
row_log_block_free(log->tail);
row_log_block_free(log->head);
row_merge_file_destroy_low(log->fd);
+
+ if (log->crypt_head) {
+ os_mem_free_large(log->crypt_head, srv_sort_buf_size);
+ }
+
+ if (log->crypt_tail) {
+ os_mem_free_large(log->crypt_tail, srv_sort_buf_size);
+ }
+
mutex_free(&log->mutex);
ut_free(log);
log = 0;
@@ -3451,11 +3535,29 @@ all_done:
goto func_exit;
}
+ byte* buf = index->online_log->head.block;
+
success = os_file_read_no_error_handling_int_fd(
index->online_log->fd,
- index->online_log->head.block, ofs,
+ buf, ofs,
srv_sort_buf_size);
+ /* If encryption is enabled decrypt buffer after reading it
+ from file system. */
+ if (success && log_tmp_is_encrypted()) {
+ if (!log_tmp_block_decrypt(buf,
+ srv_sort_buf_size,
+ index->online_log->crypt_head,
+ ofs,
+ index->table->space)) {
+ error = DB_DECRYPTION_FAILED;
+ goto func_exit;
+ }
+
+ srv_stats.n_rowlog_blocks_decrypted.inc();
+ memcpy(buf, index->online_log->crypt_head, srv_sort_buf_size);
+ }
+
if (!success) {
fprintf(stderr, "InnoDB: unable to read temporary file"
" for index %s\n", index->name + 1);
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 65569eabf57..80ab10cdbc0 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
@@ -79,88 +79,6 @@ UNIV_INTERN char srv_disable_sort_file_cache;
/* Maximum pending doc memory limit in bytes for a fts tokenization thread */
#define FTS_PENDING_DOC_MEMORY_LIMIT 1000000
-
-/******************************************************//**
-Encrypt a merge block. */
-static
-void
-row_merge_encrypt_buf(
-/*==================*/
- fil_space_crypt_t* crypt_data, /*!< in: table crypt data */
- ulint offset, /*!< in: offset where to
- write */
- ulint space, /*!< in: tablespace id */
- const byte* input_buf, /*!< in: input buffer */
- byte* crypted_buf) /*!< out: crypted buffer */
-{
- uint key_version;
- uint dstlen=0;
- os_offset_t ofs = (os_offset_t)srv_sort_buf_size * (os_offset_t)offset;
-
- key_version = encryption_key_get_latest_version(crypt_data->key_id);
-
- /* Store key_version at the begining of the input buffer */
- mach_write_to_4((byte *)crypted_buf, key_version);
-
- int rc = encryption_scheme_encrypt(input_buf+ROW_MERGE_RESERVE_SIZE,
- srv_sort_buf_size-ROW_MERGE_RESERVE_SIZE,
- crypted_buf+ROW_MERGE_RESERVE_SIZE, &dstlen,
- crypt_data, key_version,
- space, ofs, 0);
-
- if (! ((rc == MY_AES_OK) && ((ulint)dstlen == srv_sort_buf_size-ROW_MERGE_RESERVE_SIZE))) {
- ib_logf(IB_LOG_LEVEL_FATAL,
- "Unable to encrypt data-block "
- " src: %p srclen: %lu buf: %p buflen: %d."
- " return-code: %d. Can't continue!\n",
- input_buf, srv_sort_buf_size,
- crypted_buf, dstlen, rc);
- }
-}
-
-/******************************************************//**
-Decrypt a merge block. */
-static
-bool
-row_merge_decrypt_buf(
-/*==================*/
- fil_space_crypt_t* crypt_data, /*!< in: table crypt data */
- ulint offset, /*!< in: offset where to
- write */
- ulint space, /*!< in: tablespace id */
- const byte* input_buf, /*!< in: input buffer */
- byte* crypted_buf) /*!< out: crypted buffer */
-{
- uint key_version;
- uint dstlen=0;
- os_offset_t ofs = (os_offset_t)srv_sort_buf_size * (os_offset_t)offset;
-
- /* Read key_version from begining of the buffer */
- key_version = mach_read_from_4((byte *)input_buf);
-
- if (key_version == 0) {
- /* block not encrypted */
- return false;
- }
-
- int rc = encryption_scheme_decrypt(input_buf+ROW_MERGE_RESERVE_SIZE,
- srv_sort_buf_size-ROW_MERGE_RESERVE_SIZE,
- crypted_buf+ROW_MERGE_RESERVE_SIZE, &dstlen,
- crypt_data, key_version,
- space, ofs, 0);
-
- if (! ((rc == MY_AES_OK) && ((ulint)dstlen == srv_sort_buf_size-ROW_MERGE_RESERVE_SIZE))) {
- ib_logf(IB_LOG_LEVEL_FATAL,
- "Unable to encrypt data-block "
- " src: %p srclen: %lu buf: %p buflen: %d."
- " return-code: %d. Can't continue!\n",
- input_buf, srv_sort_buf_size,
- crypted_buf, dstlen, rc);
- }
-
- return true;
-}
-
#ifdef UNIV_DEBUG
/******************************************************//**
Display a merge tuple. */
@@ -279,7 +197,7 @@ row_merge_buf_create(
ulint buf_size;
mem_heap_t* heap;
- max_tuples = (srv_sort_buf_size - ROW_MERGE_RESERVE_SIZE)
+ max_tuples = (srv_sort_buf_size)
/ ut_max(1, dict_index_get_min_size(index));
buf_size = (sizeof *buf);
@@ -349,8 +267,8 @@ row_merge_buf_redundant_convert(
ulint zip_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;
@@ -366,7 +284,7 @@ row_merge_buf_redundant_convert(
field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE));
byte* data = btr_copy_externally_stored_field(
- &ext_len, field_data, zip_size, field_len, heap, NULL);
+ &ext_len, field_data, zip_size, field_len, heap);
ut_ad(ext_len < len);
@@ -476,7 +394,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 {
row_field = dtuple_get_nth_field(row, col_no);
@@ -611,7 +530,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)));
@@ -622,8 +541,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
@@ -633,14 +551,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 */
@@ -695,7 +610,7 @@ row_merge_buf_add(
ut_ad(data_size < srv_sort_buf_size);
/* Reserve bytes for the end marker of row_merge_block_t. */
- if (buf->total_size + data_size >= (srv_sort_buf_size - ROW_MERGE_RESERVE_SIZE)) {
+ if (buf->total_size + data_size >= srv_sort_buf_size) {
DBUG_RETURN(0);
}
@@ -816,7 +731,7 @@ UT_SORT_FUNCTION_BODY().
/**********************************************************************//**
Merge sort the tuple buffer in main memory. */
-static MY_ATTRIBUTE((nonnull(4,5)))
+static
void
row_merge_tuple_sort(
/*=================*/
@@ -867,7 +782,7 @@ row_merge_buf_write(
{
const dict_index_t* index = buf->index;
ulint n_fields= dict_index_get_n_fields(index);
- byte* b = &block[ROW_MERGE_RESERVE_SIZE];
+ byte* b = &block[0];
for (ulint i = 0; i < buf->n_tuples; i++) {
const mtuple_t* entry = &buf->tuples[i];
@@ -886,7 +801,7 @@ row_merge_buf_write(
/* Write an "end-of-chunk" marker. */
ut_a(b < &block[srv_sort_buf_size]);
- ut_a(b == &block[0] + buf->total_size + ROW_MERGE_RESERVE_SIZE);
+ ut_a(b == &block[0] + buf->total_size);
*b++ = 0;
#ifdef UNIV_DEBUG_VALGRIND
/* The rest of the block is uninitialized. Initialize it
@@ -936,7 +851,7 @@ row_merge_heap_create(
Read a merge block from the file system.
@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
-ibool
+bool
row_merge_read(
/*===========*/
int fd, /*!< in: file descriptor */
@@ -944,12 +859,11 @@ row_merge_read(
in number of row_merge_block_t
elements */
row_merge_block_t* buf, /*!< out: data */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_buf, /*!< in: crypt buf or NULL */
- ulint space) /*!< in: space id */
+ ulint space) /*!< in: space id */
{
os_offset_t ofs = ((os_offset_t) offset) * srv_sort_buf_size;
- ibool success;
+ bool success;
DBUG_EXECUTE_IF("row_merge_read_failure", return(FALSE););
@@ -963,11 +877,15 @@ row_merge_read(
success = os_file_read_no_error_handling_int_fd(fd, buf,
ofs, srv_sort_buf_size);
- /* For encrypted tables, decrypt data after reading and copy data */
- if (crypt_data && crypt_buf) {
- if (row_merge_decrypt_buf(crypt_data, offset, space, buf, crypt_buf)) {
- memcpy(buf, crypt_buf, srv_sort_buf_size);
+ /* If encryption is enabled decrypt buffer */
+ if (success && log_tmp_is_encrypted()) {
+ if (!log_tmp_block_decrypt(buf, srv_sort_buf_size,
+ crypt_buf, ofs, space)) {
+ return (FALSE);
}
+
+ srv_stats.n_merge_blocks_decrypted.inc();
+ memcpy(buf, crypt_buf, srv_sort_buf_size);
}
#ifdef POSIX_FADV_DONTNEED
@@ -989,31 +907,32 @@ row_merge_read(
Write a merge block to the file system.
@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
-ibool
+bool
row_merge_write(
/*============*/
int fd, /*!< in: file descriptor */
ulint offset, /*!< in: offset where to write,
in number of row_merge_block_t elements */
const void* buf, /*!< in: data */
- fil_space_crypt_t* crypt_data, /*!< in: table crypt data */
void* crypt_buf, /*!< in: crypt buf or NULL */
ulint space) /*!< in: space id */
{
size_t buf_len = srv_sort_buf_size;
os_offset_t ofs = buf_len * (os_offset_t) offset;
- ibool ret;
+ bool ret;
void* out_buf = (void *)buf;
DBUG_EXECUTE_IF("row_merge_write_failure", return(FALSE););
/* For encrypted tables, encrypt data before writing */
- if (crypt_data && crypt_buf) {
- row_merge_encrypt_buf(crypt_data, offset, space, (const byte *)buf, (byte *)crypt_buf);
+ if (log_tmp_is_encrypted()) {
+ if (!log_tmp_block_encrypt((const byte *)buf, buf_len,
+ (byte *)crypt_buf, ofs, space)) {
+ return (FALSE);
+ }
+
+ srv_stats.n_merge_blocks_encrypted.inc();
out_buf = crypt_buf;
- } else {
- /* Mark block unencrypted */
- mach_write_to_4((byte *)out_buf, 0);
}
ret = os_file_write_int_fd("(merge)", fd, out_buf, ofs, buf_len);
@@ -1051,9 +970,8 @@ row_merge_read_rec(
or NULL on end of list
(non-NULL on I/O error) */
ulint* offsets,/*!< out: offsets of mrec */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
- ulint space) /*!< in: space id */
+ ulint space) /*!< in: space id */
{
ulint extra_size;
ulint data_size;
@@ -1065,10 +983,6 @@ row_merge_read_rec(
ut_ad(*offsets == 1 + REC_OFFS_HEADER_SIZE
+ dict_index_get_n_fields(index));
- if (b == &block[0]) {
- b+= ROW_MERGE_RESERVE_SIZE;
- }
-
extra_size = *b++;
if (UNIV_UNLIKELY(!extra_size)) {
@@ -1090,7 +1004,8 @@ row_merge_read_rec(
if (UNIV_UNLIKELY(b >= &block[srv_sort_buf_size])) {
if (!row_merge_read(fd, ++(*foffs), block,
- crypt_data, crypt_block, space)) {
+ crypt_block,
+ space)) {
err_exit:
/* Signal I/O error. */
*mrec = b;
@@ -1098,7 +1013,7 @@ err_exit:
}
/* Wrap around to the beginning of the buffer. */
- b = &block[ROW_MERGE_RESERVE_SIZE];
+ b = &block[0];
}
extra_size = (extra_size & 0x7f) << 8;
@@ -1120,13 +1035,14 @@ err_exit:
memcpy(*buf, b, avail_size);
if (!row_merge_read(fd, ++(*foffs), block,
- crypt_data, crypt_block, space)) {
+ crypt_block,
+ space)) {
goto err_exit;
}
/* Wrap around to the beginning of the buffer. */
- b = &block[ROW_MERGE_RESERVE_SIZE];
+ b = &block[0];
/* Copy the record. */
memcpy(*buf + avail_size, b, extra_size - avail_size);
@@ -1182,13 +1098,14 @@ err_exit:
#endif /* UNIV_DEBUG */
if (!row_merge_read(fd, ++(*foffs), block,
- crypt_data, crypt_block, space)) {
+ crypt_block,
+ space)) {
goto err_exit;
}
/* Wrap around to the beginning of the buffer. */
- b = &block[ROW_MERGE_RESERVE_SIZE];
+ b = &block[0];
/* Copy the rest of the record. */
memcpy(*buf + avail_size, b, extra_size + data_size - avail_size);
@@ -1265,7 +1182,6 @@ row_merge_write_rec(
ulint* foffs, /*!< in/out: file offset */
const mrec_t* mrec, /*!< in: record to write */
const ulint* offsets,/*!< in: offsets of mrec */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
ulint space) /*!< in: space id */
{
@@ -1288,10 +1204,6 @@ row_merge_write_rec(
size = extra_size + (extra_size >= 0x80)
+ rec_offs_data_size(offsets);
- if (b == &block[0]) {
- b+= ROW_MERGE_RESERVE_SIZE;
- }
-
if (UNIV_UNLIKELY(b + size >= &block[srv_sort_buf_size])) {
/* The record spans two blocks.
Copy it to the temporary buffer first. */
@@ -1307,14 +1219,15 @@ row_merge_write_rec(
memcpy(b, buf[0], avail_size);
if (!row_merge_write(fd, (*foffs)++, block,
- crypt_data, crypt_block, space)) {
+ crypt_block,
+ space)) {
return(NULL);
}
UNIV_MEM_INVALID(&block[0], srv_sort_buf_size);
/* Copy the rest. */
- b = &block[ROW_MERGE_RESERVE_SIZE];
+ b = &block[0];
memcpy(b, buf[0] + avail_size, size - avail_size);
b += size - avail_size;
} else {
@@ -1337,7 +1250,6 @@ row_merge_write_eof(
byte* b, /*!< in: pointer to end of block */
int fd, /*!< in: file descriptor */
ulint* foffs, /*!< in/out: file offset */
- fil_space_crypt_t* crypt_data, /*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
ulint space) /*!< in: space id */
{
@@ -1352,10 +1264,6 @@ row_merge_write_eof(
}
#endif /* UNIV_DEBUG */
- if (b == &block[0]) {
- b+= ROW_MERGE_RESERVE_SIZE;
- }
-
*b++ = 0;
UNIV_MEM_ASSERT_RW(&block[0], b - &block[0]);
UNIV_MEM_ASSERT_W(&block[0], srv_sort_buf_size);
@@ -1367,7 +1275,8 @@ row_merge_write_eof(
#endif /* UNIV_DEBUG_VALGRIND */
if (!row_merge_write(fd, (*foffs)++, block,
- crypt_data, crypt_block, space)) {
+ crypt_block,
+ space)) {
return(NULL);
}
@@ -1445,10 +1354,9 @@ containing the index entries for the indexes to be built.
@param[in,out] block file buffer
@param[in,out] tmpfd temporary file handle
@param[in] pct_cost percent of task weight out of total alter job
-@param[in] crypt_data crypt data or NULL
@param[in,out] crypt_block crypted file buffer
-return DB_SUCCESS or error */
-static MY_ATTRIBUTE((nonnull(1,2,3,4,6,9,10,16), warn_unused_result))
+@return DB_SUCCESS or error */
+static MY_ATTRIBUTE((warn_unused_result))
dberr_t
row_merge_read_clustered_index(
trx_t* trx,
@@ -1469,7 +1377,6 @@ row_merge_read_clustered_index(
row_merge_block_t* block,
int* tmpfd,
float pct_cost,
- fil_space_crypt_t* crypt_data,
row_merge_block_t* crypt_block)
{
dict_index_t* clust_index; /* Clustered index */
@@ -2004,8 +1911,8 @@ write_buffers:
row_merge_buf_write(buf, file, block);
if (!row_merge_write(file->fd, file->offset++,
- block, crypt_data, crypt_block,
- new_table->space)) {
+ block, crypt_block,
+ new_table->space)) {
err = DB_TEMP_FILE_WRITE_FAILURE;
trx->error_key_num = i;
break;
@@ -2054,7 +1961,7 @@ write_buffers:
if(read_rows % 1000 == 0) {
/* Update progress for each 1000 rows */
curr_progress = (read_rows >= table_total_rows) ?
- pct_cost :
+ pct_cost :
((pct_cost * read_rows) / table_total_rows);
/* presenting 10.12% as 1012 integer */
onlineddl_pct_progress = curr_progress * 100;
@@ -2183,9 +2090,8 @@ wait_again:
&buf[2], b2, \
of->fd, &of->offset, \
mrec##N, offsets##N, \
- crypt_data, \
crypt_block ? &crypt_block[2 * srv_sort_buf_size] : NULL , \
- space); \
+ space); \
if (UNIV_UNLIKELY(!b2 || ++of->n_rec > file->n_rec)) { \
goto corrupt; \
} \
@@ -2193,7 +2099,6 @@ wait_again:
&buf[N], b##N, INDEX, \
file->fd, foffs##N, \
&mrec##N, offsets##N, \
- crypt_data, \
crypt_block ? &crypt_block[N * srv_sort_buf_size] : NULL, \
space); \
\
@@ -2208,7 +2113,7 @@ wait_again:
/*************************************************************//**
Merge two blocks of records on disk and write a bigger block.
@return DB_SUCCESS or error code */
-static __attribute__((nonnull(1,2,3,4,5,6), warn_unused_result))
+static __attribute__((warn_unused_result))
dberr_t
row_merge_blocks(
/*=============*/
@@ -2222,7 +2127,6 @@ row_merge_blocks(
ulint* foffs1, /*!< in/out: offset of second
source list in the file */
merge_file_t* of, /*!< in/out: output file */
- fil_space_crypt_t* crypt_data,/*!< in: crypt data or NULL */
row_merge_block_t* crypt_block,/*!< in: in/out: crypted file
buffer */
ulint space) /*!< in: space id */
@@ -2258,9 +2162,11 @@ row_merge_blocks(
file in two halves, which can be merged on the following pass. */
if (!row_merge_read(file->fd, *foffs0, &block[0],
- crypt_data, crypt_block ? &crypt_block[0] : NULL, space)
- || !row_merge_read(file->fd, *foffs1, &block[srv_sort_buf_size],
- crypt_data, crypt_block ? &crypt_block[srv_sort_buf_size] : NULL, space)) {
+ crypt_block ? &crypt_block[0] : NULL,
+ space) ||
+ !row_merge_read(file->fd, *foffs1, &block[srv_sort_buf_size],
+ crypt_block ? &crypt_block[srv_sort_buf_size] : NULL,
+ space)) {
corrupt:
mem_heap_free(heap);
return(DB_CORRUPTION);
@@ -2273,13 +2179,15 @@ corrupt:
b0 = row_merge_read_rec(
&block[0], &buf[0], b0, dup->index,
file->fd, foffs0, &mrec0, offsets0,
- crypt_data, crypt_block ? &crypt_block[0] : NULL, space);
+ crypt_block ? &crypt_block[0] : NULL,
+ space);
b1 = row_merge_read_rec(
&block[srv_sort_buf_size],
&buf[srv_sort_buf_size], b1, dup->index,
file->fd, foffs1, &mrec1, offsets1,
- crypt_data, crypt_block ? &crypt_block[srv_sort_buf_size] : NULL, space);
+ crypt_block ? &crypt_block[srv_sort_buf_size] : NULL,
+ space);
if (UNIV_UNLIKELY(!b0 && mrec0)
|| UNIV_UNLIKELY(!b1 && mrec1)) {
@@ -2325,7 +2233,8 @@ done1:
b2 = row_merge_write_eof(&block[2 * srv_sort_buf_size],
b2, of->fd, &of->offset,
- crypt_data, crypt_block ? &crypt_block[2 * srv_sort_buf_size] : NULL, space);
+ crypt_block ? &crypt_block[2 * srv_sort_buf_size] : NULL,
+ space);
return(b2 ? DB_SUCCESS : DB_CORRUPTION);
}
@@ -2333,8 +2242,8 @@ done1:
/*************************************************************//**
Copy a block of index entries.
@return TRUE on success, FALSE on failure */
-static __attribute__((nonnull(1,2,3,4,5), warn_unused_result))
-ibool
+static __attribute__((warn_unused_result))
+bool
row_merge_blocks_copy(
/*==================*/
const dict_index_t* index, /*!< in: index being created */
@@ -2342,9 +2251,8 @@ row_merge_blocks_copy(
row_merge_block_t* block, /*!< in/out: 3 buffers */
ulint* foffs0, /*!< in/out: input file offset */
merge_file_t* of, /*!< in/out: output file */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
- ulint space) /*!< in: space id */
+ ulint space) /*!< in: space id */
{
mem_heap_t* heap; /*!< memory heap for offsets0, offsets1 */
@@ -2372,7 +2280,8 @@ row_merge_blocks_copy(
file in two halves, which can be merged on the following pass. */
if (!row_merge_read(file->fd, *foffs0, &block[0],
- crypt_data, crypt_block ? &crypt_block[0] : NULL, space)) {
+ crypt_block ? &crypt_block[0] : NULL,
+ space)) {
corrupt:
mem_heap_free(heap);
return(FALSE);
@@ -2384,7 +2293,8 @@ corrupt:
b0 = row_merge_read_rec(&block[0], &buf[0], b0, index,
file->fd, foffs0, &mrec0, offsets0,
- crypt_data, crypt_block ? &crypt_block[0] : NULL, space);
+ crypt_block ? &crypt_block[0] : NULL,
+ space);
if (UNIV_UNLIKELY(!b0 && mrec0)) {
@@ -2407,15 +2317,15 @@ done0:
return(row_merge_write_eof(&block[2 * srv_sort_buf_size],
b2, of->fd, &of->offset,
- crypt_data,
- crypt_block ? &crypt_block[2 * srv_sort_buf_size] : NULL, space)
+ crypt_block ? &crypt_block[2 * srv_sort_buf_size] : NULL,
+ space)
!= NULL);
}
/*************************************************************//**
Merge disk files.
@return DB_SUCCESS or error code */
-static __attribute__((nonnull(1,2,3,4,5,6,7)))
+static
dberr_t
row_merge(
/*======*/
@@ -2431,9 +2341,8 @@ row_merge(
ulint* run_offset, /*!< in/out: Array contains the
first offset number for each merge
run */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
- ulint space) /*!< in: space id */
+ ulint space) /*!< in: space id */
{
ulint foffs0; /*!< first input offset */
ulint foffs1; /*!< second input offset */
@@ -2481,7 +2390,8 @@ row_merge(
error = row_merge_blocks(dup, file, block,
&foffs0, &foffs1, &of,
- crypt_data, crypt_block, space);
+ crypt_block,
+ space);
if (error != DB_SUCCESS) {
return(error);
@@ -2502,7 +2412,8 @@ row_merge(
if (!row_merge_blocks_copy(dup->index, file, block,
&foffs0, &of,
- crypt_data, crypt_block, space)) {
+ crypt_block,
+ space)) {
return(DB_CORRUPTION);
}
}
@@ -2520,7 +2431,8 @@ row_merge(
if (!row_merge_blocks_copy(dup->index, file, block,
&foffs1, &of,
- crypt_data, crypt_block, space)) {
+ crypt_block,
+ space)) {
return(DB_CORRUPTION);
}
}
@@ -2576,9 +2488,8 @@ row_merge_sort(
/*!< in: total progress percent
until now */
const float pct_cost, /*!< in: current progress percent */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
- ulint space) /*!< in: space id */
+ ulint space) /*!< in: space id */
{
const ulint half = file->offset / 2;
ulint num_runs;
@@ -2646,7 +2557,8 @@ row_merge_sort(
error = row_merge(trx, dup, file, block, tmpfd,
&num_runs, run_offset,
- crypt_data, crypt_block, space);
+ crypt_block,
+ space);
if(update_progress) {
merge_count++;
@@ -2708,7 +2620,7 @@ row_merge_copy_blobs(
BLOB pointers are read (row_merge_read_clustered_index())
and dereferenced (below). */
data = btr_rec_copy_externally_stored_field(
- mrec, offsets, zip_size, i, &len, heap, NULL);
+ mrec, offsets, zip_size, i, &len, heap);
/* Because we have locked the table, any records
written by incomplete transactions must have been
rolled back already. There must not be any incomplete
@@ -2723,7 +2635,7 @@ row_merge_copy_blobs(
Read sorted file containing index data tuples and insert these data
tuples to the index
@return DB_SUCCESS or error number */
-static __attribute__((nonnull(2,3,5), warn_unused_result))
+static __attribute__((warn_unused_result))
dberr_t
row_merge_insert_index_tuples(
/*==========================*/
@@ -2736,9 +2648,8 @@ row_merge_insert_index_tuples(
const float pct_progress, /*!< in: total progress percent until now */
const float pct_cost, /*!< in: current progress percent
*/
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
- ulint space) /*!< in: space id */
+ ulint space) /*!< in: space id */
{
const byte* b;
mem_heap_t* heap;
@@ -2772,7 +2683,8 @@ row_merge_insert_index_tuples(
b = &block[0];
if (!row_merge_read(fd, foffs, block,
- crypt_data, crypt_block, space)) {
+ crypt_block,
+ space)) {
error = DB_CORRUPTION;
} else {
buf = static_cast<mrec_buf_t*>(
@@ -2789,7 +2701,9 @@ row_merge_insert_index_tuples(
b = row_merge_read_rec(block, buf, b, index,
fd, &foffs, &mrec, offsets,
- crypt_data, crypt_block, space);
+ crypt_block,
+ space);
+
if (UNIV_UNLIKELY(!b)) {
/* End of list, or I/O error */
if (mrec) {
@@ -3816,11 +3730,7 @@ row_merge_create_index(
/*===================*/
trx_t* trx, /*!< in/out: trx (sets error_state) */
dict_table_t* table, /*!< in: the index is on this table */
- const index_def_t* index_def,
- /*!< in: the index definition */
- const char** col_names)
- /*! in: column names if columns are
- renamed or NULL */
+ const index_def_t* index_def) /*!< in: the index definition */
{
dict_index_t* index;
dberr_t err;
@@ -3840,28 +3750,10 @@ row_merge_create_index(
for (i = 0; i < n_fields; i++) {
index_field_t* ifield = &index_def->fields[i];
- const char * col_name;
-
- /*
- Alter table renaming a column and then adding a index
- to this new name e.g ALTER TABLE t
- CHANGE COLUMN b c INT NOT NULL, ADD UNIQUE INDEX (c);
- requires additional check as column names are not yet
- changed when new index definitions are created. Table's
- new column names are on a array of column name pointers
- if any of the column names are changed. */
-
- if (col_names && col_names[i]) {
- col_name = col_names[i];
- } else {
- col_name = ifield->col_name ?
- dict_table_get_col_name_for_mysql(table, ifield->col_name) :
- dict_table_get_col_name(table, ifield->col_no);
- }
dict_mem_index_add_field(
index,
- col_name,
+ dict_table_get_col_name(table, ifield->col_no),
ifield->prefix_len);
}
@@ -3974,7 +3866,6 @@ row_merge_build_indexes(
fts_psort_t* merge_info = NULL;
ib_int64_t sig_count = 0;
bool fts_psort_initiated = false;
- fil_space_crypt_t * crypt_data = NULL;
float total_static_cost = 0;
float total_dynamic_cost = 0;
@@ -3999,29 +3890,15 @@ row_merge_build_indexes(
DBUG_RETURN(DB_OUT_OF_MEMORY);
}
- /* Get crypt data from tablespace if present. We should be protected
- from concurrent DDL (e.g. drop table) by MDL-locks. */
- fil_space_t* space = fil_space_acquire(new_table->space);
-
- if (space) {
- crypt_data = space->crypt_data;
- } else {
- DBUG_RETURN(DB_TABLESPACE_NOT_FOUND);
- }
-
- /* If tablespace is encrypted, allocate additional buffer for
+ /* If temporal log file is encrypted allocate memory for
encryption/decryption. */
- if (crypt_data && crypt_data->should_encrypt()) {
+ if (log_tmp_is_encrypted()) {
crypt_block = static_cast<row_merge_block_t*>(
- os_mem_alloc_large(&block_size));
+ os_mem_alloc_large(&block_size));
if (crypt_block == NULL) {
- fil_space_release(space);
DBUG_RETURN(DB_OUT_OF_MEMORY);
}
- } else {
- /* Not needed */
- crypt_data = NULL;
}
trx_start_if_not_started_xa(trx);
@@ -4103,7 +3980,7 @@ row_merge_build_indexes(
fts_sort_idx, psort_info, merge_files, key_numbers,
n_indexes, add_cols, col_map,
add_autoinc, sequence, block, &tmpfd,
- pct_cost, crypt_data, crypt_block);
+ pct_cost, crypt_block);
pct_progress += pct_cost;
@@ -4126,10 +4003,6 @@ row_merge_build_indexes(
/* Now we have files containing index entries ready for
sorting and inserting. */
- DBUG_EXECUTE_IF(
- "ib_merge_wait_after_read",
- os_thread_sleep(20000000);); /* 20 sec */
-
for (i = 0; i < n_indexes; i++) {
dict_index_t* sort_idx = indexes[i];
@@ -4240,7 +4113,8 @@ wait_again:
trx, &dup, &merge_files[i],
block, &tmpfd, true,
pct_progress, pct_cost,
- crypt_data, crypt_block, new_table->space);
+ crypt_block,
+ new_table->space);
pct_progress += pct_cost;
@@ -4278,7 +4152,8 @@ wait_again:
trx->id, sort_idx, old_table,
merge_files[i].fd, block,
merge_files[i].n_rec, pct_progress, pct_cost,
- crypt_data, crypt_block, new_table->space);
+ crypt_block, new_table->space);
+
pct_progress += pct_cost;
if (global_system_variables.log_warnings > 2) {
@@ -4401,9 +4276,5 @@ func_exit:
}
}
- if (space) {
- fil_space_release(space);
- }
-
DBUG_RETURN(error);
}
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 1d64d66cd49..aa1dd98234b 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2000, 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
@@ -59,6 +59,7 @@ Created 9/17/2000 Heikki Tuuri
#include "btr0defragment.h"
#include "fil0fil.h"
#include "fil0crypt.h"
+#include "srv0srv.h"
#include "ibuf0ibuf.h"
#include "fts0fts.h"
#include "fts0types.h"
@@ -74,7 +75,7 @@ UNIV_INTERN 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 */
};
@@ -137,19 +138,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 */
-
/*******************************************************************//**
Delays an INSERT, DELETE or UPDATE operation if the purge is lagging. */
static
@@ -570,11 +558,33 @@ next_column:
/* If there is a FTS doc id column and it is not user supplied (
generated by server) then assign it a new doc id. */
- if (prebuilt->table->fts) {
+ if (!prebuilt->table->fts) {
+ return;
+ }
+
+ ut_a(prebuilt->table->fts->doc_col != ULINT_UNDEFINED);
- ut_a(prebuilt->table->fts->doc_col != ULINT_UNDEFINED);
+ doc_id_t doc_id;
- fts_create_doc_id(prebuilt->table, row, prebuilt->heap);
+ if (!DICT_TF2_FLAG_IS_SET(prebuilt->table, DICT_TF2_FTS_HAS_DOC_ID)) {
+ if (prebuilt->table->fts->cache->first_doc_id
+ == FTS_NULL_DOC_ID) {
+ fts_get_next_doc_id(prebuilt->table, &doc_id);
+ }
+ return;
+ }
+
+ dfield_t* fts_doc_id = dtuple_get_nth_field(
+ row, prebuilt->table->fts->doc_col);
+
+ if (fts_get_next_doc_id(prebuilt->table, &doc_id) == DB_SUCCESS) {
+ ut_a(doc_id != FTS_NULL_DOC_ID);
+ ut_ad(sizeof(doc_id) == fts_doc_id->type.len);
+ dfield_set_data(fts_doc_id, prebuilt->ins_upd_rec_buff
+ + prebuilt->mysql_row_len, 8);
+ fts_write_doc_id(fts_doc_id->data, doc_id);
+ } else {
+ dfield_set_null(fts_doc_id);
}
}
@@ -1049,7 +1059,10 @@ row_get_prebuilt_insert_row(
prebuilt->ins_upd_rec_buff = static_cast<byte*>(
mem_heap_alloc(
prebuilt->heap,
- prebuilt->mysql_row_len));
+ DICT_TF2_FLAG_IS_SET(prebuilt->table,
+ DICT_TF2_FTS_HAS_DOC_ID)
+ ? prebuilt->mysql_row_len + 8/* FTS_DOC_ID */
+ : prebuilt->mysql_row_len));
}
dtuple_t* row;
@@ -1973,7 +1986,7 @@ row_unlock_for_mysql(
trx_id_t rec_trx_id;
mtr_t mtr;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* Restore the cursor position and find the record */
@@ -2451,10 +2464,7 @@ err_exit:
/* We already have .ibd file here. it should be deleted. */
if (table->space
- && fil_delete_tablespace(
- table->space,
- BUF_REMOVE_FLUSH_NO_WRITE)
- != DB_SUCCESS) {
+ && fil_delete_tablespace(table->space) != DB_SUCCESS) {
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -2747,7 +2757,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);
@@ -2760,62 +2770,39 @@ 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 */
+ table = dict_table_open_on_id(drop->table_id, FALSE,
+ DICT_TABLE_OP_NORMAL);
- goto already_dropped;
+ if (!table) {
+ n_tables_dropped++;
+ mutex_enter(&row_drop_list_mutex);
+ UT_LIST_REMOVE(row_mysql_drop_list, 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, row_mysql_drop_list, drop);
+ UT_LIST_ADD_LAST(row_mysql_drop_list, 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)) {
/* 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, row_mysql_drop_list, drop);
-
- MONITOR_DEC(MONITOR_BACKGROUND_DROP_TABLE);
-
- ut_print_timestamp(stderr);
- fputs(" InnoDB: Dropped table ", stderr);
- ut_print_name(stderr, NULL, TRUE, drop->table_name);
- fputs(" in background drop queue.\n", stderr);
-
- mem_free(drop->table_name);
-
- mem_free(drop);
-
- mutex_exit(&row_drop_list_mutex);
-
goto loop;
}
@@ -2847,14 +2834,13 @@ 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);
@@ -2865,37 +2851,27 @@ 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*>(
- mem_alloc(sizeof(row_mysql_drop_t)));
-
- drop->table_name = mem_strdup(name);
+ drop = static_cast<row_mysql_drop_t*>(ut_malloc(sizeof *drop));
+ drop->table_id = table_id;
UT_LIST_ADD_LAST(row_mysql_drop_list, row_mysql_drop_list, drop);
MONITOR_INC(MONITOR_BACKGROUND_DROP_TABLE);
-
- /* fputs("InnoDB: Adding table ", stderr);
- ut_print_name(stderr, trx, TRUE, drop->table_name);
- fputs(" to background drop list\n", stderr); */
-
+func_exit:
mutex_exit(&row_drop_list_mutex);
-
- return(TRUE);
+ return added;
}
/*********************************************************************//**
Reassigns the table identifier of a table.
@return error code or DB_SUCCESS */
-UNIV_INTERN
+static
dberr_t
row_mysql_table_id_reassign(
/*========================*/
@@ -3083,9 +3059,6 @@ row_discard_tablespace(
4) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0,
we do not allow the discard. */
- /* Play safe and remove all insert buffer entries, though we should
- have removed them already when DISCARD TABLESPACE was called */
-
ibuf_delete_for_discarded_space(table->space);
table_id_t new_id;
@@ -3589,7 +3562,7 @@ row_truncate_table_for_mysql(
index = dict_table_get_next_index(index);
} while (index);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
fsp_header_init(space_id,
FIL_IBD_FILE_INITIAL_SIZE, &mtr);
mtr_commit(&mtr);
@@ -3618,7 +3591,7 @@ row_truncate_table_for_mysql(
sys_index = dict_table_get_first_index(dict_sys->sys_indexes);
dict_index_copy_types(tuple, sys_index, 1);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
BTR_MODIFY_LEAF, &pcur, &mtr);
for (;;) {
@@ -3665,7 +3638,7 @@ row_truncate_table_for_mysql(
a page in this mini-transaction, and the rest of
this loop could latch another index page. */
mtr_commit(&mtr);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
btr_pcur_restore_position(BTR_MODIFY_LEAF,
&pcur, &mtr);
}
@@ -4001,6 +3974,16 @@ row_drop_table_for_mysql(
ut_ad(!table->fts->add_wq);
ut_ad(lock_trx_has_sys_table_locks(trx) == 0);
+ for (;;) {
+ bool retry = false;
+ if (dict_fts_index_syncing(table)) {
+ retry = true;
+ }
+ if (!retry) {
+ break;
+ }
+ DICT_BG_YIELD(trx);
+ }
row_mysql_unlock_data_dictionary(trx);
fts_optimize_remove_table(table);
row_mysql_lock_data_dictionary(trx);
@@ -4101,7 +4084,7 @@ row_drop_table_for_mysql(
DBUG_EXECUTE_IF("row_drop_table_add_to_background",
- row_add_table_to_background_drop_list(table->name);
+ row_add_table_to_background_drop_list(table->id);
err = DB_SUCCESS;
goto funct_exit;
);
@@ -4113,33 +4096,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;
- ibool added;
-
- added = row_add_table_to_background_drop_list(save_tablename);
-
- if (added) {
+ if (row_add_table_to_background_drop_list(table->id)) {
ut_print_timestamp(stderr);
fputs(" InnoDB: You are trying to drop table ",
stderr);
- ut_print_name(stderr, trx, TRUE, save_tablename);
+ ut_print_name(stderr, trx, TRUE, table->name);
fputs("\n"
"InnoDB: though there is a"
" foreign key check running on it.\n"
"InnoDB: Adding the table to"
" the background drop queue.\n",
stderr);
-
- /* 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;
}
+ /* We return DB_SUCCESS to MySQL though the drop will
+ happen lazily later */
+ err = DB_SUCCESS;
goto funct_exit;
}
@@ -4164,11 +4136,7 @@ row_drop_table_for_mysql(
lock_remove_all_on_table(table, TRUE);
ut_a(table->n_rec_locks == 0);
} else if (table->n_ref_count > 0 || table->n_rec_locks > 0) {
- ibool added;
-
- added = row_add_table_to_background_drop_list(table->name);
-
- if (added) {
+ if (row_add_table_to_background_drop_list(table->id)) {
ut_print_timestamp(stderr);
fputs(" InnoDB: Warning: MySQL is"
" trying to drop table ", stderr);
@@ -4460,9 +4428,7 @@ row_drop_table_for_mysql(
fil_delete_file(filepath);
- } else if (fil_delete_tablespace(
- space_id,
- BUF_REMOVE_FLUSH_NO_WRITE)
+ } else if (fil_delete_tablespace(space_id)
!= DB_SUCCESS) {
fprintf(stderr,
"InnoDB: We removed now the InnoDB"
@@ -5375,6 +5341,7 @@ end:
trx_rollback_to_savepoint(trx, NULL);
trx->error_state = DB_SUCCESS;
}
+ table->data_dir_path= NULL;
}
funct_exit:
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index 1ed8b7377d9..98504b1e973 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -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
@@ -823,7 +823,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);
}
diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc
index 583fbe60fb3..53b4040f74e 100644
--- a/storage/innobase/row/row0quiesce.cc
+++ b/storage/innobase/row/row0quiesce.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, 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
@@ -236,7 +237,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);
@@ -542,8 +547,7 @@ row_quiesce_table_start(
}
if (!trx_is_interrupted(trx)) {
- buf_LRU_flush_or_remove_pages(
- table->space, BUF_REMOVE_FLUSH_WRITE, trx);
+ buf_LRU_flush_or_remove_pages(table->space, trx);
if (trx_is_interrupted(trx)) {
diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc
index 96d25e15777..9bf9e7182ca 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
@@ -173,7 +174,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);
@@ -588,7 +589,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));
}
@@ -702,7 +704,8 @@ notfound:
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));
}
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 189c7a7a1d2..6cca3e21c79 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
@@ -94,8 +94,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
@@ -134,8 +136,7 @@ row_sel_sec_rec_is_for_blob(
len = btr_copy_externally_stored_field_prefix(buf, prefix_len,
zip_size,
- clust_field, clust_len,
- NULL);
+ clust_field, clust_len);
if (UNIV_UNLIKELY(len == 0)) {
/* The BLOB was being deleted as the server crashed.
@@ -146,7 +147,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));
@@ -230,14 +231,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,
@@ -454,7 +455,7 @@ row_sel_fetch_columns(
data = btr_rec_copy_externally_stored_field(
rec, offsets,
dict_table_zip_size(index->table),
- field_no, &len, heap, NULL);
+ field_no, &len, heap);
/* data == NULL means that the
externally stored field was not
@@ -1401,7 +1402,7 @@ table_loop:
/* Open a cursor to index, or restore an open cursor position */
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
if (consistent_read && plan->unique_search && !plan->pcur_is_open
&& !plan->must_get_clust
@@ -1441,7 +1442,7 @@ table_loop:
plan_reset_cursor(plan);
mtr_commit(&mtr);
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
}
if (search_latch_locked) {
@@ -1539,6 +1540,7 @@ rec_loop:
switch (err) {
case DB_SUCCESS_LOCKED_REC:
err = DB_SUCCESS;
+ /* fall through */
case DB_SUCCESS:
break;
default:
@@ -1597,6 +1599,7 @@ skip_lock:
switch (err) {
case DB_SUCCESS_LOCKED_REC:
err = DB_SUCCESS;
+ /* fall through */
case DB_SUCCESS:
break;
default:
@@ -2722,6 +2725,7 @@ row_sel_field_store_in_mysql_format_func(
case DATA_SYS:
/* These column types should never be shipped to MySQL. */
ut_ad(0);
+ /* fall through */
case DATA_CHAR:
case DATA_FIXBINARY:
@@ -2756,8 +2760,6 @@ row_sel_field_store_in_mysql_format_func(
@param[in] field_no templ->rec_field_no or
templ->clust_rec_field_no
or templ->icp_rec_field_no
- or sec field no if clust_templ_for_sec
- is TRUE
@param[in] templ row template
*/
static MY_ATTRIBUTE((warn_unused_result))
@@ -2811,7 +2813,7 @@ row_sel_store_mysql_field_func(
data = btr_rec_copy_externally_stored_field(
rec, offsets,
dict_table_zip_size(prebuilt->table),
- field_no, &len, heap, NULL);
+ field_no, &len, heap);
if (UNIV_UNLIKELY(!data)) {
/* The externally stored field was not written
@@ -2910,10 +2912,6 @@ be needed in the query.
@param[in] rec_clust TRUE if the rec in the clustered index
@param[in] index index of rec
@param[in] offsets array returned by rec_get_offsets(rec)
-@param[in] clust_templ_for_sec TRUE if rec belongs to secondary index
- but the prebuilt->template is in
- clustered index format and it is
- used only for end range comparison
@return TRUE on success, FALSE if not all columns could be retrieved */
static MY_ATTRIBUTE((warn_unused_result))
ibool
@@ -3096,7 +3094,7 @@ row_sel_get_clust_rec_for_mysql(
trx_print(stderr, trx, 600);
fputs("\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n", stderr);
+ " to https://jira.mariadb.org/\n", stderr);
ut_ad(0);
}
@@ -3933,7 +3931,7 @@ row_search_for_mysql(
}
}
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/*-------------------------------------------------------------*/
/* PHASE 2: Try fast adaptive hash index search if possible */
@@ -4064,7 +4062,7 @@ release_search_latch_if_needed:
}
mtr_commit(&mtr);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
}
}
@@ -4220,6 +4218,7 @@ wait_table_again:
switch (err) {
case DB_SUCCESS_LOCKED_REC:
err = DB_SUCCESS;
+ /* fall through */
case DB_SUCCESS:
break;
default:
@@ -4310,6 +4309,7 @@ rec_loop:
switch (err) {
case DB_SUCCESS_LOCKED_REC:
err = DB_SUCCESS;
+ /* fall through */
case DB_SUCCESS:
break;
default:
@@ -4345,8 +4345,7 @@ rec_loop:
wrong_offs:
if (srv_force_recovery == 0 || moves_up == FALSE) {
ut_print_timestamp(stderr);
- buf_page_print(page_align(rec), 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page_align(rec), 0);
fprintf(stderr,
"\nInnoDB: rec address %p,"
" buf block fix count %lu\n",
@@ -4591,6 +4590,7 @@ no_gap_lock:
prebuilt->new_rec_locks = 1;
}
err = DB_SUCCESS;
+ /* fall through */
case DB_SUCCESS:
break;
case DB_LOCK_WAIT:
@@ -5138,7 +5138,7 @@ next_rec:
mtr_commit(&mtr);
mtr_has_extra_clust_latch = FALSE;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
if (sel_restore_position_for_mysql(&same_user_rec,
BTR_SEARCH_LEAF,
pcur, moves_up, &mtr)) {
@@ -5205,7 +5205,7 @@ lock_table_wait:
/* It was a lock wait, and it ended */
thr->lock_state = QUE_THR_LOCK_NOLOCK;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* Table lock waited, go try to obtain table lock
again */
diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc
index a97c89212a2..6c5e808cc38 100644
--- a/storage/innobase/row/row0umod.cc
+++ b/storage/innobase/row/row0umod.cc
@@ -299,7 +299,7 @@ row_undo_mod_clust(
pcur = &node->pcur;
index = btr_cur_get_index(btr_pcur_get_btr_cur(pcur));
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
online = dict_index_is_online_ddl(index);
if (online) {
@@ -328,7 +328,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(&mtr);
err = row_undo_mod_clust_low(
node, &offsets, &offsets_heap,
@@ -380,7 +380,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(&mtr);
/* It is not necessary to call row_log_table,
because the record is delete-marked and would thus
@@ -393,7 +393,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(&mtr);
err = row_undo_mod_remove_clust_low(node, thr, &mtr,
BTR_MODIFY_TREE);
@@ -440,7 +440,7 @@ row_undo_mod_del_mark_or_remove_sec_low(
enum row_search_result search_result;
log_free_check();
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
if (mode == BTR_MODIFY_TREE
&& index->space == IBUF_SPACE_ID
&& !dict_index_is_unique(index)) {
@@ -501,7 +501,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_start(&mtr_vers);
success = btr_pcur_restore_position(BTR_SEARCH_LEAF, &(node->pcur),
&mtr_vers);
@@ -617,7 +617,7 @@ row_undo_mod_del_unmark_sec_and_undo_update(
ut_ad(trx->id);
log_free_check();
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
if (mode == BTR_MODIFY_TREE
&& index->space == IBUF_SPACE_ID
&& !dict_index_is_unique(index)) {
@@ -683,7 +683,7 @@ row_undo_mod_del_unmark_sec_and_undo_update(
trx_print(stderr, trx, 0);
fputs("\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n", stderr);
+ " to https://jira.mariadb.org/\n", stderr);
ib_logf(IB_LOG_LEVEL_WARN,
"record in index %s was not found"
diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc
index 82b1ab049fa..552b99ab4d4 100644
--- a/storage/innobase/row/row0undo.cc
+++ b/storage/innobase/row/row0undo.cc
@@ -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
@@ -348,6 +349,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 d8d7002aad7..e2de47bf86a 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.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
@@ -259,7 +260,7 @@ row_upd_check_references_constraints(
DEBUG_SYNC_C("foreign_constraint_check_for_update");
- mtr_start_trx(mtr, trx);
+ mtr_start(mtr);
if (trx->dict_operation_lock_mode == 0) {
got_s_lock = TRUE;
@@ -1152,7 +1153,7 @@ row_upd_ext_fetch(
byte* buf = static_cast<byte*>(mem_heap_alloc(heap, *len));
*len = btr_copy_externally_stored_field_prefix(
- buf, *len, zip_size, data, local_len, NULL);
+ buf, *len, zip_size, data, local_len);
/* We should never update records containing a half-deleted BLOB. */
ut_a(*len);
@@ -1204,7 +1205,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);
@@ -1852,7 +1853,7 @@ row_upd_sec_index_entry(
}
#endif /* UNIV_DEBUG */
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
if (*index->name == TEMP_INDEX_PREFIX) {
/* The index->online_status may change if the
@@ -1952,7 +1953,7 @@ row_upd_sec_index_entry(
trx_print(stderr, trx, 0);
fputs("\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n", stderr);
+ " to https://jira.mariadb.org/\n", stderr);
ut_ad(0);
break;
case ROW_FOUND:
@@ -1982,9 +1983,9 @@ row_upd_sec_index_entry(
index, offsets, thr, &mtr);
}
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
+ if (err == DB_SUCCESS && !referenced &&
+ wsrep_on_trx(trx) &&
!wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
- err == DB_SUCCESS && !referenced &&
!(parent && que_node_get_type(parent) ==
QUE_NODE_UPDATE &&
((upd_node_t*)parent)->cascade_node == node) &&
@@ -2270,7 +2271,7 @@ err_exit:
}
}
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) && !referenced &&
+ if (!referenced && wsrep_on_trx(trx) &&
!(parent && que_node_get_type(parent) == QUE_NODE_UPDATE &&
((upd_node_t*)parent)->cascade_node == node) &&
foreign
@@ -2389,7 +2390,7 @@ 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_start(mtr);
/* NOTE: this transaction has an s-lock or x-lock on the record and
therefore other transactions cannot modify the record when we have no
@@ -2536,8 +2537,7 @@ row_upd_del_mark_clust_rec(
}
#ifdef WITH_WSREP
trx_t* trx = thr_get_trx(thr) ;
-
- if (err == DB_SUCCESS && !referenced && trx && wsrep_on(trx->mysql_thd) &&
+ if (err == DB_SUCCESS && !referenced && wsrep_on_trx(trx) &&
!(parent && que_node_get_type(parent) == QUE_NODE_UPDATE &&
((upd_node_t*)parent)->cascade_node == node) &&
foreign
@@ -2602,7 +2602,7 @@ row_upd_clust_step(
/* We have to restore the cursor to its position */
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
/* If the restoration does not succeed, then the same
transaction has deleted the record on which the cursor was,
@@ -2656,7 +2656,7 @@ row_upd_clust_step(
mtr_commit(&mtr);
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
success = btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur,
&mtr);
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 7ddd934a9a1..cb003edfbdc 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -77,10 +77,6 @@ Created 10/8/1995 Heikki Tuuri
#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;
@@ -1619,6 +1615,10 @@ srv_export_innodb_status(void)
export_vars.innodb_pages_page_compression_error = srv_stats.pages_page_compression_error;
export_vars.innodb_pages_decrypted = srv_stats.pages_decrypted;
export_vars.innodb_pages_encrypted = srv_stats.pages_encrypted;
+ export_vars.innodb_n_merge_blocks_encrypted = srv_stats.n_merge_blocks_encrypted;
+ export_vars.innodb_n_merge_blocks_decrypted = srv_stats.n_merge_blocks_decrypted;
+ export_vars.innodb_n_rowlog_blocks_encrypted = srv_stats.n_rowlog_blocks_encrypted;
+ export_vars.innodb_n_rowlog_blocks_decrypted = srv_stats.n_rowlog_blocks_decrypted;
export_vars.innodb_defragment_compression_failures =
btr_defragment_compression_failures;
@@ -1910,7 +1910,7 @@ loop:
" was greater\n"
"InnoDB: than the new log sequence number " LSN_PF "!\n"
"InnoDB: Please submit a bug report"
- " to http://bugs.mysql.com\n",
+ " to https://jira.mariadb.org\n",
old_lsn, new_lsn);
ut_ad(0);
}
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 8b963fc3259..db52e31881c 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -70,8 +70,7 @@ Created 2/16/1996 Heikki Tuuri
#include "srv0start.h"
#include "srv0srv.h"
#include "btr0defragment.h"
-
-#include <mysql/service_wsrep.h>
+#include "mysql/service_wsrep.h" /* wsrep_recovery */
#ifndef UNIV_HOTBACKUP
# include "trx0rseg.h"
@@ -3014,6 +3013,7 @@ files_checked:
*/
if (!wsrep_recovery) {
#endif /* WITH_WSREP */
+
/* Create the buffer pool dump/load thread */
srv_buf_dump_thread_active = true;
buf_dump_thread_handle=
@@ -3027,14 +3027,13 @@ files_checked:
"wsrep recovery.");
}
#endif /* WITH_WSREP */
+
/* Create thread(s) that handles key rotation */
fil_system_enter();
+ btr_scrub_init();
fil_crypt_threads_init();
fil_system_exit();
- /* Init data for datafile scrub threads */
- btr_scrub_init();
-
/* Initialize online defragmentation. */
btr_defragment_init();
btr_defragment_thread_active = true;
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index 8eff14e0e99..9e5e90128cb 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -584,32 +584,6 @@ trx_purge_rseg_get_next_history_log(
mutex_exit(&(rseg->mutex));
mtr_commit(&mtr);
-
- mutex_enter(&trx_sys->mutex);
-
- /* 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) {
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Warning: purge reached the"
- " head of the history list,\n"
- "InnoDB: but its length is still"
- " reported as %lu! Make a detailed bug\n"
- "InnoDB: report, and submit it"
- " to http://bugs.mysql.com\n",
- (ulong) trx_sys->rseg_history_len);
- ut_ad(0);
- }
-
- mutex_exit(&trx_sys->mutex);
-
return;
}
diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc
index ab92d1ef06c..cd5e51d4973 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
@@ -467,7 +467,7 @@ trx_undo_page_fetch_ext(
{
/* Fetch the BLOB. */
ulint ext_len = btr_copy_externally_stored_field_prefix(
- ext_buf, prefix_len, zip_size, field, *len, NULL);
+ ext_buf, prefix_len, zip_size, field, *len);
/* BLOBs should always be nonempty. */
ut_a(ext_len);
/* Append the BLOB pointer to the prefix. */
@@ -772,7 +772,25 @@ trx_undo_page_report_modify(
const dict_col_t* col
= dict_table_get_nth_col(table, col_no);
- if (col->ord_part) {
+ if (!col->ord_part) {
+ continue;
+ }
+
+ if (update) {
+ for (i = 0; i < update->n_fields; i++) {
+ const dict_field_t* f
+ = dict_index_get_nth_field(
+ index,
+ upd_get_nth_field(
+ update, i)
+ ->field_no);
+ if (f->col == col) {
+ goto already_logged;
+ }
+ }
+ }
+
+ if (TRUE) {
ulint pos;
/* Write field number to undo log */
@@ -823,6 +841,9 @@ trx_undo_page_report_modify(
ptr += flen;
}
}
+
+already_logged:
+ continue;
}
mach_write_to_2(old_ptr, ptr - old_ptr);
@@ -1001,7 +1022,7 @@ trx_undo_update_rec_get_update(
fprintf(stderr, "\n"
"InnoDB: but index has only %lu fields\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n"
+ " to https://jira.mariadb.org/\n"
"InnoDB: Run also CHECK TABLE ",
(ulong) dict_index_get_n_fields(index));
ut_print_name(stderr, trx, TRUE, index->table_name);
@@ -1055,6 +1076,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
@@ -1082,6 +1104,13 @@ trx_undo_rec_get_partial_row(
->mtype = DATA_MISSING;
}
+ for (const upd_field_t* uf = update->fields, * const ue
+ = update->fields + update->n_fields;
+ uf != ue; uf++) {
+ 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;
@@ -1102,6 +1131,10 @@ trx_undo_rec_get_partial_row(
ptr = trx_undo_rec_get_col_val(ptr, &field, &len, &orig_len);
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);
dict_col_copy_type(
dict_table_get_nth_col(index->table, col_no),
dfield_get_type(dfield));
@@ -1200,10 +1233,8 @@ trx_undo_report_row_operation(
marking, the record in the clustered
index, otherwise NULL */
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;
trx_undo_t* undo;
@@ -1236,7 +1267,7 @@ trx_undo_report_row_operation(
rseg = trx->rseg;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
mutex_enter(&trx->undo_mutex);
/* If the undo log is not assigned yet, assign one */
@@ -1312,7 +1343,7 @@ trx_undo_report_row_operation(
latches, such as SYNC_FSP and SYNC_FSP_PAGE. */
mtr_commit(&mtr);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
mutex_enter(&rseg->mutex);
trx_undo_free_last_page(trx, undo, &mtr);
@@ -1349,7 +1380,7 @@ trx_undo_report_row_operation(
/* We have to extend the undo log by one page */
ut_ad(++loop_count < 2);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* When we add a page to an undo log, this is analogous to
a pessimistic insert in a B-tree, and we must reserve the
diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc
index e22700c8fce..e5c57aa21ce 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,6 +24,9 @@ Transaction rollback
Created 3/26/1996 Heikki Tuuri
*******************************************************/
+#include "my_config.h"
+#include <my_systemd.h>
+
#include "trx0roll.h"
#ifdef UNIV_NONINL
@@ -55,14 +58,7 @@ rollback */
bool trx_rollback_or_clean_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. */
@@ -552,8 +548,6 @@ trx_rollback_active(
que_thr_t* thr;
roll_node_t* roll_node;
dict_table_t* table;
- ib_int64_t rows_to_undo;
- const char* unit = "";
ibool dictionary_locked = FALSE;
heap = mem_heap_create(512);
@@ -572,30 +566,8 @@ trx_rollback_active(
ut_a(thr == que_fork_start_command(fork));
- mutex_enter(&trx_sys->mutex);
-
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;
-
- mutex_exit(&trx_sys->mutex);
-
- if (rows_to_undo > 1000000000) {
- rows_to_undo = rows_to_undo / 1000000;
- unit = "M";
- }
-
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Rolling back trx with id " TRX_ID_FMT ", %lu%s"
- " rows to undo\n",
- trx->id,
- (ulong) rows_to_undo, unit);
-
if (trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) {
row_mysql_lock_data_dictionary(trx);
dictionary_locked = TRUE;
@@ -606,6 +578,16 @@ 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_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 */
@@ -650,13 +632,14 @@ trx_rollback_active(
}
}
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Rollback of trx with id " TRX_ID_FMT " completed", trx->id);
+
+func_exit:
if (dictionary_locked) {
row_mysql_unlock_data_dictionary(trx);
}
- ib_logf(IB_LOG_LEVEL_INFO,
- "Rollback of trx with id " TRX_ID_FMT " completed", trx->id);
-
mem_heap_free(heap);
trx_roll_crash_recv_trx = NULL;
@@ -673,7 +656,7 @@ ibool
trx_rollback_resurrected(
/*=====================*/
trx_t* trx, /*!< in: transaction to rollback or clean */
- ibool all) /*!< in: FALSE=roll back dictionary transactions;
+ ibool* all) /*!< in/out: FALSE=roll back dictionary transactions;
TRUE=roll back all non-PREPARED transactions */
{
ut_ad(mutex_own(&trx_sys->mutex));
@@ -684,16 +667,15 @@ trx_rollback_resurrected(
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) {
+ if (!trx->is_recovered) {
+func_exit:
+ trx_mutex_exit(trx);
return(FALSE);
}
- switch (state) {
+ switch (trx->state) {
case TRX_STATE_COMMITTED_IN_MEMORY:
+ trx_mutex_exit(trx);
mutex_exit(&trx_sys->mutex);
fprintf(stderr,
"InnoDB: Cleaning up trx with id " TRX_ID_FMT "\n",
@@ -702,21 +684,84 @@ trx_rollback_resurrected(
trx_free_for_background(trx);
return(TRUE);
case TRX_STATE_ACTIVE:
- if (all || trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) {
+ if (!srv_undo_sources && srv_fast_shutdown) {
+fake_prepared:
+ trx->state = TRX_STATE_PREPARED;
+ trx_sys->n_prepared_trx++;
+ trx_sys->n_prepared_recovered_trx++;
+ *all = FALSE;
+ goto func_exit;
+ }
+ trx_mutex_exit(trx);
+
+ if (*all || trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) {
mutex_exit(&trx_sys->mutex);
trx_rollback_active(trx);
+ if (trx->error_state != DB_SUCCESS) {
+ ut_ad(trx->error_state == DB_INTERRUPTED);
+ ut_ad(!srv_undo_sources);
+ ut_ad(srv_fast_shutdown);
+ mutex_enter(&trx_sys->mutex);
+ trx_mutex_enter(trx);
+ goto fake_prepared;
+ }
trx_free_for_background(trx);
return(TRUE);
}
return(FALSE);
case TRX_STATE_PREPARED:
- return(FALSE);
+ goto func_exit;
case TRX_STATE_NOT_STARTED:
break;
}
ut_error;
- return(FALSE);
+ goto func_exit;
+}
+
+/** Report progress when rolling back a row of a recovered transaction.
+@return whether the rollback should be aborted due to pending shutdown */
+UNIV_INTERN
+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));
+
+ if (trx_get_dict_operation(trx) == TRX_DICT_OP_NONE
+ && !srv_undo_sources && srv_fast_shutdown) {
+ return true;
+ }
+
+ ib_time_t time = ut_time();
+ mutex_enter(&trx_sys->mutex);
+ mutex_enter(&recv_sys->mutex);
+
+ if (recv_sys->report(time)) {
+ ulint n_trx = 0;
+ ulonglong n_rows = 0;
+ for (const trx_t* t = UT_LIST_GET_FIRST(trx_sys->rw_trx_list);
+ t != NULL;
+ t = UT_LIST_GET_NEXT(trx_list, t)) {
+
+ assert_trx_in_rw_list(t);
+ if (t->is_recovered
+ && trx_state_eq(t, TRX_STATE_ACTIVE)) {
+ n_trx++;
+ n_rows += t->undo_no;
+ }
+ }
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "To roll back: " ULINTPF " transactions, "
+ "%llu rows", n_trx, n_rows);
+ sd_notifyf(0, "STATUS=To roll back: " ULINTPF " transactions, "
+ "%llu rows", n_trx, n_rows);
+ }
+
+ mutex_exit(&recv_sys->mutex);
+ mutex_exit(&trx_sys->mutex);
+ return false;
}
/*******************************************************************//**
@@ -763,17 +808,11 @@ trx_rollback_or_clean_recovered(
assert_trx_in_rw_list(trx);
- if (srv_shutdown_state != SRV_SHUTDOWN_NONE
- && srv_fast_shutdown != 0) {
- all = FALSE;
- break;
- }
-
/* 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)) {
+ if (trx_rollback_resurrected(trx, &all)) {
mutex_enter(&trx_sys->mutex);
@@ -1100,7 +1139,6 @@ trx_roll_pop_top_rec_of_trx(
undo_no_t undo_no;
ibool is_insert;
trx_rseg_t* rseg;
- ulint progress_pct;
mtr_t mtr;
rseg = trx->rseg;
@@ -1158,27 +1196,6 @@ try_again:
ut_ad(undo_no + 1 == trx->undo_no);
- /* 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) {
-
- 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;
if (!trx_undo_arr_store_info(trx, undo_no)) {
diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc
index 8cb4f9a4135..0246eaf32a8 100644
--- a/storage/innobase/trx/trx0sys.cc
+++ b/storage/innobase/trx/trx0sys.cc
@@ -180,12 +180,7 @@ 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(mutex_own(&trx_sys->mutex));
-#endif /* WITH_WSREP */
if (!srv_read_only_mode) {
mtr_start(&mtr);
@@ -344,6 +339,7 @@ static inline void read_wsrep_xid_uuid(const XID* xid, unsigned char* buf)
@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,
@@ -402,8 +398,10 @@ trx_sys_update_wsrep_checkpoint(
}
/** Read WSREP XID from sys_header of TRX_SYS_PAGE_NO = 5.
-@param[out] xid Transaction XID */
-void
+@param[out] xid Transaction XID
+@return true on success, false on error. */
+UNIV_INTERN
+bool
trx_sys_read_wsrep_checkpoint(XID* xid)
{
trx_sysf_t* sys_header;
@@ -423,8 +421,8 @@ trx_sys_read_wsrep_checkpoint(XID* xid)
xid->formatID = -1;
trx_sys_update_wsrep_checkpoint(xid, sys_header, &mtr);
mtr_commit(&mtr);
- return;
- }
+ return false;
+ }
xid->formatID = (int)mach_read_from_4(
sys_header
@@ -440,6 +438,7 @@ trx_sys_read_wsrep_checkpoint(XID* xid)
XIDDATASIZE);
mtr_commit(&mtr);
+ return true;
}
#endif /* WITH_WSREP */
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index c7db5cb5efb..6d4bb202291 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
@@ -314,8 +314,9 @@ trx_free_prepared(
trx_t* trx) /*!< in, own: trx object */
{
ut_a(trx_state_eq(trx, TRX_STATE_PREPARED)
- || (trx_state_eq(trx, TRX_STATE_ACTIVE)
- && trx->is_recovered
+ || (trx->is_recovered
+ && (trx_state_eq(trx, TRX_STATE_ACTIVE)
+ || trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY))
&& (srv_read_only_mode
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO)));
ut_a(trx->magic_n == TRX_MAGIC_N);
@@ -1255,6 +1256,8 @@ trx_commit_in_memory(
trx->read_view = NULL;
if (lsn) {
+ DEBUG_SYNC_C("after_trx_committed_in_memory");
+
if (trx->insert_undo != NULL) {
trx_undo_insert_cleanup(trx);
@@ -2434,4 +2437,3 @@ trx_start_for_ddl_low(
ut_error;
}
-
diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc
index 220589dd9ff..370b3f181a1 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. 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
@@ -1070,9 +1070,11 @@ Truncates an undo log from the end. This function is used during a rollback
to free space from an undo log. */
UNIV_INTERN
void
-trx_undo_truncate_end(
+trx_undo_truncate_end_func(
/*=======================*/
- trx_t* trx, /*!< in: transaction whose undo log it is */
+#ifdef UNIV_DEBUG
+ const trx_t* trx, /*!< in: transaction whose undo log it is */
+#endif /* UNIV_DEBUG */
trx_undo_t* undo, /*!< in: undo log */
undo_no_t limit) /*!< in: all undo records with undo number
>= this value should be truncated */
@@ -1087,7 +1089,7 @@ trx_undo_truncate_end(
ut_ad(mutex_own(&(trx->rseg->mutex)));
for (;;) {
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
trunc_here = NULL;
@@ -1774,7 +1776,7 @@ trx_undo_assign_undo(
ut_ad(mutex_own(&(trx->undo_mutex)));
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
mutex_enter(&rseg->mutex);
@@ -1987,7 +1989,9 @@ trx_undo_insert_cleanup(
mutex_exit(&(rseg->mutex));
- trx_undo_seg_free(undo);
+ if (!srv_read_only_mode) {
+ trx_undo_seg_free(undo);
+ }
mutex_enter(&(rseg->mutex));
@@ -2015,11 +2019,21 @@ trx_undo_free_prepared(
switch (trx->update_undo->state) {
case TRX_UNDO_PREPARED:
break;
+ case TRX_UNDO_CACHED:
+ case TRX_UNDO_TO_FREE:
+ case TRX_UNDO_TO_PURGE:
+ ut_ad(trx_state_eq(trx,
+ TRX_STATE_COMMITTED_IN_MEMORY));
+ /* fall through */
case TRX_UNDO_ACTIVE:
/* lock_trx_release_locks() assigns
- trx->is_recovered=false */
+ trx->is_recovered=false and
+ trx->state = TRX_STATE_COMMITTED_IN_MEMORY,
+ also for transactions that we faked
+ to TRX_STATE_PREPARED in trx_rollback_resurrected(). */
ut_a(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;
@@ -2033,11 +2047,21 @@ trx_undo_free_prepared(
switch (trx->insert_undo->state) {
case TRX_UNDO_PREPARED:
break;
+ case TRX_UNDO_CACHED:
+ case TRX_UNDO_TO_FREE:
+ case TRX_UNDO_TO_PURGE:
+ ut_ad(trx_state_eq(trx,
+ TRX_STATE_COMMITTED_IN_MEMORY));
+ /* fall through */
case TRX_UNDO_ACTIVE:
/* lock_trx_release_locks() assigns
- trx->is_recovered=false */
+ trx->is_recovered=false and
+ trx->state = TRX_STATE_COMMITTED_IN_MEMORY,
+ also for transactions that we faked
+ to TRX_STATE_PREPARED in trx_rollback_resurrected(). */
ut_a(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;
diff --git a/storage/innobase/ut/ut0dbg.cc b/storage/innobase/ut/ut0dbg.cc
index a1cad144da4..a0bd82b385a 100644
--- a/storage/innobase/ut/ut0dbg.cc
+++ b/storage/innobase/ut/ut0dbg.cc
@@ -63,7 +63,7 @@ ut_dbg_assertion_failed(
fputs("InnoDB: We intentionally generate a memory trap.\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com.\n"
+ " to https://jira.mariadb.org/\n"
"InnoDB: If you get repeated assertion failures"
" or crashes, even\n"
"InnoDB: immediately after the mysqld startup, there may be\n"
diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc
index 181e713cca9..2a430c9c422 100644
--- a/storage/innobase/ut/ut0ut.cc
+++ b/storage/innobase/ut/ut0ut.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2017, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -46,6 +46,9 @@ Created 5/11/1994 Heikki Tuuri
#endif /* UNIV_HOTBACKUP */
#ifdef __WIN__
+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:
@@ -71,7 +74,7 @@ ut_gettimeofday(
return(-1);
}
- GetSystemTimeAsFileTime(&ft);
+ ut_get_system_time_as_file_time(&ft);
tm = (ib_int64_t) ft.dwHighDateTime << 32;
tm |= ft.dwLowDateTime;
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 47f759e0c05..47b24e1030b 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -2134,11 +2134,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/ma_blockrec.c b/storage/maria/ma_blockrec.c
index 57596558208..c4ec3cf2f9a 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_create.c b/storage/maria/ma_create.c
index 0ddd8b226e2..f3af97014f0 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -33,6 +33,27 @@
static int compare_columns(MARIA_COLUMNDEF **a, MARIA_COLUMNDEF **b);
+
+static ulonglong update_tot_length(ulonglong tot_length, ulonglong max_rows, uint length)
+{
+ ulonglong tot_length_part;
+
+ if (tot_length == ULONGLONG_MAX)
+ return ULONGLONG_MAX;
+
+ tot_length_part= (max_rows/(ulong) ((maria_block_size -
+ MAX_KEYPAGE_HEADER_SIZE - KEYPAGE_CHECKSUM_SIZE)/
+ (length*2)));
+ if (tot_length_part >= ULONGLONG_MAX / maria_block_size)
+ return ULONGLONG_MAX;
+
+ if (tot_length > ULONGLONG_MAX - tot_length_part * maria_block_size)
+ return ULONGLONG_MAX;
+
+ return tot_length + tot_length_part * maria_block_size;
+}
+
+
/*
Old options is used when recreating database, from maria_chk
*/
@@ -660,11 +681,8 @@ int maria_create(const char *name, enum data_file_type datafile_type,
if (length > max_key_length)
max_key_length= length;
- tot_length+= ((max_rows/(ulong) (((uint) maria_block_size -
- MAX_KEYPAGE_HEADER_SIZE -
- KEYPAGE_CHECKSUM_SIZE)/
- (length*2))) *
- maria_block_size);
+
+ tot_length= update_tot_length(tot_length, max_rows, length);
}
unique_key_parts=0;
@@ -673,11 +691,8 @@ int maria_create(const char *name, enum data_file_type datafile_type,
uniquedef->key=keys+i;
unique_key_parts+=uniquedef->keysegs;
share.state.key_root[keys+i]= HA_OFFSET_ERROR;
- tot_length+= (max_rows/(ulong) (((uint) maria_block_size -
- MAX_KEYPAGE_HEADER_SIZE -
- KEYPAGE_CHECKSUM_SIZE) /
- ((MARIA_UNIQUE_HASH_LENGTH + pointer)*2)))*
- (ulong) maria_block_size;
+
+ tot_length= update_tot_length(tot_length, max_rows, MARIA_UNIQUE_HASH_LENGTH + pointer);
}
keys+=uniques; /* Each unique has 1 key */
key_segs+=uniques; /* Each unique has 1 key seg */
@@ -746,8 +761,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
Get estimate for index file length (this may be wrong for FT keys)
This is used for pointers to other key pages.
*/
- tmp= (tot_length + maria_block_size * keys *
- MARIA_INDEX_BLOCK_MARGIN) / maria_block_size;
+ tmp= (tot_length / maria_block_size + keys * MARIA_INDEX_BLOCK_MARGIN);
/*
use maximum of key_file_length we calculated and key_file_length value we
diff --git a/storage/maria/ma_extra.c b/storage/maria/ma_extra.c
index 99c9df23030..6c74bb52f51 100644
--- a/storage/maria/ma_extra.c
+++ b/storage/maria/ma_extra.c
@@ -314,7 +314,7 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
share->state.open_count= 1;
share->changed= 1;
_ma_mark_file_changed_now(share);
- /* Fall through */
+ /* fall through */
case HA_EXTRA_PREPARE_FOR_RENAME:
{
my_bool do_flush= MY_TEST(function != HA_EXTRA_PREPARE_FOR_DROP);
@@ -660,4 +660,3 @@ my_bool ma_killed_standalone(MARIA_HA *info __attribute__((unused)))
{
return 0;
}
-
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index defa11ad6b4..129770249aa 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -2727,7 +2727,7 @@ static my_bool translog_recover_page_up_to_sector(uchar *page, uint16 offset)
DBUG_PRINT("enter", ("offset: %u first chunk: %u",
(uint) offset, (uint) chunk_offset));
- while (page[chunk_offset] != TRANSLOG_FILLER && chunk_offset < offset)
+ while (chunk_offset < offset && page[chunk_offset] != TRANSLOG_FILLER)
{
uint16 chunk_length;
if ((chunk_length=
@@ -6342,7 +6342,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_page.c b/storage/maria/ma_page.c
index 4021fb8e161..2f77f6f87ec 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)
{
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index b1d2378870f..b0b547a3070 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -3058,7 +3058,7 @@ static MARIA_HA *get_MARIA_HA_from_REDO_record(const
case LOGREC_REDO_INDEX:
case LOGREC_REDO_INDEX_FREE_PAGE:
index_page_redo_entry= 1;
- /* Fall through */
+ /* fall through*/
case LOGREC_REDO_INSERT_ROW_HEAD:
case LOGREC_REDO_INSERT_ROW_TAIL:
case LOGREC_REDO_PURGE_ROW_HEAD:
diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c
index 951850b16a4..0132dc95e5e 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;
diff --git a/storage/maria/ma_state.c b/storage/maria/ma_state.c
index 88ce88b8f98..7404fe06641 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_write.c b/storage/maria/ma_write.c
index 34ce530283c..4175a5be18c 100644
--- a/storage/maria/ma_write.c
+++ b/storage/maria/ma_write.c
@@ -340,7 +340,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_def.h b/storage/maria/maria_def.h
index 3b93dda2bad..d57a429365a 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -600,6 +600,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 */
@@ -1181,7 +1182,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,
diff --git a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c
index 39cff18a3ab..1ea31d228e1 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/mroonga/CMakeLists.txt b/storage/mroonga/CMakeLists.txt
index be14e73bd65..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,8 +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})
+ mysql_add_plugin(mroonga
+ ${MRN_ALL_SOURCES}
+ STORAGE_ENGINE MODULE_ONLY
+ LINK_LIBRARIES ${MRN_LIBRARIES})
else()
add_library(mroonga MODULE ${MRN_ALL_SOURCES})
@@ -337,9 +359,14 @@ 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()
set_source_files_properties(${MRN_SOURCES} PROPERTIES
COMPILE_FLAGS "${MYSQL_CFLAGS} ${MRN_CXX_COMPILE_FLAGS}")
@@ -358,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\"")
@@ -369,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
@@ -415,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 597ec4690cf..96f506f9e36 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
@@ -540,6 +558,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;
}
@@ -576,6 +614,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;
@@ -583,16 +622,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",
@@ -611,28 +644,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,
@@ -749,20 +767,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);
@@ -783,18 +800,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));
}
@@ -809,8 +826,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;
}
@@ -821,23 +836,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);
}
@@ -849,8 +941,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;
}
@@ -956,6 +1046,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,
@@ -1010,7 +1108,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;
@@ -1023,7 +1121,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;
@@ -1036,19 +1141,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,
@@ -1060,7 +1197,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
@@ -1102,11 +1239,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
};
@@ -1188,6 +1328,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,
@@ -1196,7 +1339,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);
@@ -1407,6 +1555,11 @@ static grn_builtin_type mrn_grn_type_from_field(grn_ctx *ctx, Field *field,
case MYSQL_TYPE_GEOMETRY: // case-by-case
type = GRN_DB_WGS84_GEO_POINT; // 8bytes
break;
+#ifdef MRN_HAVE_MYSQL_TYPE_JSON
+ case MYSQL_TYPE_JSON:
+ type = GRN_DB_TEXT;
+ break;
+#endif
}
return type;
}
@@ -1457,6 +1610,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,
@@ -1477,7 +1641,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;
@@ -1504,6 +1668,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,
@@ -1615,8 +1787,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;
@@ -1671,7 +1842,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);
@@ -1679,6 +1850,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;
}
@@ -1705,6 +1878,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);
@@ -1737,13 +1915,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,
@@ -1751,8 +1947,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,
@@ -1760,8 +1956,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;
}
@@ -1782,6 +1978,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);
@@ -1794,6 +1995,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:
@@ -1838,6 +2041,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);
@@ -1850,6 +2056,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;
@@ -2336,7 +2543,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);
@@ -2355,6 +2563,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;
@@ -2620,6 +2831,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);
}
@@ -2649,6 +2866,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);
}
@@ -2713,7 +2936,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) {
@@ -2737,7 +2960,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;
@@ -2854,9 +3077,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);
@@ -2904,6 +3129,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());
}
@@ -2967,7 +3193,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;
@@ -3014,7 +3240,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) {
@@ -3103,22 +3330,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
@@ -3307,10 +3530,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;
- 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;
}
@@ -3325,6 +3547,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;
@@ -3341,12 +3569,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);
}
}
@@ -3484,7 +3713,7 @@ 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);
@@ -3503,7 +3732,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);
@@ -3516,7 +3745,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);
@@ -3531,7 +3760,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);
@@ -3545,7 +3774,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);
@@ -3721,11 +3950,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);
}
}
@@ -3748,19 +3980,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;
- column_name_size = strlen(column_name);
- if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
+ if (strcmp(MRN_COLUMN_NAME_ID, field->field_name) == 0) {
// skipping _id virtual column
DBUG_RETURN(0);
}
+
+ if (is_foreign_key_field(table->s->table_name.str,
+ field->field_name)) {
+ 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);
+ 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);
+ 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);
@@ -3773,16 +4034,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;
@@ -3813,10 +4079,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;
- int column_name_size = strlen(column_name);
- 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);
@@ -3826,8 +4093,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);
@@ -3887,18 +4159,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);
}
@@ -3913,6 +4198,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);
@@ -3922,7 +4210,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;
@@ -3954,26 +4249,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);
@@ -4012,7 +4298,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)))
@@ -4039,6 +4325,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);
@@ -4098,6 +4417,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())));
@@ -4160,8 +4484,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];
@@ -4176,7 +4508,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);
@@ -4195,12 +4529,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);
@@ -4215,19 +4630,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);
@@ -4294,18 +4728,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;
- int column_name_size = strlen(column_name);
+ 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));
@@ -4322,25 +4764,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)
@@ -4400,6 +4848,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],
@@ -4458,7 +4911,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();
@@ -4476,9 +4936,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)
@@ -4546,7 +5006,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);
@@ -4605,7 +5068,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) {
@@ -4648,6 +5111,46 @@ 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;
+ 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);
+ 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());
@@ -4658,8 +5161,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);
@@ -5032,6 +5535,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;
@@ -5273,7 +5840,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);
@@ -5388,6 +5963,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;
@@ -5401,11 +5981,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;
+
+#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),
@@ -5489,17 +6075,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;
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 &&
@@ -5509,39 +6103,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)) {
+ 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,
+ 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) {
@@ -5862,6 +6480,12 @@ int ha_mroonga::wrapper_update_row(const uchar *old_data, uchar *new_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);
@@ -5999,6 +6623,12 @@ int ha_mroonga::storage_update_row(const uchar *old_data, uchar *new_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;
@@ -6007,11 +6637,22 @@ int ha_mroonga::storage_update_row(const uchar *old_data, uchar *new_data)
for (i = 0; i < n_columns; i++) {
Field *field = table->field[i];
- const char *column_name = field->field_name;
- 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,
@@ -6021,6 +6662,38 @@ int ha_mroonga::storage_update_row(const uchar *old_data, uchar *new_data)
}
}
}
+
+ if (!is_foreign_key_field(table->s->table_name.str, field->field_name))
+ 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,
+ 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;
@@ -6044,14 +6717,21 @@ int ha_mroonga::storage_update_row(const uchar *old_data, uchar *new_data)
GRN_VOID_INIT(&colbuf);
for (i = 0; i < n_columns; i++) {
Field *field = table->field[i];
- const char *column_name = field->field_name;
+
+#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;
}
@@ -6059,30 +6739,43 @@ int ha_mroonga::storage_update_row(const uchar *old_data, uchar *new_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, 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, 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);
@@ -6340,6 +7033,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);
@@ -6429,6 +7128,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());
@@ -6799,6 +7561,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);
}
@@ -6960,7 +7729,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;
@@ -6976,6 +7745,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);
@@ -6987,13 +7779,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,
@@ -7002,13 +7802,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());
@@ -7055,23 +7944,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"));
@@ -7509,222 +8381,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;
- 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();
@@ -7808,306 +8464,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);
}
@@ -8117,8 +8489,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();
@@ -8152,6 +8523,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));
@@ -8177,8 +8560,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) {
@@ -8186,15 +8567,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) {
@@ -8210,12 +8589,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);
}
@@ -8223,7 +8596,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;
@@ -8231,6 +8604,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;
@@ -8238,8 +8621,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,
@@ -8253,6 +8638,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,
@@ -8291,20 +8679,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
@@ -8453,7 +8852,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;
}
}
@@ -8566,6 +8966,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];
@@ -8745,7 +9186,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) {
@@ -8806,6 +9247,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);
@@ -8953,7 +9399,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();
@@ -8961,7 +9409,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),
@@ -9050,7 +9498,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);
@@ -9177,6 +9630,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();
@@ -9223,7 +9696,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;
@@ -9604,154 +10077,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)
@@ -9861,15 +10231,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;
}
@@ -9890,8 +10267,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;
- int column_name_size = strlen(column_name);
+ mrn::ColumnName column_name(field->field_name);
if (should_normalize(field))
{
@@ -9906,7 +10282,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,
@@ -10365,6 +10742,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();
@@ -10455,6 +10846,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;
@@ -10815,6 +11211,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)
{
@@ -10898,6 +11306,11 @@ void ha_mroonga::storage_store_field(Field *field,
case MYSQL_TYPE_GEOMETRY:
storage_store_field_geometry(field, value, value_length);
break;
+#ifdef MRN_HAVE_MYSQL_TYPE_JSON
+ case MYSQL_TYPE_JSON:
+ storage_store_field_json(field, value, value_length);
+ break;
+#endif
}
}
@@ -10906,6 +11319,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];
@@ -11041,6 +11458,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) &&
@@ -11658,8 +12080,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,
@@ -11671,14 +12095,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;
@@ -11686,6 +12110,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();
@@ -12349,6 +12807,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);
}
@@ -12512,6 +12993,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);
}
@@ -12592,6 +13077,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;
@@ -12622,6 +13108,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()
{
@@ -12776,11 +13263,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;
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(),
@@ -12846,6 +13338,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(),
@@ -12899,34 +13396,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;
- uint column_name_size = strlen(column_name);
- if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
+ if (!is_foreign_key_field(from_table_name, field->field_name)) {
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());
@@ -13109,6 +13604,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);
}
@@ -13125,6 +13625,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;
@@ -13138,35 +13674,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);
}
@@ -13220,9 +13728,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;
@@ -13293,8 +13801,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);
@@ -13302,7 +13819,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);
}
@@ -13416,10 +13933,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);
}
}
@@ -13575,10 +14092,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);
@@ -13627,6 +14150,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;
@@ -13969,8 +14498,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_COLUMN_TYPE |
- Alter_inplace_info::ALTER_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 |
@@ -14082,15 +14611,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);
@@ -14284,18 +14820,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);
@@ -14354,31 +14883,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, key->name)) {
- ++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,
@@ -14424,11 +14934,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
}
@@ -14437,6 +14947,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)))
@@ -14464,12 +14975,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,
@@ -14480,17 +14988,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];
@@ -14513,6 +15018,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, key->name) != 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)
@@ -14566,9 +15098,14 @@ bool ha_mroonga::storage_inplace_alter_table_add_column(
}
Field *field = altered_table->s->field[i];
- const char *column_name = field->field_name;
- int column_name_size = strlen(column_name);
+#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;
@@ -14593,20 +15130,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);
@@ -14736,16 +15367,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 =
@@ -14769,6 +15398,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);
}
@@ -15874,26 +16513,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;
- uint column_name_size = strlen(column_name);
- if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
+ if (!is_foreign_key_field(table_share->table_name.str,
+ field->field_name)) {
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);
@@ -15903,14 +16538,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);
}
@@ -16081,37 +16720,35 @@ 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;
- uint column_name_size = strlen(column_name);
- if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
+ if (!is_foreign_key_field(table_share->table_name.str, field->field_name)) {
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];
@@ -16124,14 +16761,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_STRING *field_name = thd_make_lex_string(thd, NULL, column_name,
- column_name_size, TRUE);
+ LEX_STRING *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];
@@ -16333,6 +16978,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();
@@ -16366,6 +17012,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()
@@ -16495,3 +17142,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 37059210dd1..2533913961e 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();
@@ -872,6 +965,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();
@@ -914,14 +1014,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();
@@ -929,41 +1021,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);
@@ -1041,8 +1110,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);
@@ -1069,8 +1140,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);
@@ -1111,8 +1184,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,
@@ -1208,7 +1283,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..e469ad2fd19
--- /dev/null
+++ b/storage/mroonga/lib/mrn_column_name.cpp
@@ -0,0 +1,63 @@
+/* -*- 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();
+ }
+
+ const char *ColumnName::mysql_name() {
+ return mysql_name_;
+ }
+
+ const char *ColumnName::c_str() {
+ return name_;
+ }
+
+ size_t ColumnName::length() {
+ return length_;
+ }
+
+ void ColumnName::encode() {
+ MRN_DBUG_ENTER_METHOD();
+ uint errors;
+ length_ = mrn_strconvert(system_charset_info,
+ mysql_name_,
+ strlen(mysql_name_),
+ &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..ed8fb67e506
--- /dev/null
+++ b/storage/mroonga/lib/mrn_column_name.hpp
@@ -0,0 +1,38 @@
+/* -*- 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);
+ 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();
+ };
+}
diff --git a/storage/mroonga/lib/mrn_condition_converter.cpp b/storage/mroonga/lib/mrn_condition_converter.cpp
index 1527a546938..6df601d6250 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;
@@ -352,6 +357,11 @@ namespace mrn {
case MYSQL_TYPE_GEOMETRY:
type = UNSUPPORTED_TYPE;
break;
+#ifdef MRN_HAVE_MYSQL_TYPE_JSON
+ case MYSQL_TYPE_JSON:
+ type = STRING_TYPE;
+ break;
+#endif
}
DBUG_RETURN(type);
@@ -404,11 +414,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()) {
@@ -416,14 +426,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;
@@ -432,7 +441,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;
@@ -443,7 +452,7 @@ namespace mrn {
break;
}
- DBUG_RETURN(NULL);
+ DBUG_RETURN(0);
}
void ConditionConverter::convert(const Item *where, grn_obj *expression) {
@@ -560,7 +569,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) {
@@ -574,7 +583,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..d297ee9a338
--- /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 ((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..216f3b7b7b5
--- /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);
+ 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);
+ 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);
+ 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 c7ef9dd5851..0038a7fe34f 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 =
@@ -518,6 +519,14 @@ namespace mrn {
*data_type = TYPE_BYTE_SEQUENCE;
*data_size = key_part->length;
break;
+#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 644825dcf39..086d1ea2e3f 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..d33a8c88d87 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
@@ -99,6 +107,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
@@ -206,6 +217,26 @@
# 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
# define mrn_init_sql_alloc(thd, mem_root) \
@@ -221,17 +252,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 +279,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 3320fb8ff30..c20f688fa6d 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,29 +1017,34 @@ int mrn_free_share(MRN_SHARE *share)
TABLE_SHARE *mrn_get_table_share(TABLE_LIST *table_list, int *error)
{
- uint key_length;
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->db, table_list->table_name, key,
key_length,
table_list->mdl_request.key.tc_hash_value(),
GTS_TABLE, NULL);
-#else
+# else
share = get_table_share(thd, table_list, key, key_length, 0, error);
+# endif
#endif
DBUG_RETURN(share);
}
@@ -1053,7 +1075,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_100.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_10_0.inc
index b48d4e9d1bb..356b2295743 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_100.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_10_0.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) {
- skip This test is for MariaDB version 10.0.x;
+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_10_0_or_later.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_10_0_or_later.inc
new file mode 100644
index 00000000000..1a8883f0478
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_10_0_or_later.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_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_or_later.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_version_5_6_or_later.inc
index 09e5acc0187..b9481afdee8 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_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_or_later) {
- skip This test is for MariaDB version 10.0.x or later;
+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 52a72155af3..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,
+ `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,
- `body` text,
+ `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 81feeefc589..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,
+ `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,
+ `title` varchar(40) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text,
+ `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 bb157539ac9..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,
+ `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,
+ `body` varchar(140) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`published` tinyint(1) DEFAULT NULL,
- `title` text,
+ `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 df5a15568d8..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,
+ `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,
- `body` text,
+ `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 19d5d017fb2..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,
- `body` text,
+ `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,
- `title` text,
+ `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 cf2bcc0fc2c..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,
- `body` text,
+ `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,
+ `description` varchar(140) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text,
+ `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 c73030805c8..6c87244ba47 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,
- `body` text,
+ `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,
- `internal_id` int(11) NOT NULL,
- `subject` text,
+ `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 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 6d60200e5ce..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,
- `body` text,
+ `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,
- `description` text,
+ `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 6bbedd41e95..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,
`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,
`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 3a7413e389b..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,
- `body` text,
- 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,
- `body` text,
- 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 6475de51b21..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,
- `body` text,
+ `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 cbc94cebccf..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,
- `body` text,
+ `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,
+ `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 d98dc431a0b..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,
- 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 d831d02d76a..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,
- `body` text,
+ `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,
- `title` text,
+ `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 bd936507211..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,
- `body` text,
+ `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,
+ `body` varchar(140) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
- `title` text,
+ `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 d8d963d87b4..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,
- `body` text,
+ `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,
+ `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 64f524de06c..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,
- `body` text,
- 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,
- `body` text,
- 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 eac322ceb26..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,
- `body` text,
- 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,
- `body` text,
- 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 ed36927e7b9..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,
+ `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 e24a56be3a2..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,
+ `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 018ee8eb5b8..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,
+ `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 453f641968b..70a980e2e8c 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,
- `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 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 10824d7c28d..a48be4da873 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,
- `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_32bit_max.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_32bit_max.result
index f3a7b27f342..b28a1744947 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,
- `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');
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 d7acad79bab..838eaf45f5c 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,
- `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_2038.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_64bit_2038.result
index 56e38902f28..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,
- `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 c3ca2628bca..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,
- `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 0373d17530e..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,
- `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 962212c86f8..352638031b7 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,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_fractional_seconds_with_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_fractional_seconds_with_index.result
index a31042f768d..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,
- `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 0b1bf0f0eb4..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,
- `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 82f01b9f237..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,
- `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 b205031dec1..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,
- `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 6592df35fcb..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,
- `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 c22a63f9744..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,25 +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
-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='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 4a21d62dd14..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,
- `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 cd939fa5483..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,
- `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 56a6a360dc9..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,
- `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 06162f76ddd..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,
- `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 9c2a8e876e3..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,
- `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 da75fd97424..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,
- `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 da245535f2c..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,
- `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 b310de48111..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,
- `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 3ee91c1a408..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,
- `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 254a0c0718a..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,
- `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_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 9e089e53f49..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 `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 4088caf49d5..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,
- 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 a18614d19fc..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,
- 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 77765f61dc3..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,
- 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 5b8d0cd780e..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,
- 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 9efa08bab53..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,
- 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 780ac2faa3d..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,
- 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 67170925826..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,
- 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..bfb263f11b5
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_alter_add.result
@@ -0,0 +1,21 @@
+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
+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..101a4a3de4b
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/foreign_key_alter_drop.result
@@ -0,0 +1,21 @@
+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
+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 d0e1a68f76b..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,
- 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 31d45181c96..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,
- 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 c107991d151..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,
- 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 04996d30f36..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,
- 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 623c66daaf4..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,
- 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 843c4b958ba..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,
- 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 3856d7ecc10..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,
- 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 59b26574c73..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,
- 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 d17ff6adf83..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,
- 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 81b40261a4c..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,
- `body` text,
- 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 5f85632575b..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,
- 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 29fd989b4f4..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,
- `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 508ee135ef2..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 into t1 values(1,100);
+INSERT INTO t1 VALUES(1,100);
Warnings:
Warning 1265 Data truncated for column '_id' at row 1
-insert into t1 values(1,100);
+INSERT INTO t1 VALUES(1,100);
Warnings:
Warning 1265 Data truncated for column '_id' at row 1
-insert into t1 values(1,100);
+INSERT INTO t1 VALUES(1,100);
Warnings:
Warning 1265 Data truncated for column '_id' at row 1
-insert 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 86b06bc94dd..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 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 a460c7d99d6..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,
- 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 ffbbfe3f460..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,
- 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 76c529f7fbb..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,
- 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 9b1e8e7d7e8..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,
- 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 0624ab2f2b2..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,
- 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 639114875e9..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,
- 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 6a89cdc33dd..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,
- 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 7040cc22b2e..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,
- 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 38017f6f8cc..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,
- 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 af9b3a2dbfb..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,
- 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 d58afb1f6d4..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,
- 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 12d4b173eaa..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,
- 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 fbec44527f7..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,
- 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_disabled.result b/storage/mroonga/mysql-test/mroonga/storage/r/optimization_count_skip_disabled.result
index 9971d21e386..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,
- 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 da15588ccd5..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,
- 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 0794b104a62..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,
- 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 bd34b040ad7..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,
- 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 f495a3b5956..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,
- 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 b5be750690d..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,
- 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 6f20f3b8b35..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,
- 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 5df3c12ccd8..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,
- 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 c12e69bf686..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,
- 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 6d00bac66eb..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,
- 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 529f0d521ee..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,
- 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 2320b0ffbc4..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,
- 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 c367aef808a..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,
- 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 b00a4e2a2c3..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,
- 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 5bf6bca4985..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,
- 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 5d6a19a936e..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,
- 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 6ee2991e51a..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,
- 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 e91e8af5391..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,
- 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 da01145e45a..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,
- 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 bb541c014bd..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,
- 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 fb9393687dc..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,
- 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 75ad884a268..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,
- 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 bb4ac9c3b33..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,
- 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 1b4d38e0107..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,
- 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 4fff9f9185f..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,
- 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 61119b2b74e..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,
- 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 9bf8b91ea07..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,
- 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 e4d41f5867e..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,
- 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 31a497ef8bb..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,
- 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 46c80ddcce7..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,
- 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 38263c1083f..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,
- 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 0812fc1089b..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,
- `body` text,
- 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 f2cf9667ac7..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,
- 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 4f24d0d74b0..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,
- 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 f6c036bbf9f..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,
- 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 104d1d51504..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,
- 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 6e690f45e61..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,
- 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 8de55efaccc..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,
- 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 dd3ee5b333c..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,
- 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 04b22c22ea6..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,
- `tags` text,
- 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 25a1aba61e2..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,
- `tags` text,
- 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/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/suite.pm b/storage/mroonga/mysql-test/mroonga/storage/suite.pm
index 7e4f8c1776b..528ccc5d693 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/suite.pm
+++ b/storage/mroonga/mysql-test/mroonga/storage/suite.pm
@@ -5,7 +5,7 @@ package My::Suite::Mroonga;
return "No Mroonga engine" unless $ENV{HA_MROONGA_SO} or
$::mysqld_variables{'mroonga'} eq "ON";
-sub is_default { not $::opt_embedded_server }
+sub is_default { 1 }
my $groonga_normalizer_mysql_dir=$::basedir . '/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql';
my $groonga_normalizer_mysql_install_dir=$::basedir . '/lib/groonga/plugins';
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 b732f04588c..7d982ae422e 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 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 91a20039780..552a2dfb635 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 054ea228236..bf08b878e1e 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 1a1ce992a6f..71ee07139ca 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 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 3fac76bb69b..5b25cf38e99 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 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 1e1d950ea7e..e93e38cd357 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 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 95fa60e7e59..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,8 +29,8 @@ CREATE TABLE diaries (
title TEXT,
created_at DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE diaries;
+--error ER_TRUNCATED_WRONG_VALUE
INSERT INTO diaries (title, created_at)
VALUES ('2012', '2012');
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 5742de6e392..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,14 +26,16 @@ CREATE TABLE timestamps (
id INT PRIMARY KEY AUTO_INCREMENT,
create_dt DATETIME
) DEFAULT CHARSET UTF8;
-SHOW CREATE TABLE timestamps;
-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='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 2397bdd9c8f..887d8fb51ac 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 dd0b6ba440e..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 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;
+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 0568da4508c..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 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 adc1c88236c..1f6151508e4 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 94a73a3633f..0f4306b3e08 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 6dc1ef84501..939d885a617 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 f20c2fd132c..fb647f5c6e7 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 45be9e2b9ef..a0277c18cc0 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 47e4d7c24cd..1539d9a7741 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 88a09a18a5c..92492d599e7 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 22dbbff96ac..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,
- 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,
- `body` text,
- 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 e5ce4692aa3..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,
- `body` text,
- 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,
- `body` text,
- 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 1106fcffca2..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,
- 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,
- 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 07c149a8fa8..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,
- `body` text,
- 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,
- 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 cc64daac30a..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,
- 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,
- `body` text,
- 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 08e526baa50..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,
- `body` text,
- 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,
- `body` text,
- 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 0e2f4c3bcca..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,
- `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_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 7ee07329f21..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,
- 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 f6e15804f42..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,
- 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 ddec8fdadbe..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,
- 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 08c37695f5a..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,
- 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 b0bff284532..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,
- 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 fd07ea67964..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,
- 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 8e1b0845e85..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,
- 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 64acf4aaeae..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,
- 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 c1661d7fcbf..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,
- 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 604aca172a5..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,
- 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 6f489bf37cc..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,
- 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 d9448ee82ba..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,
- `body` text,
- 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 860c8e548a8..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,
- 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 74d7426ebc1..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,
- `c` text,
- 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 3da64b2de1f..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,
- `body` text,
- 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...");
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 b3f5bee27d7..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,
- `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 28b981f9c7b..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,
- `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 20de4a32cfa..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,
- `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 be61419477f..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,
- 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/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 e330fa18c89..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,
- `body` text,
- 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 a5012384889..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,
- `body` text,
- 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 b01e85aa483..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,
- 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_rollback_delete_delete.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/transaction_rollback_delete_delete.result
index 11cc1874257..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,
- `body` text,
- 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 7dde8518db0..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,
- `body` text,
- 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 d41231ddd33..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,
- 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 e451b2b99fe..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,
- 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 f11398f3710..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,
- 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 47a844c8e68..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,
- 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 c98847cb50a..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,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,
- `tags` text,
- 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);
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 3d94ebc93ad..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,
- `tags` text,
- 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/suite.pm b/storage/mroonga/mysql-test/mroonga/wrapper/suite.pm
index 7e4f8c1776b..528ccc5d693 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/suite.pm
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/suite.pm
@@ -5,7 +5,7 @@ package My::Suite::Mroonga;
return "No Mroonga engine" unless $ENV{HA_MROONGA_SO} or
$::mysqld_variables{'mroonga'} eq "ON";
-sub is_default { not $::opt_embedded_server }
+sub is_default { 1 }
my $groonga_normalizer_mysql_dir=$::basedir . '/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql';
my $groonga_normalizer_mysql_install_dir=$::basedir . '/lib/groonga/plugins';
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 2d8a59fa664..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,43 @@ 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("-Wdisabled-optimization")
+ 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()
if(NOT DEFINED CMAKE_C_COMPILE_OPTIONS_PIC)
@@ -303,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})
@@ -338,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)
@@ -486,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)
@@ -531,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)
@@ -580,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 a16a446022c..59ce80b4444 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 92caba561eb..1b9bcc3acb1 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,41 +33,32 @@
#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 }
#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;
@@ -91,15 +84,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)
{
@@ -123,357 +135,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;
@@ -482,6 +159,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
@@ -499,6 +181,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);
}
@@ -509,24 +194,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;
@@ -536,33 +215,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 =
@@ -575,9 +269,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;
@@ -589,17 +287,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
@@ -645,12 +345,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;
@@ -669,7 +369,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
@@ -681,6 +381,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;
@@ -693,7 +402,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;
}
@@ -718,11 +426,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;
@@ -732,6 +455,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);
}
@@ -746,10 +478,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;
@@ -768,20 +500,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);
@@ -842,15 +561,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;
@@ -860,94 +587,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
@@ -1013,8 +722,6 @@ grn_set_lock_timeout(int timeout)
return GRN_SUCCESS;
}
-static int alloc_count = 0;
-
grn_rc
grn_fin(void)
{
@@ -1030,6 +737,7 @@ grn_fin(void)
}
}
grn_query_logger_fin(ctx);
+ grn_request_timer_fin();
grn_request_canceler_fin();
grn_cache_fin();
grn_tokenizers_fin();
@@ -1037,9 +745,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;
}
@@ -1062,8 +772,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;
}
@@ -1072,7 +784,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;
}
@@ -1083,12 +795,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;
@@ -1100,7 +812,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;
}
@@ -1112,25 +824,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 {
@@ -1144,7 +856,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;
}
@@ -1170,7 +882,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)) {
@@ -1195,70 +915,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;
}
@@ -1308,10 +1028,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 "&;"
@@ -1328,7 +1052,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, '?');
@@ -1362,7 +1090,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;
@@ -1371,18 +1114,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);
@@ -1397,7 +1147,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;
}
@@ -1408,7 +1160,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);
@@ -1440,7 +1196,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);
@@ -1461,10 +1232,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)) {
@@ -1477,14 +1260,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;
}
@@ -1531,12 +1310,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;
@@ -1550,11 +1331,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);
@@ -1562,8 +1347,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);
@@ -1574,19 +1361,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;
}
}
@@ -1599,30 +1398,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;
@@ -1631,11 +1446,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;
}
}
@@ -1648,7 +1463,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)) {
@@ -1664,8 +1479,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;
}
}
@@ -1676,456 +1491,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
@@ -2149,410 +1525,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
@@ -2575,6 +1564,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
@@ -2696,89 +1691,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);
}
@@ -2788,8 +1865,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 6dab51a2978..b47323a2b29 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/cursor-factory.cpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/cursor-factory.cpp
@@ -32,8 +32,6 @@ Cursor *CursorFactory::open(const Trie &trie,
UInt32 offset,
UInt32 limit,
UInt32 flags) {
- GRN_DAT_THROW_IF(PARAM_ERROR, &trie == NULL);
-
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 e213812d926..34e3392244c 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 388e0566756..04f8ec0d408 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 86b0fd58c02..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};
- 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 28fd13c33c4..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;
@@ -544,7 +549,7 @@ regexp_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
grn_obj *buffer = &(tokenizer->buffer);
const char *current = tokenizer->next;
const char *end = tokenizer->end;
- const const uint_least8_t *char_types = tokenizer->char_types;
+ const uint_least8_t *char_types = tokenizer->char_types;
grn_tokenize_mode mode = tokenizer->query->tokenize_mode;
grn_bool is_begin = tokenizer->is_begin;
grn_bool is_start_token = tokenizer->is_start_token;
@@ -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/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 82bcbdb12a9..7f2afc3130a 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -729,6 +729,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;
@@ -783,6 +784,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)
@@ -1847,7 +1872,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;
@@ -1895,27 +1919,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)
{
@@ -2261,6 +2264,17 @@ ha_myisam::check_if_supported_inplace_alter(TABLE *new_table,
}
+static bool directories_differ(const char *d1, const char *d2)
+{
+ if (!d1 && !d2)
+ return false;
+ if (!d1 || !d2)
+ return true;
+ size_t l1= dirname_length(d1), l2= dirname_length(d2);
+ return l1 != l2 || strncmp(d1, d2, l1);
+}
+
+
bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *create_info,
uint table_changes)
{
@@ -2268,8 +2282,8 @@ bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *create_info,
if ((create_info->used_fields & HA_CREATE_USED_AUTO &&
create_info->auto_increment_value != stats.auto_increment_value) ||
- create_info->data_file_name != data_file_name ||
- create_info->index_file_name != index_file_name ||
+ directories_differ(create_info->data_file_name, data_file_name) ||
+ directories_differ(create_info->index_file_name, index_file_name) ||
table_changes == IS_EQUAL_NO ||
table_changes & IS_EQUAL_PACK_LENGTH) // Not implemented yet
return COMPATIBLE_DATA_NO;
diff --git a/storage/myisam/mi_extra.c b/storage/myisam/mi_extra.c
index 04e32378fd3..bb276f0226d 100644
--- a/storage/myisam/mi_extra.c
+++ b/storage/myisam/mi_extra.c
@@ -263,7 +263,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
//share->deleting= TRUE;
share->global_changed= FALSE; /* force writing changed flag */
_mi_mark_file_changed(info);
- /* Fall through */
+ /* fall through */
case HA_EXTRA_PREPARE_FOR_RENAME:
mysql_mutex_lock(&THR_LOCK_myisam);
share->last_version= 0L; /* Impossible version */
diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c
index 1921926463e..4fd287c6038 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);
}
diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c
index 60a34c641ad..92f28f4e32a 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/oqgraph/graphcore.cc b/storage/oqgraph/graphcore.cc
index fb2b105f2fd..bf454aa3333 100644
--- a/storage/oqgraph/graphcore.cc
+++ b/storage/oqgraph/graphcore.cc
@@ -891,18 +891,18 @@ namespace open_query
boost::unordered_map<Vertex, Vertex> p;
boost::unordered_map<Vertex, EdgeWeight> d;
boost::queue<Vertex> Q;
- reverse_graph<Graph> r(share->g);
+ const reverse_graph<Graph> r(share->g);
p[ *dest ]= *dest;
d[ *dest ] = EdgeWeight();
switch (ALGORITHM & op)
{
case DIJKSTRAS:
- dijkstra_shortest_paths_no_init(share->g, *dest,
+ dijkstra_shortest_paths_no_init(r, *dest,
make_lazy_property_map(p, identity_initializer<Vertex>()),
make_lazy_property_map(d, value_initializer<EdgeWeight>(
(std::numeric_limits<EdgeWeight>::max)())),
- get(edge_weight, share->g),
- get(vertex_index, share->g),
+ get(edge_weight, r),
+ get(vertex_index, r),
std::less<EdgeWeight>(),
closed_plus<EdgeWeight>(),
EdgeWeight(),
@@ -913,10 +913,10 @@ namespace open_query
static_cast<stack_cursor*>(cursor)
)
),
- make_two_bit_judy_map(get(vertex_index, share->g)));
+ make_two_bit_judy_map(get(vertex_index, r)));
break;
case BREADTH_FIRST:
- breadth_first_visit(share->g, *dest, Q,
+ breadth_first_visit(r, *dest, Q,
make_bfs_visitor(
std::make_pair(
record_predecessors(
@@ -935,7 +935,7 @@ namespace open_query
)
))
),
- make_two_bit_judy_map(get(vertex_index, share->g)));
+ make_two_bit_judy_map(get(vertex_index, r)));
break;
default:
abort();
diff --git a/storage/oqgraph/mysql-test/oqgraph/general-Aria.result b/storage/oqgraph/mysql-test/oqgraph/general-Aria.result
index a35b5182611..e527705045f 100644
--- a/storage/oqgraph/mysql-test/oqgraph/general-Aria.result
+++ b/storage/oqgraph/mysql-test/oqgraph/general-Aria.result
@@ -455,16 +455,16 @@ breadth_first NULL 4 1 2 3
breadth_first NULL 4 0 1 4
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 5;
latch origid destid weight seq linkid
-breadth_first NULL 5 1 3 7
breadth_first NULL 5 1 2 6
breadth_first NULL 5 0 1 5
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 6;
latch origid destid weight seq linkid
-breadth_first NULL 6 2 3 7
breadth_first NULL 6 1 2 5
breadth_first NULL 6 0 1 6
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 7;
latch origid destid weight seq linkid
+breadth_first NULL 7 2 3 6
+breadth_first NULL 7 1 2 5
breadth_first NULL 7 0 1 7
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 8;
latch origid destid weight seq linkid
@@ -473,18 +473,18 @@ latch origid destid weight seq linkid
breadth_first NULL 9 0 1 9
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 10;
latch origid destid weight seq linkid
-breadth_first NULL 10 2 3 12
-breadth_first NULL 10 1 2 11
+breadth_first NULL 10 2 3 11
+breadth_first NULL 10 1 2 12
breadth_first NULL 10 0 1 10
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 11;
latch origid destid weight seq linkid
-breadth_first NULL 11 2 3 10
-breadth_first NULL 11 1 2 12
+breadth_first NULL 11 2 3 12
+breadth_first NULL 11 1 2 10
breadth_first NULL 11 0 1 11
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 12;
latch origid destid weight seq linkid
-breadth_first NULL 12 2 3 11
-breadth_first NULL 12 1 2 10
+breadth_first NULL 12 2 3 10
+breadth_first NULL 12 1 2 11
breadth_first NULL 12 0 1 12
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 1 and weight = 1;
latch origid destid weight seq linkid
@@ -502,26 +502,26 @@ latch origid destid weight seq linkid
breadth_first NULL 4 1 2 3
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 5 and weight = 1;
latch origid destid weight seq linkid
-breadth_first NULL 5 1 3 7
breadth_first NULL 5 1 2 6
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 6 and weight = 1;
latch origid destid weight seq linkid
breadth_first NULL 6 1 2 5
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 7 and weight = 1;
latch origid destid weight seq linkid
+breadth_first NULL 7 1 2 5
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 8 and weight = 1;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 9 and weight = 1;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 10 and weight = 1;
latch origid destid weight seq linkid
-breadth_first NULL 10 1 2 11
+breadth_first NULL 10 1 2 12
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 11 and weight = 1;
latch origid destid weight seq linkid
-breadth_first NULL 11 1 2 12
+breadth_first NULL 11 1 2 10
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 12 and weight = 1;
latch origid destid weight seq linkid
-breadth_first NULL 12 1 2 10
+breadth_first NULL 12 1 2 11
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 1 and weight = 2;
latch origid destid weight seq linkid
breadth_first NULL 1 2 4 4
@@ -538,22 +538,22 @@ SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 5 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 6 and weight = 2;
latch origid destid weight seq linkid
-breadth_first NULL 6 2 3 7
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 7 and weight = 2;
latch origid destid weight seq linkid
+breadth_first NULL 7 2 3 6
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 8 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 9 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 10 and weight = 2;
latch origid destid weight seq linkid
-breadth_first NULL 10 2 3 12
+breadth_first NULL 10 2 3 11
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 11 and weight = 2;
latch origid destid weight seq linkid
-breadth_first NULL 11 2 3 10
+breadth_first NULL 11 2 3 12
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 12 and weight = 2;
latch origid destid weight seq linkid
-breadth_first NULL 12 2 3 11
+breadth_first NULL 12 2 3 10
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 1 and weight = 3;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 2 and weight = 3;
@@ -847,16 +847,16 @@ latch origid destid weight seq linkid
2 NULL 4 0 1 4
SELECT * FROM graph WHERE latch = '2' AND destid = 5;
latch origid destid weight seq linkid
-2 NULL 5 1 3 7
2 NULL 5 1 2 6
2 NULL 5 0 1 5
SELECT * FROM graph WHERE latch = '2' AND destid = 6;
latch origid destid weight seq linkid
-2 NULL 6 2 3 7
2 NULL 6 1 2 5
2 NULL 6 0 1 6
SELECT * FROM graph WHERE latch = '2' AND destid = 7;
latch origid destid weight seq linkid
+2 NULL 7 2 3 6
+2 NULL 7 1 2 5
2 NULL 7 0 1 7
SELECT * FROM graph WHERE latch = '2' AND destid = 8;
latch origid destid weight seq linkid
@@ -865,18 +865,18 @@ latch origid destid weight seq linkid
2 NULL 9 0 1 9
SELECT * FROM graph WHERE latch = '2' AND destid = 10;
latch origid destid weight seq linkid
-2 NULL 10 2 3 12
-2 NULL 10 1 2 11
+2 NULL 10 2 3 11
+2 NULL 10 1 2 12
2 NULL 10 0 1 10
SELECT * FROM graph WHERE latch = '2' AND destid = 11;
latch origid destid weight seq linkid
-2 NULL 11 2 3 10
-2 NULL 11 1 2 12
+2 NULL 11 2 3 12
+2 NULL 11 1 2 10
2 NULL 11 0 1 11
SELECT * FROM graph WHERE latch = '2' AND destid = 12;
latch origid destid weight seq linkid
-2 NULL 12 2 3 11
-2 NULL 12 1 2 10
+2 NULL 12 2 3 10
+2 NULL 12 1 2 11
2 NULL 12 0 1 12
SELECT * FROM graph WHERE latch = '2' AND destid = 1 and weight = 1;
latch origid destid weight seq linkid
@@ -894,26 +894,26 @@ latch origid destid weight seq linkid
2 NULL 4 1 2 3
SELECT * FROM graph WHERE latch = '2' AND destid = 5 and weight = 1;
latch origid destid weight seq linkid
-2 NULL 5 1 3 7
2 NULL 5 1 2 6
SELECT * FROM graph WHERE latch = '2' AND destid = 6 and weight = 1;
latch origid destid weight seq linkid
2 NULL 6 1 2 5
SELECT * FROM graph WHERE latch = '2' AND destid = 7 and weight = 1;
latch origid destid weight seq linkid
+2 NULL 7 1 2 5
SELECT * FROM graph WHERE latch = '2' AND destid = 8 and weight = 1;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = '2' AND destid = 9 and weight = 1;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = '2' AND destid = 10 and weight = 1;
latch origid destid weight seq linkid
-2 NULL 10 1 2 11
+2 NULL 10 1 2 12
SELECT * FROM graph WHERE latch = '2' AND destid = 11 and weight = 1;
latch origid destid weight seq linkid
-2 NULL 11 1 2 12
+2 NULL 11 1 2 10
SELECT * FROM graph WHERE latch = '2' AND destid = 12 and weight = 1;
latch origid destid weight seq linkid
-2 NULL 12 1 2 10
+2 NULL 12 1 2 11
SELECT * FROM graph WHERE latch = '2' AND destid = 1 and weight = 2;
latch origid destid weight seq linkid
2 NULL 1 2 4 4
@@ -930,22 +930,22 @@ SELECT * FROM graph WHERE latch = '2' AND destid = 5 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = '2' AND destid = 6 and weight = 2;
latch origid destid weight seq linkid
-2 NULL 6 2 3 7
SELECT * FROM graph WHERE latch = '2' AND destid = 7 and weight = 2;
latch origid destid weight seq linkid
+2 NULL 7 2 3 6
SELECT * FROM graph WHERE latch = '2' AND destid = 8 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = '2' AND destid = 9 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = '2' AND destid = 10 and weight = 2;
latch origid destid weight seq linkid
-2 NULL 10 2 3 12
+2 NULL 10 2 3 11
SELECT * FROM graph WHERE latch = '2' AND destid = 11 and weight = 2;
latch origid destid weight seq linkid
-2 NULL 11 2 3 10
+2 NULL 11 2 3 12
SELECT * FROM graph WHERE latch = '2' AND destid = 12 and weight = 2;
latch origid destid weight seq linkid
-2 NULL 12 2 3 11
+2 NULL 12 2 3 10
SELECT * FROM graph WHERE latch = '2' AND destid = 1 and weight = 3;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = '2' AND destid = 2 and weight = 3;
@@ -1124,16 +1124,16 @@ dijkstras NULL 4 1 2 3
dijkstras NULL 4 0 1 4
SELECT * FROM graph WHERE latch='dijkstras' AND destid=5;
latch origid destid weight seq linkid
-dijkstras NULL 5 1 3 7
dijkstras NULL 5 1 2 6
dijkstras NULL 5 0 1 5
SELECT * FROM graph WHERE latch='dijkstras' AND destid=6;
latch origid destid weight seq linkid
-dijkstras NULL 6 2 3 7
dijkstras NULL 6 1 2 5
dijkstras NULL 6 0 1 6
SELECT * FROM graph WHERE latch='dijkstras' AND destid=7;
latch origid destid weight seq linkid
+dijkstras NULL 7 2 3 6
+dijkstras NULL 7 1 2 5
dijkstras NULL 7 0 1 7
SELECT * FROM graph WHERE latch='dijkstras' AND destid=8;
latch origid destid weight seq linkid
@@ -1142,18 +1142,18 @@ latch origid destid weight seq linkid
dijkstras NULL 9 0 1 9
SELECT * FROM graph WHERE latch='dijkstras' AND destid=10;
latch origid destid weight seq linkid
-dijkstras NULL 10 2 3 12
-dijkstras NULL 10 1 2 11
+dijkstras NULL 10 2 3 11
+dijkstras NULL 10 1 2 12
dijkstras NULL 10 0 1 10
SELECT * FROM graph WHERE latch='dijkstras' AND destid=11;
latch origid destid weight seq linkid
-dijkstras NULL 11 2 3 10
-dijkstras NULL 11 1 2 12
+dijkstras NULL 11 2 3 12
+dijkstras NULL 11 1 2 10
dijkstras NULL 11 0 1 11
SELECT * FROM graph WHERE latch='dijkstras' AND destid=12;
latch origid destid weight seq linkid
-dijkstras NULL 12 2 3 11
-dijkstras NULL 12 1 2 10
+dijkstras NULL 12 2 3 10
+dijkstras NULL 12 1 2 11
dijkstras NULL 12 0 1 12
# legacy string number
SELECT * FROM graph WHERE latch='1' AND origid=1 AND destid=1;
@@ -1299,16 +1299,16 @@ latch origid destid weight seq linkid
1 NULL 4 0 1 4
SELECT * FROM graph WHERE latch='1' AND destid=5;
latch origid destid weight seq linkid
-1 NULL 5 1 3 7
1 NULL 5 1 2 6
1 NULL 5 0 1 5
SELECT * FROM graph WHERE latch='1' AND destid=6;
latch origid destid weight seq linkid
-1 NULL 6 2 3 7
1 NULL 6 1 2 5
1 NULL 6 0 1 6
SELECT * FROM graph WHERE latch='1' AND destid=7;
latch origid destid weight seq linkid
+1 NULL 7 2 3 6
+1 NULL 7 1 2 5
1 NULL 7 0 1 7
SELECT * FROM graph WHERE latch='1' AND destid=8;
latch origid destid weight seq linkid
@@ -1317,18 +1317,18 @@ latch origid destid weight seq linkid
1 NULL 9 0 1 9
SELECT * FROM graph WHERE latch='1' AND destid=10;
latch origid destid weight seq linkid
-1 NULL 10 2 3 12
-1 NULL 10 1 2 11
+1 NULL 10 2 3 11
+1 NULL 10 1 2 12
1 NULL 10 0 1 10
SELECT * FROM graph WHERE latch='1' AND destid=11;
latch origid destid weight seq linkid
-1 NULL 11 2 3 10
-1 NULL 11 1 2 12
+1 NULL 11 2 3 12
+1 NULL 11 1 2 10
1 NULL 11 0 1 11
SELECT * FROM graph WHERE latch='1' AND destid=12;
latch origid destid weight seq linkid
-1 NULL 12 2 3 11
-1 NULL 12 1 2 10
+1 NULL 12 2 3 10
+1 NULL 12 1 2 11
1 NULL 12 0 1 12
INSERT INTO graph_base(from_id, to_id) VALUES (11,13);
INSERT INTO graph_base(from_id, to_id) VALUES (10,14);
@@ -1395,9 +1395,6 @@ dijkstras 1 NULL 1 2 2
dijkstras 1 NULL 0 1 1
SELECT * FROM graph WHERE latch='dijkstras' AND destid=1;
latch origid destid weight seq linkid
-dijkstras NULL 1 4 7 18
-dijkstras NULL 1 3 6 17
-dijkstras NULL 1 3 5 16
dijkstras NULL 1 2 4 4
dijkstras NULL 1 1 3 3
dijkstras NULL 1 1 2 2
diff --git a/storage/oqgraph/mysql-test/oqgraph/general-MyISAM.result b/storage/oqgraph/mysql-test/oqgraph/general-MyISAM.result
index f12e160a2b7..bbf660e7db4 100644
--- a/storage/oqgraph/mysql-test/oqgraph/general-MyISAM.result
+++ b/storage/oqgraph/mysql-test/oqgraph/general-MyISAM.result
@@ -455,16 +455,16 @@ breadth_first NULL 4 1 2 3
breadth_first NULL 4 0 1 4
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 5;
latch origid destid weight seq linkid
-breadth_first NULL 5 1 3 7
breadth_first NULL 5 1 2 6
breadth_first NULL 5 0 1 5
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 6;
latch origid destid weight seq linkid
-breadth_first NULL 6 2 3 7
breadth_first NULL 6 1 2 5
breadth_first NULL 6 0 1 6
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 7;
latch origid destid weight seq linkid
+breadth_first NULL 7 2 3 6
+breadth_first NULL 7 1 2 5
breadth_first NULL 7 0 1 7
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 8;
latch origid destid weight seq linkid
@@ -473,18 +473,18 @@ latch origid destid weight seq linkid
breadth_first NULL 9 0 1 9
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 10;
latch origid destid weight seq linkid
-breadth_first NULL 10 2 3 12
-breadth_first NULL 10 1 2 11
+breadth_first NULL 10 2 3 11
+breadth_first NULL 10 1 2 12
breadth_first NULL 10 0 1 10
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 11;
latch origid destid weight seq linkid
-breadth_first NULL 11 2 3 10
-breadth_first NULL 11 1 2 12
+breadth_first NULL 11 2 3 12
+breadth_first NULL 11 1 2 10
breadth_first NULL 11 0 1 11
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 12;
latch origid destid weight seq linkid
-breadth_first NULL 12 2 3 11
-breadth_first NULL 12 1 2 10
+breadth_first NULL 12 2 3 10
+breadth_first NULL 12 1 2 11
breadth_first NULL 12 0 1 12
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 1 and weight = 1;
latch origid destid weight seq linkid
@@ -502,26 +502,26 @@ latch origid destid weight seq linkid
breadth_first NULL 4 1 2 3
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 5 and weight = 1;
latch origid destid weight seq linkid
-breadth_first NULL 5 1 3 7
breadth_first NULL 5 1 2 6
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 6 and weight = 1;
latch origid destid weight seq linkid
breadth_first NULL 6 1 2 5
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 7 and weight = 1;
latch origid destid weight seq linkid
+breadth_first NULL 7 1 2 5
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 8 and weight = 1;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 9 and weight = 1;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 10 and weight = 1;
latch origid destid weight seq linkid
-breadth_first NULL 10 1 2 11
+breadth_first NULL 10 1 2 12
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 11 and weight = 1;
latch origid destid weight seq linkid
-breadth_first NULL 11 1 2 12
+breadth_first NULL 11 1 2 10
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 12 and weight = 1;
latch origid destid weight seq linkid
-breadth_first NULL 12 1 2 10
+breadth_first NULL 12 1 2 11
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 1 and weight = 2;
latch origid destid weight seq linkid
breadth_first NULL 1 2 4 4
@@ -538,22 +538,22 @@ SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 5 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 6 and weight = 2;
latch origid destid weight seq linkid
-breadth_first NULL 6 2 3 7
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 7 and weight = 2;
latch origid destid weight seq linkid
+breadth_first NULL 7 2 3 6
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 8 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 9 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 10 and weight = 2;
latch origid destid weight seq linkid
-breadth_first NULL 10 2 3 12
+breadth_first NULL 10 2 3 11
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 11 and weight = 2;
latch origid destid weight seq linkid
-breadth_first NULL 11 2 3 10
+breadth_first NULL 11 2 3 12
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 12 and weight = 2;
latch origid destid weight seq linkid
-breadth_first NULL 12 2 3 11
+breadth_first NULL 12 2 3 10
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 1 and weight = 3;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 2 and weight = 3;
@@ -847,16 +847,16 @@ latch origid destid weight seq linkid
2 NULL 4 0 1 4
SELECT * FROM graph WHERE latch = '2' AND destid = 5;
latch origid destid weight seq linkid
-2 NULL 5 1 3 7
2 NULL 5 1 2 6
2 NULL 5 0 1 5
SELECT * FROM graph WHERE latch = '2' AND destid = 6;
latch origid destid weight seq linkid
-2 NULL 6 2 3 7
2 NULL 6 1 2 5
2 NULL 6 0 1 6
SELECT * FROM graph WHERE latch = '2' AND destid = 7;
latch origid destid weight seq linkid
+2 NULL 7 2 3 6
+2 NULL 7 1 2 5
2 NULL 7 0 1 7
SELECT * FROM graph WHERE latch = '2' AND destid = 8;
latch origid destid weight seq linkid
@@ -865,18 +865,18 @@ latch origid destid weight seq linkid
2 NULL 9 0 1 9
SELECT * FROM graph WHERE latch = '2' AND destid = 10;
latch origid destid weight seq linkid
-2 NULL 10 2 3 12
-2 NULL 10 1 2 11
+2 NULL 10 2 3 11
+2 NULL 10 1 2 12
2 NULL 10 0 1 10
SELECT * FROM graph WHERE latch = '2' AND destid = 11;
latch origid destid weight seq linkid
-2 NULL 11 2 3 10
-2 NULL 11 1 2 12
+2 NULL 11 2 3 12
+2 NULL 11 1 2 10
2 NULL 11 0 1 11
SELECT * FROM graph WHERE latch = '2' AND destid = 12;
latch origid destid weight seq linkid
-2 NULL 12 2 3 11
-2 NULL 12 1 2 10
+2 NULL 12 2 3 10
+2 NULL 12 1 2 11
2 NULL 12 0 1 12
SELECT * FROM graph WHERE latch = '2' AND destid = 1 and weight = 1;
latch origid destid weight seq linkid
@@ -894,26 +894,26 @@ latch origid destid weight seq linkid
2 NULL 4 1 2 3
SELECT * FROM graph WHERE latch = '2' AND destid = 5 and weight = 1;
latch origid destid weight seq linkid
-2 NULL 5 1 3 7
2 NULL 5 1 2 6
SELECT * FROM graph WHERE latch = '2' AND destid = 6 and weight = 1;
latch origid destid weight seq linkid
2 NULL 6 1 2 5
SELECT * FROM graph WHERE latch = '2' AND destid = 7 and weight = 1;
latch origid destid weight seq linkid
+2 NULL 7 1 2 5
SELECT * FROM graph WHERE latch = '2' AND destid = 8 and weight = 1;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = '2' AND destid = 9 and weight = 1;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = '2' AND destid = 10 and weight = 1;
latch origid destid weight seq linkid
-2 NULL 10 1 2 11
+2 NULL 10 1 2 12
SELECT * FROM graph WHERE latch = '2' AND destid = 11 and weight = 1;
latch origid destid weight seq linkid
-2 NULL 11 1 2 12
+2 NULL 11 1 2 10
SELECT * FROM graph WHERE latch = '2' AND destid = 12 and weight = 1;
latch origid destid weight seq linkid
-2 NULL 12 1 2 10
+2 NULL 12 1 2 11
SELECT * FROM graph WHERE latch = '2' AND destid = 1 and weight = 2;
latch origid destid weight seq linkid
2 NULL 1 2 4 4
@@ -930,22 +930,22 @@ SELECT * FROM graph WHERE latch = '2' AND destid = 5 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = '2' AND destid = 6 and weight = 2;
latch origid destid weight seq linkid
-2 NULL 6 2 3 7
SELECT * FROM graph WHERE latch = '2' AND destid = 7 and weight = 2;
latch origid destid weight seq linkid
+2 NULL 7 2 3 6
SELECT * FROM graph WHERE latch = '2' AND destid = 8 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = '2' AND destid = 9 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = '2' AND destid = 10 and weight = 2;
latch origid destid weight seq linkid
-2 NULL 10 2 3 12
+2 NULL 10 2 3 11
SELECT * FROM graph WHERE latch = '2' AND destid = 11 and weight = 2;
latch origid destid weight seq linkid
-2 NULL 11 2 3 10
+2 NULL 11 2 3 12
SELECT * FROM graph WHERE latch = '2' AND destid = 12 and weight = 2;
latch origid destid weight seq linkid
-2 NULL 12 2 3 11
+2 NULL 12 2 3 10
SELECT * FROM graph WHERE latch = '2' AND destid = 1 and weight = 3;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = '2' AND destid = 2 and weight = 3;
@@ -1124,16 +1124,16 @@ dijkstras NULL 4 1 2 3
dijkstras NULL 4 0 1 4
SELECT * FROM graph WHERE latch='dijkstras' AND destid=5;
latch origid destid weight seq linkid
-dijkstras NULL 5 1 3 7
dijkstras NULL 5 1 2 6
dijkstras NULL 5 0 1 5
SELECT * FROM graph WHERE latch='dijkstras' AND destid=6;
latch origid destid weight seq linkid
-dijkstras NULL 6 2 3 7
dijkstras NULL 6 1 2 5
dijkstras NULL 6 0 1 6
SELECT * FROM graph WHERE latch='dijkstras' AND destid=7;
latch origid destid weight seq linkid
+dijkstras NULL 7 2 3 6
+dijkstras NULL 7 1 2 5
dijkstras NULL 7 0 1 7
SELECT * FROM graph WHERE latch='dijkstras' AND destid=8;
latch origid destid weight seq linkid
@@ -1142,18 +1142,18 @@ latch origid destid weight seq linkid
dijkstras NULL 9 0 1 9
SELECT * FROM graph WHERE latch='dijkstras' AND destid=10;
latch origid destid weight seq linkid
-dijkstras NULL 10 2 3 12
-dijkstras NULL 10 1 2 11
+dijkstras NULL 10 2 3 11
+dijkstras NULL 10 1 2 12
dijkstras NULL 10 0 1 10
SELECT * FROM graph WHERE latch='dijkstras' AND destid=11;
latch origid destid weight seq linkid
-dijkstras NULL 11 2 3 10
-dijkstras NULL 11 1 2 12
+dijkstras NULL 11 2 3 12
+dijkstras NULL 11 1 2 10
dijkstras NULL 11 0 1 11
SELECT * FROM graph WHERE latch='dijkstras' AND destid=12;
latch origid destid weight seq linkid
-dijkstras NULL 12 2 3 11
-dijkstras NULL 12 1 2 10
+dijkstras NULL 12 2 3 10
+dijkstras NULL 12 1 2 11
dijkstras NULL 12 0 1 12
# legacy string number
SELECT * FROM graph WHERE latch='1' AND origid=1 AND destid=1;
@@ -1299,16 +1299,16 @@ latch origid destid weight seq linkid
1 NULL 4 0 1 4
SELECT * FROM graph WHERE latch='1' AND destid=5;
latch origid destid weight seq linkid
-1 NULL 5 1 3 7
1 NULL 5 1 2 6
1 NULL 5 0 1 5
SELECT * FROM graph WHERE latch='1' AND destid=6;
latch origid destid weight seq linkid
-1 NULL 6 2 3 7
1 NULL 6 1 2 5
1 NULL 6 0 1 6
SELECT * FROM graph WHERE latch='1' AND destid=7;
latch origid destid weight seq linkid
+1 NULL 7 2 3 6
+1 NULL 7 1 2 5
1 NULL 7 0 1 7
SELECT * FROM graph WHERE latch='1' AND destid=8;
latch origid destid weight seq linkid
@@ -1317,18 +1317,18 @@ latch origid destid weight seq linkid
1 NULL 9 0 1 9
SELECT * FROM graph WHERE latch='1' AND destid=10;
latch origid destid weight seq linkid
-1 NULL 10 2 3 12
-1 NULL 10 1 2 11
+1 NULL 10 2 3 11
+1 NULL 10 1 2 12
1 NULL 10 0 1 10
SELECT * FROM graph WHERE latch='1' AND destid=11;
latch origid destid weight seq linkid
-1 NULL 11 2 3 10
-1 NULL 11 1 2 12
+1 NULL 11 2 3 12
+1 NULL 11 1 2 10
1 NULL 11 0 1 11
SELECT * FROM graph WHERE latch='1' AND destid=12;
latch origid destid weight seq linkid
-1 NULL 12 2 3 11
-1 NULL 12 1 2 10
+1 NULL 12 2 3 10
+1 NULL 12 1 2 11
1 NULL 12 0 1 12
INSERT INTO graph_base(from_id, to_id) VALUES (11,13);
INSERT INTO graph_base(from_id, to_id) VALUES (10,14);
@@ -1395,9 +1395,6 @@ dijkstras 1 NULL 1 2 2
dijkstras 1 NULL 0 1 1
SELECT * FROM graph WHERE latch='dijkstras' AND destid=1;
latch origid destid weight seq linkid
-dijkstras NULL 1 4 7 18
-dijkstras NULL 1 3 6 17
-dijkstras NULL 1 3 5 16
dijkstras NULL 1 2 4 4
dijkstras NULL 1 1 3 3
dijkstras NULL 1 1 2 2
diff --git a/storage/oqgraph/mysql-test/oqgraph/general-innodb.result b/storage/oqgraph/mysql-test/oqgraph/general-innodb.result
index b390dd38e34..927d856bc84 100644
--- a/storage/oqgraph/mysql-test/oqgraph/general-innodb.result
+++ b/storage/oqgraph/mysql-test/oqgraph/general-innodb.result
@@ -455,16 +455,16 @@ breadth_first NULL 4 1 2 3
breadth_first NULL 4 0 1 4
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 5;
latch origid destid weight seq linkid
-breadth_first NULL 5 1 3 7
breadth_first NULL 5 1 2 6
breadth_first NULL 5 0 1 5
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 6;
latch origid destid weight seq linkid
-breadth_first NULL 6 2 3 7
breadth_first NULL 6 1 2 5
breadth_first NULL 6 0 1 6
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 7;
latch origid destid weight seq linkid
+breadth_first NULL 7 2 3 6
+breadth_first NULL 7 1 2 5
breadth_first NULL 7 0 1 7
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 8;
latch origid destid weight seq linkid
@@ -473,18 +473,18 @@ latch origid destid weight seq linkid
breadth_first NULL 9 0 1 9
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 10;
latch origid destid weight seq linkid
-breadth_first NULL 10 2 3 12
-breadth_first NULL 10 1 2 11
+breadth_first NULL 10 2 3 11
+breadth_first NULL 10 1 2 12
breadth_first NULL 10 0 1 10
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 11;
latch origid destid weight seq linkid
-breadth_first NULL 11 2 3 10
-breadth_first NULL 11 1 2 12
+breadth_first NULL 11 2 3 12
+breadth_first NULL 11 1 2 10
breadth_first NULL 11 0 1 11
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 12;
latch origid destid weight seq linkid
-breadth_first NULL 12 2 3 11
-breadth_first NULL 12 1 2 10
+breadth_first NULL 12 2 3 10
+breadth_first NULL 12 1 2 11
breadth_first NULL 12 0 1 12
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 1 and weight = 1;
latch origid destid weight seq linkid
@@ -502,26 +502,26 @@ latch origid destid weight seq linkid
breadth_first NULL 4 1 2 3
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 5 and weight = 1;
latch origid destid weight seq linkid
-breadth_first NULL 5 1 3 7
breadth_first NULL 5 1 2 6
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 6 and weight = 1;
latch origid destid weight seq linkid
breadth_first NULL 6 1 2 5
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 7 and weight = 1;
latch origid destid weight seq linkid
+breadth_first NULL 7 1 2 5
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 8 and weight = 1;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 9 and weight = 1;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 10 and weight = 1;
latch origid destid weight seq linkid
-breadth_first NULL 10 1 2 11
+breadth_first NULL 10 1 2 12
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 11 and weight = 1;
latch origid destid weight seq linkid
-breadth_first NULL 11 1 2 12
+breadth_first NULL 11 1 2 10
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 12 and weight = 1;
latch origid destid weight seq linkid
-breadth_first NULL 12 1 2 10
+breadth_first NULL 12 1 2 11
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 1 and weight = 2;
latch origid destid weight seq linkid
breadth_first NULL 1 2 4 4
@@ -538,22 +538,22 @@ SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 5 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 6 and weight = 2;
latch origid destid weight seq linkid
-breadth_first NULL 6 2 3 7
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 7 and weight = 2;
latch origid destid weight seq linkid
+breadth_first NULL 7 2 3 6
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 8 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 9 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 10 and weight = 2;
latch origid destid weight seq linkid
-breadth_first NULL 10 2 3 12
+breadth_first NULL 10 2 3 11
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 11 and weight = 2;
latch origid destid weight seq linkid
-breadth_first NULL 11 2 3 10
+breadth_first NULL 11 2 3 12
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 12 and weight = 2;
latch origid destid weight seq linkid
-breadth_first NULL 12 2 3 11
+breadth_first NULL 12 2 3 10
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 1 and weight = 3;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 2 and weight = 3;
@@ -847,16 +847,16 @@ latch origid destid weight seq linkid
2 NULL 4 0 1 4
SELECT * FROM graph WHERE latch = '2' AND destid = 5;
latch origid destid weight seq linkid
-2 NULL 5 1 3 7
2 NULL 5 1 2 6
2 NULL 5 0 1 5
SELECT * FROM graph WHERE latch = '2' AND destid = 6;
latch origid destid weight seq linkid
-2 NULL 6 2 3 7
2 NULL 6 1 2 5
2 NULL 6 0 1 6
SELECT * FROM graph WHERE latch = '2' AND destid = 7;
latch origid destid weight seq linkid
+2 NULL 7 2 3 6
+2 NULL 7 1 2 5
2 NULL 7 0 1 7
SELECT * FROM graph WHERE latch = '2' AND destid = 8;
latch origid destid weight seq linkid
@@ -865,18 +865,18 @@ latch origid destid weight seq linkid
2 NULL 9 0 1 9
SELECT * FROM graph WHERE latch = '2' AND destid = 10;
latch origid destid weight seq linkid
-2 NULL 10 2 3 12
-2 NULL 10 1 2 11
+2 NULL 10 2 3 11
+2 NULL 10 1 2 12
2 NULL 10 0 1 10
SELECT * FROM graph WHERE latch = '2' AND destid = 11;
latch origid destid weight seq linkid
-2 NULL 11 2 3 10
-2 NULL 11 1 2 12
+2 NULL 11 2 3 12
+2 NULL 11 1 2 10
2 NULL 11 0 1 11
SELECT * FROM graph WHERE latch = '2' AND destid = 12;
latch origid destid weight seq linkid
-2 NULL 12 2 3 11
-2 NULL 12 1 2 10
+2 NULL 12 2 3 10
+2 NULL 12 1 2 11
2 NULL 12 0 1 12
SELECT * FROM graph WHERE latch = '2' AND destid = 1 and weight = 1;
latch origid destid weight seq linkid
@@ -894,26 +894,26 @@ latch origid destid weight seq linkid
2 NULL 4 1 2 3
SELECT * FROM graph WHERE latch = '2' AND destid = 5 and weight = 1;
latch origid destid weight seq linkid
-2 NULL 5 1 3 7
2 NULL 5 1 2 6
SELECT * FROM graph WHERE latch = '2' AND destid = 6 and weight = 1;
latch origid destid weight seq linkid
2 NULL 6 1 2 5
SELECT * FROM graph WHERE latch = '2' AND destid = 7 and weight = 1;
latch origid destid weight seq linkid
+2 NULL 7 1 2 5
SELECT * FROM graph WHERE latch = '2' AND destid = 8 and weight = 1;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = '2' AND destid = 9 and weight = 1;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = '2' AND destid = 10 and weight = 1;
latch origid destid weight seq linkid
-2 NULL 10 1 2 11
+2 NULL 10 1 2 12
SELECT * FROM graph WHERE latch = '2' AND destid = 11 and weight = 1;
latch origid destid weight seq linkid
-2 NULL 11 1 2 12
+2 NULL 11 1 2 10
SELECT * FROM graph WHERE latch = '2' AND destid = 12 and weight = 1;
latch origid destid weight seq linkid
-2 NULL 12 1 2 10
+2 NULL 12 1 2 11
SELECT * FROM graph WHERE latch = '2' AND destid = 1 and weight = 2;
latch origid destid weight seq linkid
2 NULL 1 2 4 4
@@ -930,22 +930,22 @@ SELECT * FROM graph WHERE latch = '2' AND destid = 5 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = '2' AND destid = 6 and weight = 2;
latch origid destid weight seq linkid
-2 NULL 6 2 3 7
SELECT * FROM graph WHERE latch = '2' AND destid = 7 and weight = 2;
latch origid destid weight seq linkid
+2 NULL 7 2 3 6
SELECT * FROM graph WHERE latch = '2' AND destid = 8 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = '2' AND destid = 9 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = '2' AND destid = 10 and weight = 2;
latch origid destid weight seq linkid
-2 NULL 10 2 3 12
+2 NULL 10 2 3 11
SELECT * FROM graph WHERE latch = '2' AND destid = 11 and weight = 2;
latch origid destid weight seq linkid
-2 NULL 11 2 3 10
+2 NULL 11 2 3 12
SELECT * FROM graph WHERE latch = '2' AND destid = 12 and weight = 2;
latch origid destid weight seq linkid
-2 NULL 12 2 3 11
+2 NULL 12 2 3 10
SELECT * FROM graph WHERE latch = '2' AND destid = 1 and weight = 3;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = '2' AND destid = 2 and weight = 3;
@@ -1124,16 +1124,16 @@ dijkstras NULL 4 1 2 3
dijkstras NULL 4 0 1 4
SELECT * FROM graph WHERE latch='dijkstras' AND destid=5;
latch origid destid weight seq linkid
-dijkstras NULL 5 1 3 7
dijkstras NULL 5 1 2 6
dijkstras NULL 5 0 1 5
SELECT * FROM graph WHERE latch='dijkstras' AND destid=6;
latch origid destid weight seq linkid
-dijkstras NULL 6 2 3 7
dijkstras NULL 6 1 2 5
dijkstras NULL 6 0 1 6
SELECT * FROM graph WHERE latch='dijkstras' AND destid=7;
latch origid destid weight seq linkid
+dijkstras NULL 7 2 3 6
+dijkstras NULL 7 1 2 5
dijkstras NULL 7 0 1 7
SELECT * FROM graph WHERE latch='dijkstras' AND destid=8;
latch origid destid weight seq linkid
@@ -1142,18 +1142,18 @@ latch origid destid weight seq linkid
dijkstras NULL 9 0 1 9
SELECT * FROM graph WHERE latch='dijkstras' AND destid=10;
latch origid destid weight seq linkid
-dijkstras NULL 10 2 3 12
-dijkstras NULL 10 1 2 11
+dijkstras NULL 10 2 3 11
+dijkstras NULL 10 1 2 12
dijkstras NULL 10 0 1 10
SELECT * FROM graph WHERE latch='dijkstras' AND destid=11;
latch origid destid weight seq linkid
-dijkstras NULL 11 2 3 10
-dijkstras NULL 11 1 2 12
+dijkstras NULL 11 2 3 12
+dijkstras NULL 11 1 2 10
dijkstras NULL 11 0 1 11
SELECT * FROM graph WHERE latch='dijkstras' AND destid=12;
latch origid destid weight seq linkid
-dijkstras NULL 12 2 3 11
-dijkstras NULL 12 1 2 10
+dijkstras NULL 12 2 3 10
+dijkstras NULL 12 1 2 11
dijkstras NULL 12 0 1 12
# legacy string number
SELECT * FROM graph WHERE latch='1' AND origid=1 AND destid=1;
@@ -1299,16 +1299,16 @@ latch origid destid weight seq linkid
1 NULL 4 0 1 4
SELECT * FROM graph WHERE latch='1' AND destid=5;
latch origid destid weight seq linkid
-1 NULL 5 1 3 7
1 NULL 5 1 2 6
1 NULL 5 0 1 5
SELECT * FROM graph WHERE latch='1' AND destid=6;
latch origid destid weight seq linkid
-1 NULL 6 2 3 7
1 NULL 6 1 2 5
1 NULL 6 0 1 6
SELECT * FROM graph WHERE latch='1' AND destid=7;
latch origid destid weight seq linkid
+1 NULL 7 2 3 6
+1 NULL 7 1 2 5
1 NULL 7 0 1 7
SELECT * FROM graph WHERE latch='1' AND destid=8;
latch origid destid weight seq linkid
@@ -1317,18 +1317,18 @@ latch origid destid weight seq linkid
1 NULL 9 0 1 9
SELECT * FROM graph WHERE latch='1' AND destid=10;
latch origid destid weight seq linkid
-1 NULL 10 2 3 12
-1 NULL 10 1 2 11
+1 NULL 10 2 3 11
+1 NULL 10 1 2 12
1 NULL 10 0 1 10
SELECT * FROM graph WHERE latch='1' AND destid=11;
latch origid destid weight seq linkid
-1 NULL 11 2 3 10
-1 NULL 11 1 2 12
+1 NULL 11 2 3 12
+1 NULL 11 1 2 10
1 NULL 11 0 1 11
SELECT * FROM graph WHERE latch='1' AND destid=12;
latch origid destid weight seq linkid
-1 NULL 12 2 3 11
-1 NULL 12 1 2 10
+1 NULL 12 2 3 10
+1 NULL 12 1 2 11
1 NULL 12 0 1 12
INSERT INTO graph_base(from_id, to_id) VALUES (11,13);
INSERT INTO graph_base(from_id, to_id) VALUES (10,14);
@@ -1395,9 +1395,6 @@ dijkstras 1 NULL 1 2 2
dijkstras 1 NULL 0 1 1
SELECT * FROM graph WHERE latch='dijkstras' AND destid=1;
latch origid destid weight seq linkid
-dijkstras NULL 1 4 7 18
-dijkstras NULL 1 3 6 17
-dijkstras NULL 1 3 5 16
dijkstras NULL 1 2 4 4
dijkstras NULL 1 1 3 3
dijkstras NULL 1 1 2 2
diff --git a/storage/oqgraph/mysql-test/oqgraph/regression_1196036.result b/storage/oqgraph/mysql-test/oqgraph/regression_1196036.result
index 45bbccfa87e..c372a0c088f 100644
--- a/storage/oqgraph/mysql-test/oqgraph/regression_1196036.result
+++ b/storage/oqgraph/mysql-test/oqgraph/regression_1196036.result
@@ -41,19 +41,19 @@ dijkstras 3 NULL 256 2 2
dijkstras 3 NULL 0 1 3
SELECT * FROM graph WHERE latch = 'dijkstras' AND destid = 1;
latch origid destid weight seq linkid
-dijkstras NULL 1 784 4 4
+dijkstras NULL 1 65808 4 4
dijkstras NULL 1 272 3 3
dijkstras NULL 1 16 2 2
dijkstras NULL 1 0 1 1
SELECT * FROM graph WHERE latch = 'dijkstras' AND destid = 2;
latch origid destid weight seq linkid
-dijkstras NULL 2 768 4 4
+dijkstras NULL 2 65792 4 4
dijkstras NULL 2 256 3 3
dijkstras NULL 2 16 2 1
dijkstras NULL 2 0 1 2
SELECT * FROM graph WHERE latch = 'dijkstras' AND destid = 3;
latch origid destid weight seq linkid
-dijkstras NULL 3 1024 4 4
+dijkstras NULL 3 65536 4 4
dijkstras NULL 3 272 3 1
dijkstras NULL 3 256 2 2
dijkstras NULL 3 0 1 3
diff --git a/storage/oqgraph/mysql-test/oqgraph/regression_1213120.result b/storage/oqgraph/mysql-test/oqgraph/regression_1213120.result
index b6cd53ab673..642c0aa3b5d 100644
--- a/storage/oqgraph/mysql-test/oqgraph/regression_1213120.result
+++ b/storage/oqgraph/mysql-test/oqgraph/regression_1213120.result
@@ -464,16 +464,16 @@ breadth_first NULL 4 1 2 3
breadth_first NULL 4 0 1 4
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 5;
latch origid destid weight seq linkid
-breadth_first NULL 5 1 3 7
breadth_first NULL 5 1 2 6
breadth_first NULL 5 0 1 5
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 6;
latch origid destid weight seq linkid
-breadth_first NULL 6 2 3 7
breadth_first NULL 6 1 2 5
breadth_first NULL 6 0 1 6
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 7;
latch origid destid weight seq linkid
+breadth_first NULL 7 2 3 6
+breadth_first NULL 7 1 2 5
breadth_first NULL 7 0 1 7
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 8;
latch origid destid weight seq linkid
@@ -482,18 +482,18 @@ latch origid destid weight seq linkid
breadth_first NULL 9 0 1 9
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 10;
latch origid destid weight seq linkid
-breadth_first NULL 10 2 3 12
-breadth_first NULL 10 1 2 11
+breadth_first NULL 10 2 3 11
+breadth_first NULL 10 1 2 12
breadth_first NULL 10 0 1 10
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 11;
latch origid destid weight seq linkid
-breadth_first NULL 11 2 3 10
-breadth_first NULL 11 1 2 12
+breadth_first NULL 11 2 3 12
+breadth_first NULL 11 1 2 10
breadth_first NULL 11 0 1 11
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 12;
latch origid destid weight seq linkid
-breadth_first NULL 12 2 3 11
-breadth_first NULL 12 1 2 10
+breadth_first NULL 12 2 3 10
+breadth_first NULL 12 1 2 11
breadth_first NULL 12 0 1 12
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 1 and weight = 1;
latch origid destid weight seq linkid
@@ -511,26 +511,26 @@ latch origid destid weight seq linkid
breadth_first NULL 4 1 2 3
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 5 and weight = 1;
latch origid destid weight seq linkid
-breadth_first NULL 5 1 3 7
breadth_first NULL 5 1 2 6
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 6 and weight = 1;
latch origid destid weight seq linkid
breadth_first NULL 6 1 2 5
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 7 and weight = 1;
latch origid destid weight seq linkid
+breadth_first NULL 7 1 2 5
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 8 and weight = 1;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 9 and weight = 1;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 10 and weight = 1;
latch origid destid weight seq linkid
-breadth_first NULL 10 1 2 11
+breadth_first NULL 10 1 2 12
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 11 and weight = 1;
latch origid destid weight seq linkid
-breadth_first NULL 11 1 2 12
+breadth_first NULL 11 1 2 10
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 12 and weight = 1;
latch origid destid weight seq linkid
-breadth_first NULL 12 1 2 10
+breadth_first NULL 12 1 2 11
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 1 and weight = 2;
latch origid destid weight seq linkid
breadth_first NULL 1 2 4 4
@@ -547,22 +547,22 @@ SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 5 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 6 and weight = 2;
latch origid destid weight seq linkid
-breadth_first NULL 6 2 3 7
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 7 and weight = 2;
latch origid destid weight seq linkid
+breadth_first NULL 7 2 3 6
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 8 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 9 and weight = 2;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 10 and weight = 2;
latch origid destid weight seq linkid
-breadth_first NULL 10 2 3 12
+breadth_first NULL 10 2 3 11
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 11 and weight = 2;
latch origid destid weight seq linkid
-breadth_first NULL 11 2 3 10
+breadth_first NULL 11 2 3 12
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 12 and weight = 2;
latch origid destid weight seq linkid
-breadth_first NULL 12 2 3 11
+breadth_first NULL 12 2 3 10
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 1 and weight = 3;
latch origid destid weight seq linkid
SELECT * FROM graph WHERE latch = 'breadth_first' AND destid = 2 and weight = 3;
@@ -838,8 +838,8 @@ latch origid destid weight seq linkid
2 NULL 1 0 1 1
SELECT * FROM graph WHERE latch = '2' AND destid = 12;
latch origid destid weight seq linkid
-2 NULL 12 2 3 11
-2 NULL 12 1 2 10
+2 NULL 12 2 3 10
+2 NULL 12 1 2 11
2 NULL 12 0 1 12
SELECT * FROM graph WHERE latch = '2' AND destid = 1 and weight = 1;
latch origid destid weight seq linkid
@@ -997,16 +997,16 @@ dijkstras NULL 4 1 2 3
dijkstras NULL 4 0 1 4
SELECT * FROM graph WHERE latch='dijkstras' AND destid=5;
latch origid destid weight seq linkid
-dijkstras NULL 5 1 3 7
dijkstras NULL 5 1 2 6
dijkstras NULL 5 0 1 5
SELECT * FROM graph WHERE latch='dijkstras' AND destid=6;
latch origid destid weight seq linkid
-dijkstras NULL 6 2 3 7
dijkstras NULL 6 1 2 5
dijkstras NULL 6 0 1 6
SELECT * FROM graph WHERE latch='dijkstras' AND destid=7;
latch origid destid weight seq linkid
+dijkstras NULL 7 2 3 6
+dijkstras NULL 7 1 2 5
dijkstras NULL 7 0 1 7
SELECT * FROM graph WHERE latch='dijkstras' AND destid=8;
latch origid destid weight seq linkid
@@ -1015,18 +1015,18 @@ latch origid destid weight seq linkid
dijkstras NULL 9 0 1 9
SELECT * FROM graph WHERE latch='dijkstras' AND destid=10;
latch origid destid weight seq linkid
-dijkstras NULL 10 2 3 12
-dijkstras NULL 10 1 2 11
+dijkstras NULL 10 2 3 11
+dijkstras NULL 10 1 2 12
dijkstras NULL 10 0 1 10
SELECT * FROM graph WHERE latch='dijkstras' AND destid=11;
latch origid destid weight seq linkid
-dijkstras NULL 11 2 3 10
-dijkstras NULL 11 1 2 12
+dijkstras NULL 11 2 3 12
+dijkstras NULL 11 1 2 10
dijkstras NULL 11 0 1 11
SELECT * FROM graph WHERE latch='dijkstras' AND destid=12;
latch origid destid weight seq linkid
-dijkstras NULL 12 2 3 11
-dijkstras NULL 12 1 2 10
+dijkstras NULL 12 2 3 10
+dijkstras NULL 12 1 2 11
dijkstras NULL 12 0 1 12
# legacy string number
SELECT * FROM graph WHERE latch='1' AND origid=1 AND destid=1;
@@ -1172,16 +1172,16 @@ latch origid destid weight seq linkid
1 NULL 4 0 1 4
SELECT * FROM graph WHERE latch='1' AND destid=5;
latch origid destid weight seq linkid
-1 NULL 5 1 3 7
1 NULL 5 1 2 6
1 NULL 5 0 1 5
SELECT * FROM graph WHERE latch='1' AND destid=6;
latch origid destid weight seq linkid
-1 NULL 6 2 3 7
1 NULL 6 1 2 5
1 NULL 6 0 1 6
SELECT * FROM graph WHERE latch='1' AND destid=7;
latch origid destid weight seq linkid
+1 NULL 7 2 3 6
+1 NULL 7 1 2 5
1 NULL 7 0 1 7
SELECT * FROM graph WHERE latch='1' AND destid=8;
latch origid destid weight seq linkid
@@ -1190,18 +1190,18 @@ latch origid destid weight seq linkid
1 NULL 9 0 1 9
SELECT * FROM graph WHERE latch='1' AND destid=10;
latch origid destid weight seq linkid
-1 NULL 10 2 3 12
-1 NULL 10 1 2 11
+1 NULL 10 2 3 11
+1 NULL 10 1 2 12
1 NULL 10 0 1 10
SELECT * FROM graph WHERE latch='1' AND destid=11;
latch origid destid weight seq linkid
-1 NULL 11 2 3 10
-1 NULL 11 1 2 12
+1 NULL 11 2 3 12
+1 NULL 11 1 2 10
1 NULL 11 0 1 11
SELECT * FROM graph WHERE latch='1' AND destid=12;
latch origid destid weight seq linkid
-1 NULL 12 2 3 11
-1 NULL 12 1 2 10
+1 NULL 12 2 3 10
+1 NULL 12 1 2 11
1 NULL 12 0 1 12
SELECT count(*) FROM graph;
count(*)
@@ -1280,9 +1280,6 @@ dijkstras 1 NULL 1 2 2
dijkstras 1 NULL 0 1 1
SELECT * FROM graph WHERE latch='dijkstras' AND destid=1;
latch origid destid weight seq linkid
-dijkstras NULL 1 4 7 18
-dijkstras NULL 1 3 6 17
-dijkstras NULL 1 3 5 16
dijkstras NULL 1 2 4 4
dijkstras NULL 1 1 3 3
dijkstras NULL 1 1 2 2
diff --git a/storage/oqgraph/oqgraph_shim.h b/storage/oqgraph/oqgraph_shim.h
index c0a9dbb2b40..f24732af4ef 100644
--- a/storage/oqgraph/oqgraph_shim.h
+++ b/storage/oqgraph/oqgraph_shim.h
@@ -154,12 +154,12 @@ namespace oqgraph3
typedef std::input_iterator_tag iterator_category;
in_edge_iterator() { }
in_edge_iterator(const cursor_ptr& cursor) : _cursor(cursor) { }
- value_type operator*() { return value_type(_cursor); }
+ value_type operator*() const { return value_type(_cursor); }
self& operator++() { _cursor->seek_next(); return *this; }
self operator++(int)
{ cursor_ptr t(new cursor(*_cursor)); ++(*this); return in_edge_iterator(t); }
- bool operator==(const self& x) { return _cursor == x._cursor; }
- bool operator!=(const self& x) { return _cursor != x._cursor; }
+ bool operator==(const self& x) const { return _cursor == x._cursor; }
+ bool operator!=(const self& x) const { return _cursor != x._cursor; }
cursor_ptr _cursor;
};
diff --git a/storage/perfschema/pfs.cc b/storage/perfschema/pfs.cc
index c30ff4b6640..1a3f066bd00 100644
--- a/storage/perfschema/pfs.cc
+++ b/storage/perfschema/pfs.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -41,6 +41,7 @@
#include "sp_head.h"
#include "pfs_digest.h"
+using std::min;
/**
@page PAGE_PERFORMANCE_SCHEMA The Performance Schema main page
MySQL PERFORMANCE_SCHEMA implementation.
@@ -2018,7 +2019,8 @@ static void set_thread_account_v1(const char *user, int user_len,
DBUG_ASSERT((uint) user_len <= sizeof(pfs->m_username));
DBUG_ASSERT((host != NULL) || (host_len == 0));
DBUG_ASSERT(host_len >= 0);
- DBUG_ASSERT((uint) host_len <= sizeof(pfs->m_hostname));
+
+ host_len= min<size_t>(host_len, sizeof(pfs->m_hostname));
if (unlikely(pfs == NULL))
return;
diff --git a/storage/sphinx/ha_sphinx.cc b/storage/sphinx/ha_sphinx.cc
index 650bc93cf67..5308f780e0e 100644
--- a/storage/sphinx/ha_sphinx.cc
+++ b/storage/sphinx/ha_sphinx.cc
@@ -1712,13 +1712,16 @@ bool CSphSEQuery::ParseField ( char * sField )
char * sLat = sValue;
char * p = sValue;
- if (!( p = strchr ( p, ',' ) )) break; *p++ = '\0';
+ if (!( p = strchr ( p, ',' ) )) break;
+ *p++ = '\0';
char * sLong = p;
- if (!( p = strchr ( p, ',' ) )) break; *p++ = '\0';
+ if (!( p = strchr ( p, ',' ) )) break;
+ *p++ = '\0';
char * sLatVal = p;
- if (!( p = strchr ( p, ',' ) )) break; *p++ = '\0';
+ if (!( p = strchr ( p, ',' ) )) break;
+ *p++ = '\0';
char * sLongVal = p;
m_sGeoLatAttr = chop(sLat);
@@ -1787,7 +1790,8 @@ bool CSphSEQuery::ParseField ( char * sField )
while ( sRest )
{
char * sId = sRest;
- if (!( sRest = strchr ( sRest, ':' ) )) break; *sRest++ = '\0';
+ if (!( sRest = strchr ( sRest, ':' ) )) break;
+ *sRest++ = '\0';
if (!( sRest - sId )) break;
char * sValue = sRest;
diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc
index 294fe92323c..d94c34d6772 100644
--- a/storage/spider/spd_db_conn.cc
+++ b/storage/spider/spd_db_conn.cc
@@ -4130,8 +4130,10 @@ void spider_db_discard_multiple_result(
if (!conn->db_conn->cmp_request_key_to_snd(&request_key))
break;
if ((result = conn->db_conn->use_result(&request_key, &error_num)))
+ {
result->free_result();
delete result;
+ }
} while (!conn->db_conn->next_result());
DBUG_VOID_RETURN;
}
diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt
index ee757977800..7ea98728034 100644
--- a/storage/tokudb/CMakeLists.txt
+++ b/storage/tokudb/CMakeLists.txt
@@ -1,14 +1,22 @@
-SET(TOKUDB_VERSION 5.6.36-82.1)
+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(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()
@@ -34,6 +42,7 @@ IF(NOT LIBJEMALLOC)
ENDIF()
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-vla" DEBUG)
+MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-implicit-fallthrough")
############################################
SET(TOKUDB_DEB_FILES "usr/lib/mysql/plugin/ha_tokudb.so\netc/mysql/conf.d/tokudb.cnf\nusr/bin/tokuftdump" PARENT_SCOPE)
diff --git a/storage/tokudb/PerconaFT/CMakeLists.txt b/storage/tokudb/PerconaFT/CMakeLists.txt
index d42525f1089..3973ec71b52 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 6f0b7c5f419..95d6207edda 100644
--- a/storage/tokudb/PerconaFT/buildheader/make_tdb.cc
+++ b/storage/tokudb/PerconaFT/buildheader/make_tdb.cc
@@ -231,6 +231,8 @@ static void print_defines (void) {
printf("#define DB_SET_RANGE_REVERSE 252\n"); // private tokudb
//printf("#define DB_GET_BOTH_RANGE_REVERSE 251\n"); // private tokudb. No longer supported #2862.
dodefine(DB_RMW);
+
+ printf("#define DB_LOCKING_READ 0x80000000\n");
printf("#define DB_IS_RESETTING_OP 0x01000000\n"); // private tokudb
printf("#define DB_PRELOCKED 0x00800000\n"); // private tokudb
printf("#define DB_PRELOCKED_WRITE 0x00400000\n"); // private tokudb
@@ -443,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 31aab932fd6..ae2bb2846e8 100644
--- a/storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc
+++ b/storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc
@@ -57,6 +57,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
//
@@ -779,18 +798,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;
@@ -3229,16 +3255,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);
}
}
@@ -3578,9 +3614,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);
}
//
@@ -3629,11 +3665,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;
@@ -3641,11 +3680,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;
}
@@ -4702,7 +4742,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 3223ab0a4ce..13ff5eff5af 100644
--- a/storage/tokudb/PerconaFT/ft/cachetable/checkpoint.cc
+++ b/storage/tokudb/PerconaFT/ft/cachetable/checkpoint.cc
@@ -86,8 +86,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;
@@ -116,11 +124,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;
}
@@ -145,10 +156,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 07e244947e4..60885ed9f33 100644
--- a/storage/tokudb/PerconaFT/ft/ft-ops.cc
+++ b/storage/tokudb/PerconaFT/ft/ft-ops.cc
@@ -186,9 +186,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;
@@ -2643,11 +2669,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);
}
}
@@ -2721,7 +2750,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
@@ -2933,6 +2962,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) {
@@ -2944,7 +2975,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);
@@ -4614,20 +4644,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;
@@ -4641,7 +4916,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 700e532d5cf..454bf11794f 100644
--- a/storage/tokudb/PerconaFT/ft/ft.cc
+++ b/storage/tokudb/PerconaFT/ft/ft.cc
@@ -50,9 +50,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
@@ -100,15 +101,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 28d8d49ba9f..9ff712bcbae 100644
--- a/storage/tokudb/PerconaFT/ft/loader/dbufio.cc
+++ b/storage/tokudb/PerconaFT/ft/loader/dbufio.cc
@@ -48,6 +48,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;
@@ -275,39 +279,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);
{
@@ -338,14 +347,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);
@@ -376,34 +387,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);
@@ -430,13 +443,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 528c86a8f79..9528af95627 100644
--- a/storage/tokudb/PerconaFT/ft/loader/loader.cc
+++ b/storage/tokudb/PerconaFT/ft/loader/loader.cc
@@ -62,21 +62,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;
@@ -98,7 +94,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;
}
@@ -130,7 +126,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) {
@@ -149,9 +148,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;
@@ -195,11 +194,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) {
@@ -229,11 +227,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;
@@ -306,20 +305,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);
@@ -338,7 +337,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.
@@ -634,12 +633,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);
}
@@ -658,17 +661,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);
@@ -719,31 +722,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;
@@ -766,29 +761,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);
@@ -799,8 +793,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.
@@ -809,24 +804,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;
@@ -836,8 +821,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;
@@ -891,13 +875,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.
@@ -915,8 +906,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.
@@ -1086,7 +1078,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;
@@ -1107,14 +1099,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;
@@ -1625,11 +1617,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) {
@@ -1726,14 +1719,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.
@@ -1746,9 +1755,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];
@@ -1942,12 +1952,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;
@@ -2177,7 +2193,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;
}
@@ -2417,7 +2433,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)
@@ -2704,21 +2720,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]);
@@ -2729,10 +2759,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;
@@ -2752,24 +2786,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;
@@ -3106,7 +3143,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++) {
@@ -3158,8 +3195,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;
}
@@ -3274,8 +3312,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;
@@ -3295,7 +3336,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 f13419ae43e..494d3b1d531 100644
--- a/storage/tokudb/PerconaFT/ft/logger/logcursor.cc
+++ b/storage/tokudb/PerconaFT/ft/logger/logcursor.cc
@@ -85,10 +85,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 eacec9cb83f..3f13fe10feb 100644
--- a/storage/tokudb/PerconaFT/ft/logger/logger.cc
+++ b/storage/tokudb/PerconaFT/ft/logger/logger.cc
@@ -49,11 +49,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);
@@ -131,10 +137,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);
@@ -300,10 +309,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);
@@ -345,9 +354,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);
}
@@ -677,18 +690,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();
}
}
@@ -834,10 +857,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
@@ -1237,11 +1261,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
@@ -1258,10 +1284,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 d2532134d96..56d51f56915 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/block_table.cc
+++ b/storage/tokudb/PerconaFT/ft/serialize/block_table.cc
@@ -54,6 +54,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};
@@ -99,8 +104,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
@@ -128,7 +135,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 88eca36a261..384a960b1f3 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_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 28ea8014f53..1096467a35d 100644
--- a/storage/tokudb/PerconaFT/portability/toku_portability.h
+++ b/storage/tokudb/PerconaFT/portability/toku_portability.h
@@ -125,6 +125,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
@@ -240,28 +267,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));
@@ -271,9 +542,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);
@@ -283,28 +556,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/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-internal.h b/storage/tokudb/PerconaFT/src/ydb-internal.h
index a1eb43a67c5..db2041095f7 100644
--- a/storage/tokudb/PerconaFT/src/ydb-internal.h
+++ b/storage/tokudb/PerconaFT/src/ydb-internal.h
@@ -239,13 +239,16 @@ struct __toku_dbc_internal {
struct simple_dbt skey_s,sval_s;
struct simple_dbt *skey,*sval;
- // if the rmw flag is asserted, cursor operations (like set) grab write locks instead of read locks
+ // if the rmw flag is asserted, cursor operations (like set) grab write
+ // locks instead of read locks
// the rmw flag is set when the cursor is created with the DB_RMW flag set
bool rmw;
+ bool locking_read;
};
-static_assert(sizeof(__toku_dbc_internal) <= sizeof(((DBC *) nullptr)->_internal),
- "__toku_dbc_internal doesn't fit in the internal portion of a DBC");
+static_assert(
+ sizeof(__toku_dbc_internal) <= sizeof(((DBC *)nullptr)->_internal),
+ "__toku_dbc_internal doesn't fit in the internal portion of a DBC");
static inline __toku_dbc_internal *dbc_struct_i(DBC *c) {
union dbc_union {
diff --git a/storage/tokudb/PerconaFT/src/ydb.cc b/storage/tokudb/PerconaFT/src/ydb.cc
index 1edfe9c81f9..41f48d4ec09 100644
--- a/storage/tokudb/PerconaFT/src/ydb.cc
+++ b/storage/tokudb/PerconaFT/src/ydb.cc
@@ -227,7 +227,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));
@@ -643,7 +643,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 {
@@ -668,7 +668,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
@@ -710,7 +710,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
@@ -856,10 +856,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;
@@ -875,13 +876,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;
@@ -2931,7 +2941,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_cursor.cc b/storage/tokudb/PerconaFT/src/ydb_cursor.cc
index 015e302f1c6..1f4f00b7423 100644
--- a/storage/tokudb/PerconaFT/src/ydb_cursor.cc
+++ b/storage/tokudb/PerconaFT/src/ydb_cursor.cc
@@ -110,12 +110,14 @@ c_get_wrapper_callback(DBT const *key, DBT const *val, void *extra) {
return r;
}
-static inline uint32_t
-get_cursor_prelocked_flags(uint32_t flags, DBC* dbc) {
+static inline uint32_t get_cursor_prelocked_flags(uint32_t flags, DBC *dbc) {
uint32_t lock_flags = flags & (DB_PRELOCKED | DB_PRELOCKED_WRITE);
- //DB_READ_UNCOMMITTED and DB_READ_COMMITTED transactions 'own' all read locks for user-data dictionaries.
- if (dbc_struct_i(dbc)->iso != TOKU_ISO_SERIALIZABLE) {
+ // DB_READ_UNCOMMITTED and DB_READ_COMMITTED transactions 'own' all read
+ // locks for user-data dictionaries.
+ if (dbc_struct_i(dbc)->iso != TOKU_ISO_SERIALIZABLE &&
+ !(dbc_struct_i(dbc)->iso == TOKU_ISO_SNAPSHOT &&
+ dbc_struct_i(dbc)->locking_read)) {
lock_flags |= DB_PRELOCKED;
}
return lock_flags;
@@ -671,37 +673,44 @@ int toku_c_close(DBC *c) {
return 0;
}
-static int
-c_set_bounds(DBC *dbc, const DBT *left_key, const DBT *right_key, bool pre_acquire, int out_of_range_error) {
+static int c_set_bounds(DBC *dbc,
+ const DBT *left_key,
+ const DBT *right_key,
+ bool pre_acquire,
+ int out_of_range_error) {
if (out_of_range_error != DB_NOTFOUND &&
- out_of_range_error != TOKUDB_OUT_OF_RANGE &&
- out_of_range_error != 0) {
- return toku_ydb_do_error(
- dbc->dbp->dbenv,
- EINVAL,
- "Invalid out_of_range_error [%d] for %s\n",
- out_of_range_error,
- __FUNCTION__
- );
- }
- if (left_key == toku_dbt_negative_infinity() && right_key == toku_dbt_positive_infinity()) {
+ out_of_range_error != TOKUDB_OUT_OF_RANGE && out_of_range_error != 0) {
+ return toku_ydb_do_error(dbc->dbp->dbenv,
+ EINVAL,
+ "Invalid out_of_range_error [%d] for %s\n",
+ out_of_range_error,
+ __FUNCTION__);
+ }
+ if (left_key == toku_dbt_negative_infinity() &&
+ right_key == toku_dbt_positive_infinity()) {
out_of_range_error = 0;
}
DB *db = dbc->dbp;
DB_TXN *txn = dbc_struct_i(dbc)->txn;
HANDLE_PANICKED_DB(db);
- toku_ft_cursor_set_range_lock(dbc_ftcursor(dbc), left_key, right_key,
- (left_key == toku_dbt_negative_infinity()),
- (right_key == toku_dbt_positive_infinity()),
- out_of_range_error);
+ toku_ft_cursor_set_range_lock(dbc_ftcursor(dbc),
+ left_key,
+ right_key,
+ (left_key == toku_dbt_negative_infinity()),
+ (right_key == toku_dbt_positive_infinity()),
+ out_of_range_error);
if (!db->i->lt || !txn || !pre_acquire)
return 0;
- //READ_UNCOMMITTED and READ_COMMITTED transactions do not need read locks.
- if (!dbc_struct_i(dbc)->rmw && dbc_struct_i(dbc)->iso != TOKU_ISO_SERIALIZABLE)
+ // READ_UNCOMMITTED and READ_COMMITTED transactions do not need read locks.
+ if (!dbc_struct_i(dbc)->rmw &&
+ dbc_struct_i(dbc)->iso != TOKU_ISO_SERIALIZABLE &&
+ !(dbc_struct_i(dbc)->iso == TOKU_ISO_SNAPSHOT &&
+ dbc_struct_i(dbc)->locking_read))
return 0;
- toku::lock_request::type lock_type = dbc_struct_i(dbc)->rmw ?
- toku::lock_request::type::WRITE : toku::lock_request::type::READ;
+ toku::lock_request::type lock_type = dbc_struct_i(dbc)->rmw
+ ? toku::lock_request::type::WRITE
+ : toku::lock_request::type::READ;
int r = toku_db_get_range_lock(db, txn, left_key, right_key, lock_type);
return r;
}
@@ -783,18 +792,20 @@ toku_c_get(DBC* c, DBT* key, DBT* val, uint32_t flag) {
return r;
}
-int
-toku_db_cursor_internal(DB * db, DB_TXN * txn, DBC *c, uint32_t flags, int is_temporary_cursor) {
+int toku_db_cursor_internal(DB *db,
+ DB_TXN *txn,
+ DBC *c,
+ uint32_t flags,
+ int is_temporary_cursor) {
HANDLE_PANICKED_DB(db);
HANDLE_DB_ILLEGAL_WORKING_PARENT_TXN(db, txn);
- DB_ENV* env = db->dbenv;
+ DB_ENV *env = db->dbenv;
- if (flags & ~(DB_SERIALIZABLE | DB_INHERIT_ISOLATION | DB_RMW | DBC_DISABLE_PREFETCHING)) {
+ if (flags &
+ ~(DB_SERIALIZABLE | DB_INHERIT_ISOLATION | DB_LOCKING_READ | DB_RMW |
+ DBC_DISABLE_PREFETCHING)) {
return toku_ydb_do_error(
- env,
- EINVAL,
- "Invalid flags set for toku_db_cursor\n"
- );
+ env, EINVAL, "Invalid flags set for toku_db_cursor\n");
}
#define SCRS(name) c->name = name
@@ -819,8 +830,8 @@ toku_db_cursor_internal(DB * db, DB_TXN * txn, DBC *c, uint32_t flags, int is_te
c->dbp = db;
dbc_struct_i(c)->txn = txn;
- dbc_struct_i(c)->skey_s = (struct simple_dbt){0,0};
- dbc_struct_i(c)->sval_s = (struct simple_dbt){0,0};
+ dbc_struct_i(c)->skey_s = (struct simple_dbt){0, 0};
+ dbc_struct_i(c)->sval_s = (struct simple_dbt){0, 0};
if (is_temporary_cursor) {
dbc_struct_i(c)->skey = &db->i->skey;
dbc_struct_i(c)->sval = &db->i->sval;
@@ -831,28 +842,27 @@ toku_db_cursor_internal(DB * db, DB_TXN * txn, DBC *c, uint32_t flags, int is_te
if (flags & DB_SERIALIZABLE) {
dbc_struct_i(c)->iso = TOKU_ISO_SERIALIZABLE;
} else {
- dbc_struct_i(c)->iso = txn ? db_txn_struct_i(txn)->iso : TOKU_ISO_SERIALIZABLE;
+ dbc_struct_i(c)->iso =
+ txn ? db_txn_struct_i(txn)->iso : TOKU_ISO_SERIALIZABLE;
}
dbc_struct_i(c)->rmw = (flags & DB_RMW) != 0;
- enum cursor_read_type read_type = C_READ_ANY; // default, used in serializable and read uncommitted
+ dbc_struct_i(c)->locking_read = (flags & DB_LOCKING_READ) != 0;
+ enum cursor_read_type read_type =
+ C_READ_ANY; // default, used in serializable and read uncommitted
if (txn) {
if (dbc_struct_i(c)->iso == TOKU_ISO_READ_COMMITTED ||
- dbc_struct_i(c)->iso == TOKU_ISO_SNAPSHOT)
- {
+ dbc_struct_i(c)->iso == TOKU_ISO_SNAPSHOT) {
read_type = C_READ_SNAPSHOT;
- }
- else if (dbc_struct_i(c)->iso == TOKU_ISO_READ_COMMITTED_ALWAYS) {
+ } else if (dbc_struct_i(c)->iso == TOKU_ISO_READ_COMMITTED_ALWAYS) {
read_type = C_READ_COMMITTED;
}
}
- int r = toku_ft_cursor_create(
- db->i->ft_handle,
- dbc_ftcursor(c),
- txn ? db_txn_struct_i(txn)->tokutxn : NULL,
- read_type,
- ((flags & DBC_DISABLE_PREFETCHING) != 0),
- is_temporary_cursor != 0
- );
+ int r = toku_ft_cursor_create(db->i->ft_handle,
+ dbc_ftcursor(c),
+ txn ? db_txn_struct_i(txn)->tokutxn : NULL,
+ read_type,
+ ((flags & DBC_DISABLE_PREFETCHING) != 0),
+ is_temporary_cursor != 0);
if (r != 0) {
invariant(r == TOKUDB_MVCC_DICTIONARY_TOO_NEW);
}
diff --git a/storage/tokudb/PerconaFT/src/ydb_db.cc b/storage/tokudb/PerconaFT/src/ydb_db.cc
index 100d1bfa20b..40c4a7f6577 100644
--- a/storage/tokudb/PerconaFT/src/ydb_db.cc
+++ b/storage/tokudb/PerconaFT/src/ydb_db.cc
@@ -83,53 +83,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
@@ -187,10 +190,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));
@@ -1221,15 +1221,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 13c56fec6bf..b8f0a634116 100644
--- a/storage/tokudb/PerconaFT/src/ydb_env_func.cc
+++ b/storage/tokudb/PerconaFT/src/ydb_env_func.cc
@@ -109,7 +109,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/third_party/snappy-1.1.2/CMakeLists.txt b/storage/tokudb/PerconaFT/third_party/snappy-1.1.2/CMakeLists.txt
index f9d93917627..c241f7918ee 100644
--- a/storage/tokudb/PerconaFT/third_party/snappy-1.1.2/CMakeLists.txt
+++ b/storage/tokudb/PerconaFT/third_party/snappy-1.1.2/CMakeLists.txt
@@ -1,3 +1,4 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8.9)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
set(snappy_srcs
diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/configure b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/configure
index 9dc3178ba75..f0a417e0d29 100755
--- a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/configure
+++ b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/configure
@@ -19870,98 +19870,6 @@ if test -n "$CFLAG_VISIBILITY" && test "$is_w32" = no; then
AM_CFLAGS="$AM_CFLAGS $CFLAG_VISIBILITY"
fi
-if test "$GCC" = yes ; then
- # Enable as much warnings as possible. These commented warnings won't
- # work for this package though:
- # * -Wunreachable-code breaks several assert(0) cases, which are
- # backed up with "return LZMA_PROG_ERROR".
- # * -Wcast-qual would break various things where we need a non-const
- # pointer although we don't modify anything through it.
- # * -Wcast-align breaks optimized CRC32 and CRC64 implementation
- # on some architectures (not on x86), where this warning is bogus,
- # because we take care of correct alignment.
- # * -Winline, -Wdisabled-optimization, -Wunsafe-loop-optimizations
- # don't seem so useful here; at least the last one gives some
- # warnings which are not bugs.
- for NEW_FLAG in \
- -Wall \
- -Wextra \
- -Wformat=2 \
- -Winit-self \
- -Wmissing-include-dirs \
- -Wstrict-aliasing \
- -Wfloat-equal \
- -Wundef \
- -Wshadow \
- -Wpointer-arith \
- -Wbad-function-cast \
- -Wwrite-strings \
- -Wlogical-op \
- -Waggregate-return \
- -Wstrict-prototypes \
- -Wold-style-definition \
- -Wmissing-prototypes \
- -Wmissing-declarations \
- -Wmissing-noreturn \
- -Wredundant-decls
- do
- { $as_echo "$as_me:$LINENO: checking if $CC accepts $NEW_FLAG" >&5
-$as_echo_n "checking if $CC accepts $NEW_FLAG... " >&6; }
- OLD_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $NEW_FLAG"
- cat >conftest.$ac_ext <<_ACEOF
-void foo(void) { }
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
-$as_echo "$ac_try_echo") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
-
- AM_CFLAGS="$AM_CFLAGS $NEW_FLAG"
- { $as_echo "$as_me:$LINENO: result: yes" >&5
-$as_echo "yes" >&6; }
-
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
- { $as_echo "$as_me:$LINENO: result: no" >&5
-$as_echo "no" >&6; }
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- CFLAGS="$OLD_CFLAGS"
- done
-
- # Check whether --enable-werror was given.
-if test "${enable_werror+set}" = set; then
- enableval=$enable_werror;
-else
- enable_werror=no
-fi
-
- if test "x$enable_werror" = "xyes"; then
- AM_CFLAGS="$AM_CFLAGS -Werror"
- fi
-fi
-
-
###############################################################################
# Create the makefiles and config.h
###############################################################################
diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/configure.ac b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/configure.ac
index d125a6936da..fbc59b230c9 100644
--- a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/configure.ac
+++ b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/configure.ac
@@ -569,63 +569,6 @@ if test -n "$CFLAG_VISIBILITY" && test "$is_w32" = no; then
AM_CFLAGS="$AM_CFLAGS $CFLAG_VISIBILITY"
fi
-if test "$GCC" = yes ; then
- # Enable as much warnings as possible. These commented warnings won't
- # work for this package though:
- # * -Wunreachable-code breaks several assert(0) cases, which are
- # backed up with "return LZMA_PROG_ERROR".
- # * -Wcast-qual would break various things where we need a non-const
- # pointer although we don't modify anything through it.
- # * -Wcast-align breaks optimized CRC32 and CRC64 implementation
- # on some architectures (not on x86), where this warning is bogus,
- # because we take care of correct alignment.
- # * -Winline, -Wdisabled-optimization, -Wunsafe-loop-optimizations
- # don't seem so useful here; at least the last one gives some
- # warnings which are not bugs.
- for NEW_FLAG in \
- -Wall \
- -Wextra \
- -Wformat=2 \
- -Winit-self \
- -Wmissing-include-dirs \
- -Wstrict-aliasing \
- -Wfloat-equal \
- -Wundef \
- -Wshadow \
- -Wpointer-arith \
- -Wbad-function-cast \
- -Wwrite-strings \
- -Wlogical-op \
- -Waggregate-return \
- -Wstrict-prototypes \
- -Wold-style-definition \
- -Wmissing-prototypes \
- -Wmissing-declarations \
- -Wmissing-noreturn \
- -Wredundant-decls
- do
- AC_MSG_CHECKING([if $CC accepts $NEW_FLAG])
- OLD_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $NEW_FLAG"
- AC_COMPILE_IFELSE([void foo(void) { }], [
- AM_CFLAGS="$AM_CFLAGS $NEW_FLAG"
- AC_MSG_RESULT([yes])
- ], [
- AC_MSG_RESULT([no])
- ])
- CFLAGS="$OLD_CFLAGS"
- done
-
- AC_ARG_ENABLE([werror],
- AC_HELP_STRING([--enable-werror], [Enable -Werror to abort
- compilation on all compiler warnings.]),
- [], [enable_werror=no])
- if test "x$enable_werror" = "xyes"; then
- AM_CFLAGS="$AM_CFLAGS -Werror"
- fi
-fi
-
-
###############################################################################
# Create the makefiles and config.h
###############################################################################
diff --git a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/m4/libtool.m4 b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/m4/libtool.m4
index 39ba996cb96..faec0c309e8 100644
--- a/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/m4/libtool.m4
+++ b/storage/tokudb/PerconaFT/third_party/xz-4.999.9beta/m4/libtool.m4
@@ -1021,7 +1021,7 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
# to the aix ld manual.
m4_defun([_LT_SYS_MODULE_PATH_AIX],
[m4_require([_LT_DECL_SED])dnl
-AC_LINK_IFELSE(AC_LANG_PROGRAM,[
+AC_LINK_IFELSE([AC_LANG_PROGRAM],[
lt_aix_libpath_sed='
/Import File Strings/,/^$/ {
/^0/ {
@@ -4826,9 +4826,9 @@ _LT_EOF
# implicitly export all symbols.
save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
- AC_LINK_IFELSE(int foo(void) {},
+ AC_LINK_IFELSE([AC_LANG_SOURCE([int foo(void) {}]),
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
- )
+ ])
LDFLAGS="$save_LDFLAGS"
else
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
diff --git a/storage/tokudb/PerconaFT/tools/CMakeLists.txt b/storage/tokudb/PerconaFT/tools/CMakeLists.txt
index e6540bf69be..af40a838b9a 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} mysqlclient)
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 e6626e5e145..cdd4adb0947 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) &&
@@ -4030,14 +4024,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;
}
}
@@ -4208,7 +4201,7 @@ int ha_tokudb::update_row(const uchar * old_row, 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;
@@ -4350,7 +4343,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;
@@ -4641,6 +4634,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))) {
@@ -6212,6 +6208,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);
}
@@ -6295,7 +6293,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) {
@@ -6651,8 +6649,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();
@@ -7225,10 +7224,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);
@@ -7644,7 +7661,13 @@ static bool tokudb_check_db_dir_exist_from_table_name(const char *table_name) {
memcpy(db_name, db_name_begin, db_name_size);
db_name[db_name_size] = '\0';
- mysql_dir_exists = (check_db_dir_existence(db_name) == 0);
+
+ // At this point, db_name contains the MySQL formatted database name.
+ // This is exactly the same format that would come into us through a
+ // CREATE TABLE. Some charaters (like ':' for example) might be expanded
+ // into hex (':' would papear as "@003a").
+ // We need to check that the MySQL destination database directory exists.
+ mysql_dir_exists = (my_access(db_name, F_OK) == 0);
return mysql_dir_exists;
}
@@ -8106,8 +8129,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
@@ -8217,7 +8240,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) {
@@ -8451,7 +8474,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();
}
@@ -8500,10 +8523,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 3891e57738b..a2fd747bb92 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 23de81f3d8a..9fe5e729ec4 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 13bc60e9d98..88ba83ea0ab 100644
--- a/storage/tokudb/hatoku_cmp.cc
+++ b/storage/tokudb/hatoku_cmp.cc
@@ -1984,6 +1984,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 1b33e0a53e4..360272969e5 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 7b44044bd81..ac0976fb119 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_row_log_tokudb.result b/storage/tokudb/mysql-test/rpl/r/rpl_row_log_tokudb.result
deleted file mode 100644
index 8cbbda48c1f..00000000000
--- a/storage/tokudb/mysql-test/rpl/r/rpl_row_log_tokudb.result
+++ /dev/null
@@ -1,293 +0,0 @@
-include/master-slave.inc
-[connection master]
-include/stop_slave.inc
-include/wait_for_slave_to_stop.inc
-reset master;
-reset slave;
-start slave;
-include/wait_for_slave_to_start.inc
-set @save_slave_ddl_exec_mode=@@global.slave_ddl_exec_mode;
-set @@global.slave_ddl_exec_mode=STRICT;
-create table t1(n int not null auto_increment primary key)ENGINE=TokuDB;
-insert into t1 values (NULL);
-drop table t1;
-create table t1 (word char(20) not null)ENGINE=TokuDB;
-load data infile 'LOAD_FILE' into table t1 ignore 1 lines;
-select count(*) from t1;
-count(*)
-69
-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 table t1(n int not null auto_increment primary key)ENGINE=TokuDB
-master-bin.000001 # Gtid # # BEGIN GTID #-#-#
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
-master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; create table t1 (word char(20) not null)ENGINE=TokuDB
-master-bin.000001 # Gtid # # BEGIN GTID #-#-#
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
-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 table t1(n int not null auto_increment primary key)ENGINE=TokuDB
-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 table t1(n int not null auto_increment primary key)ENGINE=TokuDB
-master-bin.000001 # Gtid # # BEGIN GTID #-#-#
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Gtid # # BEGIN GTID #-#-#
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
-flush logs;
-create table t3 (a int)ENGINE=TokuDB;
-select * from t1 order by 1 asc;
-word
-Aarhus
-Aaron
-Aaron
-Ababa
-Ababa
-aback
-aback
-abaft
-abaft
-abandon
-abandon
-abandoned
-abandoned
-abandoning
-abandoning
-abandonment
-abandonment
-abandons
-abandons
-abase
-abased
-abasement
-abasements
-abases
-abash
-abashed
-abashes
-abashing
-abasing
-abate
-abated
-abatement
-abatements
-abater
-abates
-abating
-Abba
-abbe
-abbey
-abbeys
-abbot
-abbots
-Abbott
-abbreviate
-abbreviated
-abbreviates
-abbreviating
-abbreviation
-abbreviations
-Abby
-abdomen
-abdomens
-abdominal
-abduct
-abducted
-abduction
-abductions
-abductor
-abductors
-abducts
-Abe
-abed
-Abel
-Abelian
-Abelson
-Aberdeen
-Abernathy
-aberrant
-aberration
-select * from t1 order by 1 asc;
-word
-Aarhus
-Aaron
-Aaron
-Ababa
-Ababa
-aback
-aback
-abaft
-abaft
-abandon
-abandon
-abandoned
-abandoned
-abandoning
-abandoning
-abandonment
-abandonment
-abandons
-abandons
-abase
-abased
-abasement
-abasements
-abases
-abash
-abashed
-abashes
-abashing
-abasing
-abate
-abated
-abatement
-abatements
-abater
-abates
-abating
-Abba
-abbe
-abbey
-abbeys
-abbot
-abbots
-Abbott
-abbreviate
-abbreviated
-abbreviates
-abbreviating
-abbreviation
-abbreviations
-Abby
-abdomen
-abdomens
-abdominal
-abduct
-abducted
-abduction
-abductions
-abductor
-abductors
-abducts
-Abe
-abed
-Abel
-Abelian
-Abelson
-Aberdeen
-Abernathy
-aberrant
-aberration
-flush logs;
-include/stop_slave.inc
-include/start_slave.inc
-create table t2 (n int)ENGINE=TokuDB;
-insert into t2 values (1);
-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 table t1(n int not null auto_increment primary key)ENGINE=TokuDB
-master-bin.000001 # Gtid # # BEGIN GTID #-#-#
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
-master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; create table t1 (word char(20) not null)ENGINE=TokuDB
-master-bin.000001 # Gtid # # BEGIN GTID #-#-#
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-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 #-#-#
-master-bin.000002 # Query # # use `test`; create table t2 (n int)ENGINE=TokuDB
-master-bin.000002 # Gtid # # BEGIN GTID #-#-#
-master-bin.000002 # Table_map # # table_id: # (test.t2)
-master-bin.000002 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-master-bin.000002 # Xid # # COMMIT /* XID */
-show binary logs;
-Log_name File_size
-master-bin.000001 #
-master-bin.000002 #
-show binary logs;
-Log_name File_size
-slave-bin.000001 #
-slave-bin.000002 #
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-slave-bin.000001 # Gtid # # GTID #-#-#
-slave-bin.000001 # Query # # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=TokuDB
-slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
-slave-bin.000001 # Table_map # # table_id: # (test.t1)
-slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-slave-bin.000001 # Xid # # COMMIT /* XID */
-slave-bin.000001 # Gtid # # GTID #-#-#
-slave-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
-slave-bin.000001 # Gtid # # GTID #-#-#
-slave-bin.000001 # Query # # use `test`; create table t1 (word char(20) not null)ENGINE=TokuDB
-slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
-slave-bin.000001 # Table_map # # table_id: # (test.t1)
-slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-slave-bin.000001 # Xid # # COMMIT /* XID */
-slave-bin.000001 # Gtid # # GTID #-#-#
-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 #-#-#
-slave-bin.000002 # Table_map # # table_id: # (test.t2)
-slave-bin.000002 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-slave-bin.000002 # Xid # # COMMIT /* XID */
-include/check_slave_is_running.inc
-show binlog events in 'slave-bin.000005' from 4;
-ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log
-DROP TABLE t1;
-DROP TABLE t2;
-DROP TABLE t3;
-include/rpl_reset.inc
-create table t1(a int auto_increment primary key, b int);
-insert into t1 values (NULL, 1);
-set insert_id=5;
-insert into t1 values (NULL, last_insert_id()), (NULL, last_insert_id());
-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 table t1(a int auto_increment primary key, b int)
-master-bin.000001 # Gtid # # BEGIN GTID #-#-#
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # COMMIT
-master-bin.000001 # Gtid # # BEGIN GTID #-#-#
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # COMMIT
-select * from t1;
-a b
-1 1
-5 1
-6 1
-drop table t1;
-set @@global.slave_ddl_exec_mode=@save_slave_ddl_exec_mode;
-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 8cbbda48c1f..f283b3adf80 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
@@ -215,7 +215,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 #-#-#
@@ -253,7 +252,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 42defbe07b5..0334000f12e 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
@@ -215,7 +215,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 #-#-#
@@ -252,7 +251,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/t/rpl_row_log_tokudb-master.opt b/storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb-master.opt
deleted file mode 100644
index 773ec62bef2..00000000000
--- a/storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb-master.opt
+++ /dev/null
@@ -1,2 +0,0 @@
---skip-external-locking
---default-storage-engine=MyISAM
diff --git a/storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb.test b/storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb.test
deleted file mode 100644
index 826eb5eab86..00000000000
--- a/storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb.test
+++ /dev/null
@@ -1,14 +0,0 @@
-###################################
-# Wrapper for rpl_row_log.test #
-# Added wrapper so that MyISAM & #
-# Innodb and NDB could all use the#
-# Same test. NDB produced a diff #
-# bin-log #
-###################################
--- source include/have_binlog_format_row.inc
--- source include/have_tokudb.inc
--- source include/master-slave.inc
-let $engine_type=TokuDB;
--- source extra/rpl_tests/rpl_log.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..7f354cd8ba6 100644
--- a/storage/tokudb/mysql-test/tokudb/disabled.def
+++ b/storage/tokudb/mysql-test/tokudb/disabled.def
@@ -29,3 +29,4 @@ 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
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/dir_per_db.result b/storage/tokudb/mysql-test/tokudb/r/dir_per_db.result
index 371f97406c8..30d4e4244fd 100644
--- a/storage/tokudb/mysql-test/tokudb/r/dir_per_db.result
+++ b/storage/tokudb/mysql-test/tokudb/r/dir_per_db.result
@@ -1,3 +1,4 @@
+SET @orig_tokudb_dir_per_db=@@global.tokudb_dir_per_db;
########
# tokudb_dir_per_db = 1
########
@@ -177,4 +178,11 @@ t1_status_id.tokudb
DROP TABLE t2;
## Looking for *.tokudb files in data_dir
## Looking for *.tokudb files in data_dir/test
-SET GLOBAL tokudb_dir_per_db=default;
+CREATE DATABASE `a::a@@`;
+CREATE TABLE `a::a@@`.`t1` (a INT) ENGINE=TOKUDB;
+CREATE DATABASE `!@#$%^&*()`;
+ALTER TABLE `a::a@@`.`t1` RENAME `!@#$%^&*()`.`t1`;
+DROP TABLE `!@#$%^&*()`.`t1`;
+DROP DATABASE `!@#$%^&*()`;
+DROP DATABASE `a::a@@`;
+SET GLOBAL tokudb_dir_per_db=@orig_tokudb_dir_per_db;
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..c9fcb5e2273
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-1.result
@@ -0,0 +1,13 @@
+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
+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
+commit;
+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..f1b214e514c
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-2.result
@@ -0,0 +1,17 @@
+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
+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
+commit;
+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/type_blob.result b/storage/tokudb/mysql-test/tokudb/r/type_blob.result
index b48524db7f8..9aa6fef163c 100644
--- a/storage/tokudb/mysql-test/tokudb/r/type_blob.result
+++ b/storage/tokudb/mysql-test/tokudb/r/type_blob.result
@@ -38,7 +38,7 @@ ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT
CREATE TABLE t2 (a char(256));
ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT instead
CREATE TABLE t1 (a varchar(70000) default "hello");
-ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead
+ERROR 42000: Column length too big for column 'a' (max = 65532); use BLOB or TEXT instead
CREATE TABLE t2 (a blob default "hello");
ERROR 42000: BLOB/TEXT column 'a' can't have a default value
drop table if exists t1,t2;
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/dir_per_db.test b/storage/tokudb/mysql-test/tokudb/t/dir_per_db.test
index b638b706d87..64745cb049c 100644
--- a/storage/tokudb/mysql-test/tokudb/t/dir_per_db.test
+++ b/storage/tokudb/mysql-test/tokudb/t/dir_per_db.test
@@ -1,5 +1,7 @@
source include/have_tokudb.inc;
+SET @orig_tokudb_dir_per_db=@@global.tokudb_dir_per_db;
+
--let $DB= test
--let $DATADIR= `select @@datadir`
--let $i= 2
@@ -73,4 +75,17 @@ while ($i) {
--source dir_per_db_show_table_files.inc
}
-SET GLOBAL tokudb_dir_per_db=default;
+
+# test case for TDB-72 : Can not rename table in database with non alphanum
+# characters in its name.
+CREATE DATABASE `a::a@@`;
+CREATE TABLE `a::a@@`.`t1` (a INT) ENGINE=TOKUDB;
+CREATE DATABASE `!@#$%^&*()`;
+ALTER TABLE `a::a@@`.`t1` RENAME `!@#$%^&*()`.`t1`;
+
+DROP TABLE `!@#$%^&*()`.`t1`;
+DROP DATABASE `!@#$%^&*()`;
+DROP DATABASE `a::a@@`;
+
+# cleanup
+SET GLOBAL tokudb_dir_per_db=@orig_tokudb_dir_per_db;
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_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_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 dcb1fd6ec63..dec58f3fd35 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 = 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 = pthread_mutex_destroy(&_mutex);
+#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 = 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 = 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 = pthread_rwlock_init(&_rwlock, NULL);
+inline rwlock_t::rwlock_t(pfs_key_t key) {
+ int r MY_ATTRIBUTE((unused)) = mysql_rwlock_init(key, &_rwlock);
assert_debug(r == 0);
}
inline rwlock_t::~rwlock_t(void) {
- int r = pthread_rwlock_destroy(&_rwlock);
- assert_debug(r == 0);
-}
-inline void rwlock_t::lock_read(void) {
- int r;
- while ((r = pthread_rwlock_rdlock(&_rwlock)) != 0) {
- if (r == EBUSY || r == EAGAIN) {
- time::sleep_microsec(1000);
- continue;
- }
- break;
- }
- assert_debug(r == 0);
-}
-inline int rwlock_t::lock_read(ulonglong microseconds) {
- int r;
- timespec waittime = time::offset_timespec(microseconds);
- while ((r = pthread_rwlock_timedrdlock(&_rwlock, &waittime)) != 0) {
- if (r == EBUSY || r == EAGAIN) {
- time::sleep_microsec(1000);
- continue;
- } else if (r == ETIMEDOUT) {
- return ETIMEDOUT;
- }
- break;
- }
+ 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 = 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 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt
index f66a142ecd8..67d068748d2 100644
--- a/storage/xtradb/CMakeLists.txt
+++ b/storage/xtradb/CMakeLists.txt
@@ -93,6 +93,12 @@ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DUNIV_DEBUG -DUNIV_SYNC_DEB
CHECK_FUNCTION_EXISTS(sched_getcpu HAVE_SCHED_GETCPU)
IF(NOT MSVC)
+
+ CHECK_FUNCTION_EXISTS(posix_memalign HAVE_POSIX_MEMALIGN)
+ IF(HAVE_POSIX_MEMALIGN)
+ ADD_DEFINITIONS(-DHAVE_POSIX_MEMALIGN)
+ ENDIF()
+
# either define HAVE_IB_GCC_ATOMIC_BUILTINS or not
# workaround for old gcc on x86, gcc atomic ops only work under -march=i686
IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "i686" AND CMAKE_COMPILER_IS_GNUCC AND
diff --git a/storage/xtradb/api/api0api.cc b/storage/xtradb/api/api0api.cc
index bc83e98374f..55ed555ed48 100644
--- a/storage/xtradb/api/api0api.cc
+++ b/storage/xtradb/api/api0api.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2008, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2008, 2017, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -398,7 +398,7 @@ ib_read_tuple(
data = btr_rec_copy_externally_stored_field(
copy, offsets, zip_size, i, &len,
- tuple->heap, NULL);
+ tuple->heap);
ut_a(len != UNIV_SQL_NULL);
}
@@ -1988,6 +1988,7 @@ ib_cursor_read_row(
page_format = static_cast<ib_bool_t>(
dict_table_is_comp(tuple->index->table));
+
rec = btr_pcur_get_rec(pcur);
if (prebuilt->innodb_api_rec &&
@@ -2029,6 +2030,7 @@ ib_cursor_position(
buf = static_cast<unsigned char*>(mem_alloc(UNIV_PAGE_SIZE));
+
/* We want to position at one of the ends, row_search_for_mysql()
uses the search_tuple fields to work out what to do. */
dtuple_set_n_fields(prebuilt->search_tuple, 0);
diff --git a/storage/xtradb/btr/btr0btr.cc b/storage/xtradb/btr/btr0btr.cc
index 85a083aaee0..dca8542633f 100644
--- a/storage/xtradb/btr/btr0btr.cc
+++ b/storage/xtradb/btr/btr0btr.cc
@@ -77,10 +77,9 @@ btr_corruption_report(
index->name, index->table_name);
if (block->page.zip.data) {
buf_page_print(block->page.zip.data,
- buf_block_get_zip_size(block),
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_block_get_zip_size(block));
}
- buf_page_print(buf_nonnull_block_get_frame(block), 0, 0);
+ buf_page_print(buf_nonnull_block_get_frame(block), 0);
}
#ifndef UNIV_HOTBACKUP
@@ -1601,11 +1600,9 @@ btr_page_get_father_node_ptr_func(
if (btr_node_ptr_get_child_page_no(node_ptr, offsets) != page_no) {
rec_t* print_rec;
fputs("InnoDB: Dump of the child page:\n", stderr);
- buf_page_print(page_align(user_rec), 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page_align(user_rec), 0);
fputs("InnoDB: Dump of the parent page:\n", stderr);
- buf_page_print(page_align(node_ptr), 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page_align(node_ptr), 0);
fputs("InnoDB: Corruption of an index tree: table ", stderr);
ut_print_name(stderr, NULL, TRUE, index->table_name);
@@ -2080,8 +2077,8 @@ btr_page_reorganize_low(
max_ins_size2 = page_get_max_insert_size_after_reorganize(page, 1);
if (data_size1 != data_size2 || max_ins_size1 != max_ins_size2) {
- buf_page_print(page, 0, BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(temp_page, 0, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page, 0);
+ buf_page_print(temp_page, 0);
fprintf(stderr,
"InnoDB: Error: page old data size %lu"
@@ -2089,7 +2086,7 @@ btr_page_reorganize_low(
"InnoDB: Error: page old max ins size %lu"
" new max ins size %lu\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n",
+ " to https://jira.mariadb.org/\n",
(unsigned long) data_size1, (unsigned long) data_size2,
(unsigned long) max_ins_size1,
(unsigned long) max_ins_size2);
@@ -4609,7 +4606,7 @@ btr_index_rec_validate(
(ulong) rec_get_n_fields_old(rec), (ulong) n);
if (dump_on_error) {
- buf_page_print(page, 0, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page, 0);
fputs("InnoDB: corrupt record ", stderr);
rec_print_old(stderr, rec);
@@ -4647,8 +4644,7 @@ btr_index_rec_validate(
(ulong) i, (ulong) len, (ulong) fixed_size);
if (dump_on_error) {
- buf_page_print(page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page, 0);
fputs("InnoDB: corrupt record ", stderr);
rec_print_new(stderr, rec, offsets);
@@ -4925,8 +4921,8 @@ loop:
btr_validate_report2(index, level, block, right_block);
fputs("InnoDB: broken FIL_PAGE_NEXT"
" or FIL_PAGE_PREV links\n", stderr);
- buf_page_print(page, 0, BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(right_page, 0, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page, 0);
+ buf_page_print(right_page, 0);
ret = false;
}
@@ -4934,8 +4930,8 @@ loop:
if (page_is_comp(right_page) != page_is_comp(page)) {
btr_validate_report2(index, level, block, right_block);
fputs("InnoDB: 'compact' flag mismatch\n", stderr);
- buf_page_print(page, 0, BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(right_page, 0, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page, 0);
+ buf_page_print(right_page, 0);
ret = false;
@@ -4957,8 +4953,8 @@ loop:
fputs("InnoDB: records in wrong order"
" on adjacent pages\n", stderr);
- buf_page_print(page, 0, BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(right_page, 0, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page, 0);
+ buf_page_print(right_page, 0);
fputs("InnoDB: record ", stderr);
rec = page_rec_get_prev(page_get_supremum_rec(page));
@@ -5006,8 +5002,8 @@ loop:
fputs("InnoDB: node pointer to the page is wrong\n",
stderr);
- buf_page_print(father_page, 0, BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(page, 0, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(father_page, 0);
+ buf_page_print(page, 0);
fputs("InnoDB: node ptr ", stderr);
rec_print(stderr, node_ptr, index);
@@ -5039,10 +5035,8 @@ loop:
btr_validate_report1(index, level, block);
- buf_page_print(father_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(father_page, 0);
+ buf_page_print(page, 0);
fputs("InnoDB: Error: node ptrs differ"
" on levels > 0\n"
@@ -5087,15 +5081,9 @@ loop:
btr_validate_report1(index, level,
block);
- buf_page_print(
- father_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(
- page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(
- right_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(father_page, 0);
+ buf_page_print(page, 0);
+ buf_page_print(right_page, 0);
}
} else {
page_t* right_father_page
@@ -5113,18 +5101,10 @@ loop:
btr_validate_report1(index, level,
block);
- buf_page_print(
- father_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(
- right_father_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(
- page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(
- right_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(father_page, 0);
+ buf_page_print(right_father_page, 0);
+ buf_page_print(page, 0);
+ buf_page_print(right_page, 0);
}
if (page_get_page_no(right_father_page)
@@ -5138,18 +5118,10 @@ loop:
btr_validate_report1(index, level,
block);
- buf_page_print(
- father_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(
- right_father_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(
- page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(
- right_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(father_page, 0);
+ buf_page_print(right_father_page, 0);
+ buf_page_print(page, 0);
+ buf_page_print(right_page, 0);
}
}
}
diff --git a/storage/xtradb/btr/btr0cur.cc b/storage/xtradb/btr/btr0cur.cc
index 1a27fd0d6ea..e29d9091f8e 100644
--- a/storage/xtradb/btr/btr0cur.cc
+++ b/storage/xtradb/btr/btr0cur.cc
@@ -3624,7 +3624,6 @@ btr_cur_pessimistic_delete(
ulint n_reserved = 0;
ibool success;
ibool ret = FALSE;
- ulint level;
mem_heap_t* heap;
ulint* offsets;
@@ -3677,6 +3676,10 @@ btr_cur_pessimistic_delete(
#endif /* UNIV_ZIP_DEBUG */
}
+ if (flags == 0) {
+ lock_update_delete(block, rec);
+ }
+
if (UNIV_UNLIKELY(page_get_n_recs(page) < 2)
&& UNIV_UNLIKELY(dict_index_get_page(index)
!= buf_block_get_page_no(block))) {
@@ -3691,13 +3694,7 @@ btr_cur_pessimistic_delete(
goto return_after_reservations;
}
- if (flags == 0) {
- lock_update_delete(block, rec);
- }
-
- level = btr_page_get_level(page, mtr);
-
- if (level > 0
+ if (!page_is_leaf(page)
&& UNIV_UNLIKELY(rec == page_rec_get_next(
page_get_infimum_rec(page)))) {
@@ -3720,6 +3717,7 @@ btr_cur_pessimistic_delete(
on a page, we have to change the father node pointer
so that it is equal to the new leftmost node pointer
on the page */
+ ulint level = btr_page_get_level(page, mtr);
btr_node_ptr_delete(index, block, mtr);
@@ -3993,7 +3991,6 @@ static const ib_int64_t rows_in_range_arbitrary_ret_val = 10;
@param[in] mode1 search mode for range start
@param[in] tuple2 range end, may also be empty tuple
@param[in] mode2 search mode for range end
-@param[in] trx trx
@param[in] nth_attempt if the tree gets modified too much while
we are trying to analyze it, then we will retry (this function will call
itself, incrementing this parameter)
@@ -4010,7 +4007,6 @@ btr_estimate_n_rows_in_range_low(
ulint mode1,
const dtuple_t* tuple2,
ulint mode2,
- trx_t* trx,
unsigned nth_attempt)
{
btr_path_t path1[BTR_PATH_ARRAY_N_SLOTS];
@@ -4029,7 +4025,7 @@ btr_estimate_n_rows_in_range_low(
table_n_rows = dict_table_get_n_rows(index->table);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
cursor.path_arr = path1;
@@ -4051,7 +4047,7 @@ btr_estimate_n_rows_in_range_low(
return (0);
}
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
#ifdef UNIV_DEBUG
if (!strcmp(index->name, "iC")) {
@@ -4146,7 +4142,7 @@ btr_estimate_n_rows_in_range_low(
const ib_int64_t ret =
btr_estimate_n_rows_in_range_low(
index, tuple1, mode1,
- tuple2, mode2, trx,
+ tuple2, mode2,
nth_attempt + 1);
return(ret);
@@ -4207,7 +4203,6 @@ btr_estimate_n_rows_in_range_low(
@param[in] mode1 search mode for range start
@param[in] tuple2 range end, may also be empty tuple
@param[in] mode2 search mode for range end
-@param[in] trx trx
@return estimated number of rows */
ib_int64_t
btr_estimate_n_rows_in_range(
@@ -4215,11 +4210,10 @@ btr_estimate_n_rows_in_range(
const dtuple_t* tuple1,
ulint mode1,
const dtuple_t* tuple2,
- ulint mode2,
- trx_t* trx)
+ ulint mode2)
{
const ib_int64_t ret = btr_estimate_n_rows_in_range_low(
- index, tuple1, mode1, tuple2, mode2, trx,
+ index, tuple1, mode1, tuple2, mode2,
1 /* first attempt */);
return(ret);
@@ -4379,7 +4373,7 @@ btr_estimate_number_of_different_key_vals(
if (index->stat_index_size > 1) {
n_sample_pages = (srv_stats_transient_sample_pages < index->stat_index_size) ?
ut_min(index->stat_index_size,
- log2(index->stat_index_size)*srv_stats_transient_sample_pages)
+ ulint(log2(index->stat_index_size)*srv_stats_transient_sample_pages))
: index->stat_index_size;
}
@@ -5759,8 +5753,7 @@ btr_copy_blob_prefix(
ulint len, /*!< in: length of buf, in bytes */
ulint space_id,/*!< in: space id of the BLOB pages */
ulint page_no,/*!< in: page number of the first BLOB page */
- ulint offset, /*!< in: offset on the first BLOB page */
- trx_t* trx) /*!< in: transaction handle */
+ ulint offset) /*!< in: offset on the first BLOB page */
{
ulint copied_len = 0;
@@ -5772,7 +5765,7 @@ btr_copy_blob_prefix(
ulint part_len;
ulint copy_len;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
block = buf_page_get(space_id, 0, page_no, RW_S_LATCH, &mtr);
buf_block_dbg_add_level(block, SYNC_EXTERN_STORAGE);
@@ -5975,8 +5968,7 @@ btr_copy_externally_stored_field_prefix_low(
zero for uncompressed BLOBs */
ulint space_id,/*!< in: space id of the first BLOB page */
ulint page_no,/*!< in: page number of the first BLOB page */
- ulint offset, /*!< in: offset on the first BLOB page */
- trx_t* trx) /*!< in: transaction handle */
+ ulint offset) /*!< in: offset on the first BLOB page */
{
if (UNIV_UNLIKELY(len == 0)) {
return(0);
@@ -5987,7 +5979,7 @@ btr_copy_externally_stored_field_prefix_low(
space_id, page_no, offset));
} else {
return(btr_copy_blob_prefix(buf, len, space_id,
- page_no, offset, trx));
+ page_no, offset));
}
}
@@ -6008,8 +6000,7 @@ btr_copy_externally_stored_field_prefix(
field containing also the reference to
the external part; must be protected by
a lock or a page latch */
- ulint local_len,/*!< in: length of data, in bytes */
- trx_t* trx) /*!< in: transaction handle */
+ ulint local_len)/*!< in: length of data, in bytes */
{
ulint space_id;
ulint page_no;
@@ -6048,7 +6039,7 @@ btr_copy_externally_stored_field_prefix(
len - local_len,
zip_size,
space_id, page_no,
- offset, trx));
+ offset));
}
/*******************************************************************//**
@@ -6067,8 +6058,7 @@ btr_copy_externally_stored_field(
ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
ulint local_len,/*!< in: length of data */
- mem_heap_t* heap, /*!< in: mem heap */
- trx_t* trx) /*!< in: transaction handle */
+ mem_heap_t* heap) /*!< in: mem heap */
{
ulint space_id;
ulint page_no;
@@ -6099,8 +6089,7 @@ btr_copy_externally_stored_field(
extern_len,
zip_size,
space_id,
- page_no, offset,
- trx);
+ page_no, offset);
return(buf);
}
@@ -6119,8 +6108,7 @@ btr_rec_copy_externally_stored_field(
zero for uncompressed BLOBs */
ulint no, /*!< in: field number */
ulint* len, /*!< out: length of the field */
- mem_heap_t* heap, /*!< in: mem heap */
- trx_t* trx) /*!< in: transaction handle */
+ mem_heap_t* heap) /*!< in: mem heap */
{
ulint local_len;
const byte* data;
@@ -6151,7 +6139,6 @@ btr_rec_copy_externally_stored_field(
}
return(btr_copy_externally_stored_field(len, data,
- zip_size, local_len, heap,
- trx));
+ zip_size, local_len, heap));
}
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/btr/btr0pcur.cc b/storage/xtradb/btr/btr0pcur.cc
index 0b970e1cf49..06166e1aa16 100644
--- a/storage/xtradb/btr/btr0pcur.cc
+++ b/storage/xtradb/btr/btr0pcur.cc
@@ -33,6 +33,7 @@ Created 2/23/1996 Heikki Tuuri
#include "rem0cmp.h"
#include "trx0trx.h"
#include "srv0srv.h"
+
/**************************************************************//**
Allocates memory for a persistent cursor object and initializes the cursor.
@return own: persistent cursor */
@@ -511,7 +512,7 @@ btr_pcur_move_backward_from_page(
mtr_commit(mtr);
- mtr_start_trx(mtr, mtr->trx);
+ mtr_start(mtr);
btr_pcur_restore_position(latch_mode2, cursor, mtr);
diff --git a/storage/xtradb/btr/btr0scrub.cc b/storage/xtradb/btr/btr0scrub.cc
index 24c84ed301b..1b10b79838d 100644
--- a/storage/xtradb/btr/btr0scrub.cc
+++ b/storage/xtradb/btr/btr0scrub.cc
@@ -886,17 +886,15 @@ btr_scrub_update_total_stat(btr_scrub_t *scrub_data)
memset(&scrub_data->scrub_stat, 0, sizeof(scrub_data->scrub_stat));
}
-/**************************************************************//**
-Complete iterating a space */
+/** Complete iterating a space.
+@param[in,out] scrub_data scrub data */
UNIV_INTERN
-bool
-btr_scrub_complete_space(
-/*=====================*/
- btr_scrub_t* scrub_data) /*!< in/out: scrub data */
+void
+btr_scrub_complete_space(btr_scrub_t* scrub_data)
{
+ ut_ad(scrub_data->scrubbing);
btr_scrub_table_close_for_thread(scrub_data);
btr_scrub_update_total_stat(scrub_data);
- return scrub_data->scrubbing;
}
/*********************************************************************
diff --git a/storage/xtradb/btr/btr0sea.cc b/storage/xtradb/btr/btr0sea.cc
index 2ed383b0dcb..12c99246f16 100644
--- a/storage/xtradb/btr/btr0sea.cc
+++ b/storage/xtradb/btr/btr0sea.cc
@@ -2034,9 +2034,7 @@ btr_search_validate_one_table(
(ulong) block->curr_left_side);
if (n_page_dumps < 20) {
- buf_page_print(
- page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page, 0);
n_page_dumps++;
}
}
diff --git a/storage/xtradb/buf/buf0buddy.cc b/storage/xtradb/buf/buf0buddy.cc
index 2ee39c6c992..1c50e71e687 100644
--- a/storage/xtradb/buf/buf0buddy.cc
+++ b/storage/xtradb/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
@@ -667,7 +668,7 @@ buf_buddy_free_low(
ut_ad(buf_pool->buddy_stat[i].used > 0);
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) {
mutex_exit(&buf_pool->zip_free_mutex);
diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc
index 54f3ac311be..83e38fbcc98 100644
--- a/storage/xtradb/buf/buf0buf.cc
+++ b/storage/xtradb/buf/buf0buf.cc
@@ -102,10 +102,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;
}
@@ -730,6 +733,8 @@ buf_page_is_corrupted(
ulint zip_size,
const fil_space_t* space)
{
+ DBUG_EXECUTE_IF("buf_page_import_corrupt_failure", return(TRUE); );
+
ulint checksum_field1;
ulint checksum_field2;
ulint space_id = mach_read_from_4(
@@ -838,8 +843,6 @@ buf_page_is_corrupted(
return(false);
}
- DBUG_EXECUTE_IF("buf_page_is_corrupt_failure", return(true); );
-
ulint page_no = mach_read_from_4(read_buf + FIL_PAGE_OFFSET);
const srv_checksum_algorithm_t curr_algo =
@@ -956,19 +959,12 @@ buf_page_is_corrupted(
return(false);
}
-/********************************************************************//**
-Prints a page to stderr. */
+/** Dump a page to stderr.
+@param[in] read_buf database page
+@param[in] zip_size compressed page size, or 0 for uncompressed */
UNIV_INTERN
void
-buf_page_print(
-/*===========*/
- const byte* read_buf, /*!< in: a database page */
- ulint zip_size, /*!< in: compressed page size, or
- 0 for uncompressed pages */
- ulint flags) /*!< in: 0 or
- BUF_PAGE_PRINT_NO_CRASH or
- BUF_PAGE_PRINT_NO_FULL */
-
+buf_page_print(const byte* read_buf, ulint zip_size)
{
#ifndef UNIV_HOTBACKUP
dict_index_t* index;
@@ -979,14 +975,12 @@ buf_page_print(
size = UNIV_PAGE_SIZE;
}
- if (!(flags & BUF_PAGE_PRINT_NO_FULL)) {
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Page dump in ascii and hex (%lu bytes):\n",
- size);
- ut_print_buf(stderr, read_buf, size);
- fputs("\nInnoDB: End of page dump\n", stderr);
- }
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Page dump in ascii and hex (%lu bytes):\n",
+ size);
+ ut_print_buf(stderr, read_buf, size);
+ fputs("\nInnoDB: End of page dump\n", stderr);
if (zip_size) {
/* Print compressed page. */
@@ -1141,8 +1135,6 @@ buf_page_print(
stderr);
break;
}
-
- ut_ad(flags & BUF_PAGE_PRINT_NO_CRASH);
}
#ifndef UNIV_HOTBACKUP
@@ -2964,8 +2956,8 @@ buf_page_get_gen(
ib_mutex_t* fix_mutex = NULL;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
- ut_ad(mtr);
- ut_ad(mtr->state == MTR_ACTIVE);
+ ut_ad((mtr == NULL) == (mode == BUF_EVICT_IF_IN_POOL));
+ ut_ad(!mtr || mtr->state == MTR_ACTIVE);
ut_ad((rw_latch == RW_S_LATCH)
|| (rw_latch == RW_X_LATCH)
|| (rw_latch == RW_NO_LATCH));
@@ -2976,23 +2968,29 @@ buf_page_get_gen(
#ifdef UNIV_DEBUG
switch (mode) {
+ case BUF_EVICT_IF_IN_POOL:
+ /* After DISCARD TABLESPACE, the tablespace would not exist,
+ but in IMPORT TABLESPACE, PageConverter::operator() must
+ replace any old pages, which were not evicted during DISCARD.
+ Skip the assertion on zip_size. */
+ break;
case BUF_GET_NO_LATCH:
ut_ad(rw_latch == RW_NO_LATCH);
- break;
+ /* fall through */
case BUF_GET:
case BUF_GET_IF_IN_POOL:
case BUF_PEEK_IF_IN_POOL:
case BUF_GET_IF_IN_POOL_OR_WATCH:
case BUF_GET_POSSIBLY_FREED:
+ ut_ad(zip_size == fil_space_get_zip_size(space));
break;
default:
ut_error;
}
#endif /* UNIV_DEBUG */
- ut_ad(zip_size == fil_space_get_zip_size(space));
ut_ad(ut_is_2pow(zip_size));
#ifndef UNIV_LOG_DEBUG
- ut_ad(!ibuf_inside(mtr)
+ ut_ad(!mtr || !ibuf_inside(mtr)
|| ibuf_page_low(space, zip_size, offset,
FALSE, file, line, NULL));
#endif
@@ -3062,9 +3060,11 @@ loop:
rw_lock_x_unlock(hash_lock);
}
- if (mode == BUF_GET_IF_IN_POOL
- || mode == BUF_PEEK_IF_IN_POOL
- || mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
+ switch (mode) {
+ case BUF_GET_IF_IN_POOL:
+ 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_EX));
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_SHARED));
@@ -3153,8 +3153,10 @@ got_block:
ut_ad(page_zip_get_size(&block->page.zip) == zip_size);
- if (mode == BUF_GET_IF_IN_POOL || mode == BUF_PEEK_IF_IN_POOL) {
-
+ switch (mode) {
+ case BUF_GET_IF_IN_POOL:
+ case BUF_PEEK_IF_IN_POOL:
+ case BUF_EVICT_IF_IN_POOL:
bool must_read;
{
@@ -3192,6 +3194,22 @@ got_block:
case BUF_BLOCK_FILE_PAGE:
ut_ad(fix_mutex != &buf_pool->zip_mutex);
+
+ if (UNIV_UNLIKELY(mode == BUF_EVICT_IF_IN_POOL)) {
+evict_from_pool:
+ ut_ad(!fix_block->page.oldest_modification);
+ mutex_enter(&buf_pool->LRU_list_mutex);
+ buf_block_unfix(fix_block);
+ mutex_enter(fix_mutex);
+
+ if (!buf_LRU_free_page(&fix_block->page, true)) {
+ ut_ad(0);
+ mutex_exit(&buf_pool->LRU_list_mutex);
+ }
+
+ mutex_exit(fix_mutex);
+ return(NULL);
+ }
break;
case BUF_BLOCK_ZIP_PAGE:
@@ -3226,6 +3244,10 @@ got_block:
goto loop;
}
+ if (UNIV_UNLIKELY(mode == BUF_EVICT_IF_IN_POOL)) {
+ goto evict_from_pool;
+ }
+
/* Buffer-fix the block so that it cannot be evicted
or relocated while we are attempting to allocate an
uncompressed page. */
@@ -3347,6 +3369,8 @@ got_block:
mutex_enter(&buf_pool->LRU_list_mutex);
buf_block_unfix(fix_block);
mutex_exit(&buf_pool->LRU_list_mutex);
+
+ *err = DB_PAGE_CORRUPTED;
return NULL;
}
}
@@ -4806,7 +4830,7 @@ database_corrupted:
if (err != DB_SUCCESS) {
/* Not a real corruption if it was triggered by
error injection */
- DBUG_EXECUTE_IF("buf_page_is_corrupt_failure",
+ DBUG_EXECUTE_IF("buf_page_import_corrupt_failure",
if (bpage->space > TRX_SYS_SPACE) {
buf_mark_space_corrupt(bpage);
ib_logf(IB_LOG_LEVEL_INFO,
@@ -4829,8 +4853,8 @@ database_corrupted:
space->name,
bpage->space, bpage->offset);
- buf_page_print(frame, buf_page_get_zip_size(bpage),
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(frame,
+ buf_page_get_zip_size(bpage));
ib_logf(IB_LOG_LEVEL_INFO,
"It is also possible that your"
@@ -4874,7 +4898,7 @@ database_corrupted:
}
}
- DBUG_EXECUTE_IF("buf_page_is_corrupt_failure",
+ DBUG_EXECUTE_IF("buf_page_import_corrupt_failure",
page_not_corrupt: bpage = bpage; );
if (recv_recovery_is_on()) {
diff --git a/storage/xtradb/buf/buf0dblwr.cc b/storage/xtradb/buf/buf0dblwr.cc
index d6e738f15fa..ee8c85446e9 100644
--- a/storage/xtradb/buf/buf0dblwr.cc
+++ b/storage/xtradb/buf/buf0dblwr.cc
@@ -800,7 +800,7 @@ buf_dblwr_assert_on_corrupt_block(
/*==============================*/
const buf_block_t* block) /*!< in: block to check */
{
- buf_page_print(block->frame, 0, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(block->frame, 0);
ut_print_timestamp(stderr);
fprintf(stderr,
diff --git a/storage/xtradb/buf/buf0dump.cc b/storage/xtradb/buf/buf0dump.cc
index 023a267ee22..bf384390a98 100644
--- a/storage/xtradb/buf/buf0dump.cc
+++ b/storage/xtradb/buf/buf0dump.cc
@@ -41,9 +41,7 @@ Created April 08, 2011 Vasil Dimov
#include "sync0rw.h" /* rw_lock_s_lock() */
#include "ut0byte.h" /* ut_ull_create() */
#include "ut0sort.h" /* UT_SORT_FUNCTION_BODY */
-#ifdef WITH_WSREP
-extern my_bool wsrep_recovery;
-#endif /* WITH_WSREP */
+#include "mysql/service_wsrep.h" /* wsrep_recovery */
enum status_severity {
STATUS_INFO,
diff --git a/storage/xtradb/buf/buf0flu.cc b/storage/xtradb/buf/buf0flu.cc
index b1a0f2daa21..abbcd5141cf 100644
--- a/storage/xtradb/buf/buf0flu.cc
+++ b/storage/xtradb/buf/buf0flu.cc
@@ -757,7 +757,6 @@ buf_flush_update_zip_checksum(
srv_checksum_algorithm)));
mach_write_to_8(page + FIL_PAGE_LSN, lsn);
- memset(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8);
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum);
}
@@ -935,8 +934,6 @@ buf_flush_write_block_low(
bpage->newest_modification);
ut_a(page_zip_verify_checksum(frame, zip_size));
-
- memset(frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8);
break;
case BUF_BLOCK_FILE_PAGE:
frame = bpage->zip.data;
diff --git a/storage/xtradb/buf/buf0lru.cc b/storage/xtradb/buf/buf0lru.cc
index d979eb44a96..7bf423ed740 100644
--- a/storage/xtradb/buf/buf0lru.cc
+++ b/storage/xtradb/buf/buf0lru.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 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
@@ -87,6 +87,10 @@ buffer pools. */
frames in the buffer pool, we set this to TRUE */
static ibool 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,
@@ -571,26 +575,20 @@ 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.
+@param[in,out] buf_pool buffer pool
+@param[in] id tablespace identifier
+@param[in] trx transaction (to check for interrupt),
+ or NULL if the files should not be written to
@retval DB_SUCCESS if all freed
@retval DB_FAIL if not all freed
@retval DB_INTERRUPTED if the transaction was interrupted */
static MY_ATTRIBUTE((nonnull(1), warn_unused_result))
dberr_t
-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 */
- 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_flush_or_remove_pages(buf_pool_t* buf_pool, ulint id, const trx_t* trx)
{
buf_page_t* prev;
buf_page_t* bpage;
@@ -621,7 +619,7 @@ rescan:
/* Skip this block, as it does not belong to
the target space. */
- } else if (!buf_flush_or_remove_page(buf_pool, bpage, flush,
+ } else if (!buf_flush_or_remove_page(buf_pool, bpage, trx,
&must_restart)) {
/* Remove was unsuccessful, we have to try again
@@ -647,7 +645,7 @@ rescan:
/* Cannot trust the prev pointer */
break;
}
- } else if (flush) {
+ } else if (trx) {
/* The processing was successful. And during the
processing we have released all the buf_pool mutexes
@@ -674,19 +672,17 @@ rescan:
break;
}
-#ifdef DBUG_OFF
- if (flush) {
+ if (trx) {
DBUG_EXECUTE_IF("ib_export_flush_crash",
static ulint n_pages;
if (++n_pages == 4) {DBUG_SUICIDE();});
- }
-#endif /* DBUG_OFF */
- /* The check for trx is interrupted is expensive, we want
- to check every N iterations. */
- if (!processed && trx && trx_is_interrupted(trx)) {
- buf_flush_list_mutex_exit(buf_pool);
- return(DB_INTERRUPTED);
+ /* The check for trx is interrupted is
+ expensive, we want to check every N iterations. */
+ if (!processed && trx_is_interrupted(trx)) {
+ buf_flush_list_mutex_exit(buf_pool);
+ return(DB_INTERRUPTED);
+ }
}
}
@@ -695,28 +691,25 @@ rescan:
return(all_freed ? DB_SUCCESS : DB_FAIL);
}
-/******************************************************************//**
-Remove or flush all the dirty pages that belong to a given tablespace
+/** Remove or flush all the dirty pages that belong to a given tablespace
inside a specific buffer pool instance. The pages will remain in the LRU
list and will be evicted from the LRU list as they age and move towards
-the tail of the LRU list. */
+the tail of the LRU list.
+@param[in,out] buf_pool buffer pool
+@param[in] id tablespace identifier
+@param[in] trx transaction (to check for interrupt),
+ or NULL if the files should not be written to
+*/
static MY_ATTRIBUTE((nonnull(1)))
void
-buf_flush_dirty_pages(
-/*==================*/
- buf_pool_t* buf_pool, /*!< buffer pool instance */
- ulint id, /*!< in: space id */
- bool flush, /*!< in: flush to disk if true otherwise
- remove the pages without flushing */
- const trx_t* trx) /*!< to check if the operation must
- be interrupted */
+buf_flush_dirty_pages(buf_pool_t* buf_pool, ulint id, const trx_t* trx)
{
dberr_t err;
do {
mutex_enter(&buf_pool->LRU_list_mutex);
- err = buf_flush_or_remove_pages(buf_pool, id, flush, trx);
+ err = buf_flush_or_remove_pages(buf_pool, id, trx);
mutex_exit(&buf_pool->LRU_list_mutex);
@@ -737,239 +730,27 @@ buf_flush_dirty_pages(
|| buf_pool_get_dirty_pages_count(buf_pool, id) == 0);
}
-/******************************************************************//**
-Remove all pages that belong to a given tablespace inside a specific
-buffer pool instance when we are DISCARDing the tablespace. */
-static MY_ATTRIBUTE((nonnull))
+/** 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
void
-buf_LRU_remove_all_pages(
-/*=====================*/
- buf_pool_t* buf_pool, /*!< buffer pool instance */
- ulint id) /*!< in: space id */
+buf_LRU_flush_or_remove_pages(ulint id, const trx_t* trx, bool drop_ahi)
{
- buf_page_t* bpage;
- ibool all_freed;
-
-scan_again:
- mutex_enter(&buf_pool->LRU_list_mutex);
-
- all_freed = TRUE;
-
- for (bpage = UT_LIST_GET_LAST(buf_pool->LRU);
- bpage != NULL;
- /* No op */) {
-
- prio_rw_lock_t* hash_lock;
- buf_page_t* prev_bpage;
- ib_mutex_t* block_mutex = NULL;
-
- ut_a(buf_page_in_file(bpage));
- ut_ad(bpage->in_LRU_list);
-
- prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
-
- /* It is safe to check bpage->space and bpage->io_fix while
- holding buf_pool->LRU_list_mutex only and later recheck
- while holding the buf_page_get_mutex() mutex. */
-
- if (buf_page_get_space(bpage) != id) {
- /* Skip this block, as it does not belong to
- the space that is being invalidated. */
- goto next_page;
- } else if (UNIV_UNLIKELY(buf_page_get_io_fix_unlocked(bpage)
- != BUF_IO_NONE)) {
- /* We cannot remove this page during this scan
- yet; maybe the system is currently reading it
- in, or flushing the modifications to the file */
-
- all_freed = FALSE;
- goto next_page;
- } else {
- ulint fold = buf_page_address_fold(
- bpage->space, bpage->offset);
-
- hash_lock = buf_page_hash_lock_get(buf_pool, fold);
-
- rw_lock_x_lock(hash_lock);
-
- block_mutex = buf_page_get_mutex(bpage);
- mutex_enter(block_mutex);
-
- if (UNIV_UNLIKELY(
- buf_page_get_space(bpage) != id
- || bpage->buf_fix_count > 0
- || (buf_page_get_io_fix(bpage)
- != BUF_IO_NONE))) {
-
- mutex_exit(block_mutex);
-
- rw_lock_x_unlock(hash_lock);
-
- /* We cannot remove this page during
- this scan yet; maybe the system is
- currently reading it in, or flushing
- the modifications to the file */
-
- all_freed = FALSE;
-
- goto next_page;
- }
- }
-
- ut_ad(mutex_own(block_mutex));
-
-#ifdef UNIV_DEBUG
- if (buf_debug_prints) {
- fprintf(stderr,
- "Dropping space %lu page %lu\n",
- (ulong) buf_page_get_space(bpage),
- (ulong) buf_page_get_page_no(bpage));
- }
-#endif
- if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
- /* Do nothing, because the adaptive hash index
- covers uncompressed pages only. */
- } else if (((buf_block_t*) bpage)->index) {
- ulint page_no;
- ulint zip_size;
-
- mutex_exit(&buf_pool->LRU_list_mutex);
-
- zip_size = buf_page_get_zip_size(bpage);
- page_no = buf_page_get_page_no(bpage);
-
- mutex_exit(block_mutex);
-
- rw_lock_x_unlock(hash_lock);
-
- /* Note that the following call will acquire
- and release block->lock X-latch. */
-
- btr_search_drop_page_hash_when_freed(
- id, zip_size, page_no);
-
- goto scan_again;
- }
-
- if (bpage->oldest_modification != 0) {
-
- buf_flush_remove(bpage);
- }
-
- ut_ad(!bpage->in_flush_list);
-
- /* Remove from the LRU list. */
-
- if (buf_LRU_block_remove_hashed(bpage, true)) {
-
- mutex_enter(block_mutex);
- buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
- mutex_exit(block_mutex);
- } else {
- ut_ad(block_mutex == &buf_pool->zip_mutex);
+ for (ulint i = 0; i < srv_buf_pool_instances; i++) {
+ buf_pool_t* buf_pool = buf_pool_from_array(i);
+ if (drop_ahi) {
+ buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
}
-
- ut_ad(!mutex_own(block_mutex));
-
-#ifdef UNIV_SYNC_DEBUG
- /* buf_LRU_block_remove_hashed() releases the hash_lock */
- ut_ad(!rw_lock_own(hash_lock, RW_LOCK_EX));
- ut_ad(!rw_lock_own(hash_lock, RW_LOCK_SHARED));
-#endif /* UNIV_SYNC_DEBUG */
-
-next_page:
- bpage = prev_bpage;
+ buf_flush_dirty_pages(buf_pool, id, trx);
}
- mutex_exit(&buf_pool->LRU_list_mutex);
-
- if (!all_freed) {
- os_thread_sleep(20000);
-
- goto scan_again;
- }
-}
-
-/******************************************************************//**
-Remove 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 only if buf_remove
-is BUF_REMOVE_FLUSH_NO_WRITE. */
-static MY_ATTRIBUTE((nonnull(1)))
-void
-buf_LRU_remove_pages(
-/*=================*/
- buf_pool_t* buf_pool, /*!< buffer pool instance */
- ulint id, /*!< in: space id */
- buf_remove_t buf_remove, /*!< in: remove or flush strategy */
- const trx_t* trx) /*!< to check if the operation must
- be interrupted */
-{
- switch (buf_remove) {
- case BUF_REMOVE_ALL_NO_WRITE:
- buf_LRU_remove_all_pages(buf_pool, id);
- break;
-
- case BUF_REMOVE_FLUSH_NO_WRITE:
- ut_a(trx == 0);
- buf_flush_dirty_pages(buf_pool, id, false, NULL);
- break;
-
- case BUF_REMOVE_FLUSH_WRITE:
- ut_a(trx != 0);
- buf_flush_dirty_pages(buf_pool, id, true, trx);
+ if (trx && !trx_is_interrupted(trx)) {
/* Ensure that all asynchronous IO is completed. */
os_aio_wait_until_no_pending_writes();
fil_flush(id);
- break;
- }
-}
-
-/******************************************************************//**
-Flushes all dirty pages or removes all pages belonging
-to a given tablespace. A PROBLEM: if readahead is being started, what
-guarantees that it will not try to read in pages after this operation
-has completed? */
-UNIV_INTERN
-void
-buf_LRU_flush_or_remove_pages(
-/*==========================*/
- ulint id, /*!< in: space id */
- buf_remove_t buf_remove, /*!< in: remove or flush strategy */
- const trx_t* trx) /*!< to check if the operation must
- be interrupted */
-{
- ulint i;
-
- /* Before we attempt to drop pages one by one we first
- attempt to drop page hash index entries in batches to make
- it more efficient. The batching attempt is a best effort
- attempt and does not guarantee that all pages hash entries
- will be dropped. We get rid of remaining page hash entries
- one by one below. */
- for (i = 0; i < srv_buf_pool_instances; i++) {
- buf_pool_t* buf_pool;
-
- buf_pool = buf_pool_from_array(i);
-
- switch (buf_remove) {
- case BUF_REMOVE_ALL_NO_WRITE:
- buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
- break;
-
- case BUF_REMOVE_FLUSH_NO_WRITE:
- /* It is a DROP TABLE for a single table
- tablespace. No AHI entries exist because
- we already dealt with them when freeing up
- extents. */
- case BUF_REMOVE_FLUSH_WRITE:
- /* We allow read-only queries against the
- table, there is no need to drop the AHI entries. */
- break;
- }
-
- buf_LRU_remove_pages(buf_pool, id, buf_remove, trx);
}
}
@@ -1303,68 +1084,39 @@ buf_LRU_check_size_of_non_data_objects(
}
/** Diagnose failure to get a free page and request InnoDB monitor output in
-the error log if more than two seconds have been spent already.
+the error log if it has not yet printed.
@param[in] n_iterations how many buf_LRU_get_free_page iterations
already completed
-@param[in] started_ms timestamp in ms of when the attempt to get the
- free page started
@param[in] flush_failures how many times single-page flush, if allowed,
has failed
-@param[out] mon_value_was previous srv_print_innodb_monitor value
-@param[out] started_monitor whether InnoDB monitor print has been requested
*/
static
void
-buf_LRU_handle_lack_of_free_blocks(ulint n_iterations, ulint started_ms,
- ulint flush_failures,
- ibool *mon_value_was,
- ibool *started_monitor)
+buf_LRU_handle_lack_of_free_blocks(
+ ulint n_iterations,
+ ulint flush_failures)
{
- static ulint last_printout_ms = 0;
-
- /* Legacy algorithm started warning after at least 2 seconds, we
- emulate this. */
- const ulint current_ms = ut_time_ms();
-
- if ((current_ms > started_ms + 2000)
- && (current_ms > last_printout_ms + 2000)) {
-
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Warning: difficult to find free blocks in\n"
- "InnoDB: the buffer pool (%lu search iterations)!\n"
- "InnoDB: %lu failed attempts to flush a page!"
- " Consider\n"
- "InnoDB: increasing the buffer pool size.\n"
- "InnoDB: It is also possible that"
- " in your Unix version\n"
- "InnoDB: fsync is very slow, or"
- " completely frozen inside\n"
- "InnoDB: the OS kernel. Then upgrading to"
- " a newer version\n"
- "InnoDB: of your operating system may help."
- " Look at the\n"
- "InnoDB: number of fsyncs in diagnostic info below.\n"
- "InnoDB: Pending flushes (fsync) log: %lu;"
- " buffer pool: %lu\n"
- "InnoDB: %lu OS file reads, %lu OS file writes,"
- " %lu OS fsyncs\n"
- "InnoDB: Starting InnoDB Monitor to print further\n"
- "InnoDB: diagnostics to the standard output.\n",
- (ulong) n_iterations,
- (ulong) flush_failures,
- (ulong) fil_n_pending_log_flushes,
- (ulong) fil_n_pending_tablespace_flushes,
- (ulong) os_n_file_reads, (ulong) os_n_file_writes,
- (ulong) os_n_fsyncs);
-
- last_printout_ms = current_ms;
- *mon_value_was = srv_print_innodb_monitor;
- *started_monitor = TRUE;
- srv_print_innodb_monitor = TRUE;
- os_event_set(lock_sys->timeout_event);
+ if (n_iterations > 20 && !buf_lru_free_blocks_error_printed) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Difficult to find free blocks in"
+ " the buffer pool (" ULINTPF " search iterations)! "
+ ULINTPF " failed attempts to flush a page!",
+ n_iterations, flush_failures);
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Consider increasing the buffer pool size.");
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Pending flushes (fsync) log: " ULINTPF
+ " buffer pool: " ULINTPF
+ " OS file reads: " ULINTPF " OS file writes: "
+ ULINTPF " OS fsyncs: " ULINTPF "",
+ fil_n_pending_log_flushes,
+ fil_n_pending_tablespace_flushes,
+ os_n_file_reads,
+ os_n_file_writes,
+ os_n_fsyncs);
+
+ buf_lru_free_blocks_error_printed = true;
}
-
}
/** The maximum allowed backoff sleep time duration, microseconds */
@@ -1412,9 +1164,6 @@ buf_LRU_get_free_block(
ibool freed = FALSE;
ulint n_iterations = 0;
ulint flush_failures = 0;
- ibool mon_value_was = FALSE;
- ibool started_monitor = FALSE;
- ulint started_ms = 0;
ut_ad(!mutex_own(&buf_pool->LRU_list_mutex));
@@ -1422,42 +1171,20 @@ buf_LRU_get_free_block(
loop:
buf_LRU_check_size_of_non_data_objects(buf_pool);
- /* If there is a block in the free list, take it */
- if (DBUG_EVALUATE_IF("simulate_lack_of_pages", true, false)) {
+ DBUG_EXECUTE_IF("ib_lru_force_no_free_page",
+ if (!buf_lru_free_blocks_error_printed) {
+ n_iterations = 21;
+ goto not_found;});
- block = NULL;
-
- if (srv_debug_monitor_printed)
- DBUG_SET("-d,simulate_lack_of_pages");
-
- } else if (DBUG_EVALUATE_IF("simulate_recovery_lack_of_pages",
- recv_recovery_on, false)) {
-
- block = NULL;
-
- if (srv_debug_monitor_printed)
- DBUG_SUICIDE();
- } else {
-
- block = buf_LRU_get_free_only(buf_pool);
- }
+ block = buf_LRU_get_free_only(buf_pool);
if (block) {
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);
- }
-
return(block);
}
- if (!started_ms)
- started_ms = ut_time_ms();
-
if (srv_empty_free_list_algorithm == SRV_EMPTY_FREE_LIST_BACKOFF
&& buf_lru_manager_is_active
&& (srv_shutdown_state == SRV_SHUTDOWN_NONE
@@ -1495,10 +1222,7 @@ loop:
: FREE_LIST_BACKOFF_LOW_PRIO_DIVIDER));
}
- buf_LRU_handle_lack_of_free_blocks(n_iterations, started_ms,
- flush_failures,
- &mon_value_was,
- &started_monitor);
+ buf_LRU_handle_lack_of_free_blocks(n_iterations, flush_failures);
n_iterations++;
@@ -1537,13 +1261,8 @@ loop:
mutex_exit(&buf_pool->flush_state_mutex);
- if (DBUG_EVALUATE_IF("simulate_recovery_lack_of_pages", true, false)
- || DBUG_EVALUATE_IF("simulate_lack_of_pages", true, false)) {
-
- buf_pool->try_LRU_scan = false;
- }
-
freed = FALSE;
+
if (buf_pool->try_LRU_scan || n_iterations > 0) {
/* If no block was in the free list, search from the
@@ -1568,9 +1287,11 @@ loop:
}
- buf_LRU_handle_lack_of_free_blocks(n_iterations, started_ms,
- flush_failures, &mon_value_was,
- &started_monitor);
+#ifndef DBUG_OFF
+not_found:
+#endif
+
+ buf_LRU_handle_lack_of_free_blocks(n_iterations, flush_failures);
/* If we have scanned the whole LRU and still are unable to
find a free block then we should sleep here to let the
@@ -2349,7 +2070,7 @@ buf_LRU_block_free_non_file_page(
ut_d(block->page.in_free_list = TRUE);
mutex_exit(&buf_pool->free_list_mutex);
- UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE);
+ UNIV_MEM_FREE(block->frame, UNIV_PAGE_SIZE);
}
/******************************************************************//**
diff --git a/storage/xtradb/buf/buf0rea.cc b/storage/xtradb/buf/buf0rea.cc
index 76b71550710..43e678ed7d4 100644
--- a/storage/xtradb/buf/buf0rea.cc
+++ b/storage/xtradb/buf/buf0rea.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 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
@@ -124,7 +124,12 @@ not exist or is being dropped
use to stop dangling page reads from a tablespace
which we have DISCARDed + IMPORTed back
@param[in] offset page number
-@param[in] trx transaction
+@param[in,out] trx transaction
+@param[in] should_buffer whether to buffer an aio request.
+ AIO read ahead uses this. If you plan to
+ use this parameter, make sure you remember
+ to call os_aio_dispatch_read_array_submit()
+ when you're ready to commit all your requests
@return 1 if read request is issued. 0 if it is not */
static
ulint
@@ -137,7 +142,8 @@ buf_read_page_low(
ibool unzip,
ib_int64_t tablespace_version,
ulint offset,
- trx_t* trx = NULL)
+ trx_t* trx = NULL,
+ bool should_buffer = false)
{
buf_page_t* bpage;
ulint wake_later;
@@ -240,17 +246,18 @@ not_to_recover:
}
if (zip_size) {
- *err = _fil_io(OS_FILE_READ | wake_later
- | ignore_nonexistent_pages,
- sync, space, zip_size, offset, 0, zip_size,
- frame, bpage, 0, trx);
+ *err = fil_io(OS_FILE_READ | wake_later
+ | ignore_nonexistent_pages,
+ sync, space, zip_size, offset, 0, zip_size,
+ frame, bpage, 0, trx, should_buffer);
} else {
ut_a(buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
- *err = _fil_io(OS_FILE_READ | wake_later
+ *err = fil_io(OS_FILE_READ | wake_later
| ignore_nonexistent_pages,
sync, space, 0, offset, 0, UNIV_PAGE_SIZE,
- frame, bpage, &bpage->write_size, trx);
+ frame, bpage, &bpage->write_size,
+ trx, should_buffer);
}
if (sync) {
@@ -848,7 +855,7 @@ buf_read_ahead_linear(
&err, false,
ibuf_mode,
space, zip_size, FALSE, tablespace_version,
- i, trx);
+ i, trx, true);
switch(err) {
case DB_SUCCESS:
@@ -876,6 +883,7 @@ buf_read_ahead_linear(
}
}
}
+ os_aio_dispatch_read_array_submit();
/* In simulated aio we wake the aio handler threads only after
queuing all aio requests, in native aio the following call does
@@ -952,7 +960,7 @@ buf_read_ibuf_merge_pages(
buf_read_page_low(&err, sync && (i + 1 == n_stored),
BUF_READ_ANY_PAGE, space_ids[i],
zip_size, TRUE, space_versions[i],
- page_nos[i], NULL);
+ page_nos[i]);
switch(err) {
case DB_SUCCESS:
@@ -1100,13 +1108,12 @@ not_to_recover:
if ((i + 1 == n_stored) && sync) {
buf_read_page_low(&err, true, BUF_READ_ANY_PAGE, space,
zip_size, TRUE, tablespace_version,
- page_nos[i], NULL);
+ page_nos[i]);
} else {
buf_read_page_low(&err, false, BUF_READ_ANY_PAGE
| OS_AIO_SIMULATED_WAKE_LATER,
space, zip_size, TRUE,
- tablespace_version, page_nos[i],
- NULL);
+ tablespace_version, page_nos[i]);
}
if (err == DB_DECRYPTION_FAILED) {
diff --git a/storage/xtradb/data/data0type.cc b/storage/xtradb/data/data0type.cc
index 0b9e08544a5..34ca399f9b2 100644
--- a/storage/xtradb/data/data0type.cc
+++ b/storage/xtradb/data/data0type.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2011, 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
@@ -49,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) */
@@ -58,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(data_len != UNIV_SQL_NULL);
ut_ad(!mbmaxlen || !(prefix_len % mbmaxlen));
diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc
index 7550943de7a..9257321c7ef 100644
--- a/storage/xtradb/dict/dict0dict.cc
+++ b/storage/xtradb/dict/dict0dict.cc
@@ -570,15 +570,14 @@ dict_table_close(
ut_ad(mutex_own(&dict_sys->mutex));
ut_a(table->n_ref_count > 0);
- --table->n_ref_count;
+ const bool last_handle = !--table->n_ref_count;
/* Force persistent stats re-read upon next open of the table
so that FLUSH TABLE can be used to forcibly fetch stats from disk
if they have been manually modified. We reset table->stat_initialized
only if table reference count is 0 because we do not want too frequent
stats re-reads (e.g. in other cases than FLUSH TABLE). */
- if (strchr(table->name, '/') != NULL
- && table->n_ref_count == 0
+ if (last_handle && strchr(table->name, '/') != NULL
&& dict_stats_is_persistent_enabled(table)) {
dict_stats_deinit(table);
@@ -598,11 +597,8 @@ dict_table_close(
if (!dict_locked) {
table_id_t table_id = table->id;
- ibool drop_aborted;
-
- drop_aborted = try_drop
+ const bool drop_aborted = last_handle && try_drop
&& table->drop_aborted
- && table->n_ref_count == 1
&& dict_table_get_first_index(table);
mutex_exit(&dict_sys->mutex);
@@ -642,40 +638,6 @@ dict_table_get_col_name(
return(s);
}
-/**********************************************************************//**
-Returns a column's name.
-@return column name. NOTE: not guaranteed to stay valid if table is
-modified in any way (columns added, etc.). */
-UNIV_INTERN
-const char*
-dict_table_get_col_name_for_mysql(
-/*==============================*/
- const dict_table_t* table, /*!< in: table */
- const char* col_name)/*! in: MySQL table column name */
-{
- ulint i;
- const char* s;
-
- ut_ad(table);
- ut_ad(col_name);
- ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
-
- s = table->col_names;
- if (s) {
- /* If we have many virtual columns MySQL key_part->fieldnr
- could be larger than number of columns in InnoDB table
- when creating new indexes. */
- for (i = 0; i < table->n_def; i++) {
-
- if (!innobase_strcasecmp(s, col_name)) {
- break; /* Found */
- }
- s += strlen(s) + 1;
- }
- }
-
- return(s);
-}
#ifndef UNIV_HOTBACKUP
/** Allocate and init the autoinc latch of a given table.
This function must not be called concurrently on the same table object.
@@ -1717,7 +1679,7 @@ dict_table_rename_in_cache(
filepath = fil_make_ibd_name(table->name, false);
}
- fil_delete_tablespace(table->space, BUF_REMOVE_ALL_NO_WRITE);
+ fil_delete_tablespace(table->space, true);
/* Delete any temp file hanging around. */
if (os_file_status(filepath, &exists, &ftype)
@@ -2151,8 +2113,9 @@ dict_table_remove_from_cache_low(
}
if (lru_evict && table->drop_aborted) {
- /* Do as dict_table_try_drop_aborted() does. */
-
+ /* When evicting the table definition,
+ drop the orphan indexes from the data dictionary
+ and free the index pages. */
trx_t* trx = trx_allocate_for_background();
ut_ad(mutex_own(&dict_sys->mutex));
@@ -2163,12 +2126,8 @@ dict_table_remove_from_cache_low(
trx->dict_operation_lock_mode = RW_X_LATCH;
trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
+ row_merge_drop_indexes_dict(trx, table->id);
- /* Silence a debug assertion in row_merge_drop_indexes(). */
- ut_d(table->n_ref_count++);
- row_merge_drop_indexes(trx, table, TRUE);
- ut_d(table->n_ref_count--);
- ut_ad(table->n_ref_count == 0);
trx_commit_for_mysql(trx);
trx->dict_operation_lock_mode = 0;
trx_free_for_background(trx);
@@ -3450,6 +3409,7 @@ dict_foreign_find_index(
if (types_idx != index
&& !(index->type & DICT_FTS)
&& !index->to_be_dropped
+ && !dict_index_is_online_ddl(index)
&& dict_foreign_qualify_index(
table, col_names, columns, n_cols,
index, types_idx,
diff --git a/storage/xtradb/dict/dict0mem.cc b/storage/xtradb/dict/dict0mem.cc
index 125d7d78a1f..cf27caf6c28 100644
--- a/storage/xtradb/dict/dict0mem.cc
+++ b/storage/xtradb/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
@@ -533,7 +533,8 @@ dict_mem_fill_column_struct(
column->len = (unsigned int) col_len;
#ifndef UNIV_HOTBACKUP
dtype_get_mblen(mtype, prtype, &mbminlen, &mbmaxlen);
- dict_col_set_mbminmaxlen(column, mbminlen, mbmaxlen);
+ column->mbminlen = mbminlen;
+ column->mbmaxlen = mbmaxlen;
#endif /* !UNIV_HOTBACKUP */
}
diff --git a/storage/xtradb/dict/dict0stats_bg.cc b/storage/xtradb/dict/dict0stats_bg.cc
index ba6fd115551..884f62103f5 100644
--- a/storage/xtradb/dict/dict0stats_bg.cc
+++ b/storage/xtradb/dict/dict0stats_bg.cc
@@ -337,7 +337,7 @@ dict_stats_wait_bg_to_stop_using_table(
unlocking/locking the data dict */
{
while (!dict_stats_stop_bg(table)) {
- DICT_STATS_BG_YIELD(trx);
+ DICT_BG_YIELD(trx);
}
}
@@ -479,7 +479,6 @@ 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;
@@ -501,31 +500,19 @@ 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;
- }
+ mutex_exit(&dict_sys->mutex);
dict_stats_save_defrag_stats(index);
dict_table_close(table, FALSE, FALSE);
}
diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc
index a388ce4b604..3095503cfc5 100644
--- a/storage/xtradb/fil/fil0crypt.cc
+++ b/storage/xtradb/fil/fil0crypt.cc
@@ -742,11 +742,12 @@ fil_space_encrypt(
fprintf(stderr, "ok %d corrupted %d corrupted1 %d err %d different %d\n",
ok , corrupted, corrupted1, err, different);
fprintf(stderr, "src_frame\n");
- buf_page_print(src_frame, zip_size, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(src_frame, zip_size);
fprintf(stderr, "encrypted_frame\n");
- buf_page_print(tmp, zip_size, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(tmp, zip_size);
fprintf(stderr, "decrypted_frame\n");
- buf_page_print(tmp_mem, zip_size, 0);
+ buf_page_print(tmp_mem, zip_size);
+ ut_ad(0);
}
free(tmp_mem);
@@ -2127,7 +2128,8 @@ fil_crypt_complete_rotate_space(
mutex_exit(&crypt_data->mutex);
/* all threads must call btr_scrub_complete_space wo/ mutex held */
- if (btr_scrub_complete_space(&state->scrub_data) == true) {
+ if (state->scrub_data.scrubbing) {
+ btr_scrub_complete_space(&state->scrub_data);
if (should_flush) {
/* only last thread updates last_scrub_completed */
ut_ad(crypt_data);
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index 0cd67f5b19d..96902cd77ec 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 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
@@ -1045,156 +1045,24 @@ fil_space_extend_must_retry(
page_size = UNIV_PAGE_SIZE;
}
-#ifdef _WIN32
- const ulint io_completion_type = OS_FILE_READ;
- /* Logically or physically extend the file with zero bytes,
- depending on whether it is sparse. */
+ /* fil_read_first_page() expects UNIV_PAGE_SIZE bytes.
+ fil_node_open_file() expects at least 4 * UNIV_PAGE_SIZE bytes.*/
+ os_offset_t new_size = std::max(
+ os_offset_t(size - file_start_page_no) * page_size,
+ os_offset_t(FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE));
- /* FIXME: Call DeviceIoControl(node->handle, FSCTL_SET_SPARSE, ...)
- when opening a file when FSP_FLAGS_HAS_PAGE_COMPRESSION(). */
- {
- FILE_END_OF_FILE_INFO feof;
- /* fil_read_first_page() expects UNIV_PAGE_SIZE bytes.
- fil_node_open_file() expects at least 4 * UNIV_PAGE_SIZE bytes.
- Do not shrink short ROW_FORMAT=COMPRESSED files. */
- feof.EndOfFile.QuadPart = std::max(
- os_offset_t(size - file_start_page_no) * page_size,
- os_offset_t(FIL_IBD_FILE_INITIAL_SIZE
- * UNIV_PAGE_SIZE));
- *success = SetFileInformationByHandle(node->handle,
- FileEndOfFileInfo,
- &feof, sizeof feof);
- if (!*success) {
- ib_logf(IB_LOG_LEVEL_ERROR, "extending file %s"
- " from " INT64PF
- " to " INT64PF " bytes failed with %u",
- node->name,
- os_offset_t(node->size) * page_size,
- feof.EndOfFile.QuadPart, GetLastError());
- } else {
- start_page_no = size;
- }
- }
-#else
- /* We will logically extend the file with ftruncate() if
- page_compression is enabled, because the file is expected to
- be sparse in that case. Make sure that ftruncate() can deal
- with large files. */
- const bool is_sparse = sizeof(off_t) >= 8
- && FSP_FLAGS_HAS_PAGE_COMPRESSION(space->flags);
-
-# ifdef HAVE_POSIX_FALLOCATE
- /* We must complete the I/O request after invoking
- posix_fallocate() to avoid an assertion failure at shutdown.
- Because no actual writes were dispatched, a read operation
- will suffice. */
- const ulint io_completion_type = srv_use_posix_fallocate
- || is_sparse ? OS_FILE_READ : OS_FILE_WRITE;
-
- if (srv_use_posix_fallocate && !is_sparse) {
- const os_offset_t start_offset
- = os_offset_t(start_page_no - file_start_page_no)
- * page_size;
- const ulint n_pages = size - start_page_no;
- const os_offset_t len = os_offset_t(n_pages) * page_size;
-
- int err;
- do {
- err = posix_fallocate(node->handle, start_offset, len);
- } while (err == EINTR
- && srv_shutdown_state == SRV_SHUTDOWN_NONE);
-
- *success = !err;
- if (!*success) {
- ib_logf(IB_LOG_LEVEL_ERROR, "extending file %s"
- " from " INT64PF " to " INT64PF " bytes"
- " failed with error %d",
- node->name, start_offset, len + start_offset,
- err);
- }
-
- DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28",
- *success = FALSE;
- os_has_said_disk_full = TRUE;);
-
- if (*success) {
- os_has_said_disk_full = FALSE;
- start_page_no = size;
- }
- } else
-# else
- const ulint io_completion_type = is_sparse
- ? OS_FILE_READ : OS_FILE_WRITE;
-# endif
- if (is_sparse) {
- /* fil_read_first_page() expects UNIV_PAGE_SIZE bytes.
- fil_node_open_file() expects at least 4 * UNIV_PAGE_SIZE bytes.
- Do not shrink short ROW_FORMAT=COMPRESSED files. */
- off_t s = std::max(off_t(size - file_start_page_no)
- * off_t(page_size),
- off_t(FIL_IBD_FILE_INITIAL_SIZE
- * UNIV_PAGE_SIZE));
- *success = !ftruncate(node->handle, s);
- if (!*success) {
- ib_logf(IB_LOG_LEVEL_ERROR, "ftruncate of file %s"
- " from " INT64PF " to " INT64PF " bytes"
- " failed with error %d",
- node->name,
- os_offset_t(start_page_no - file_start_page_no)
- * page_size, os_offset_t(s), errno);
- } else {
- start_page_no = size;
- }
- } else {
- /* Extend at most 64 pages at a time */
- ulint buf_size = ut_min(64, size - start_page_no)
- * page_size;
- byte* buf2 = static_cast<byte*>(
- calloc(1, buf_size + page_size));
- *success = buf2 != NULL;
- if (!buf2) {
- ib_logf(IB_LOG_LEVEL_ERROR, "Cannot allocate " ULINTPF
- " bytes to extend file",
- buf_size + page_size);
- }
- byte* const buf = static_cast<byte*>(
- ut_align(buf2, page_size));
-
- while (*success && start_page_no < size) {
- ulint n_pages
- = ut_min(buf_size / page_size,
- size - start_page_no);
-
- os_offset_t offset = static_cast<os_offset_t>(
- start_page_no - file_start_page_no)
- * page_size;
-
- *success = os_aio(OS_FILE_WRITE, 0, OS_AIO_SYNC,
- node->name, node->handle, buf,
- offset, page_size * n_pages,
- page_size, node, NULL,
- space->id, NULL, 0);
-
- DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28",
- *success = FALSE;
- os_has_said_disk_full = TRUE;);
-
- if (*success) {
- os_has_said_disk_full = FALSE;
- }
- /* Let us measure the size of the file
- to determine how much we were able to
- extend it */
- os_offset_t fsize = os_file_get_size(node->handle);
- ut_a(fsize != os_offset_t(-1));
+ *success = os_file_set_size(node->name, node->handle, new_size,
+ FSP_FLAGS_HAS_PAGE_COMPRESSION(space->flags));
- start_page_no = ulint(fsize / page_size)
- + file_start_page_no;
- }
- free(buf2);
+ DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28",
+ *success = FALSE;
+ os_has_said_disk_full = TRUE;);
+
+ if (*success) {
+ os_has_said_disk_full = FALSE;
+ start_page_no = size;
}
-#endif
mutex_enter(&fil_system->mutex);
ut_a(node->being_extended);
@@ -1204,7 +1072,7 @@ fil_space_extend_must_retry(
space->size += file_size - node->size;
node->size = file_size;
- fil_node_complete_io(node, fil_system, io_completion_type);
+ fil_node_complete_io(node, fil_system, OS_FILE_READ);
node->being_extended = FALSE;
@@ -2257,7 +2125,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(2 * UNIV_PAGE_SIZE));
buf = static_cast<byte*>(ut_align(buf1, UNIV_PAGE_SIZE));
@@ -2268,7 +2136,8 @@ fil_write_flushed_lsn(
/* If tablespace is not encrypted, stamp flush_lsn to
first page of all system tablespace datafiles to avoid
unnecessary error messages on possible downgrade. */
- if (!space->crypt_data || space->crypt_data->min_key_version == 0) {
+ if (!space->crypt_data
+ || !space->crypt_data->should_encrypt()) {
fil_node_t* node;
ulint sum_of_sizes = 0;
@@ -2704,8 +2573,7 @@ fil_op_log_parse_or_replay(
switch (type) {
case MLOG_FILE_DELETE:
if (fil_tablespace_exists_in_mem(space_id)) {
- dberr_t err = fil_delete_tablespace(
- space_id, BUF_REMOVE_FLUSH_NO_WRITE);
+ dberr_t err = fil_delete_tablespace(space_id);
ut_a(err == DB_SUCCESS);
}
@@ -2983,7 +2851,7 @@ 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, BUF_REMOVE_FLUSH_WRITE, trx);
+ buf_LRU_flush_or_remove_pages(id, trx);
#endif
mutex_enter(&fil_system->mutex);
@@ -3010,18 +2878,13 @@ fil_close_tablespace(
return(err);
}
-/*******************************************************************//**
-Deletes a single-table tablespace. The tablespace must be cached in the
-memory cache.
+/** 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 */
UNIV_INTERN
dberr_t
-fil_delete_tablespace(
-/*==================*/
- ulint id, /*!< in: space id */
- buf_remove_t buf_remove) /*!< in: specify the action to take
- on the tables pages in the buffer
- pool */
+fil_delete_tablespace(ulint id, bool drop_ahi)
{
char* path = 0;
fil_space_t* space = 0;
@@ -3077,7 +2940,7 @@ fil_delete_tablespace(
To deal with potential read requests by checking the
::stop_new_ops flag in fil_io() */
- buf_LRU_flush_or_remove_pages(id, buf_remove, 0);
+ buf_LRU_flush_or_remove_pages(id, NULL, drop_ahi);
#endif /* !UNIV_HOTBACKUP */
@@ -3188,7 +3051,7 @@ fil_discard_tablespace(
{
dberr_t err;
- switch (err = fil_delete_tablespace(id, BUF_REMOVE_ALL_NO_WRITE)) {
+ switch (err = fil_delete_tablespace(id, true)) {
case DB_SUCCESS:
break;
@@ -4995,7 +4858,7 @@ fil_load_single_table_tablespace(
/* Check for a link file which locates a remote tablespace. */
- remote.success = fil_open_linked_file(
+ remote.success = (IS_XTRABACKUP() && !srv_backup_mode) ? 0 : fil_open_linked_file(
tablename, &remote.filepath, &remote.file, FALSE);
/* Read the first page of the remote tablespace */
@@ -5104,6 +4967,11 @@ will_not_choose:
return;
}
+ /* In mariabackup lets not crash. */
+ if (IS_XTRABACKUP()) {
+ return;
+ }
+
abort();
}
@@ -6193,7 +6061,7 @@ Reads or writes data. This operation is asynchronous (aio).
i/o on a tablespace which does not exist */
UNIV_INTERN
dberr_t
-_fil_io(
+fil_io(
/*===*/
ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE,
ORed to OS_FILE_LOG, if a log i/o
@@ -6225,7 +6093,12 @@ _fil_io(
operation for this page and if
initialized we do not trim again if
actual page size does not decrease. */
- trx_t* trx)
+ trx_t* trx,
+ bool should_buffer) /*!< in: whether to buffer an aio request.
+ AIO read ahead uses this. If you plan to
+ use this parameter, make sure you remember
+ to call os_aio_dispatch_read_array_submit()
+ when you're ready to commit all your requests.*/
{
ulint mode;
fil_space_t* space;
@@ -6445,8 +6318,8 @@ _fil_io(
/* Queue the aio request */
ret = os_aio(type, is_log, mode | wake_later, name, node->handle, buf,
- offset, len, zip_size ? zip_size : UNIV_PAGE_SIZE, node,
- message, space_id, trx, write_size);
+ offset, len, zip_size ? zip_size : UNIV_PAGE_SIZE, node,
+ message, space_id, trx, write_size, should_buffer);
#else
/* In mysqlbackup do normal i/o, not aio */
diff --git a/storage/xtradb/fil/fil0pagecompress.cc b/storage/xtradb/fil/fil0pagecompress.cc
index 2b6ae95640f..edc932f36f5 100644
--- a/storage/xtradb/fil/fil0pagecompress.cc
+++ b/storage/xtradb/fil/fil0pagecompress.cc
@@ -106,6 +106,9 @@ fil_compress_page(
int comp_level = level;
ulint header_len = FIL_PAGE_DATA + FIL_PAGE_COMPRESSED_SIZE;
ulint write_size = 0;
+#if HAVE_LZO
+ lzo_uint write_size_lzo = write_size;
+#endif
/* Cache to avoid change during function execution */
ulint comp_method = innodb_compression_algorithm;
bool allocated = false;
@@ -207,7 +210,9 @@ fil_compress_page(
#ifdef HAVE_LZO
case PAGE_LZO_ALGORITHM:
err = lzo1x_1_15_compress(
- buf, len, out_buf+header_len, &write_size, out_buf+UNIV_PAGE_SIZE);
+ buf, len, out_buf+header_len, &write_size_lzo, out_buf+UNIV_PAGE_SIZE);
+
+ write_size = write_size_lzo;
if (err != LZO_E_OK || write_size > UNIV_PAGE_SIZE-header_len) {
if (space && !space->printed_compression_failure) {
@@ -397,7 +402,8 @@ fil_compress_page(
fil_decompress_page(uncomp_page, comp_page, ulong(len), NULL);
if (buf_page_is_corrupted(false, uncomp_page, 0, space)) {
- buf_page_print(uncomp_page, 0, 0);
+ buf_page_print(uncomp_page, 0);
+ ut_ad(0);
}
ut_free(comp_page);
@@ -603,8 +609,11 @@ fil_decompress_page(
#ifdef HAVE_LZO
case PAGE_LZO_ALGORITHM: {
ulint olen = 0;
+ lzo_uint olen_lzo = olen;
err = lzo1x_decompress((const unsigned char *)buf+header_len,
- actual_size,(unsigned char *)in_buf, &olen, NULL);
+ actual_size,(unsigned char *)in_buf, &olen_lzo, NULL);
+
+ olen = olen_lzo;
if (err != LZO_E_OK || (olen == 0 || olen > UNIV_PAGE_SIZE)) {
ib_logf(IB_LOG_LEVEL_ERROR,
diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc
index e1a95bcd427..98aaf610f2a 100644
--- a/storage/xtradb/fts/fts0fts.cc
+++ b/storage/xtradb/fts/fts0fts.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, MariaDB Corporation. All Rights reserved.
+Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2016, 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
@@ -26,6 +26,7 @@ Full Text Search interface
#include "row0mysql.h"
#include "row0upd.h"
#include "dict0types.h"
+#include "dict0stats_bg.h"
#include "row0sel.h"
#include "fts0fts.h"
@@ -868,18 +869,37 @@ fts_drop_index(
err = fts_drop_index_tables(trx, index);
- fts_free(table);
-
+ for(;;) {
+ bool retry = false;
+ if (index->index_fts_syncing) {
+ retry = true;
+ }
+ if (!retry){
+ fts_free(table);
+ break;
+ }
+ DICT_BG_YIELD(trx);
+ }
return(err);
}
- current_doc_id = table->fts->cache->next_doc_id;
- first_doc_id = table->fts->cache->first_doc_id;
- fts_cache_clear(table->fts->cache);
- fts_cache_destroy(table->fts->cache);
- table->fts->cache = fts_cache_create(table);
- table->fts->cache->next_doc_id = current_doc_id;
- table->fts->cache->first_doc_id = first_doc_id;
+ for(;;) {
+ bool retry = false;
+ if (index->index_fts_syncing) {
+ retry = true;
+ }
+ if (!retry){
+ current_doc_id = table->fts->cache->next_doc_id;
+ first_doc_id = table->fts->cache->first_doc_id;
+ fts_cache_clear(table->fts->cache);
+ fts_cache_destroy(table->fts->cache);
+ table->fts->cache = fts_cache_create(table);
+ table->fts->cache->next_doc_id = current_doc_id;
+ table->fts->cache->first_doc_id = first_doc_id;
+ break;
+ }
+ DICT_BG_YIELD(trx);
+ }
} else {
fts_cache_t* cache = table->fts->cache;
fts_index_cache_t* index_cache;
@@ -889,9 +909,17 @@ fts_drop_index(
index_cache = fts_find_index_cache(cache, index);
if (index_cache != NULL) {
- if (index_cache->words) {
- fts_words_free(index_cache->words);
- rbt_free(index_cache->words);
+ for(;;) {
+ bool retry = false;
+ if (index->index_fts_syncing) {
+ retry = true;
+ }
+ if (!retry && index_cache->words) {
+ fts_words_free(index_cache->words);
+ rbt_free(index_cache->words);
+ break;
+ }
+ DICT_BG_YIELD(trx);
}
ib_vector_remove(cache->indexes, *(void**) index_cache);
@@ -1973,7 +2001,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,
@@ -2644,22 +2672,23 @@ fts_get_next_doc_id(
will consult the CONFIG table and user table to re-establish
the initial value of the Doc ID */
- if (cache->first_doc_id != 0 || !fts_init_doc_id(table)) {
- if (!DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID)) {
- *doc_id = FTS_NULL_DOC_ID;
- return(DB_SUCCESS);
+ if (!DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID)) {
+ if (cache->first_doc_id == FTS_NULL_DOC_ID) {
+ fts_init_doc_id(table);
}
+ *doc_id = FTS_NULL_DOC_ID;
+ return(DB_SUCCESS);
+ }
- /* Otherwise, simply increment the value in cache */
- mutex_enter(&cache->doc_id_lock);
- *doc_id = ++cache->next_doc_id;
- mutex_exit(&cache->doc_id_lock);
- } else {
- mutex_enter(&cache->doc_id_lock);
- *doc_id = cache->next_doc_id;
- mutex_exit(&cache->doc_id_lock);
+ if (cache->first_doc_id == FTS_NULL_DOC_ID) {
+ fts_init_doc_id(table);
}
+ DEBUG_SYNC_C("get_next_FTS_DOC_ID");
+ mutex_enter(&cache->doc_id_lock);
+ *doc_id = cache->next_doc_id++;
+ mutex_exit(&cache->doc_id_lock);
+
return(DB_SUCCESS);
}
@@ -3033,53 +3062,6 @@ fts_modify(
}
/*********************************************************************//**
-Create a new document id.
-@return DB_SUCCESS if all went well else error */
-UNIV_INTERN
-dberr_t
-fts_create_doc_id(
-/*==============*/
- dict_table_t* table, /*!< in: row is of this table. */
- dtuple_t* row, /* in/out: add doc id value to this
- row. This is the current row that is
- being inserted. */
- mem_heap_t* heap) /*!< in: heap */
-{
- doc_id_t doc_id;
- dberr_t error = DB_SUCCESS;
-
- ut_a(table->fts->doc_col != ULINT_UNDEFINED);
-
- if (!DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID)) {
- if (table->fts->cache->first_doc_id == FTS_NULL_DOC_ID) {
- error = fts_get_next_doc_id(table, &doc_id);
- }
- return(error);
- }
-
- error = fts_get_next_doc_id(table, &doc_id);
-
- if (error == DB_SUCCESS) {
- dfield_t* dfield;
- doc_id_t* write_doc_id;
-
- ut_a(doc_id > 0);
-
- dfield = dtuple_get_nth_field(row, table->fts->doc_col);
- write_doc_id = static_cast<doc_id_t*>(
- mem_heap_alloc(heap, sizeof(*write_doc_id)));
-
- ut_a(doc_id != FTS_NULL_DOC_ID);
- ut_a(sizeof(doc_id) == dfield->type.len);
- fts_write_doc_id((byte*) write_doc_id, doc_id);
-
- dfield_set_data(dfield, write_doc_id, sizeof(*write_doc_id));
- }
-
- return(error);
-}
-
-/*********************************************************************//**
The given transaction is about to be committed; do whatever is necessary
from the FTS system's POV.
@return DB_SUCCESS or error code */
@@ -3379,8 +3361,7 @@ fts_fetch_doc_from_rec(
dict_table_zip_size(table),
clust_pos, &doc->text.f_len,
static_cast<mem_heap_t*>(
- doc->self_heap->arg),
- NULL);
+ doc->self_heap->arg));
} else {
doc->text.f_str = (byte*) rec_get_nth_field(
clust_rec, offsets, clust_pos,
@@ -4614,10 +4595,16 @@ begin_sync:
index_cache = static_cast<fts_index_cache_t*>(
ib_vector_get(cache->indexes, i));
- if (index_cache->index->to_be_dropped) {
+ if (index_cache->index->to_be_dropped
+ || index_cache->index->table->to_be_dropped) {
continue;
}
+ index_cache->index->index_fts_syncing = true;
+ DBUG_EXECUTE_IF("fts_instrument_sync_sleep_drop_waits",
+ os_thread_sleep(10000000);
+ );
+
error = fts_sync_index(sync, index_cache);
if (error != DB_SUCCESS && !sync->interrupted) {
@@ -4650,11 +4637,33 @@ begin_sync:
end_sync:
if (error == DB_SUCCESS && !sync->interrupted) {
error = fts_sync_commit(sync);
+ if (error == DB_SUCCESS) {
+ for (i = 0; i < ib_vector_size(cache->indexes); ++i) {
+ fts_index_cache_t* index_cache;
+ index_cache = static_cast<fts_index_cache_t*>(
+ ib_vector_get(cache->indexes, i));
+ if (index_cache->index->index_fts_syncing) {
+ index_cache->index->index_fts_syncing
+ = false;
+ }
+ }
+ }
} else {
fts_sync_rollback(sync);
}
rw_lock_x_lock(&cache->lock);
+ /* Clear fts syncing flags of any indexes incase sync is
+ interrupeted */
+ for (i = 0; i < ib_vector_size(cache->indexes); ++i) {
+ fts_index_cache_t* index_cache;
+ index_cache = static_cast<fts_index_cache_t*>(
+ ib_vector_get(cache->indexes, i));
+ if (index_cache->index->index_fts_syncing == true) {
+ index_cache->index->index_fts_syncing = false;
+ }
+ }
+
sync->interrupted = false;
sync->in_progress = false;
os_event_set(sync->event);
@@ -7581,8 +7590,7 @@ fts_init_recover_doc(
&doc.text.f_len,
static_cast<byte*>(dfield_get_data(dfield)),
zip_size, len,
- static_cast<mem_heap_t*>(doc.self_heap->arg),
- NULL);
+ 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/xtradb/fts/fts0opt.cc b/storage/xtradb/fts/fts0opt.cc
index cb30122adcb..d9f96948000 100644
--- a/storage/xtradb/fts/fts0opt.cc
+++ b/storage/xtradb/fts/fts0opt.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2007, 2017, 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
@@ -2971,13 +2971,6 @@ fts_optimize_sync_table(
{
dict_table_t* table = NULL;
- /* Prevent DROP INDEX etc. from running when we are syncing
- cache in background. */
- if (!rw_lock_s_lock_nowait(&dict_operation_lock, __FILE__, __LINE__)) {
- /* Exit when fail to get dict operation lock. */
- return;
- }
-
table = dict_table_open_on_id(table_id, FALSE, DICT_TABLE_OP_NORMAL);
if (table) {
@@ -2987,8 +2980,6 @@ fts_optimize_sync_table(
dict_table_close(table, FALSE, FALSE);
}
-
- rw_lock_s_unlock(&dict_operation_lock);
}
/**********************************************************************//**
diff --git a/storage/xtradb/fts/fts0que.cc b/storage/xtradb/fts/fts0que.cc
index f24973e26fb..0b0aecaeaa2 100644
--- a/storage/xtradb/fts/fts0que.cc
+++ b/storage/xtradb/fts/fts0que.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
-Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2007, 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
the terms of the GNU General Public License as published by the Free Software
@@ -1936,8 +1937,7 @@ fts_query_fetch_document(
if (dfield_is_ext(dfield)) {
data = btr_copy_externally_stored_field(
&cur_len, data, phrase->zip_size,
- dfield_get_len(dfield), phrase->heap,
- NULL);
+ dfield_get_len(dfield), phrase->heap);
} else {
cur_len = dfield_get_len(dfield);
}
@@ -3653,6 +3653,11 @@ fts_query_free(
fts_doc_ids_free(query->deleted);
}
+ if (query->intersection) {
+ fts_query_free_doc_ids(query, query->intersection);
+ query->intersection = NULL;
+ }
+
if (query->doc_ids) {
fts_query_free_doc_ids(query, query->doc_ids);
}
@@ -3677,8 +3682,6 @@ fts_query_free(
rbt_free(query->word_freqs);
}
- ut_a(!query->intersection);
-
if (query->word_map) {
rbt_free(query->word_map);
}
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index c333f3e9686..65ac41c26de 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -1289,6 +1289,8 @@ static SHOW_VAR innodb_status_variables[]= {
(char*) &export_vars.innodb_sec_rec_cluster_reads, SHOW_LONG},
{"secondary_index_triggered_cluster_reads_avoided",
(char*) &export_vars.innodb_sec_rec_cluster_reads_avoided, SHOW_LONG},
+ {"buffered_aio_submitted",
+ (char*) &export_vars.innodb_buffered_aio_submitted, SHOW_LONG},
/* Encryption */
{"encryption_rotation_pages_read_from_cache",
@@ -1309,6 +1311,18 @@ static SHOW_VAR innodb_status_variables[]= {
{"encryption_key_rotation_list_length",
(char*)&export_vars.innodb_key_rotation_list_length,
SHOW_LONGLONG},
+ {"encryption_n_merge_blocks_encrypted",
+ (char*)&export_vars.innodb_n_merge_blocks_encrypted,
+ SHOW_LONGLONG},
+ {"encryption_n_merge_blocks_decrypted",
+ (char*)&export_vars.innodb_n_merge_blocks_decrypted,
+ SHOW_LONGLONG},
+ {"encryption_n_rowlog_blocks_encrypted",
+ (char*)&export_vars.innodb_n_rowlog_blocks_encrypted,
+ SHOW_LONGLONG},
+ {"encryption_n_rowlog_blocks_decrypted",
+ (char*)&export_vars.innodb_n_rowlog_blocks_decrypted,
+ SHOW_LONGLONG},
/* Scrubing feature */
{"scrub_background_page_reorganizations",
@@ -3922,6 +3936,17 @@ innobase_init(
}
}
+#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) {
+ /* Do not allow InnoDB startup with VATS and Galera */
+ sql_print_error("In Galera, innodb_lock_schedule_algorithm=vats"
+ " is not supported.");
+ goto error;
+ }
+#endif /* WITH_WSREP */
+
#ifndef HAVE_LZ4
if (innodb_compression_algorithm == PAGE_LZ4_ALGORITHM) {
sql_print_error("InnoDB: innodb_compression_algorithm = %lu unsupported.\n"
@@ -4621,7 +4646,7 @@ innobase_commit_low(
trx_commit_for_mysql(trx);
}
#ifdef WITH_WSREP
- if (wsrep_on(thd)) { thd_proc_info(thd, tmp); }
+ if (thd && wsrep_on(thd)) { thd_proc_info(thd, tmp); }
#endif /* WITH_WSREP */
}
@@ -5473,8 +5498,8 @@ innobase_kill_connection(
wsrep_thd_is_BF(current_thd, FALSE),
lock_get_info(trx->lock.wait_lock).c_str());
- if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
- trx->abort_type == TRX_SERVER_ABORT) {
+ if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE)
+ && trx->abort_type == TRX_SERVER_ABORT) {
ut_ad(!lock_mutex_own());
lock_mutex_enter();
}
@@ -5971,8 +5996,6 @@ innobase_match_index_columns(
if (innodb_idx_fld >= innodb_idx_fld_end) {
DBUG_RETURN(FALSE);
}
-
- mtype = innodb_idx_fld->col->mtype;
}
if (col_type != mtype) {
@@ -8860,7 +8883,7 @@ no_commit:
table->next_number_field);
/* Get the value that MySQL attempted to store in the table.*/
- auto_inc = table->next_number_field->val_int();
+ auto_inc = table->next_number_field->val_uint();
switch (error) {
case DB_DUPLICATE_KEY:
@@ -9452,7 +9475,7 @@ ha_innobase::update_row(
ulonglong auto_inc;
ulonglong col_max_value;
- auto_inc = table->next_number_field->val_int();
+ auto_inc = table->next_number_field->val_uint();
/* We need the upper limit of the col type to check for
whether we update the table autoinc counter or not. */
@@ -10586,6 +10609,27 @@ ha_innobase::ft_init_ext(
}
/*****************************************************************//**
+Copy a cached MySQL row.
+If requested, also avoids overwriting non-read columns.
+@param[out] buf Row in MySQL format.
+@param[in] cached_row Which row to copy.
+@param[in] rec_len Record length. */
+void
+ha_innobase::copy_cached_row(
+ uchar* buf,
+ const uchar* cached_row,
+ uint rec_len)
+{
+ if (prebuilt->keep_other_fields_on_keyread) {
+ row_sel_copy_cached_fields_for_mysql(buf, cached_row,
+ prebuilt);
+ } else {
+ memcpy(buf, cached_row, rec_len);
+ }
+}
+
+
+/*****************************************************************//**
Set up search tuple for a query through FTS_DOC_ID_INDEX on
supplied Doc ID. This is used by MySQL to retrieve the documents
once the search result (Doc IDs) is available */
@@ -10953,7 +10997,7 @@ wsrep_append_foreign_key(
shared ? WSREP_KEY_SHARED : WSREP_KEY_EXCLUSIVE,
copy);
if (rcode) {
- DBUG_PRINT("wsrep", ("row key failed: %lu", rcode));
+ DBUG_PRINT("wsrep", ("row key failed: %zu", rcode));
WSREP_ERROR("Appending cascaded fk row key failed: %s, %lu",
(wsrep_thd_query(thd)) ?
wsrep_thd_query(thd) : "void", rcode);
@@ -12279,6 +12323,7 @@ index_bad:
case ROW_TYPE_DEFAULT:
/* If we fell through, set row format to Compact. */
row_format = ROW_TYPE_COMPACT;
+ /* fall through */
case ROW_TYPE_COMPACT:
break;
}
@@ -13668,7 +13713,7 @@ ha_innobase::records_in_range(
n_rows = btr_estimate_n_rows_in_range(index, range_start,
mode1, range_end,
- mode2, prebuilt->trx);
+ mode2);
} else {
n_rows = HA_POS_ERROR;
@@ -17144,6 +17189,10 @@ innobase_commit_by_xid(
DBUG_ASSERT(hton == innodb_hton_ptr);
+ if (high_level_read_only) {
+ return(XAER_RMFAIL);
+ }
+
trx = trx_get_trx_by_xid(xid);
if (trx) {
@@ -17171,8 +17220,11 @@ innobase_rollback_by_xid(
DBUG_ASSERT(hton == innodb_hton_ptr);
- trx = trx_get_trx_by_xid(xid);
+ if (high_level_read_only) {
+ return(XAER_RMFAIL);
+ }
+ trx = trx_get_trx_by_xid(xid);
if (trx) {
int ret = innobase_rollback_trx(trx);
trx_free_for_background(trx);
@@ -19418,7 +19470,7 @@ buffer_pool_load_now(
const void* save) /*!< in: immediate result from
check function */
{
- if (*(my_bool*) save) {
+ if (*(my_bool*) save && !srv_read_only_mode) {
buf_load_start();
}
}
@@ -19441,7 +19493,7 @@ buffer_pool_load_abort(
const void* save) /*!< in: immediate result from
check function */
{
- if (*(my_bool*) save) {
+ if (*(my_bool*) save && !srv_read_only_mode) {
buf_load_abort();
}
}
@@ -19713,7 +19765,7 @@ wsrep_innobase_kill_one_trx(
wsrep_thd_awake(thd, signal);
} else {
/* abort currently executing query */
- DBUG_PRINT("wsrep",("sending KILL_QUERY to: %ld",
+ DBUG_PRINT("wsrep",("sending KILL_QUERY to: %lu",
thd_get_thread_id(thd)));
WSREP_DEBUG("kill query for: %ld",
thd_get_thread_id(thd));
@@ -19840,7 +19892,8 @@ wsrep_fake_trx_id(
mutex_enter(&trx_sys->mutex);
trx_id_t trx_id = trx_sys_get_new_trx_id();
mutex_exit(&trx_sys->mutex);
- WSREP_DEBUG("innodb fake trx id: %lu thd: %s", trx_id, wsrep_thd_query(thd));
+ 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);
}
@@ -20461,7 +20514,7 @@ static MYSQL_SYSVAR_ENUM(empty_free_list_algorithm,
&innodb_empty_free_list_algorithm_typelib);
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"
@@ -21031,6 +21084,13 @@ static MYSQL_SYSVAR_BOOL(print_all_deadlocks, srv_print_all_deadlocks,
"Print all deadlocks to MySQL error log (off by default)",
NULL, NULL, FALSE);
+static MYSQL_SYSVAR_BOOL(
+ print_lock_wait_timeout_info,
+ srv_print_lock_wait_timeout_info,
+ PLUGIN_VAR_OPCMDARG,
+ "Print lock wait timeout info to MySQL error log (off by default)",
+ NULL, NULL, FALSE);
+
static MYSQL_SYSVAR_ULONG(compression_failure_threshold_pct,
zip_failure_threshold_pct, PLUGIN_VAR_OPCMDARG,
"If the compression failure rate of a table is greater than this number"
@@ -21489,6 +21549,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(foreground_preflush),
MYSQL_SYSVAR(empty_free_list_algorithm),
MYSQL_SYSVAR(print_all_deadlocks),
+ MYSQL_SYSVAR(print_lock_wait_timeout_info),
MYSQL_SYSVAR(cmp_per_index_enabled),
MYSQL_SYSVAR(undo_logs),
MYSQL_SYSVAR(rollback_segments),
@@ -21930,27 +21991,21 @@ ib_logf(
str = static_cast<char*>(malloc(BUFSIZ));
my_vsnprintf(str, BUFSIZ, format, args);
#endif /* __WIN__ */
- if (!IS_XTRABACKUP()) {
- switch (level) {
- case IB_LOG_LEVEL_INFO:
- sql_print_information("InnoDB: %s", str);
- break;
- case IB_LOG_LEVEL_WARN:
- sql_print_warning("InnoDB: %s", str);
- break;
- case IB_LOG_LEVEL_ERROR:
- sql_print_error("InnoDB: %s", str);
- sd_notifyf(0, "STATUS=InnoDB: Error: %s", str);
- break;
- case IB_LOG_LEVEL_FATAL:
- sql_print_error("InnoDB: %s", str);
- sd_notifyf(0, "STATUS=InnoDB: Fatal: %s", str);
- break;
- }
- }
- else {
- /* Don't use server logger for XtraBackup, just print to stderr. */
- fprintf(stderr, "InnoDB: %s\n", str);
+ switch (level) {
+ case IB_LOG_LEVEL_INFO:
+ sql_print_information("InnoDB: %s", str);
+ break;
+ case IB_LOG_LEVEL_WARN:
+ sql_print_warning("InnoDB: %s", str);
+ break;
+ case IB_LOG_LEVEL_ERROR:
+ sql_print_error("InnoDB: %s", str);
+ sd_notifyf(0, "STATUS=InnoDB: Error: %s", str);
+ break;
+ case IB_LOG_LEVEL_FATAL:
+ sql_print_error("InnoDB: %s", str);
+ sd_notifyf(0, "STATUS=InnoDB: Fatal: %s", str);
+ break;
}
va_end(args);
diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h
index 426136e4d51..c5b0e723702 100644
--- a/storage/xtradb/handler/ha_innodb.h
+++ b/storage/xtradb/handler/ha_innodb.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2013, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -167,6 +167,10 @@ class ha_innobase: public handler
int index_first(uchar * buf);
int index_last(uchar * buf);
+ /* Copy a cached MySQL row. If requested, also avoids
+ overwriting non-read columns. */
+ void copy_cached_row(uchar *to_rec, const uchar *from_rec,
+ uint rec_length);
bool has_gap_locks() const { return true; }
int rnd_init(bool scan);
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index ef2478bd239..2a2c466fd4f 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2013, 2018, 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
@@ -212,60 +212,44 @@ innobase_fulltext_exist(
return(false);
}
-/*******************************************************************//**
-Determine if ALTER TABLE needs to rebuild the table.
-@param ha_alter_info the DDL operation
-@param altered_table MySQL original table
+/** Determine if ALTER TABLE needs to rebuild the table.
+@param ha_alter_info the DDL operation
+@param table metadata before ALTER TABLE
@return whether it is necessary to rebuild the table */
static MY_ATTRIBUTE((nonnull, warn_unused_result))
bool
innobase_need_rebuild(
-/*==================*/
const Alter_inplace_info* ha_alter_info,
- const TABLE* altered_table)
+ const TABLE* table)
{
Alter_inplace_info::HA_ALTER_FLAGS alter_inplace_flags =
- ha_alter_info->handler_flags & ~(INNOBASE_INPLACE_IGNORE);
+ ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE;
+
+ if (alter_inplace_flags & Alter_inplace_info::CHANGE_CREATE_OPTION) {
+ const ha_table_option_struct& alt_opt=
+ *ha_alter_info->create_info->option_struct;
+ const ha_table_option_struct& opt= *table->s->option_struct;
+
+ if (alt_opt.page_compressed != opt.page_compressed
+ || alt_opt.page_compression_level
+ != opt.page_compression_level
+ || alt_opt.encryption != opt.encryption
+ || alt_opt.encryption_key_id != opt.encryption_key_id) {
+ return(true);
+ }
+ }
- if (alter_inplace_flags
- == Alter_inplace_info::CHANGE_CREATE_OPTION
+ if (alter_inplace_flags == Alter_inplace_info::CHANGE_CREATE_OPTION
&& !(ha_alter_info->create_info->used_fields
& (HA_CREATE_USED_ROW_FORMAT
| HA_CREATE_USED_KEY_BLOCK_SIZE))) {
/* Any other CHANGE_CREATE_OPTION than changing
- ROW_FORMAT or KEY_BLOCK_SIZE is ignored. */
+ ROW_FORMAT or KEY_BLOCK_SIZE can be done without
+ rebuilding the table. */
return(false);
}
- /* If alter table changes column name and adds a new
- index, we need to check is this new index created
- to new column name. This is because column name
- changes are done normally after creating indexes. */
- if ((ha_alter_info->handler_flags
- & Alter_inplace_info::ALTER_COLUMN_NAME) &&
- ((ha_alter_info->handler_flags
- & Alter_inplace_info::ADD_INDEX) ||
- (ha_alter_info->handler_flags
- & Alter_inplace_info::ADD_FOREIGN_KEY))) {
- for (ulint i = 0; i < ha_alter_info->index_add_count; i++) {
- const KEY* key = &ha_alter_info->key_info_buffer[
- ha_alter_info->index_add_buffer[i]];
-
- for (ulint j = 0; j < key->user_defined_key_parts; j++) {
- const KEY_PART_INFO* key_part = &(key->key_part[j]);
- const Field* field = altered_table->field[key_part->fieldnr];
-
- /* Field used on added index is renamed on
- this same alter table. We need table
- rebuild. */
- if (field && field->flags & FIELD_IS_RENAMED) {
- return (true);
- }
- }
- }
- }
-
- return(!!(ha_alter_info->handler_flags & INNOBASE_ALTER_REBUILD));
+ return(!!(alter_inplace_flags & INNOBASE_ALTER_REBUILD));
}
/** Check if InnoDB supports a particular alter table in-place
@@ -315,29 +299,6 @@ ha_innobase::check_if_supported_inplace_alter(
update_thd();
trx_search_latch_release_if_reserved(prebuilt->trx);
- /* Change on engine specific table options require rebuild of the
- table */
- if (ha_alter_info->handler_flags
- & Alter_inplace_info::CHANGE_CREATE_OPTION) {
- ha_table_option_struct *new_options= ha_alter_info->create_info->option_struct;
- ha_table_option_struct *old_options= table->s->option_struct;
-
- if (new_options->page_compressed != old_options->page_compressed ||
- new_options->page_compression_level != old_options->page_compression_level ||
- new_options->atomic_writes != old_options->atomic_writes) {
- ha_alter_info->unsupported_reason = innobase_get_err_msg(
- ER_ALTER_OPERATION_NOT_SUPPORTED_REASON);
- DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
- }
-
- if (new_options->encryption != old_options->encryption ||
- new_options->encryption_key_id != old_options->encryption_key_id) {
- ha_alter_info->unsupported_reason = innobase_get_err_msg(
- ER_ALTER_OPERATION_NOT_SUPPORTED_REASON);
- DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
- }
- }
-
if (ha_alter_info->handler_flags
& ~(INNOBASE_INPLACE_IGNORE
| INNOBASE_ALTER_NOREBUILD
@@ -617,7 +578,7 @@ ha_innobase::check_if_supported_inplace_alter(
operation is possible. */
} else if (((ha_alter_info->handler_flags
& Alter_inplace_info::ADD_PK_INDEX)
- || innobase_need_rebuild(ha_alter_info, table))
+ || innobase_need_rebuild(ha_alter_info, table))
&& (innobase_fulltext_exist(altered_table))) {
/* Refuse to rebuild the table online, if
fulltext indexes are to survive the rebuild. */
@@ -1239,8 +1200,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;
@@ -1551,38 +1511,49 @@ name_ok:
return(0);
}
-/*******************************************************************//**
-Create index field definition for key part */
+/** Create index field definition for key part
+@param[in] new_clustered true if alter is generating a new clustered
+index
+@param[in] altered_table MySQL table that is being altered
+@param[in] key_part MySQL key definition
+@param[out] index_field index field defition for key_part */
static MY_ATTRIBUTE((nonnull(2,3)))
void
innobase_create_index_field_def(
-/*============================*/
- const TABLE* altered_table, /*!< in: MySQL table that is
- being altered, or NULL
- if a new clustered index is
- not being created */
- const KEY_PART_INFO* key_part, /*!< in: MySQL key definition */
- index_field_t* index_field, /*!< out: index field
- definition for key_part */
- const Field** fields) /*!< in: MySQL table fields */
+ bool new_clustered,
+ const TABLE* altered_table,
+ const KEY_PART_INFO* key_part,
+ index_field_t* index_field)
{
const Field* field;
ibool is_unsigned;
ulint col_type;
+ ulint innodb_fieldnr=0;
DBUG_ENTER("innobase_create_index_field_def");
ut_ad(key_part);
ut_ad(index_field);
+ ut_ad(altered_table);
+
+ /* Virtual columns are not stored in InnoDB data dictionary, thus
+ if there is virtual columns we need to skip them to find the
+ correct field. */
+ for(ulint i = 0; i < key_part->fieldnr; i++) {
+ const Field* table_field = altered_table->field[i];
+ if (!table_field->stored_in_db) {
+ continue;
+ }
+ innodb_fieldnr++;
+ }
- field = altered_table
- ? altered_table->field[key_part->fieldnr]
+ field = new_clustered ?
+ altered_table->field[key_part->fieldnr]
: key_part->field;
- ut_a(field);
- index_field->col_no = key_part->fieldnr;
- index_field->col_name = altered_table ? field->field_name : fields[key_part->fieldnr]->field_name;
+ ut_a(field);
+ index_field->col_no = innodb_fieldnr;
col_type = get_innobase_type_from_mysql_type(&is_unsigned, field);
if (DATA_BLOB == col_type
@@ -1616,10 +1587,8 @@ innobase_create_index_def(
bool key_clustered, /*!< in: true if this is
the new clustered index */
index_def_t* index, /*!< out: index definition */
- mem_heap_t* heap, /*!< in: heap where memory
+ mem_heap_t* heap) /*!< in: heap where memory
is allocated */
- const Field** fields) /*!< in: MySQL table fields
- */
{
const KEY* key = &keys[key_number];
ulint i;
@@ -1630,11 +1599,10 @@ innobase_create_index_def(
DBUG_ENTER("innobase_create_index_def");
DBUG_ASSERT(!key_clustered || new_clustered);
+ ut_ad(altered_table);
+
index->fields = static_cast<index_field_t*>(
mem_heap_alloc(heap, n_fields * sizeof *index->fields));
-
- memset(index->fields, 0, n_fields * sizeof *index->fields);
-
index->ind_type = 0;
index->key_number = key_number;
index->n_fields = n_fields;
@@ -1665,13 +1633,12 @@ innobase_create_index_def(
index->ind_type |= DICT_FTS;
}
- if (!new_clustered) {
- altered_table = NULL;
- }
-
for (i = 0; i < n_fields; i++) {
innobase_create_index_field_def(
- altered_table, &key->key_part[i], &index->fields[i], fields);
+ new_clustered,
+ altered_table,
+ &key->key_part[i],
+ &index->fields[i]);
}
DBUG_VOID_RETURN;
@@ -1997,7 +1964,7 @@ innobase_create_key_defs(
/* Create the PRIMARY key index definition */
innobase_create_index_def(
altered_table, key_info, primary_key_number,
- TRUE, TRUE, indexdef++, heap, (const Field **)altered_table->field);
+ TRUE, TRUE, indexdef++, heap);
created_clustered:
n_add = 1;
@@ -2009,7 +1976,7 @@ created_clustered:
/* Copy the index definitions. */
innobase_create_index_def(
altered_table, key_info, i, TRUE, FALSE,
- indexdef, heap, (const Field **)altered_table->field);
+ indexdef, heap);
if (indexdef->ind_type & DICT_FTS) {
n_fts_add++;
@@ -2054,7 +2021,7 @@ created_clustered:
for (ulint i = 0; i < n_add; i++) {
innobase_create_index_def(
altered_table, key_info, add[i], FALSE, FALSE,
- indexdef, heap, (const Field **)altered_table->field);
+ indexdef, heap);
if (indexdef->ind_type & DICT_FTS) {
n_fts_add++;
@@ -2071,7 +2038,6 @@ created_clustered:
index->fields = static_cast<index_field_t*>(
mem_heap_alloc(heap, sizeof *index->fields));
- memset(index->fields, 0, sizeof *index->fields);
index->n_fields = 1;
index->fields->col_no = fts_doc_id_col;
index->fields->prefix_len = 0;
@@ -2161,7 +2127,7 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
/** mapping of old column numbers to new ones, or NULL */
const ulint* col_map;
/** new column names, or NULL if nothing was renamed */
- const char** col_names;
+ const char** col_names;
/** added AUTO_INCREMENT column position, or ULINT_UNDEFINED */
const ulint add_autoinc;
/** default values of ADD COLUMN, or NULL */
@@ -2892,7 +2858,6 @@ prepare_inplace_alter_table_dict(
to rebuild the table with a temporary name. */
if (new_clustered) {
- fil_space_crypt_t* crypt_data;
const char* new_table_name
= dict_mem_create_temporary_tablename(
ctx->heap,
@@ -2903,13 +2868,29 @@ prepare_inplace_alter_table_dict(
ulint key_id = FIL_DEFAULT_ENCRYPTION_KEY;
fil_encryption_t mode = FIL_ENCRYPTION_DEFAULT;
- fil_space_t* space = fil_space_acquire(ctx->prebuilt->table->space);
- crypt_data = space->crypt_data;
- fil_space_release(space);
+ if (fil_space_t* space
+ = fil_space_acquire(ctx->prebuilt->table->space)) {
+ if (const fil_space_crypt_t* crypt_data
+ = space->crypt_data) {
+ key_id = crypt_data->key_id;
+ mode = crypt_data->encryption;
+ }
- if (crypt_data) {
- key_id = crypt_data->key_id;
- mode = crypt_data->encryption;
+ fil_space_release(space);
+ }
+
+ if (ha_alter_info->handler_flags
+ & Alter_inplace_info::CHANGE_CREATE_OPTION) {
+ const ha_table_option_struct& alt_opt=
+ *ha_alter_info->create_info->option_struct;
+ const ha_table_option_struct& opt=
+ *old_table->s->option_struct;
+ if (alt_opt.encryption != opt.encryption
+ || alt_opt.encryption_key_id
+ != opt.encryption_key_id) {
+ key_id = alt_opt.encryption_key_id;
+ mode = fil_encryption_t(alt_opt.encryption);
+ }
}
if (innobase_check_foreigns(
@@ -3122,8 +3103,7 @@ prepare_inplace_alter_table_dict(
for (ulint a = 0; a < ctx->num_to_add_index; a++) {
ctx->add_index[a] = row_merge_create_index(
- ctx->trx, ctx->new_table,
- &index_defs[a], ctx->col_names);
+ ctx->trx, ctx->new_table, &index_defs[a]);
add_key_nums[a] = index_defs[a].key_number;
@@ -5936,7 +5916,47 @@ ha_innobase::commit_inplace_alter_table(
break;
}
- DICT_STATS_BG_YIELD(trx);
+ DICT_BG_YIELD(trx);
+ }
+
+ /* Make a concurrent Drop fts Index to wait until sync of that
+ fts index is happening in the background */
+ for (;;) {
+ bool retry = false;
+
+ for (inplace_alter_handler_ctx** pctx = ctx_array;
+ *pctx; pctx++) {
+ int count =0;
+ ha_innobase_inplace_ctx* ctx
+ = static_cast<ha_innobase_inplace_ctx*>(*pctx);
+ DBUG_ASSERT(new_clustered == ctx->need_rebuild());
+
+ if (dict_fts_index_syncing(ctx->old_table)) {
+ count++;
+ if (count == 100) {
+ fprintf(stderr,
+ "Drop index waiting for background sync"
+ "to finish\n");
+ }
+ retry = true;
+ }
+
+ if (new_clustered && dict_fts_index_syncing(ctx->new_table)) {
+ count++;
+ if (count == 100) {
+ fprintf(stderr,
+ "Drop index waiting for background sync"
+ "to finish\n");
+ }
+ retry = true;
+ }
+ }
+
+ if (!retry) {
+ break;
+ }
+
+ DICT_BG_YIELD(trx);
}
/* Apply the changes to the data dictionary tables, for all
@@ -6252,8 +6272,13 @@ foreign_fail:
ut_d(dict_table_check_for_dup_indexes(
ctx->new_table, CHECK_ABORTED_OK));
- ut_a(fts_check_cached_index(ctx->new_table));
+#ifdef UNIV_DEBUG
+ if (!(ctx->new_table->fts != NULL
+ && ctx->new_table->fts->cache->sync->in_progress)) {
+ ut_a(fts_check_cached_index(ctx->new_table));
+ }
+#endif
if (new_clustered) {
/* Since the table has been rebuilt, we remove
all persistent statistics corresponding to the
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index ca2c76c31ad..94cd6f29558 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -6363,6 +6363,7 @@ i_s_sys_tables_fill_table_stats(
}
heap = mem_heap_create(1000);
+ rw_lock_s_lock(&dict_operation_lock);
mutex_enter(&dict_sys->mutex);
mtr_start(&mtr);
@@ -6389,9 +6390,11 @@ i_s_sys_tables_fill_table_stats(
err_msg);
}
+ rw_lock_s_unlock(&dict_operation_lock);
mem_heap_empty(heap);
/* Get the next record */
+ rw_lock_s_lock(&dict_operation_lock);
mutex_enter(&dict_sys->mutex);
mtr_start(&mtr);
rec = dict_getnext_system(&pcur, &mtr);
@@ -6399,6 +6402,7 @@ i_s_sys_tables_fill_table_stats(
mtr_commit(&mtr);
mutex_exit(&dict_sys->mutex);
+ rw_lock_s_unlock(&dict_operation_lock);
mem_heap_free(heap);
DBUG_RETURN(0);
@@ -7690,8 +7694,6 @@ i_s_dict_fill_sys_tablespaces(
{
Field** fields;
ulint atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(flags);
- ulint page_size = fsp_flags_get_page_size(flags);
- ulint zip_size = fsp_flags_get_zip_size(flags);
const char* file_format;
const char* row_format;
@@ -7708,13 +7710,11 @@ i_s_dict_fill_sys_tablespaces(
fields = table_to_fill->field;
- OK(fields[SYS_TABLESPACES_SPACE]->store(
- static_cast<double>(space)));
+ OK(fields[SYS_TABLESPACES_SPACE]->store(space, true));
OK(field_store_string(fields[SYS_TABLESPACES_NAME], name));
- OK(fields[SYS_TABLESPACES_FLAGS]->store(
- static_cast<double>(flags)));
+ OK(fields[SYS_TABLESPACES_FLAGS]->store(flags, true));
OK(field_store_string(fields[SYS_TABLESPACES_FILE_FORMAT],
file_format));
@@ -7722,11 +7722,18 @@ i_s_dict_fill_sys_tablespaces(
OK(field_store_string(fields[SYS_TABLESPACES_ROW_FORMAT],
row_format));
- OK(fields[SYS_TABLESPACES_PAGE_SIZE]->store(
- static_cast<double>(page_size)));
+ ulint cflags = fsp_flags_is_valid(flags, space)
+ ? flags : fsp_flags_convert_from_101(flags);
+ if (cflags != ULINT_UNDEFINED) {
+ OK(fields[SYS_TABLESPACES_PAGE_SIZE]->store(
+ fsp_flags_get_page_size(cflags), true));
- OK(fields[SYS_TABLESPACES_ZIP_PAGE_SIZE]->store(
- static_cast<double>(zip_size)));
+ OK(fields[SYS_TABLESPACES_ZIP_PAGE_SIZE]->store(
+ fsp_flags_get_zip_size(cflags), true));
+ } else {
+ fields[SYS_TABLESPACES_PAGE_SIZE]->set_null();
+ fields[SYS_TABLESPACES_ZIP_PAGE_SIZE]->set_null();
+ }
OK(schema_table_store_record(thd, table_to_fill));
diff --git a/storage/xtradb/ibuf/ibuf0ibuf.cc b/storage/xtradb/ibuf/ibuf0ibuf.cc
index b920c2ae594..b169916c34e 100644
--- a/storage/xtradb/ibuf/ibuf0ibuf.cc
+++ b/storage/xtradb/ibuf/ibuf0ibuf.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 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
@@ -4042,7 +4042,7 @@ ibuf_insert_to_index_page_low(
(ulong) zip_size, (ulong) old_bits);
fputs("InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n", stderr);
+ " to https://jira.mariadb.org/\n", stderr);
ut_ad(0);
DBUG_RETURN(NULL);
}
@@ -4104,7 +4104,7 @@ ibuf_insert_to_index_page(
"InnoDB: but the number of fields does not match!\n",
stderr);
dump:
- buf_page_print(page, 0, BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page, 0);
dtuple_print(stderr, entry);
ut_ad(0);
@@ -4115,7 +4115,7 @@ dump:
" Please run CHECK TABLE on\n"
"InnoDB: your tables.\n"
"InnoDB: Submit a detailed bug report to"
- " http://bugs.mysql.com!\n", stderr);
+ " https://jira.mariadb.org/\n", stderr);
DBUG_VOID_RETURN;
}
@@ -4291,7 +4291,7 @@ ibuf_set_del_mark(
fprintf(stderr, "\nspace %u offset %u"
" (%u records, index id %llu)\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n",
+ " to https://jira.mariadb.org/\n",
(unsigned) buf_block_get_space(block),
(unsigned) buf_block_get_page_no(block),
(unsigned) page_get_n_recs(page),
@@ -4355,7 +4355,7 @@ ibuf_delete(
fprintf(stderr, "\nspace %u offset %u"
" (%u records, index id %llu)\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n",
+ " to https://jira.mariadb.org/\n",
(unsigned) buf_block_get_space(block),
(unsigned) buf_block_get_page_no(block),
(unsigned) page_get_n_recs(page),
@@ -4426,7 +4426,7 @@ ibuf_restore_pos(
} else {
fprintf(stderr,
"InnoDB: ERROR: Submit the output to"
- " http://bugs.mysql.com\n"
+ " https://jira.mariadb.org/\n"
"InnoDB: ibuf cursor restoration fails!\n"
"InnoDB: ibuf record inserted to page %lu:%lu\n",
(ulong) space, (ulong) page_no);
@@ -4645,7 +4645,7 @@ ibuf_merge_or_delete_for_page(
function. When the counter is > 0, that prevents tablespace
from being dropped. */
- space = fil_space_acquire(space_id);
+ space = fil_space_acquire_silent(space_id);
if (UNIV_UNLIKELY(!space)) {
/* Do not try to read the bitmap page from space;
@@ -4723,15 +4723,13 @@ ibuf_merge_or_delete_for_page(
fputs("InnoDB: cannot retrieve bitmap page\n",
stderr);
} else {
- buf_page_print(bitmap_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(bitmap_page, 0);
}
ibuf_mtr_commit(&mtr);
fputs("\nInnoDB: Dump of the page:\n", stderr);
- buf_page_print(block->frame, 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(block->frame, 0);
fprintf(stderr,
"InnoDB: Error: corruption in the tablespace."
@@ -4747,7 +4745,7 @@ ibuf_merge_or_delete_for_page(
"InnoDB: to determine if they are corrupt"
" after this.\n\n"
"InnoDB: Please submit a detailed bug report"
- " to http://bugs.mysql.com\n\n",
+ " to https://jira.mariadb.org/\n\n",
(ulong) page_no,
(ulong)
fil_page_get_type(block->frame));
@@ -5180,7 +5178,20 @@ ibuf_check_bitmap_on_import(
return(DB_TABLE_NOT_FOUND);
}
- size = fil_space_get_size(space_id);
+ mtr_t mtr;
+ mtr_start(&mtr);
+ {
+ buf_block_t* sp = buf_page_get(space_id, zip_size, 0,
+ RW_S_LATCH, &mtr);
+ if (sp) {
+ size = mach_read_from_4(
+ FSP_HEADER_OFFSET + FSP_FREE_LIMIT
+ + sp->frame);
+ } else {
+ size = 0;
+ }
+ }
+ mtr_commit(&mtr);
if (size == 0) {
return(DB_TABLE_NOT_FOUND);
@@ -5191,7 +5202,6 @@ ibuf_check_bitmap_on_import(
page_size = zip_size ? zip_size : UNIV_PAGE_SIZE;
for (page_no = 0; page_no < size; page_no += page_size) {
- mtr_t mtr;
page_t* bitmap_page;
ulint i;
diff --git a/storage/xtradb/include/btr0btr.ic b/storage/xtradb/include/btr0btr.ic
index 0f5f025d6a3..9f13c9303ca 100644
--- a/storage/xtradb/include/btr0btr.ic
+++ b/storage/xtradb/include/btr0btr.ic
@@ -306,7 +306,7 @@ btr_node_ptr_get_child_page_no(
"InnoDB: a nonsensical page number 0"
" in a node ptr record at offset %lu\n",
(ulong) page_offset(rec));
- buf_page_print(page_align(rec), 0, 0);
+ buf_page_print(page_align(rec), 0);
ut_ad(0);
}
diff --git a/storage/xtradb/include/btr0cur.h b/storage/xtradb/include/btr0cur.h
index e478b33bf8e..1b0632e2120 100644
--- a/storage/xtradb/include/btr0cur.h
+++ b/storage/xtradb/include/btr0cur.h
@@ -568,8 +568,7 @@ btr_estimate_n_rows_in_range(
const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
ulint mode1, /*!< in: search mode for range start */
const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
- ulint mode2, /*!< in: search mode for range end */
- trx_t* trx); /*!< in: trx */
+ ulint mode2); /*!< in: search mode for range end */
/*******************************************************************//**
Estimates the number of different key values in a given index, for
each n-column prefix of the index where 1 <= n <= dict_index_get_n_unique(index).
@@ -704,8 +703,7 @@ btr_copy_externally_stored_field_prefix(
field containing also the reference to
the external part; must be protected by
a lock or a page latch */
- ulint local_len,/*!< in: length of data, in bytes */
- trx_t* trx); /*!< in: transaction handle */
+ ulint local_len);/*!< in: length of data, in bytes */
/*******************************************************************//**
Copies an externally stored field of a record to mem heap. The
clustered index record must be protected by a lock or a page latch.
@@ -722,8 +720,7 @@ btr_copy_externally_stored_field(
ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
ulint local_len,/*!< in: length of data */
- mem_heap_t* heap, /*!< in: mem heap */
- trx_t* trx); /*!< in: transaction handle */
+ mem_heap_t* heap); /*!< in: mem heap */
/*******************************************************************//**
Copies an externally stored field of a record to mem heap.
@return the field copied to heap, or NULL if the field is incomplete */
@@ -738,8 +735,7 @@ btr_rec_copy_externally_stored_field(
zero for uncompressed BLOBs */
ulint no, /*!< in: field number */
ulint* len, /*!< out: length of the field */
- mem_heap_t* heap, /*!< in: mem heap */
- trx_t* trx); /*!< in: transaction handle */
+ mem_heap_t* heap); /*!< in: mem heap */
/*******************************************************************//**
Flags the data tuple fields that are marked as extern storage in the
update vector. We use this function to remember which fields we must
diff --git a/storage/xtradb/include/btr0scrub.h b/storage/xtradb/include/btr0scrub.h
index 608266c206d..8029cc91005 100644
--- a/storage/xtradb/include/btr0scrub.h
+++ b/storage/xtradb/include/btr0scrub.h
@@ -154,13 +154,10 @@ btr_scrub_start_space(
ulint space, /*!< in: space */
btr_scrub_t* scrub_data); /*!< in/out: scrub data */
-/****************************************************************
-Complete iterating a space
-* @return true if space was scrubbed */
+/** Complete iterating a space.
+@param[in,out] scrub_data scrub data */
UNIV_INTERN
-bool
-btr_scrub_complete_space(
-/*=====================*/
- btr_scrub_t* scrub_data); /*!< in/out: scrub data */
+void
+btr_scrub_complete_space(btr_scrub_t* scrub_data);
#endif
diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h
index 1899165ace0..7661ba1785d 100644
--- a/storage/xtradb/include/buf0buf.h
+++ b/storage/xtradb/include/buf0buf.h
@@ -58,6 +58,7 @@ Created 11/5/1995 Heikki Tuuri
#define BUF_GET_POSSIBLY_FREED 16
/*!< Like BUF_GET, but do not mind
if the file page has been freed. */
+#define BUF_EVICT_IF_IN_POOL 20 /*!< evict a clean block if found */
/* @} */
/** @name Modes for buf_page_get_known_nowait */
/* @{ */
@@ -758,26 +759,15 @@ buf_print(void);
/*============*/
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
#endif /* !UNIV_HOTBACKUP */
-enum buf_page_print_flags {
- /** Do not crash at the end of buf_page_print(). */
- BUF_PAGE_PRINT_NO_CRASH = 1,
- /** Do not print the full page dump. */
- BUF_PAGE_PRINT_NO_FULL = 2
-};
-/********************************************************************//**
-Prints a page to stderr. */
+/** Dump a page to stderr.
+@param[in] read_buf database page
+@param[in] zip_size compressed page size, or 0 for uncompressed */
UNIV_INTERN
void
-buf_page_print(
-/*===========*/
- const byte* read_buf, /*!< in: a database page */
- ulint zip_size, /*!< in: compressed page size, or
- 0 for uncompressed pages */
- ulint flags) /*!< in: 0 or
- BUF_PAGE_PRINT_NO_CRASH or
- BUF_PAGE_PRINT_NO_FULL */
+buf_page_print(const byte* read_buf, ulint zip_size)
UNIV_COLD;
+
/********************************************************************//**
Decompress a block.
@return TRUE if successful */
diff --git a/storage/xtradb/include/buf0lru.h b/storage/xtradb/include/buf0lru.h
index f056c6c4116..1bc11937fa1 100644
--- a/storage/xtradb/include/buf0lru.h
+++ b/storage/xtradb/include/buf0lru.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 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
@@ -53,19 +54,14 @@ These are low-level functions
/** Minimum LRU list length for which the LRU_old pointer is defined */
#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
-/******************************************************************//**
-Flushes all dirty pages or removes all pages belonging
-to a given tablespace. A PROBLEM: if readahead is being started, what
-guarantees that it will not try to read in pages after this operation
-has completed? */
+/** 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
void
-buf_LRU_flush_or_remove_pages(
-/*==========================*/
- ulint id, /*!< in: space id */
- buf_remove_t buf_remove, /*!< in: remove or flush strategy */
- const trx_t* trx); /*!< to check if the operation must
- be interrupted */
+buf_LRU_flush_or_remove_pages(ulint id, const trx_t* trx, bool drop_ahi=false);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/********************************************************************//**
diff --git a/storage/xtradb/include/buf0types.h b/storage/xtradb/include/buf0types.h
index 4eb5ea18cef..6db3cb1238c 100644
--- a/storage/xtradb/include/buf0types.h
+++ b/storage/xtradb/include/buf0types.h
@@ -58,17 +58,6 @@ enum buf_flush_t {
BUF_FLUSH_N_TYPES /*!< index of last element + 1 */
};
-/** Algorithm to remove the pages for a tablespace from the buffer pool.
-See buf_LRU_flush_or_remove_pages(). */
-enum buf_remove_t {
- BUF_REMOVE_ALL_NO_WRITE, /*!< Remove all pages from the buffer
- pool, don't write or sync to disk */
- BUF_REMOVE_FLUSH_NO_WRITE, /*!< Remove only, from the flush list,
- don't write or sync to disk */
- BUF_REMOVE_FLUSH_WRITE /*!< Flush dirty pages to disk only
- don't remove from the buffer pool */
-};
-
/** Flags for io_fix types */
enum buf_io_fix {
BUF_IO_NONE = 0, /**< no pending I/O */
diff --git a/storage/xtradb/include/data0type.h b/storage/xtradb/include/data0type.h
index df6b6a41c11..f3ecab5a3ba 100644
--- a/storage/xtradb/include/data0type.h
+++ b/storage/xtradb/include/data0type.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2012, 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
@@ -182,18 +182,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) \
- ((mbmaxlen) * DATA_MBMAX + (mbminlen))
-/* Get mbminlen from mbminmaxlen. Cast the result of UNIV_EXPECT to ulint
-because in GCC it returns a long. */
-#define DATA_MBMINLEN(mbminmaxlen) ((ulint) \
- UNIV_EXPECT(((mbminmaxlen) % DATA_MBMAX), \
- 1))
-/* Get mbmaxlen from mbminmaxlen. */
-#define DATA_MBMAXLEN(mbminmaxlen) ((ulint) ((mbminmaxlen) / DATA_MBMAX))
+#define DATA_MBMAX 8
/* We now support 15 bits (up to 32767) collation number */
#define MAX_CHAR_COLL_NUM 32767
@@ -220,8 +209,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) */
@@ -366,19 +357,6 @@ 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 */
-/*********************************************************************//**
Gets the padding character code for the type.
@return padding character code, or ULINT_UNDEFINED if no padding specified */
UNIV_INLINE
@@ -398,7 +376,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 */
#ifndef UNIV_HOTBACKUP
@@ -412,8 +392,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.
@@ -530,11 +510,10 @@ struct dtype_t{
the string, MySQL uses 1 or 2
bytes to store the string length) */
#ifndef UNIV_HOTBACKUP
- 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 */
#endif /* !UNIV_HOTBACKUP */
};
diff --git a/storage/xtradb/include/data0type.ic b/storage/xtradb/include/data0type.ic
index 8f5cee0fd5f..96b001e197e 100644
--- a/storage/xtradb/include/data0type.ic
+++ b/storage/xtradb/include/data0type.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2012, 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,27 +105,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
@@ -137,7 +116,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));
}
@@ -233,8 +213,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.
@@ -246,8 +225,7 @@ dtype_get_mbmaxlen(
/*===============*/
const dtype_t* type) /*!< in: type */
{
- ut_ad(type);
- return(DATA_MBMAXLEN(type->mbminmaxlen));
+ return type->mbmaxlen;
}
/*********************************************************************//**
@@ -523,8 +501,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) {
@@ -565,11 +545,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);
}
}
@@ -577,7 +556,7 @@ dtype_get_fixed_size_low(
return(len);
#endif /* !UNIV_HOTBACKUP */
/* Treat as variable-length. */
- /* Fall through */
+ /* fall through */
case DATA_VARCHAR:
case DATA_BINARY:
case DATA_DECIMAL:
@@ -602,8 +581,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:
@@ -633,9 +612,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);
}
@@ -706,9 +682,9 @@ dtype_get_sql_null_size(
{
#ifndef UNIV_HOTBACKUP
return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
- type->mbminmaxlen, comp));
+ type->mbminlen, type->mbmaxlen, comp));
#else /* !UNIV_HOTBACKUP */
return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
- 0, 0));
+ 0, 0, 0));
#endif /* !UNIV_HOTBACKUP */
}
diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h
index a43b04d9d1e..241ed89e36b 100644
--- a/storage/xtradb/include/dict0dict.h
+++ b/storage/xtradb/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
@@ -197,18 +197,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
@@ -619,17 +607,6 @@ dict_table_get_col_name(
ulint col_nr) /*!< in: column number */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/**********************************************************************//**
-Returns a column's name.
-@return column name. NOTE: not guaranteed to stay valid if table is
-modified in any way (columns added, etc.). */
-UNIV_INTERN
-const char*
-dict_table_get_col_name_for_mysql(
-/*==============================*/
- const dict_table_t* table, /*!< in: table */
- const char* col_name)/*!< in: MySQL table column name */
- __attribute__((nonnull, warn_unused_result));
-/**********************************************************************//**
Prints a table data. */
UNIV_INTERN
void
diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic
index 4db6a73bbc2..17b4adc10e2 100644
--- a/storage/xtradb/include/dict0dict.ic
+++ b/storage/xtradb/include/dict0dict.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
+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;
}
#endif /* !UNIV_HOTBACKUP */
@@ -109,7 +92,8 @@ dict_col_type_assert_equal(
ut_ad(col->prtype == type->prtype);
//ut_ad(col->len == type->len);
# ifndef UNIV_HOTBACKUP
- ut_ad(col->mbminmaxlen == type->mbminmaxlen);
+ ut_ad(col->mbminlen == type->mbminlen);
+ ut_ad(col->mbmaxlen == type->mbmaxlen);
# endif /* !UNIV_HOTBACKUP */
return(TRUE);
@@ -127,7 +111,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.
@@ -152,7 +136,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.
@@ -1077,6 +1061,27 @@ dict_table_x_lock_indexes(
}
/*********************************************************************//**
+Returns true if the particular FTS index in the table is still syncing
+in the background, false otherwise.
+@param [in] table Table containing FTS index
+@return True if sync of fts index is still going in the background */
+UNIV_INLINE
+bool
+dict_fts_index_syncing(
+ dict_table_t* table)
+{
+ dict_index_t* index;
+
+ for (index = dict_table_get_first_index(table);
+ index != NULL;
+ index = dict_table_get_next_index(index)) {
+ if (index->index_fts_syncing) {
+ return(true);
+ }
+ }
+ return(false);
+}
+/*********************************************************************//**
Release the exclusive locks on all index tree. */
UNIV_INLINE
void
diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h
index 2a4422fc18b..bdec503c88c 100644
--- a/storage/xtradb/include/dict0mem.h
+++ b/storage/xtradb/include/dict0mem.h
@@ -1,8 +1,8 @@
/*****************************************************************************
-Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+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
@@ -538,11 +538,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 */
/* @} */
@@ -720,6 +719,8 @@ struct dict_index_t{
dict_sys->mutex. Other changes are
protected by index->lock. */
dict_field_t* fields; /*!< array of field descriptions */
+ bool index_fts_syncing;/*!< Whether the fts index is
+ still syncing in the background */
#ifndef UNIV_HOTBACKUP
UT_LIST_NODE_T(dict_index_t)
indexes;/*!< list of indexes of the table */
diff --git a/storage/xtradb/include/dict0stats_bg.h b/storage/xtradb/include/dict0stats_bg.h
index 8f3385eb22b..66fcf7a0998 100644
--- a/storage/xtradb/include/dict0stats_bg.h
+++ b/storage/xtradb/include/dict0stats_bg.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2012, 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
@@ -83,7 +83,7 @@ dict_stats_defrag_pool_del(
/** Yield the data dictionary latch when waiting
for the background thread to stop accessing a table.
@param trx transaction holding the data dictionary locks */
-#define DICT_STATS_BG_YIELD(trx) do { \
+#define DICT_BG_YIELD(trx) do { \
row_mysql_unlock_data_dictionary(trx); \
os_thread_sleep(250000); \
row_mysql_lock_data_dictionary(trx); \
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index a33cec65ed5..8c3bf7d2b06 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 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
@@ -849,18 +849,13 @@ fil_op_log_parse_or_replay(
only be parsed but not replayed */
ulint log_flags); /*!< in: redo log flags
(stored in the page number parameter) */
-/*******************************************************************//**
-Deletes a single-table tablespace. The tablespace must be cached in the
-memory cache.
-@return TRUE if success */
+/** 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 */
UNIV_INTERN
dberr_t
-fil_delete_tablespace(
-/*==================*/
- ulint id, /*!< in: space id */
- buf_remove_t buf_remove); /*!< in: specify the action to take
- on the tables pages in the buffer
- pool */
+fil_delete_tablespace(ulint id, bool drop_ahi = false);
/*******************************************************************//**
Closes a single-table tablespace. The tablespace must be cached in the
memory cache. Free all pages used by the tablespace.
@@ -1166,7 +1161,7 @@ Reads or writes data. This operation is asynchronous (aio).
i/o on a tablespace which does not exist */
UNIV_INTERN
dberr_t
-_fil_io(
+fil_io(
/*===*/
ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE,
ORed to OS_FILE_LOG, if a log i/o
@@ -1194,16 +1189,18 @@ _fil_io(
void* message, /*!< in: message for aio handler if non-sync
aio used, else ignored */
ulint* write_size, /*!< in/out: Actual write size initialized
- after fist successfull trim
- operation for this page and if
- initialized we do not trim again if
- actual page size does not decrease. */
- trx_t* trx) /*!< in: trx */
-
- __attribute__((nonnull(8)));
-
-#define fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, write_size) \
- _fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, write_size, NULL)
+ after fist successfull trim
+ operation for this page and if
+ initialized we do not trim again if
+ actual page size does not decrease. */
+ trx_t* trx = NULL, /*!< in: trx */
+ bool should_buffer = false)
+ /*!< in: whether to buffer an aio request.
+ AIO read ahead uses this. If you plan to
+ use this parameter, make sure you remember
+ to call os_aio_dispatch_read_array_submit()
+ when you're ready to commit all your requests.*/
+ MY_ATTRIBUTE((nonnull(8)));
/** Determine the block size of the data file.
@param[in] space tablespace
diff --git a/storage/xtradb/include/fts0fts.h b/storage/xtradb/include/fts0fts.h
index 7aa7055640c..cd94956dc55 100644
--- a/storage/xtradb/include/fts0fts.h
+++ b/storage/xtradb/include/fts0fts.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, MariaDB Corporation. All Rights reserved.
+Copyright (c) 2016, 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
@@ -429,21 +429,6 @@ fts_update_next_doc_id(
MY_ATTRIBUTE((nonnull(2)));
/******************************************************************//**
-Create a new document id .
-@return DB_SUCCESS if all went well else error */
-UNIV_INTERN
-dberr_t
-fts_create_doc_id(
-/*==============*/
- dict_table_t* table, /*!< in: row is of this
- table. */
- dtuple_t* row, /*!< in/out: add doc id
- value to this row. This is the
- current row that is being
- inserted. */
- mem_heap_t* heap) /*!< in: heap */
- MY_ATTRIBUTE((nonnull));
-/******************************************************************//**
Create a new fts_doc_ids_t.
@return new fts_doc_ids_t. */
UNIV_INTERN
diff --git a/storage/xtradb/include/lock0lock.h b/storage/xtradb/include/lock0lock.h
index 923c463aa22..5aff67db0ee 100644
--- a/storage/xtradb/include/lock0lock.h
+++ b/storage/xtradb/include/lock0lock.h
@@ -1029,6 +1029,8 @@ std::string
lock_get_info(
const lock_t*);
+#define wsrep_on_trx(trx) ((trx)->mysql_thd && wsrep_on((trx)->mysql_thd))
+
#ifndef UNIV_NONINL
#include "lock0lock.ic"
#endif
diff --git a/storage/xtradb/include/log0crypt.h b/storage/xtradb/include/log0crypt.h
index 6b164e90d6e..b7a221e0a81 100644
--- a/storage/xtradb/include/log0crypt.h
+++ b/storage/xtradb/include/log0crypt.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
-Copyright (C) 2014, 2016, MariaDB Corporation. 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
@@ -29,6 +29,7 @@ Modified Jan Lindström jan.lindstrom@mariadb.com
#include "univ.i"
#include "ut0byte.h"
#include "my_crypt.h"
+#include "os0file.h"
typedef int Crypt_result;
@@ -72,6 +73,8 @@ log_encrypt_before_write(
/*=====================*/
ib_uint64_t next_checkpoint_no, /*!< in: log group to be flushed */
byte* block, /*!< in/out: pointer to a log block */
+ lsn_t lsn, /*!< in: log sequence number of
+ the start of the buffer */
const ulint size); /*!< in: size of log blocks */
/********************************************************
@@ -82,6 +85,8 @@ void
log_decrypt_after_read(
/*===================*/
byte* frame, /*!< in/out: log segment */
+ lsn_t lsn, /*!< in: log sequence number of the start
+ of the buffer */
const ulint size); /*!< in: log segment size */
/* Error codes for crypt info */
@@ -125,4 +130,45 @@ log_crypt_print_checkpoint_keys(
/*============================*/
const byte* log_block);
+/** Encrypt temporary log block.
+@param[in] src_block block to encrypt or decrypt
+@param[in] size size of the block
+@param[out] dst_block destination block
+@param[in] offs offset to block
+@param[in] space_id tablespace id
+@return true if successfull, false in case of failure
+*/
+UNIV_INTERN
+bool
+log_tmp_block_encrypt(
+ const byte* src_block,
+ ulint size,
+ byte* dst_block,
+ os_offset_t offs,
+ ulint space_id)
+ MY_ATTRIBUTE((warn_unused_result));
+
+/** Decrypt temporary log block.
+@param[in] src_block block to encrypt or decrypt
+@param[in] size size of the block
+@param[out] dst_block destination block
+@param[in] offs offset to block
+@param[in] space_id tablespace id
+@return true if successfull, false in case of failure
+*/
+UNIV_INTERN
+bool
+log_tmp_block_decrypt(
+ const byte* src_block,
+ ulint size,
+ byte* dst_block,
+ os_offset_t offs,
+ ulint space_id)
+ MY_ATTRIBUTE((warn_unused_result));
+
+/** Find out is temporary log files encrypted.
+@return true if temporary log file should be encrypted, false if not */
+UNIV_INTERN
+bool
+log_tmp_is_encrypted() MY_ATTRIBUTE((warn_unused_result));
#endif // log0crypt.h
diff --git a/storage/xtradb/include/log0online.h b/storage/xtradb/include/log0online.h
index 5c3e7d07fd9..2d1febe9b9f 100644
--- a/storage/xtradb/include/log0online.h
+++ b/storage/xtradb/include/log0online.h
@@ -129,7 +129,11 @@ log_online_bitmap_iterator_next(
/** Struct for single bitmap file information */
struct log_online_bitmap_file_struct {
- char name[FN_REFLEN]; /*!< Name with full path */
+ /** Name with full path
+ 61 is a nice magic constant for the extra space needed for the sprintf
+ template in the cc file
+ */
+ char name[FN_REFLEN+61]; /*!< Name with full path */
pfs_os_file_t file; /*!< Handle to opened file */
ib_uint64_t size; /*!< Size of the file */
os_offset_t offset; /*!< Offset of the next read,
diff --git a/storage/xtradb/include/mem0mem.ic b/storage/xtradb/include/mem0mem.ic
index 63e68150b61..2b4638718fd 100644
--- a/storage/xtradb/include/mem0mem.ic
+++ b/storage/xtradb/include/mem0mem.ic
@@ -305,8 +305,8 @@ 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);
#if defined UNIV_MEM_DEBUG
+ UNIV_MEM_ALLOC(old_top, (byte*)block + block->len - old_top);
/* In the debug version erase block from top up */
mem_erase_buf(old_top, (byte*) block + block->len - old_top);
@@ -315,7 +315,7 @@ mem_heap_free_heap_top(
mem_current_allocated_memory -= (total_size - size);
mutex_exit(&mem_hash_mutex);
#endif /* UNIV_MEM_DEBUG */
- 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 */
@@ -396,11 +396,11 @@ 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);
#ifdef UNIV_MEM_DEBUG
ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
+ UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n);
/* In the debug version check the consistency, and erase field */
mem_field_erase((byte*) block + mem_block_get_free(block), n);
#endif
@@ -412,11 +412,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/xtradb/include/mtr0log.ic b/storage/xtradb/include/mtr0log.ic
index d508d30fafe..8c891fac55b 100644
--- a/storage/xtradb/include/mtr0log.ic
+++ b/storage/xtradb/include/mtr0log.ic
@@ -216,7 +216,7 @@ mlog_write_initial_log_record_fast(
"%d on page %lu of space %lu in the "
"doublewrite buffer, continuing anyway.\n"
"Please post a bug report to "
- "bugs.mysql.com.\n",
+ "https://jira.mariadb.org/\n",
type, offset, space);
ut_ad(0);
}
diff --git a/storage/xtradb/include/mtr0mtr.h b/storage/xtradb/include/mtr0mtr.h
index ef6cd61719d..42a57f1022a 100644
--- a/storage/xtradb/include/mtr0mtr.h
+++ b/storage/xtradb/include/mtr0mtr.h
@@ -35,7 +35,6 @@ Created 11/26/1995 Heikki Tuuri
#include "ut0byte.h"
#include "mtr0types.h"
#include "page0types.h"
-#include "trx0types.h"
/* Logging modes for a mini-transaction */
#define MTR_LOG_ALL 21 /* default mode: log all operations
@@ -213,22 +212,10 @@ functions). The page number parameter was originally written as 0. @{ */
Starts a mini-transaction. */
UNIV_INLINE
void
-mtr_start_trx(
-/*======*/
- mtr_t* mtr, /*!< out: mini-transaction */
- trx_t* trx) /*!< in: transaction */
- __attribute__((nonnull (1)));
-/***************************************************************//**
-Starts a mini-transaction. */
-UNIV_INLINE
-void
mtr_start(
/*======*/
mtr_t* mtr) /*!< out: mini-transaction */
-{
- mtr_start_trx(mtr, NULL);
-}
- MY_ATTRIBUTE((nonnull))
+ MY_ATTRIBUTE((nonnull));
/***************************************************************//**
Commits a mini-transaction. */
UNIV_INTERN
@@ -435,7 +422,6 @@ struct mtr_t{
#ifdef UNIV_DEBUG
ulint magic_n;
#endif /* UNIV_DEBUG */
- trx_t* trx; /*!< transaction */
};
#ifdef UNIV_DEBUG
diff --git a/storage/xtradb/include/mtr0mtr.ic b/storage/xtradb/include/mtr0mtr.ic
index a6d9df09925..04c39cf7f7e 100644
--- a/storage/xtradb/include/mtr0mtr.ic
+++ b/storage/xtradb/include/mtr0mtr.ic
@@ -43,10 +43,9 @@ mtr_block_dirtied(
Starts a mini-transaction. */
UNIV_INLINE
void
-mtr_start_trx(
+mtr_start(
/*======*/
- mtr_t* mtr, /*!< out: mini-transaction */
- trx_t* trx) /*!< in: transaction */
+ mtr_t* mtr) /*!< out: mini-transaction */
{
UNIV_MEM_INVALID(mtr, sizeof *mtr);
@@ -59,7 +58,6 @@ mtr_start_trx(
mtr->made_dirty = FALSE;
mtr->n_log_recs = 0;
mtr->n_freed_pages = 0;
- mtr->trx = trx;
ut_d(mtr->state = MTR_ACTIVE);
ut_d(mtr->magic_n = MTR_MAGIC_N);
diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h
index b17e09cf0fa..5e93b3454c7 100644
--- a/storage/xtradb/include/os0file.h
+++ b/storage/xtradb/include/os0file.h
@@ -382,11 +382,12 @@ The wrapper functions have the prefix of "innodb_". */
pfs_os_file_close_no_error_handling_func(file, __FILE__, __LINE__)
# define os_aio(type, is_log, mode, name, file, buf, offset, \
- n, page_size, message1, message2, space_id, \
- trx, write_size) \
+ n, page_size, message1, message2, space_id, \
+ trx, write_size, should_buffer) \
pfs_os_aio_func(type, is_log, mode, name, file, buf, offset, \
- n, page_size, message1, message2, space_id, trx, write_size, \
- __FILE__, __LINE__)
+ n, page_size, message1, message2, space_id, \
+ trx, write_size, should_buffer, \
+ __FILE__, __LINE__)
# define os_file_read(file, buf, offset, n) \
pfs_os_file_read_func(file, buf, offset, n, NULL, \
@@ -454,10 +455,12 @@ to original un-instrumented file I/O APIs */
# define os_file_close_no_error_handling(file) \
os_file_close_no_error_handling_func(file)
-# define os_aio(type, is_log, mode, name, file, buf, offset, n, page_size, message1, \
- message2, space_id, trx, write_size) \
+# define os_aio(type, is_log, mode, name, file, buf, offset, \
+ n, page_size, message1, \
+ message2, space_id, trx, write_size, should_buffer) \
os_aio_func(type, is_log, mode, name, file, buf, offset, n, \
- page_size, message1, message2, space_id, trx, write_size)
+ page_size, message1, message2, space_id, \
+ trx, write_size, should_buffer)
# define os_file_read(file, buf, offset, n) \
os_file_read_func(file, buf, offset, n, NULL)
@@ -469,10 +472,10 @@ to original un-instrumented file I/O APIs */
os_file_read_no_error_handling_func(file, buf, offset, n)
# define os_file_read_no_error_handling_int_fd( \
file, buf, offset, n) \
- os_file_read_no_error_handling_func(file, buf, offset, n)
+ os_file_read_no_error_handling_func(OS_FILE_FROM_FD(file), buf, offset, n)
# define os_file_write_int_fd(name, file, buf, offset, n) \
- os_file_write_func(name, file, buf, offset, n)
+ os_file_write_func(name, OS_FILE_FROM_FD(file), buf, offset, n)
# define os_file_write(name, file, buf, offset, n) \
os_file_write_func(name, file, buf, offset, n)
@@ -939,6 +942,12 @@ pfs_os_aio_func(
operation for this page and if
initialized we do not trim again if
actual page size does not decrease. */
+ bool should_buffer,
+ /*!< in: Whether to buffer an aio request.
+ AIO read ahead uses this. If you plan to
+ use this parameter, make sure you remember
+ to call os_aio_dispatch_read_array_submit()
+ when you're ready to commit all your requests.*/
const char* src_file,/*!< in: file name where func invoked */
ulint src_line);/*!< in: line where the func invoked */
/*******************************************************************//**
@@ -1359,11 +1368,17 @@ os_aio_func(
OS_AIO_SYNC */
ulint space_id,
trx_t* trx,
- ulint* write_size);/*!< in/out: Actual write size initialized
+ ulint* write_size,/*!< in/out: Actual write size initialized
after fist successfull trim
operation for this page and if
initialized we do not trim again if
actual page size does not decrease. */
+ bool should_buffer);
+ /*!< in: Whether to buffer an aio request.
+ AIO read ahead uses this. If you plan to
+ use this parameter, make sure you remember
+ to call os_aio_dispatch_read_array_submit()
+ when you're ready to commit all your requests.*/
/************************************************************************//**
Wakes up all async i/o threads so that they know to exit themselves in
shutdown. */
@@ -1547,6 +1562,10 @@ os_file_handle_error_no_exit(
ibool on_error_silent);/*!< in: if TRUE then don't print
any message to the log. */
+/** Submit buffered AIO requests on the given segment to the kernel. */
+UNIV_INTERN
+void
+os_aio_dispatch_read_array_submit();
/***********************************************************************//**
Try to get number of bytes per sector from file system.
diff --git a/storage/xtradb/include/os0file.ic b/storage/xtradb/include/os0file.ic
index 72ac9d9dd6a..a2011da3545 100644
--- a/storage/xtradb/include/os0file.ic
+++ b/storage/xtradb/include/os0file.ic
@@ -258,6 +258,9 @@ pfs_os_aio_func(
operation for this page and if
initialized we do not trim again if
actual page size does not decrease. */
+ bool should_buffer,
+ /*!< in: whether to buffer an aio request.
+ Only used by aio read ahead*/
const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the func invoked */
{
@@ -274,7 +277,7 @@ pfs_os_aio_func(
result = os_aio_func(type, is_log, mode, name, file, buf, offset,
n, page_size, message1, message2, space_id, trx,
- write_size);
+ write_size, should_buffer);
register_pfs_file_io_end(locker, n);
diff --git a/storage/xtradb/include/page0page.ic b/storage/xtradb/include/page0page.ic
index 364536b86f8..b37715b53be 100644
--- a/storage/xtradb/include/page0page.ic
+++ b/storage/xtradb/include/page0page.ic
@@ -771,7 +771,7 @@ page_rec_get_next_low(
(void*) rec,
(ulong) page_get_space_id(page),
(ulong) page_get_page_no(page));
- buf_page_print(page, 0, 0);
+ buf_page_print(page, 0);
ut_error;
} else if (offs == 0) {
diff --git a/storage/xtradb/include/page0zip.ic b/storage/xtradb/include/page0zip.ic
index bee35a48cc2..3fa8a08c4f9 100644
--- a/storage/xtradb/include/page0zip.ic
+++ b/storage/xtradb/include/page0zip.ic
@@ -174,7 +174,7 @@ page_zip_rec_needs_ext(
ulint zip_size) /*!< in: compressed page size in bytes, or 0 */
{
ut_ad(rec_size
- > (comp ? REC_N_NEW_EXTRA_BYTES : REC_N_OLD_EXTRA_BYTES));
+ > ulint(comp ? REC_N_NEW_EXTRA_BYTES : REC_N_OLD_EXTRA_BYTES));
ut_ad(ut_is_2pow(zip_size));
ut_ad(comp || !zip_size);
diff --git a/storage/xtradb/include/que0que.h b/storage/xtradb/include/que0que.h
index e5b2a1ba3fc..005f28d2af1 100644
--- a/storage/xtradb/include/que0que.h
+++ b/storage/xtradb/include/que0que.h
@@ -385,9 +385,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
diff --git a/storage/xtradb/include/rem0rec.ic b/storage/xtradb/include/rem0rec.ic
index 5811a77a48b..89f6902059d 100644
--- a/storage/xtradb/include/rem0rec.ic
+++ b/storage/xtradb/include/rem0rec.ic
@@ -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
@@ -922,7 +923,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/xtradb/include/row0ftsort.h b/storage/xtradb/include/row0ftsort.h
index 7c9ed23645c..b2dd90e7e3b 100644
--- a/storage/xtradb/include/row0ftsort.h
+++ b/storage/xtradb/include/row0ftsort.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, MariaDB Corporation.
+Copyright (c) 2016, 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
@@ -72,7 +72,6 @@ struct fts_psort_common_t {
store Doc ID during sort, if
Doc ID will not be big enough
to use 8 bytes value */
- fil_space_crypt_t* crypt_data; /*!< crypt data or NULL */
};
struct fts_psort_t {
diff --git a/storage/xtradb/include/row0merge.h b/storage/xtradb/include/row0merge.h
index 04d4010ad48..af21ef49cb7 100644
--- a/storage/xtradb/include/row0merge.h
+++ b/storage/xtradb/include/row0merge.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2016, MariaDB Corporation.
+Copyright (c) 2015, 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
@@ -41,9 +41,6 @@ Created 13/06/2005 Jan Lindstrom
#include "lock0types.h"
#include "srv0srv.h"
-/* Reserve free space from every block for key_version */
-#define ROW_MERGE_RESERVE_SIZE 4
-
/* Cluster index read task is mandatory */
#define COST_READ_CLUSTERED_INDEX 1.0
@@ -111,7 +108,6 @@ struct index_field_t {
ulint col_no; /*!< column offset */
ulint prefix_len; /*!< column prefix length, or 0
if indexing the whole column */
- const char* col_name; /*!< column name or NULL */
};
/** Definition of an index being created */
@@ -268,11 +264,7 @@ row_merge_create_index(
/*===================*/
trx_t* trx, /*!< in/out: trx (sets error_state) */
dict_table_t* table, /*!< in: the index is on this table */
- const index_def_t* index_def,
- /*!< in: the index definition */
- const char** col_names);
- /*! in: column names if columns are
- renamed or NULL */
+ const index_def_t* index_def); /*!< in: the index definition */
/*********************************************************************//**
Check if a transaction can use an index.
@return TRUE if index can be used by the transaction else FALSE */
@@ -352,17 +344,16 @@ row_merge_buf_sort(
Write a merge block to the file system.
@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
-ibool
+bool
row_merge_write(
/*============*/
int fd, /*!< in: file descriptor */
ulint offset, /*!< in: offset where to write,
in number of row_merge_block_t elements */
const void* buf, /*!< in: data */
- fil_space_crypt_t* crypt_data, /*!< in: table crypt data */
void* crypt_buf, /*!< in: crypt buf or NULL */
- ulint space); /*!< in: space id */
-
+ ulint space) /*!< in: space id */
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Empty a sort buffer.
@return sort buffer */
@@ -400,10 +391,9 @@ row_merge_sort(
const bool update_progress, /*!< in: update progress status variable or not */
const float pct_progress, /*!< in: total progress percent until now */
const float pct_cost, /*!< in: current progress percent */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
- ulint space) /*!< in: space id */
- __attribute__((nonnull(1,2,3,4,5)));
+ ulint space) /*!< in: space id */
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Allocate a sort buffer.
@return own: sort buffer */
@@ -433,7 +423,7 @@ row_merge_file_destroy(
Read a merge block from the file system.
@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
-ibool
+bool
row_merge_read(
/*===========*/
int fd, /*!< in: file descriptor */
@@ -441,10 +431,9 @@ row_merge_read(
in number of row_merge_block_t
elements */
row_merge_block_t* buf, /*!< out: data */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_buf, /*!< in: crypt buf or NULL */
- ulint space); /*!< in: space id */
-
+ ulint space) /*!< in: space id */
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Read a merge record.
@return pointer to next record, or NULL on I/O error or end of list */
@@ -462,8 +451,8 @@ row_merge_read_rec(
or NULL on end of list
(non-NULL on I/O error) */
ulint* offsets,/*!< out: offsets of mrec */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
- ulint space) /*!< in: space id */
- __attribute__((nonnull(1,2,3,4,6,7,8), warn_unused_result));
+ ulint space) /*!< in: space id */
+ MY_ATTRIBUTE((warn_unused_result));
+
#endif /* row0merge.h */
diff --git a/storage/xtradb/include/row0mysql.h b/storage/xtradb/include/row0mysql.h
index a8503a5cfda..4915e7c7a31 100644
--- a/storage/xtradb/include/row0mysql.h
+++ b/storage/xtradb/include/row0mysql.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2000, 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
@@ -591,18 +591,6 @@ void
row_mysql_close(void);
/*=================*/
-/*********************************************************************//**
-Reassigns the table identifier of a table.
-@return error code or DB_SUCCESS */
-UNIV_INTERN
-dberr_t
-row_mysql_table_id_reassign(
-/*========================*/
- dict_table_t* table, /*!< in/out: table */
- trx_t* trx, /*!< in/out: transaction */
- table_id_t* new_id) /*!< out: new table id */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-
/* A struct describing a place for an individual column in the MySQL
row format which is presented to the table handler in ha_innobase.
This template struct is used to speed up row transformations between
diff --git a/storage/xtradb/include/row0sel.h b/storage/xtradb/include/row0sel.h
index fd5bc755a22..afeb216c2a2 100644
--- a/storage/xtradb/include/row0sel.h
+++ b/storage/xtradb/include/row0sel.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -205,6 +205,18 @@ struct sel_buf_t{
when data != NULL */
};
+/** Copy used fields from cached row.
+Copy cache record field by field, don't touch fields that
+are not covered by current key.
+@param[out] buf Where to copy the MySQL row.
+@param[in] cached_rec What to copy (in MySQL row format).
+@param[in] prebuilt prebuilt struct. */
+void
+row_sel_copy_cached_fields_for_mysql(
+ byte* buf,
+ const byte* cached_rec,
+ row_prebuilt_t* prebuilt);
+
/** Query plan */
struct plan_t{
dict_table_t* table; /*!< table struct in the dictionary
diff --git a/storage/xtradb/include/row0upd.h b/storage/xtradb/include/row0upd.h
index 4312fcf7339..9efaaa41cf0 100644
--- a/storage/xtradb/include/row0upd.h
+++ b/storage/xtradb/include/row0upd.h
@@ -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
@@ -119,8 +120,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. */
UNIV_INTERN
diff --git a/storage/xtradb/include/row0upd.ic b/storage/xtradb/include/row0upd.ic
index 618a77fa4bf..efc6c1be4b5 100644
--- a/storage/xtradb/include/row0upd.ic
+++ b/storage/xtradb/include/row0upd.ic
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2012, 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
@@ -153,8 +154,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/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index 30c125ea269..6df60e0e52d 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -137,6 +137,14 @@ struct srv_stats_t {
ulint_ctr_64_t pages_encrypted;
/* Number of pages decrypted */
ulint_ctr_64_t pages_decrypted;
+ /* Number of merge blocks encrypted */
+ ulint_ctr_64_t n_merge_blocks_encrypted;
+ /* Number of merge blocks decrypted */
+ ulint_ctr_64_t n_merge_blocks_decrypted;
+ /* Number of row log blocks encrypted */
+ ulint_ctr_64_t n_rowlog_blocks_encrypted;
+ /* Number of row log blocks decrypted */
+ ulint_ctr_64_t n_rowlog_blocks_decrypted;
/** Number of data read in total (in bytes) */
ulint_ctr_1_t data_read;
@@ -187,6 +195,9 @@ struct srv_stats_t {
wait timeout */
ulint_ctr_1_t n_lock_max_wait_time;
+ /** Number of buffered aio requests submitted */
+ ulint_ctr_64_t n_aio_submitted;
+
/** Number of times page 0 is read from tablespace */
ulint_ctr_64_t page0_read;
@@ -712,6 +723,9 @@ extern ulong srv_sync_array_size;
/* print all user-level transactions deadlocks to mysqld stderr */
extern my_bool srv_print_all_deadlocks;
+/* print lock wait timeout info to mysqld stderr */
+extern my_bool srv_print_lock_wait_timeout_info;
+
extern my_bool srv_cmp_per_index_enabled;
/* is encryption enabled */
@@ -1276,8 +1290,19 @@ struct export_var_t{
ib_int64_t innodb_pages_decrypted; /*!< Number of pages
decrypted */
+ /*!< Number of merge blocks encrypted */
+ ib_int64_t innodb_n_merge_blocks_encrypted;
+ /*!< Number of merge blocks decrypted */
+ ib_int64_t innodb_n_merge_blocks_decrypted;
+ /*!< Number of row log blocks encrypted */
+ ib_int64_t innodb_n_rowlog_blocks_encrypted;
+ /*!< Number of row log blocks decrypted */
+ ib_int64_t innodb_n_rowlog_blocks_decrypted;
+
ulint innodb_sec_rec_cluster_reads; /*!< srv_sec_rec_cluster_reads */
- ulint innodb_sec_rec_cluster_reads_avoided;/*!< srv_sec_rec_cluster_reads_avoided */
+ ulint innodb_sec_rec_cluster_reads_avoided; /*!< srv_sec_rec_cluster_reads_avoided */
+
+ ulint innodb_buffered_aio_submitted;
ulint innodb_encryption_rotation_pages_read_from_cache;
ulint innodb_encryption_rotation_pages_read_from_disk;
diff --git a/storage/xtradb/include/trx0rec.h b/storage/xtradb/include/trx0rec.h
index a6e202d04e4..fef12548003 100644
--- a/storage/xtradb/include/trx0rec.h
+++ b/storage/xtradb/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
@@ -196,6 +196,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
@@ -226,11 +227,9 @@ trx_undo_report_row_operation(
marking, the record in the clustered
index, otherwise NULL */
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 */
- MY_ATTRIBUTE((nonnull(1,2,8), warn_unused_result));
+ roll_ptr_t* roll_ptr) /*!< out: DB_ROLL_PTR to the
+ undo log record */
+ MY_ATTRIBUTE((nonnull(2,8), warn_unused_result));
/******************************************************************//**
Copies an undo record to heap. This function can be called if we know that
the undo log record exists.
diff --git a/storage/xtradb/include/trx0roll.h b/storage/xtradb/include/trx0roll.h
index b2e9d8a077f..565079b17b4 100644
--- a/storage/xtradb/include/trx0roll.h
+++ b/storage/xtradb/include/trx0roll.h
@@ -1,6 +1,7 @@
/*****************************************************************************
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
@@ -33,7 +34,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_or_clean_is_active;
+extern const trx_t* trx_roll_crash_recv_trx;
/*******************************************************************//**
Determines if this transaction is rolling back an incomplete transaction
@@ -104,6 +106,11 @@ trx_undo_rec_release(
/*=================*/
trx_t* trx, /*!< in/out: transaction */
undo_no_t undo_no);/*!< in: undo number */
+/** Report progress when rolling back a row of a recovered transaction.
+@return whether the rollback should be aborted due to pending shutdown */
+UNIV_INTERN
+bool
+trx_roll_must_shutdown();
/*******************************************************************//**
Rollback or clean up any incomplete transactions which were
encountered in crash recovery. If the transaction already was
diff --git a/storage/xtradb/include/trx0sys.h b/storage/xtradb/include/trx0sys.h
index 1b418dfe380..85c454c4cf9 100644
--- a/storage/xtradb/include/trx0sys.h
+++ b/storage/xtradb/include/trx0sys.h
@@ -336,14 +336,17 @@ trx_sys_print_mysql_binlog_offset(void);
@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.
+/** Read WSREP checkpoint XID from sys header.
+@param[out] xid Transaction XID
@return true on success, false on error. */
+UNIV_INTERN
bool
trx_sys_read_wsrep_checkpoint(
XID* xid); /*!< out: WSREP XID */
diff --git a/storage/xtradb/include/trx0sys.ic b/storage/xtradb/include/trx0sys.ic
index 6024c1dc94e..699148cff6d 100644
--- a/storage/xtradb/include/trx0sys.ic
+++ b/storage/xtradb/include/trx0sys.ic
@@ -474,10 +474,7 @@ trx_id_t
trx_sys_get_new_trx_id(void)
/*========================*/
{
-#ifndef WITH_WSREP
- /* wsrep_fake_trx_id violates this assert */
ut_ad(mutex_own(&trx_sys->mutex));
-#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
diff --git a/storage/xtradb/include/trx0undo.h b/storage/xtradb/include/trx0undo.h
index 190308112ba..0148cc61579 100644
--- a/storage/xtradb/include/trx0undo.h
+++ b/storage/xtradb/include/trx0undo.h
@@ -243,13 +243,22 @@ Truncates an undo log from the end. This function is used during a rollback
to free space from an undo log. */
UNIV_INTERN
void
-trx_undo_truncate_end(
+trx_undo_truncate_end_func(
/*=======================*/
- trx_t* trx, /*!< in: transaction whose undo log it is */
+#ifdef UNIV_DEBUG
+ const trx_t* trx, /*!< in: transaction whose undo log it is */
+#endif /* UNIV_DEBUG */
trx_undo_t* undo, /*!< in/out: undo log */
undo_no_t limit) /*!< in: all undo records with undo number
>= this value should be truncated */
MY_ATTRIBUTE((nonnull));
+#ifdef UNIV_DEBUG
+# define trx_undo_truncate_end(trx,undo,limit) \
+ trx_undo_truncate_end_func(trx,undo,limit)
+#else /* UNIV_DEBUG */
+# define trx_undo_truncate_end(trx,undo,limit) \
+ trx_undo_truncate_end_func(undo,limit)
+#endif /* UNIV_DEBUG */
/***********************************************************************//**
Truncates an undo log from the start. This function is used during a purge
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index 739f6640eef..e6c4917f532 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -45,10 +45,10 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 5
#define INNODB_VERSION_MINOR 6
-#define INNODB_VERSION_BUGFIX 36
+#define INNODB_VERSION_BUGFIX 38
#ifndef PERCONA_INNODB_VERSION
-#define PERCONA_INNODB_VERSION 82.1
+#define PERCONA_INNODB_VERSION 83.0
#endif
/* Enable UNIV_LOG_ARCHIVE in XtraDB */
@@ -691,14 +691,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/xtradb/include/ut0timer.ic b/storage/xtradb/include/ut0timer.ic
index 62e17a10fb1..815726e9d0a 100644
--- a/storage/xtradb/include/ut0timer.ic
+++ b/storage/xtradb/include/ut0timer.ic
@@ -106,7 +106,7 @@ ut_microseconds_to_timer(
/*=====================*/
ulonglong when) /*!< in: time where to calculate */
{
- double ret = when;
+ double ret = (double)when;
ret *= (double)(ut_timer.frequency);
ret /= 1000000.0;
return (ulonglong)ret;
diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc
index 71612f66fcd..b50452c1d5d 100644
--- a/storage/xtradb/lock/lock0lock.cc
+++ b/storage/xtradb/lock/lock0lock.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 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
@@ -937,14 +937,21 @@ lock_reset_lock_and_trx_wait(
ib_logf(IB_LOG_LEVEL_INFO,
"Trx id " TRX_ID_FMT
- " is waiting a lock in statement %s"
+ " is waiting a lock "
" for this trx id " TRX_ID_FMT
- " and statement %s wait_lock %p",
+ " wait_lock %p",
lock->trx->id,
- stmt ? stmt : "NULL",
trx_id,
- stmt2 ? stmt2 : "NULL",
lock->trx->lock.wait_lock);
+
+ if (stmt) {
+ ib_logf(IB_LOG_LEVEL_INFO, " SQL1: %s\n", stmt);
+ }
+
+ if (stmt2) {
+ ib_logf(IB_LOG_LEVEL_INFO, " SQL2: %s\n", stmt2);
+ }
+
ut_ad(lock->trx->lock.wait_lock == lock);
}
@@ -1162,7 +1169,7 @@ lock_rec_has_to_wait(
type_mode, lock_is_on_supremum);
fprintf(stderr,
"conflicts states: my %d locked %d\n",
- wsrep_thd_conflict_state(trx->mysql_thd, FALSE),
+ wsrep_thd_conflict_state(trx->mysql_thd, FALSE),
wsrep_thd_conflict_state(lock2->trx->mysql_thd, FALSE) );
lock_rec_print(stderr, lock2);
if (for_locking) return FALSE;
@@ -1714,7 +1721,7 @@ lock_rec_other_has_expl_req(
ulint heap_no,/*!< in: heap number of the record */
trx_id_t trx_id) /*!< in: transaction */
{
- const lock_t* lock;
+ lock_t* lock;
ut_ad(lock_mutex_own());
ut_ad(mode == LOCK_X || mode == LOCK_S);
@@ -1723,7 +1730,7 @@ lock_rec_other_has_expl_req(
for (lock = lock_rec_get_first(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->id != trx_id
&& (gap
@@ -1810,7 +1817,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(
/*===========================*/
enum lock_mode mode, /*!< in: LOCK_S or LOCK_X,
@@ -1822,7 +1829,7 @@ 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;
ibool is_supremum;
ut_ad(lock_mutex_own());
@@ -1831,13 +1838,16 @@ lock_rec_other_has_conflicting(
for (lock = lock_rec_get_first(block, heap_no);
lock != NULL;
- lock = lock_rec_get_next_const(heap_no, lock)) {
+ lock = lock_rec_get_next(heap_no, lock)) {
#ifdef WITH_WSREP
if (lock_rec_has_to_wait(TRUE, trx, mode, lock, is_supremum)) {
- if (wsrep_on(trx->mysql_thd)) {
+ if (wsrep_on_trx(trx)) {
trx_mutex_enter(lock->trx);
- wsrep_kill_victim(trx, 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);
}
#else
@@ -1921,7 +1931,7 @@ lock_sec_rec_some_has_impl(
} else if (!lock_check_trx_id_sanity(max_trx_id, rec, index, offsets)) {
- buf_page_print(page, 0, 0);
+ buf_page_print(page, 0);
/* The page is corrupt: try to avoid a crash by returning 0 */
trx_id = 0;
@@ -2045,15 +2055,17 @@ wsrep_print_wait_locks(
{
if (wsrep_debug && c_lock->trx->lock.wait_lock != c_lock) {
fprintf(stderr, "WSREP: c_lock != wait lock\n");
- if (lock_get_type_low(c_lock) & LOCK_TABLE)
+ if (lock_get_type_low(c_lock) & LOCK_TABLE) {
lock_table_print(stderr, c_lock);
- else
+ } else {
lock_rec_print(stderr, c_lock);
+ }
- if (lock_get_type_low(c_lock->trx->lock.wait_lock) & LOCK_TABLE)
+ if (lock_get_type_low(c_lock->trx->lock.wait_lock) & LOCK_TABLE) {
lock_table_print(stderr, c_lock->trx->lock.wait_lock);
- else
+ } else {
lock_rec_print(stderr, c_lock->trx->lock.wait_lock);
+ }
}
}
#endif /* WITH_WSREP */
@@ -2141,6 +2153,7 @@ lock_rec_insert_by_trx_age(
return DB_SUCCESS;
}
+#ifdef UNIV_DEBUG
static
bool
lock_queue_validate(
@@ -2174,6 +2187,7 @@ lock_queue_validate(
}
return true;
}
+#endif /* UNIV_DEBUG */
static
void
@@ -2290,7 +2304,7 @@ lock_rec_create(
#ifdef WITH_WSREP
if (c_lock &&
- wsrep_on(trx->mysql_thd) &&
+ wsrep_on_trx(trx) &&
wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
lock_t *hash = (lock_t *)c_lock->hash;
lock_t *prev = NULL;
@@ -2356,8 +2370,8 @@ lock_rec_create(
if (wsrep_debug) {
fprintf(
stderr,
- "WSREP: c_lock canceled %llu\n",
- (ulonglong) c_lock->trx->id);
+ "WSREP: c_lock canceled " TRX_ID_FMT "\n",
+ c_lock->trx->id);
}
/* have to bail out here to avoid lock_set_lock... */
@@ -2478,7 +2492,7 @@ lock_rec_enqueue_waiting(
dict_index_name_print(stderr, trx, index);
fputs(".\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n",
+ " to https://jira.mariadb.org/\n",
stderr);
ut_ad(0);
}
@@ -2549,6 +2563,16 @@ lock_rec_enqueue_waiting(
err = DB_LOCK_WAIT;
}
+#ifdef WITH_WSREP
+ if (!lock_get_wait(lock) && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
+ if (wsrep_debug) {
+ fprintf(stderr, "WSREP: BF thread got lock granted early, ID " TRX_ID_FMT
+ "\n",
+ lock->trx->id);
+ }
+ return(DB_SUCCESS);
+ }
+#endif /* WITH_WSREP */
// Move it only when it does not cause a deadlock.
if (err != DB_DEADLOCK
&& innodb_lock_schedule_algorithm
@@ -2979,6 +3003,15 @@ 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) {
+ fprintf(stderr,
+ "BF-BF lock conflict " TRX_ID_FMT
+ " : " TRX_ID_FMT "\n",
+ wait_lock->trx->id,
+ lock->trx->id);
+ lock_rec_print(stderr, wait_lock);
+ lock_rec_print(stderr, lock);
+ }
/* don't wait for another BF lock */
continue;
}
@@ -3137,7 +3170,7 @@ lock_grant_and_move_on_page(
&& !lock_rec_has_to_wait_in_queue(lock)) {
lock_grant(lock, false);
-
+
if (previous != NULL) {
/* Move the lock to the head of the list. */
HASH_GET_NEXT(hash, previous) = HASH_GET_NEXT(hash, lock);
@@ -5015,8 +5048,8 @@ lock_table_create(
}
if (wsrep_debug) {
- fprintf(stderr, "WSREP: c_lock canceled %llu\n",
- (ulonglong) c_lock->trx->id);
+ fprintf(stderr, "WSREP: c_lock canceled " TRX_ID_FMT "\n",
+ c_lock->trx->id);
}
}
if (c_lock) {
@@ -5226,7 +5259,7 @@ lock_table_enqueue_waiting(
ut_print_name(stderr, trx, TRUE, table->name);
fputs(".\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n",
+ " to https://jira.mariadb.org/\n",
stderr);
ut_ad(0);
}
@@ -5295,7 +5328,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
@@ -5306,7 +5339,7 @@ lock_table_other_has_incompatible(
const dict_table_t* table, /*!< in: table */
enum lock_mode mode) /*!< in: lock mode */
{
- const lock_t* lock;
+ lock_t* lock;
ut_ad(lock_mutex_own());
@@ -5359,7 +5392,7 @@ lock_table(
#endif
trx_t* trx;
dberr_t err;
- const lock_t* wait_for;
+ lock_t* wait_for;
ut_ad(table != NULL);
ut_ad(thr != NULL);
@@ -5410,13 +5443,13 @@ lock_table(
if (wait_for != NULL) {
#ifdef WITH_WSREP
- err = lock_table_enqueue_waiting((ib_lock_t*)wait_for, mode | flags, table, thr);
+ err = lock_table_enqueue_waiting(wait_for, mode | flags, table, thr);
#else
err = lock_table_enqueue_waiting(mode | flags, table, thr);
#endif
} else {
#ifdef WITH_WSREP
- lock_table_create(c_lock, table, mode | flags, trx);
+ lock_table_create(c_lock, table, mode | flags, trx);
#else
lock_table_create(table, mode | flags, trx);
#endif
@@ -6937,7 +6970,7 @@ lock_rec_block_validate(
/* Make sure that the tablespace is not deleted while we are
trying to access the page. */
- if (fil_space_t* space = fil_space_acquire(space_id)) {
+ if (fil_space_t* space = fil_space_acquire_silent(space_id)) {
mtr_start(&mtr);
block = buf_page_get_gen(
@@ -7099,10 +7132,10 @@ lock_rec_insert_check_and_lock(
on the successor, which produced an unnecessary deadlock. */
#ifdef WITH_WSREP
- if ((c_lock = (ib_lock_t*)lock_rec_other_has_conflicting(
- static_cast<enum lock_mode>(
- LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION),
- block, next_rec_heap_no, trx))) {
+ if ((c_lock = lock_rec_other_has_conflicting(
+ static_cast<enum lock_mode>(
+ LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION),
+ block, next_rec_heap_no, trx))) {
#else
if (lock_rec_other_has_conflicting(
static_cast<enum lock_mode>(
@@ -7115,7 +7148,7 @@ lock_rec_insert_check_and_lock(
#ifdef WITH_WSREP
err = lock_rec_enqueue_waiting(c_lock,
- LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION,
+ LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION,
block, next_rec_heap_no, index, thr);
#else
err = lock_rec_enqueue_waiting(
@@ -8009,7 +8042,10 @@ lock_trx_release_locks(
}
mutex_exit(&trx_sys->mutex);
} else {
- ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE));
+ ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE)
+ || (trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY)
+ && trx->is_recovered
+ && !UT_LIST_GET_LEN(trx->lock.trx_locks)));
}
/* The transition of trx->state to TRX_STATE_COMMITTED_IN_MEMORY
diff --git a/storage/xtradb/lock/lock0wait.cc b/storage/xtradb/lock/lock0wait.cc
index a447027e336..da4b0301df8 100644
--- a/storage/xtradb/lock/lock0wait.cc
+++ b/storage/xtradb/lock/lock0wait.cc
@@ -33,6 +33,20 @@ Created 25/5/2010 Sunny Bains
#include "srv0start.h"
#include "ha_prototypes.h"
#include "lock0priv.h"
+#include "lock0iter.h"
+
+#include <sstream>
+
+extern "C"
+LEX_STRING* thd_query_string(MYSQL_THD thd);
+
+struct blocking_trx_info {
+ uint64_t trx_id;
+ uint32_t thread_id;
+ int64_t query_id;
+};
+
+static const size_t MAX_BLOCKING_TRX_IN_REPORT = 10;
#include <mysql/service_wsrep.h>
@@ -187,26 +201,69 @@ lock_wait_table_reserve_slot(
return(NULL);
}
+/** Print lock wait timeout info to stderr. It's supposed this function
+is executed in trx's THD thread as it calls some non-thread-safe
+functions to get some info from THD.
+@param[in] trx requested trx
+@param[in] blocking blocking info array
+@param[in] blocking_count blocking info array size */
+void
+print_lock_wait_timeout(
+ const trx_t &trx,
+ blocking_trx_info *blocking,
+ size_t blocking_count)
+{
+ std::ostringstream outs;
+
+ outs << "Lock wait timeout info:\n";
+ outs << "Requested thread id: " <<
+ thd_get_thread_id(trx.mysql_thd) <<
+ "\n";
+ outs << "Requested trx id: " << trx.id << "\n";
+ outs << "Requested query: " <<
+ thd_query_string(trx.mysql_thd)->str << "\n";
+
+ outs << "Total blocking transactions count: " <<
+ blocking_count <<
+ "\n";
+
+ for (size_t i = 0; i < blocking_count; ++i) {
+ outs << "Blocking transaction number: " << (i + 1) << "\n";
+ outs << "Blocking thread id: " <<
+ blocking[i].thread_id <<
+ "\n";
+ outs << "Blocking query id: " <<
+ blocking[i].query_id <<
+ "\n";
+ outs << "Blocking trx id: " << blocking[i].trx_id << "\n";
+ }
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " %s", outs.str().c_str());
+}
+
#ifdef WITH_WSREP
/*********************************************************************//**
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->mysql_thd) &&
- wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
- fprintf(stderr, "WSREP: BF lock wait long\n");
- srv_print_innodb_monitor = TRUE;
- srv_print_innodb_lock_monitor = TRUE;
- os_event_set(srv_monitor_event);
- return TRUE;
- }
- return FALSE;
- }
+ if (wsrep_on_trx(trx)
+ && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
+ fprintf(stderr, "WSREP: BF lock wait long for trx " TRX_ID_FMT "\n", trx->id);
+ srv_print_innodb_monitor = TRUE;
+ srv_print_innodb_lock_monitor = TRUE;
+ os_event_set(srv_monitor_event);
+ return true;
+ }
+ return false;
+}
#endif /* WITH_WSREP */
/***************************************************************//**
@@ -232,6 +289,8 @@ lock_wait_suspend_thread(
ulint sec;
ulint ms;
ulong lock_wait_timeout;
+ blocking_trx_info blocking[MAX_BLOCKING_TRX_IN_REPORT];
+ size_t blocking_count = 0;
trx = thr_get_trx(thr);
@@ -402,15 +461,17 @@ lock_wait_suspend_thread(
if (lock_wait_timeout < 100000000
&& wait_time > (double) lock_wait_timeout) {
#ifdef WITH_WSREP
- if (!wsrep_on(trx->mysql_thd) ||
- (!wsrep_is_BF_lock_timeout(trx) &&
- trx->error_state != DB_DEADLOCK)) {
+ if (!wsrep_on_trx(trx) ||
+ (!wsrep_is_BF_lock_timeout(trx) &&
+ trx->error_state != DB_DEADLOCK)) {
#endif /* WITH_WSREP */
- trx->error_state = DB_LOCK_WAIT_TIMEOUT;
+ trx->error_state = DB_LOCK_WAIT_TIMEOUT;
+ if (srv_print_lock_wait_timeout_info)
+ print_lock_wait_timeout(*trx, blocking, blocking_count);
#ifdef WITH_WSREP
- }
+ }
#endif /* WITH_WSREP */
MONITOR_INC(MONITOR_TIMEOUT);
}
diff --git a/storage/xtradb/log/log0crypt.cc b/storage/xtradb/log/log0crypt.cc
index f6c1416d81a..2a0a7abb686 100644
--- a/storage/xtradb/log/log0crypt.cc
+++ b/storage/xtradb/log/log0crypt.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
-Copyright (C) 2014, 2016, MariaDB Corporation. 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
@@ -70,22 +70,6 @@ struct crypt_info_t {
static std::deque<crypt_info_t> crypt_info;
/*********************************************************************//**
-Get a log block's start lsn.
-@return a log block's start lsn */
-static inline
-lsn_t
-log_block_get_start_lsn(
-/*====================*/
- lsn_t lsn, /*!< in: checkpoint lsn */
- ulint log_block_no) /*!< in: log block number */
-{
- lsn_t start_lsn =
- (lsn & (lsn_t)0xffffffff00000000ULL) |
- (((log_block_no - 1) & (lsn_t)0x3fffffff) << 9);
- return start_lsn;
-}
-
-/*********************************************************************//**
Get crypt info from checkpoint.
@return a crypt info or NULL if not present. */
static
@@ -161,6 +145,8 @@ Crypt_result
log_blocks_crypt(
/*=============*/
const byte* block, /*!< in: blocks before encrypt/decrypt*/
+ lsn_t lsn, /*!< in: log sequence number of the start
+ of the buffer */
ulint size, /*!< in: size of block */
byte* dst_block, /*!< out: blocks after encrypt/decrypt */
int what, /*!< in: encrypt or decrypt*/
@@ -170,21 +156,18 @@ log_blocks_crypt(
Crypt_result rc = MY_AES_OK;
uint dst_len;
byte aes_ctr_counter[MY_AES_BLOCK_SIZE];
- byte is_encrypt= what == ENCRYPTION_FLAG_ENCRYPT;
- lsn_t lsn = is_encrypt ? log_sys->lsn : srv_start_lsn;
const uint src_len = OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_HDR_SIZE;
- for (ulint i = 0; i < size ; i += OS_FILE_LOG_BLOCK_SIZE) {
+ for (ulint i = 0; i < size ; i += OS_FILE_LOG_BLOCK_SIZE,
+ lsn += OS_FILE_LOG_BLOCK_SIZE) {
ulint log_block_no = log_block_get_hdr_no(log_block);
- lsn_t log_block_start_lsn = log_block_get_start_lsn(
- lsn, log_block_no);
const crypt_info_t* info = crypt_info == NULL ? get_crypt_info(log_block) :
crypt_info;
#ifdef DEBUG_CRYPT
fprintf(stderr,
"%s %lu chkpt: %lu key: %u lsn: %lu\n",
- is_encrypt ? "crypt" : "decrypt",
+ what == ENCRYPTION_FLAG_ENCRYPT ? "crypt" : "decrypt",
log_block_no,
log_block_get_checkpoint_no(log_block),
info ? info->key_version : 0,
@@ -213,7 +196,7 @@ log_blocks_crypt(
// (1-byte, only 5 bits are used). "+" means concatenate.
bzero(aes_ctr_counter, MY_AES_BLOCK_SIZE);
memcpy(aes_ctr_counter, info->crypt_nonce, 3);
- mach_write_to_8(aes_ctr_counter + 3, log_block_start_lsn);
+ mach_write_to_8(aes_ctr_counter + 3, lsn);
mach_write_to_4(aes_ctr_counter + 11, log_block_no);
bzero(aes_ctr_counter + 15, 1);
@@ -236,6 +219,129 @@ next:
return rc;
}
+/** Encrypt/decrypt temporary log blocks.
+
+@param[in] src_block block to encrypt or decrypt
+@param[in] size size of the block
+@param[out] dst_block destination block
+@param[in] what ENCRYPTION_FLAG_ENCRYPT or
+ ENCRYPTION_FLAG_DECRYPT
+@param[in] offs offset to block
+@param[in] space_id tablespace id
+@return true if successful, false in case of failure
+*/
+static
+bool
+log_tmp_blocks_crypt(
+ const byte* src_block,
+ ulint size,
+ byte* dst_block,
+ int what,
+ os_offset_t offs,
+ ulint space_id)
+{
+ Crypt_result rc = MY_AES_OK;
+ uint dst_len;
+ byte aes_ctr_counter[MY_AES_BLOCK_SIZE];
+ byte is_encrypt= what == ENCRYPTION_FLAG_ENCRYPT;
+ const crypt_info_t* info = static_cast<const crypt_info_t*>(&crypt_info[0]);
+
+ // AES_CTR_COUNTER = space_id + offs
+
+ bzero(aes_ctr_counter, MY_AES_BLOCK_SIZE);
+ mach_write_to_8(aes_ctr_counter, space_id);
+ mach_write_to_8(aes_ctr_counter + 8, offs);
+
+ rc = encryption_crypt(src_block, size,
+ dst_block, &dst_len,
+ (unsigned char*)(info->crypt_key), 16,
+ aes_ctr_counter, MY_AES_BLOCK_SIZE,
+ what | ENCRYPTION_FLAG_NOPAD,
+ LOG_DEFAULT_ENCRYPTION_KEY,
+ info->key_version);
+
+ if (rc != MY_AES_OK) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "%s failed for temporary log file with rc = %d",
+ is_encrypt ? "Encryption" : "Decryption",
+ rc);
+ return false;
+ }
+
+ return true;
+}
+
+/** Get crypt info
+@return pointer to log crypt info or NULL
+*/
+inline
+const crypt_info_t*
+get_crypt_info()
+{
+ mutex_enter(&log_sys->mutex);
+ const crypt_info_t* info = get_crypt_info(log_sys->next_checkpoint_no);
+ mutex_exit(&log_sys->mutex);
+
+ return info;
+}
+
+/** Find out is temporary log files encrypted.
+@return true if temporary log file should be encrypted, false if not */
+UNIV_INTERN
+bool
+log_tmp_is_encrypted()
+{
+ const crypt_info_t* info = get_crypt_info();
+
+ if (info == NULL || info->key_version == UNENCRYPTED_KEY_VER) {
+ return false;
+ }
+
+ return true;
+}
+
+/** Encrypt temporary log block.
+@param[in] src_block block to encrypt or decrypt
+@param[in] size size of the block
+@param[out] dst_block destination block
+@param[in] offs offset to block
+@param[in] space_id tablespace id
+@return true if successfull, false in case of failure
+*/
+UNIV_INTERN
+bool
+log_tmp_block_encrypt(
+ const byte* src_block,
+ ulint size,
+ byte* dst_block,
+ os_offset_t offs,
+ ulint space_id)
+{
+ return (log_tmp_blocks_crypt(src_block, size, dst_block,
+ ENCRYPTION_FLAG_ENCRYPT, offs, space_id));
+}
+
+/** Decrypt temporary log block.
+@param[in] src_block block to encrypt or decrypt
+@param[in] size size of the block
+@param[out] dst_block destination block
+@param[in] offs offset to block
+@param[in] space_id tablespace id
+@return true if successfull, false in case of failure
+*/
+UNIV_INTERN
+bool
+log_tmp_block_decrypt(
+ const byte* src_block,
+ ulint size,
+ byte* dst_block,
+ os_offset_t offs,
+ ulint space_id)
+{
+ return (log_tmp_blocks_crypt(src_block, size, dst_block,
+ ENCRYPTION_FLAG_DECRYPT, offs, space_id));
+}
+
/*********************************************************************//**
Generate crypt key from crypt msg.
@return true if successfull, false if not. */
@@ -336,19 +442,6 @@ add_crypt_info(
}
/*********************************************************************//**
-Encrypt log blocks. */
-UNIV_INTERN
-Crypt_result
-log_blocks_encrypt(
-/*===============*/
- const byte* block, /*!< in: blocks before encryption */
- const ulint size, /*!< in: size of blocks, must be multiple of a log block */
- byte* dst_block) /*!< out: blocks after encryption */
-{
- return log_blocks_crypt(block, size, dst_block, ENCRYPTION_FLAG_ENCRYPT, NULL);
-}
-
-/*********************************************************************//**
Set next checkpoint's key version to latest one, and generate current
key. Key version 0 means no encryption. */
UNIV_INTERN
@@ -399,6 +492,8 @@ log_encrypt_before_write(
/*=====================*/
ib_uint64_t next_checkpoint_no, /*!< in: log group to be flushed */
byte* block, /*!< in/out: pointer to a log block */
+ lsn_t lsn, /*!< in: log sequence number of
+ the start of the buffer */
const ulint size) /*!< in: size of log blocks */
{
ut_ad(size % OS_FILE_LOG_BLOCK_SIZE == 0);
@@ -417,7 +512,8 @@ log_encrypt_before_write(
byte* dst_frame = (byte*)malloc(size);
//encrypt log blocks content
- Crypt_result result = log_blocks_crypt(block, size, dst_frame, ENCRYPTION_FLAG_ENCRYPT, NULL);
+ Crypt_result result = log_blocks_crypt(
+ block, lsn, size, dst_frame, ENCRYPTION_FLAG_ENCRYPT, NULL);
if (result == MY_AES_OK) {
ut_ad(block[0] == dst_frame[0]);
@@ -437,13 +533,16 @@ void
log_decrypt_after_read(
/*===================*/
byte* frame, /*!< in/out: log segment */
+ lsn_t lsn, /*!< in: log sequence number of the start
+ of the buffer */
const ulint size) /*!< in: log segment size */
{
ut_ad(size % OS_FILE_LOG_BLOCK_SIZE == 0);
byte* dst_frame = (byte*)malloc(size);
// decrypt log blocks content
- Crypt_result result = log_blocks_crypt(frame, size, dst_frame, ENCRYPTION_FLAG_DECRYPT, NULL);
+ Crypt_result result = log_blocks_crypt(
+ frame, lsn, size, dst_frame, ENCRYPTION_FLAG_DECRYPT, NULL);
if (result == MY_AES_OK) {
memcpy(frame, dst_frame, size);
diff --git a/storage/xtradb/log/log0log.cc b/storage/xtradb/log/log0log.cc
index 31a2cad05eb..8f8984f8880 100644
--- a/storage/xtradb/log/log0log.cc
+++ b/storage/xtradb/log/log0log.cc
@@ -1490,7 +1490,7 @@ loop:
ut_a(next_offset / UNIV_PAGE_SIZE <= ULINT_MAX);
log_encrypt_before_write(log_sys->next_checkpoint_no,
- buf, write_len);
+ buf, start_lsn, write_len);
#ifdef DEBUG_CRYPT
fprintf(stderr, "WRITE: block: %lu checkpoint: %lu %.8lx %.8lx\n",
@@ -2582,7 +2582,7 @@ loop:
log_block_get_checksum(buf), source_offset);
#endif
- log_decrypt_after_read(buf, len);
+ log_decrypt_after_read(buf, start_lsn, len);
#ifdef DEBUG_CRYPT
fprintf(stderr, "AFTER DECRYPT: block: %lu checkpoint: %lu %.8lx %.8lx\n",
@@ -2599,7 +2599,7 @@ loop:
start_lsn += len;
buf += len;
- if (recv_sys && recv_sys->report(ut_time())) {
+ if (recv_recovery_is_on() && recv_sys && recv_sys->report(ut_time())) {
ib_logf(IB_LOG_LEVEL_INFO, "Read redo log up to LSN=" LSN_PF,
start_lsn);
sd_notifyf(0, "STATUS=Read redo log up to LSN=" LSN_PF,
@@ -2890,7 +2890,8 @@ loop:
MONITOR_INC(MONITOR_LOG_IO);
//TODO (jonaso): This must be dead code??
- log_encrypt_before_write(log_sys->next_checkpoint_no, buf, len);
+ log_encrypt_before_write(log_sys->next_checkpoint_no,
+ buf, start_lsn, len);
fil_io(OS_FILE_WRITE | OS_FILE_LOG, false, group->archive_space_id,
0,
diff --git a/storage/xtradb/log/log0online.cc b/storage/xtradb/log/log0online.cc
index 27382977e5c..af32237243b 100644
--- a/storage/xtradb/log/log0online.cc
+++ b/storage/xtradb/log/log0online.cc
@@ -479,9 +479,9 @@ log_online_make_bitmap_name(
/*=========================*/
lsn_t start_lsn) /*!< in: the start LSN name part */
{
- ut_snprintf(log_bmp_sys->out.name, FN_REFLEN, bmp_file_name_template,
- log_bmp_sys->bmp_file_home, bmp_file_name_stem,
- log_bmp_sys->out_seq_num, start_lsn);
+ ut_snprintf(log_bmp_sys->out.name, sizeof(log_bmp_sys->out.name),
+ bmp_file_name_template, log_bmp_sys->bmp_file_home,
+ bmp_file_name_stem, log_bmp_sys->out_seq_num, start_lsn);
}
/*********************************************************************//**
diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc
index fb64309cee4..1943fb51f37 100644
--- a/storage/xtradb/log/log0recv.cc
+++ b/storage/xtradb/log/log0recv.cc
@@ -842,10 +842,8 @@ not_consistent:
fprintf(stderr,
"InnoDB: No valid checkpoint found.\n"
- "InnoDB: If you are attempting downgrade"
- " from MySQL 5.7.9 or later,\n"
- "InnoDB: please refer to " REFMAN
- "upgrading-downgrading.html\n"
+ "InnoDB: A downgrade from MariaDB 10.2.2"
+ " or later is not supported.\n"
"InnoDB: If this error appears when you are"
" creating an InnoDB database,\n"
"InnoDB: the problem may be that during"
@@ -1982,7 +1980,7 @@ recv_apply_hashed_log_recs(bool last_batch)
mutex_enter(&(log_sys->mutex));
mutex_enter(&(recv_sys->mutex));
- ut_d(recv_no_log_write = FALSE);
+ ut_d(recv_no_log_write = srv_apply_log_only);
recv_no_ibuf_operations = FALSE;
}
@@ -3463,7 +3461,8 @@ recv_recovery_from_checkpoint_finish(void)
that the data dictionary tables will be free of any locks.
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) {
+ if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO
+ && !srv_apply_log_only) {
trx_rollback_or_clean_recovered(FALSE);
}
}
@@ -3566,6 +3565,7 @@ recv_reset_logs(
log_sys->tracked_lsn = log_sys->lsn;
+ memset(log_sys->buf, 0, log_sys->buf_size);
log_block_init(log_sys->buf, log_sys->lsn);
log_block_set_first_rec_group(log_sys->buf, LOG_BLOCK_HDR_SIZE);
diff --git a/storage/xtradb/mem/mem0mem.cc b/storage/xtradb/mem/mem0mem.cc
index e066aff5b30..b9f190509ee 100644
--- a/storage/xtradb/mem/mem0mem.cc
+++ b/storage/xtradb/mem/mem0mem.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2011, 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
@@ -506,13 +507,13 @@ mem_heap_block_free(
#ifndef UNIV_HOTBACKUP
if (!srv_use_sys_malloc) {
#ifdef UNIV_MEM_DEBUG
+ UNIV_MEM_ALLOC(block, len);
/* In the debug version we set the memory to a random
combination of hex 0xDE and 0xAD. */
- mem_erase_buf((byte*) block, len);
-#else /* UNIV_MEM_DEBUG */
- UNIV_MEM_ASSERT_AND_FREE(block, len);
+ mem_erase_buf((byte*)block, len);
#endif /* UNIV_MEM_DEBUG */
+ UNIV_MEM_FREE(block, len);
}
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
@@ -526,13 +527,13 @@ mem_heap_block_free(
}
#else /* !UNIV_HOTBACKUP */
#ifdef UNIV_MEM_DEBUG
+ UNIV_MEM_ALLOC(block, len);
/* In the debug version we set the memory to a random
combination of hex 0xDE and 0xAD. */
- mem_erase_buf((byte*) block, len);
-#else /* UNIV_MEM_DEBUG */
- UNIV_MEM_ASSERT_AND_FREE(block, len);
+ mem_erase_buf((byte*)block, len);
#endif /* UNIV_MEM_DEBUG */
+ UNIV_MEM_FREE(block, len);
ut_free(block);
#endif /* !UNIV_HOTBACKUP */
}
diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc
index 32536306320..634ebb2af49 100644
--- a/storage/xtradb/os/os0file.cc
+++ b/storage/xtradb/os/os0file.cc
@@ -296,6 +296,16 @@ struct os_aio_array_t{
There is one such event for each
possible pending IO. The size of the
array is equal to n_slots. */
+ struct iocb** pending;
+ /* Array to buffer the not-submitted aio
+ requests. The array length is n_slots.
+ It is divided into n_segments segments.
+ pending requests on each segment are buffered
+ separately.*/
+ ulint* count;
+ /* Array of length n_segments. Each element
+ counts the number of not-submitted aio
+ request on that segment.*/
#endif /* LINUX_NATIV_AIO */
};
@@ -676,10 +686,9 @@ os_file_get_last_error_low(
REFMAN
"operating-system-error-codes.html\n");
}
+ fflush(stderr);
}
- fflush(stderr);
-
if (err == ERROR_FILE_NOT_FOUND) {
return(OS_FILE_NOT_FOUND);
} else if (err == ERROR_DISK_FULL) {
@@ -2571,12 +2580,21 @@ os_file_get_size(
return(offset);
#else
- return((os_offset_t) lseek(file, 0, SEEK_END));
-
+ struct stat statbuf;
+ return fstat(file, &statbuf) ? os_offset_t(-1) : statbuf.st_size;
#endif /* __WIN__ */
}
-/** Set the size of a newly created file.
+/** Extend a file.
+
+On Windows, extending a file allocates blocks for the file,
+unless the file is sparse.
+
+On Unix, we will extend the file with ftruncate(), if
+file needs to be sparse. Otherwise posix_fallocate() is used
+when available, and if not, binary zeroes are added to the end
+of file.
+
@param[in] name file name
@param[in] file file handle
@param[in] size desired file size
@@ -2617,25 +2635,41 @@ os_file_set_size(
if (srv_use_posix_fallocate) {
int err;
do {
- err = posix_fallocate(file, 0, size);
+ os_offset_t current_size = os_file_get_size(file);
+ err = current_size >= size
+ ? 0 : posix_fallocate(file, current_size,
+ size - current_size);
} while (err == EINTR
&& srv_shutdown_state == SRV_SHUTDOWN_NONE);
- if (err) {
+ switch (err) {
+ case 0:
+ return true;
+ default:
ib_logf(IB_LOG_LEVEL_ERROR,
"preallocating " INT64PF " bytes for"
"file %s failed with error %d",
size, name, err);
+ /* fall through */
+ case EINTR:
+ errno = err;
+ return false;
+ case EINVAL:
+ /* fall back to the code below */
+ break;
}
- return(!err);
}
# endif
+ os_offset_t current_size = os_file_get_size(file);
+
+ if (current_size >= size) {
+ return true;
+ }
+
/* Write up to 1 megabyte at a time. */
ulint buf_size = ut_min(64, (ulint) (size / UNIV_PAGE_SIZE))
* UNIV_PAGE_SIZE;
- os_offset_t current_size = 0;
-
byte* buf2 = static_cast<byte*>(calloc(1, buf_size + UNIV_PAGE_SIZE));
if (!buf2) {
@@ -2665,11 +2699,12 @@ os_file_set_size(
}
current_size += n_bytes;
- } while (current_size < size);
+ } while (current_size < size
+ && srv_shutdown_state == SRV_SHUTDOWN_NONE);
free(buf2);
- return(ret && os_file_flush(file));
+ return(ret && current_size >= size && os_file_flush(file));
#endif
}
@@ -4251,6 +4286,13 @@ os_aio_array_create(
memset(io_event, 0x0, sizeof(*io_event) * n);
array->aio_events = io_event;
+ array->pending = static_cast<struct iocb**>(
+ ut_malloc(n * sizeof(struct iocb*)));
+ memset(array->pending, 0x0, sizeof(struct iocb*) * n);
+ array->count = static_cast<ulint*>(
+ ut_malloc(n_segments * sizeof(ulint)));
+ memset(array->count, 0x0, sizeof(ulint) * n_segments);
+
skip_native_aio:
#endif /* LINUX_NATIVE_AIO */
for (ulint i = 0; i < n; i++) {
@@ -4285,6 +4327,16 @@ os_aio_array_free(
if (srv_use_native_aio) {
ut_free(array->aio_events);
ut_free(array->aio_ctx);
+
+#ifdef UNIV_DEBUG
+ for (size_t idx = 0; idx < array->n_slots; ++idx)
+ ut_ad(array->pending[idx] == NULL);
+ for (size_t idx = 0; idx < array->n_segments; ++idx)
+ ut_ad(array->count[idx] == 0);
+#endif
+
+ ut_free(array->pending);
+ ut_free(array->count);
}
#endif /* LINUX_NATIVE_AIO */
@@ -4932,6 +4984,83 @@ readahead requests. */
}
#endif /* _WIN32 */
+/** Submit buffered AIO requests on the given segment to the kernel
+(low level function).
+@param acquire_mutex specifies whether to lock array mutex
+*/
+static
+void
+os_aio_dispatch_read_array_submit_low(bool acquire_mutex MY_ATTRIBUTE((unused)))
+{
+ if (!srv_use_native_aio) {
+ return;
+ }
+#if defined(LINUX_NATIVE_AIO)
+ os_aio_array_t* array = os_aio_read_array;
+ ulint total_submitted = 0;
+ if (acquire_mutex)
+ os_mutex_enter(array->mutex);
+ /* Submit aio requests buffered on all segments. */
+ for (ulint i = 0; i < array->n_segments; i++) {
+ const int count = array->count[i];
+ int offset = 0;
+ while (offset != count) {
+ struct iocb** const iocb_array = array->pending
+ + i * array->n_slots / array->n_segments
+ + offset;
+ const int partial_count = count - offset;
+ /* io_submit() returns number of successfully queued
+ requests or (-errno).
+ It returns 0 only if the number of iocb blocks passed
+ is also 0. */
+ const int submitted = io_submit(array->aio_ctx[i],
+ partial_count, iocb_array);
+
+ /* This assertion prevents infinite loop in both
+ debug and release modes. */
+ ut_a(submitted != 0);
+
+ if (submitted < 0) {
+ /* Terminating with fatal error */
+ const char* errmsg =
+ strerror(-submitted);
+ ib_logf(IB_LOG_LEVEL_FATAL,
+ "Trying to sumbit %d aio requests, "
+ "io_submit() set errno to %d: %s",
+ partial_count, -submitted,
+ errmsg ? errmsg : "<unknown>");
+ }
+ ut_ad(submitted <= partial_count);
+ if (submitted < partial_count)
+ {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Trying to sumbit %d aio requests, "
+ "io_submit() submitted only %d",
+ partial_count, submitted);
+ }
+ offset += submitted;
+ }
+ total_submitted += count;
+ }
+ /* Reset the aio request buffer. */
+ memset(array->pending, 0x0, sizeof(struct iocb*) * array->n_slots);
+ memset(array->count, 0x0, sizeof(ulint) * array->n_segments);
+
+ if (acquire_mutex)
+ os_mutex_exit(array->mutex);
+
+ srv_stats.n_aio_submitted.add(total_submitted);
+#endif
+}
+
+/** Submit buffered AIO requests on the given segment to the kernel. */
+UNIV_INTERN
+void
+os_aio_dispatch_read_array_submit()
+{
+ os_aio_dispatch_read_array_submit_low(true);
+}
+
#if defined(LINUX_NATIVE_AIO)
/*******************************************************************//**
Dispatch an AIO request to the kernel.
@@ -4941,10 +5070,11 @@ ibool
os_aio_linux_dispatch(
/*==================*/
os_aio_array_t* array, /*!< in: io request array. */
- os_aio_slot_t* slot) /*!< in: an already reserved slot. */
+ os_aio_slot_t* slot, /*!< in: an already reserved slot. */
+ bool should_buffer) /*!< in: should buffer the request
+ rather than submit. */
{
int ret;
- ulint io_ctx_index;
struct iocb* iocb;
ut_ad(slot != NULL);
@@ -4956,9 +5086,31 @@ os_aio_linux_dispatch(
The iocb struct is directly in the slot.
The io_context is one per segment. */
+ ulint slots_per_segment = array->n_slots / array->n_segments;
iocb = &slot->control;
- io_ctx_index = (slot->pos * array->n_segments) / array->n_slots;
+ ulint io_ctx_index = slot->pos / slots_per_segment;
+ if (should_buffer) {
+ ut_ad(array == os_aio_read_array);
+ os_mutex_enter(array->mutex);
+ /* There are array->n_slots elements in array->pending,
+ which is divided into array->n_segments area of equal size.
+ The iocb of each segment are buffered in its corresponding area
+ in the pending array consecutively as they come.
+ array->count[i] records the number of buffered aio requests
+ in the ith segment.*/
+ ulint& count = array->count[io_ctx_index];
+ ut_ad(count != slots_per_segment);
+ ulint n = io_ctx_index * slots_per_segment + count;
+ array->pending[n] = iocb;
+ ++count;
+ if (count == slots_per_segment) {
+ os_aio_dispatch_read_array_submit_low(false);
+ }
+ os_mutex_exit(array->mutex);
+ return(TRUE);
+ }
+ /* Submit the given request. */
ret = io_submit(array->aio_ctx[io_ctx_index], 1, &iocb);
#if defined(UNIV_AIO_DEBUG)
@@ -5021,11 +5173,17 @@ os_aio_func(
OS_AIO_SYNC */
ulint space_id,
trx_t* trx,
- ulint* write_size)/*!< in/out: Actual write size initialized
+ ulint* write_size,/*!< in/out: Actual write size initialized
after fist successfull trim
operation for this page and if
initialized we do not trim again if
actual page size does not decrease. */
+ bool should_buffer)
+ /*!< in: Whether to buffer an aio request.
+ AIO read ahead uses this. If you plan to
+ use this parameter, make sure you remember
+ to call os_aio_dispatch_read_array_submit()
+ when you're ready to commit all your requests.*/
{
os_aio_array_t* array;
os_aio_slot_t* slot;
@@ -5143,7 +5301,8 @@ try_again:
goto err_exit;
#elif defined(LINUX_NATIVE_AIO)
- if (!os_aio_linux_dispatch(array, slot)) {
+ if (!os_aio_linux_dispatch(array, slot,
+ should_buffer)) {
goto err_exit;
}
#endif /* WIN_ASYNC_IO */
@@ -5167,7 +5326,7 @@ try_again:
if(!ret && GetLastError() != ERROR_IO_PENDING)
goto err_exit;
#elif defined(LINUX_NATIVE_AIO)
- if (!os_aio_linux_dispatch(array, slot)) {
+ if (!os_aio_linux_dispatch(array, slot, false)) {
goto err_exit;
}
#endif /* WIN_ASYNC_IO */
diff --git a/storage/xtradb/page/page0cur.cc b/storage/xtradb/page/page0cur.cc
index 76e4c2aed9b..692cb393afd 100644
--- a/storage/xtradb/page/page0cur.cc
+++ b/storage/xtradb/page/page0cur.cc
@@ -903,7 +903,7 @@ page_cur_parse_insert_rec(
ut_print_buf(stderr, ptr2, 300);
putc('\n', stderr);
- buf_page_print(page, 0, 0);
+ buf_page_print(page, 0);
ut_error;
}
diff --git a/storage/xtradb/page/page0page.cc b/storage/xtradb/page/page0page.cc
index 3f8e47adafd..fc93eebd445 100644
--- a/storage/xtradb/page/page0page.cc
+++ b/storage/xtradb/page/page0page.cc
@@ -154,7 +154,7 @@ page_dir_find_owner_slot(
fputs("\n"
"InnoDB: on that page!\n", stderr);
- buf_page_print(page, 0, 0);
+ buf_page_print(page, 0);
ut_error;
}
@@ -618,10 +618,8 @@ page_copy_rec_list_end_no_locks(
/* Track an assertion failure reported on the mailing
list on June 18th, 2003 */
- buf_page_print(new_page, 0,
- BUF_PAGE_PRINT_NO_CRASH);
- buf_page_print(page_align(rec), 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(new_page, 0);
+ buf_page_print(page_align(rec), 0);
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -1953,7 +1951,8 @@ page_check_dir(
fprintf(stderr,
"InnoDB: Page directory corruption:"
" infimum not pointed to\n");
- buf_page_print(page, 0, 0);
+ buf_page_print(page, 0);
+ ut_ad(0);
}
if (UNIV_UNLIKELY(!page_rec_is_supremum_low(supremum_offs))) {
@@ -1961,7 +1960,8 @@ page_check_dir(
fprintf(stderr,
"InnoDB: Page directory corruption:"
" supremum not pointed to\n");
- buf_page_print(page, 0, 0);
+ buf_page_print(page, 0);
+ ut_ad(0);
}
}
#endif /* !UNIV_HOTBACKUP */
@@ -2679,7 +2679,8 @@ func_exit2:
(ulong) page_get_space_id(page),
(ulong) page_get_page_no(page),
index->name);
- buf_page_print(page, 0, 0);
+ buf_page_print(page, 0);
+ ut_ad(0);
}
return(ret);
@@ -2838,7 +2839,7 @@ page_warn_strict_checksum(
ulint space_id,
ulint page_no)
{
- srv_checksum_algorithm_t curr_algo_nonstrict;
+ srv_checksum_algorithm_t curr_algo_nonstrict = srv_checksum_algorithm_t();
switch (curr_algo) {
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
curr_algo_nonstrict = SRV_CHECKSUM_ALGORITHM_CRC32;
diff --git a/storage/xtradb/rem/rem0rec.cc b/storage/xtradb/rem/rem0rec.cc
index c62e8c90434..2314f110312 100644
--- a/storage/xtradb/rem/rem0rec.cc
+++ b/storage/xtradb/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
@@ -865,13 +865,10 @@ 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);
- 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 */
ut_ad(!field->prefix_len
@@ -1259,14 +1256,10 @@ rec_convert_dtuple_to_rec_comp(
it is 128 or more, or when the field is stored externally. */
if (fixed_len) {
#ifdef UNIV_DEBUG
- ulint mbminlen = DATA_MBMINLEN(
- ifield->col->mbminmaxlen);
- ulint mbmaxlen = DATA_MBMAXLEN(
- ifield->col->mbminmaxlen);
-
ut_ad(len <= fixed_len);
- ut_ad(!mbmaxlen || len >= mbminlen
- * (fixed_len / mbmaxlen));
+ ut_ad(!ifield->col->mbmaxlen
+ || len >= ifield->col->mbminlen
+ * (fixed_len / ifield->col->mbmaxlen));
ut_ad(!dfield_is_ext(field));
#endif /* UNIV_DEBUG */
} else if (dfield_is_ext(field)) {
diff --git a/storage/xtradb/row/row0ext.cc b/storage/xtradb/row/row0ext.cc
index ad852577ad2..32b78391d6a 100644
--- a/storage/xtradb/row/row0ext.cc
+++ b/storage/xtradb/row/row0ext.cc
@@ -78,8 +78,7 @@ row_ext_cache_fill(
crashed during the execution of
btr_free_externally_stored_field(). */
ext->len[i] = btr_copy_externally_stored_field_prefix(
- buf, ext->max_len, zip_size, field, f_len,
- NULL);
+ buf, ext->max_len, zip_size, field, f_len);
}
}
}
diff --git a/storage/xtradb/row/row0ftsort.cc b/storage/xtradb/row/row0ftsort.cc
index 7ffcc59dc5f..bd57685b71c 100644
--- a/storage/xtradb/row/row0ftsort.cc
+++ b/storage/xtradb/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
@@ -40,7 +40,7 @@ Created 10/13/2010 Jimmy Yang
b[N] = row_merge_read_rec( \
block[N], buf[N], b[N], index, \
fd[N], &foffs[N], &mrec[N], offsets[N], \
- crypt_data, crypt_block[N], space); \
+ crypt_block[N], space); \
if (UNIV_UNLIKELY(!b[N])) { \
if (mrec[N]) { \
goto exit; \
@@ -106,8 +106,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;
@@ -150,7 +151,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);
@@ -162,7 +164,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);
}
@@ -194,7 +197,6 @@ row_fts_psort_info_init(
fts_psort_t* merge_info = NULL;
ulint block_size;
ibool ret = TRUE;
- fil_space_crypt_t* crypt_data = NULL;
bool encrypted = false;
block_size = 3 * srv_sort_buf_size;
@@ -225,21 +227,8 @@ row_fts_psort_info_init(
common_info->merge_event = os_event_create();
common_info->opt_doc_id_size = opt_doc_id_size;
- /* Theoretically the tablespace can be dropped straight away.
- In practice, the DDL completion will wait for this thread to
- finish. */
- if (fil_space_t* space = fil_space_acquire(new_table->space)) {
- crypt_data = space->crypt_data;
- fil_space_release(space);
- }
-
- if (crypt_data && crypt_data->should_encrypt()) {
- common_info->crypt_data = crypt_data;
+ if (log_tmp_is_encrypted()) {
encrypted = true;
- } else {
- /* Not needed */
- common_info->crypt_data = NULL;
- crypt_data = NULL;
}
ut_ad(trx->mysql_thd != NULL);
@@ -554,7 +543,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);
@@ -573,15 +563,14 @@ 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);
- /* Reserve one byte for the end marker of row_merge_block_t
- and we have reserved ROW_MERGE_RESERVE_SIZE (= 4) for
- encryption key_version in the beginning of the buffer. */
+ /* Reserve one byte for the end marker of row_merge_block_t */
if (buf->total_size + data_size[idx] + cur_len
- >= (srv_sort_buf_size - 1 - ROW_MERGE_RESERVE_SIZE)) {
+ >= (srv_sort_buf_size - 1)) {
buf_full = TRUE;
break;
@@ -675,7 +664,6 @@ fts_parallel_tokenization(
fts_tokenize_ctx_t t_ctx;
ulint retried = 0;
dberr_t error = DB_SUCCESS;
- fil_space_crypt_t* crypt_data = NULL;
ut_ad(psort_info->psort_common->trx->mysql_thd != NULL);
@@ -696,7 +684,6 @@ fts_parallel_tokenization(
block = psort_info->merge_block;
crypt_block = psort_info->crypt_block;
- crypt_data = psort_info->psort_common->crypt_data;
zip_size = dict_table_zip_size(table);
row_merge_fts_get_next_doc_item(psort_info, &doc_item);
@@ -727,8 +714,7 @@ loop:
doc.text.f_str =
btr_copy_externally_stored_field(
&doc.text.f_len, data,
- zip_size, data_len, blob_heap,
- NULL);
+ zip_size, data_len, blob_heap);
} else {
doc.text.f_str = data;
doc.text.f_len = data_len;
@@ -791,7 +777,6 @@ loop:
if (!row_merge_write(merge_file[t_ctx.buf_used]->fd,
merge_file[t_ctx.buf_used]->offset++,
block[t_ctx.buf_used],
- crypt_data,
crypt_block[t_ctx.buf_used],
table->space)) {
error = DB_TEMP_FILE_WRITE_FAILURE;
@@ -887,7 +872,6 @@ exit:
if (!row_merge_write(merge_file[i]->fd,
merge_file[i]->offset++,
block[i],
- crypt_data,
crypt_block[i],
table->space)) {
error = DB_TEMP_FILE_WRITE_FAILURE;
@@ -927,7 +911,7 @@ exit:
psort_info->psort_common->dup,
merge_file[i], block[i], &tmpfd[i],
false, 0.0/* pct_progress */, 0.0/* pct_cost */,
- crypt_data, crypt_block[i], table->space);
+ crypt_block[i], table->space);
if (error != DB_SUCCESS) {
close(tmpfd[i]);
@@ -1439,7 +1423,6 @@ row_fts_merge_insert(
ulint start;
fts_psort_insert_t ins_ctx;
ulint count_diag = 0;
- fil_space_crypt_t* crypt_data = NULL;
ulint space;
ut_ad(index);
@@ -1453,7 +1436,6 @@ row_fts_merge_insert(
ins_ctx.trx->op_info = "inserting index entries";
ins_ctx.opt_doc_id_size = psort_info[0].psort_common->opt_doc_id_size;
- crypt_data = psort_info[0].psort_common->crypt_data;
heap = mem_heap_create(500 + sizeof(mrec_buf_t));
@@ -1547,7 +1529,6 @@ row_fts_merge_insert(
&& (!row_merge_read(
fd[i], foffs[i],
(row_merge_block_t*) block[i],
- crypt_data,
(row_merge_block_t*) crypt_block[i],
space))) {
error = DB_CORRUPTION;
diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc
index a99c72c01b5..8a06342cafd 100644
--- a/storage/xtradb/row/row0import.cc
+++ b/storage/xtradb/row/row0import.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 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
@@ -1259,7 +1259,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,
@@ -1602,18 +1603,16 @@ PageConverter::PageConverter(
:
AbstractCallback(trx),
m_cfg(cfg),
+ m_index(cfg->m_indexes),
+ m_current_lsn(log_get_lsn()),
m_page_zip_ptr(0),
- m_heap(0) UNIV_NOTHROW
+ m_rec_iter(),
+ m_offsets_(), m_offsets(m_offsets_),
+ m_heap(0),
+ m_cluster_index(dict_table_get_first_index(cfg->m_table)) UNIV_NOTHROW
{
- m_index = m_cfg->m_indexes;
-
- m_current_lsn = log_get_lsn();
ut_a(m_current_lsn > 0);
-
- m_offsets = m_offsets_;
rec_offs_init(m_offsets_);
-
- m_cluster_index = dict_table_get_first_index(m_cfg->m_table);
}
/**
@@ -1771,7 +1770,7 @@ PageConverter::adjust_cluster_record(
row_upd_rec_sys_fields(
rec, m_page_zip_ptr, m_cluster_index, m_offsets,
- m_trx, 0);
+ m_trx, roll_ptr_t(1) << 55);
}
return(err);
@@ -1793,16 +1792,12 @@ PageConverter::update_records(
m_rec_iter.open(block);
- while (!m_rec_iter.end()) {
+ if (!page_is_leaf(block->frame)) {
+ return DB_SUCCESS;
+ }
+ while (!m_rec_iter.end()) {
rec_t* rec = m_rec_iter.current();
-
- /* FIXME: Move out of the loop */
-
- if (rec_get_status(rec) == REC_STATUS_NODE_PTR) {
- break;
- }
-
ibool deleted = rec_get_deleted_flag(rec, comp);
/* For the clustered index we have to adjust the BLOB
@@ -2108,7 +2103,7 @@ PageConverter::operator() (
we can work on them */
if ((err = update_page(block, page_type)) != DB_SUCCESS) {
- return(err);
+ break;
}
/* Note: For compressed pages this function will write to the
@@ -2145,9 +2140,15 @@ PageConverter::operator() (
"%s: Page %lu at offset " UINT64PF " looks corrupted.",
m_filepath, (ulong) (offset / m_page_size), offset);
- return(DB_CORRUPTION);
+ err = DB_CORRUPTION;
}
+ /* If we already had and old page with matching number
+ in the buffer pool, evict it now, because
+ we no longer evict the pages on DISCARD TABLESPACE. */
+ buf_page_get_gen(get_space_id(), get_zip_size(), block->page.offset,
+ RW_NO_LATCH, NULL, BUF_EVICT_IF_IN_POOL,
+ __FILE__, __LINE__, NULL);
return(err);
}
@@ -2877,7 +2878,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);
@@ -3721,8 +3724,7 @@ 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, BUF_REMOVE_FLUSH_WRITE, trx);
+ buf_LRU_flush_or_remove_pages(prebuilt->table->space, trx);
if (trx_is_interrupted(trx)) {
ib_logf(IB_LOG_LEVEL_INFO, "Phase III - Flush interrupted");
diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc
index 33f8ec443dd..472be8ad848 100644
--- a/storage/xtradb/row/row0ins.cc
+++ b/storage/xtradb/row/row0ins.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 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
@@ -571,7 +571,8 @@ 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*>(
@@ -1143,7 +1144,7 @@ row_ins_foreign_check_on_constraint(
rec_print(stderr, clust_rec, clust_index);
fputs("\n"
"InnoDB: Submit a detailed bug report to"
- " http://bugs.mysql.com\n", stderr);
+ " https://jira.mariadb.org/\n", stderr);
ut_ad(0);
err = DB_SUCCESS;
@@ -1297,12 +1298,11 @@ row_ins_foreign_check_on_constraint(
#ifdef WITH_WSREP
err = wsrep_append_foreign_key(
- thr_get_trx(thr),
- foreign,
- clust_rec,
- clust_index,
- FALSE,
- (node) ? TRUE : FALSE);
+ thr_get_trx(thr),
+ foreign,
+ clust_rec,
+ clust_index,
+ FALSE, FALSE);
if (err != DB_SUCCESS) {
fprintf(stderr,
"WSREP: foreign key append failed: %d\n", err);
@@ -1331,7 +1331,7 @@ row_ins_foreign_check_on_constraint(
row_mysql_freeze_data_dictionary(thr_get_trx(thr));
- mtr_start_trx(mtr, trx);
+ mtr_start(mtr);
/* Restore pcur position */
@@ -1359,7 +1359,7 @@ nonstandard_exit_func:
btr_pcur_store_position(pcur, mtr);
mtr_commit(mtr);
- mtr_start_trx(mtr, trx);
+ mtr_start(mtr);
btr_pcur_restore_position(BTR_SEARCH_LEAF, pcur, mtr);
@@ -1572,7 +1572,7 @@ run_again:
}
}
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* Store old value on n_fields_cmp */
@@ -2391,7 +2391,7 @@ row_ins_clust_index_entry_low(
search_mode = mode;
}
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
if (mode == BTR_MODIFY_LEAF && dict_index_is_online_ddl(index)) {
@@ -2629,10 +2629,9 @@ Starts a mini-transaction and checks if the index will be dropped.
@return true if the index is to be dropped */
static MY_ATTRIBUTE((nonnull, warn_unused_result))
bool
-row_ins_sec_mtr_start_trx_and_check_if_aborted(
+row_ins_sec_mtr_start_and_check_if_aborted(
/*=======================================*/
mtr_t* mtr, /*!< out: mini-transaction */
- trx_t* trx, /*!< in: transaction handle */
dict_index_t* index, /*!< in/out: secondary index */
bool check, /*!< in: whether to check */
ulint search_mode)
@@ -2640,7 +2639,7 @@ row_ins_sec_mtr_start_trx_and_check_if_aborted(
{
ut_ad(!dict_index_is_clust(index));
- mtr_start_trx(mtr, trx);
+ mtr_start(mtr);
if (!check) {
return(false);
@@ -2698,14 +2697,13 @@ row_ins_sec_index_entry_low(
ulint n_unique;
mtr_t mtr;
ulint* offsets = NULL;
- trx_t* trx = thr_get_trx(thr);
ut_ad(!dict_index_is_clust(index));
ut_ad(mode == BTR_MODIFY_LEAF || mode == BTR_MODIFY_TREE);
cursor.thr = thr;
ut_ad(thr_get_trx(thr)->id);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* If running with fake_changes mode on then avoid using insert buffer
and also switch from modify to search so that code takes only s-latch
@@ -2767,7 +2765,7 @@ row_ins_sec_index_entry_low(
if (err != DB_SUCCESS) {
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. "
@@ -2803,8 +2801,8 @@ row_ins_sec_index_entry_low(
DEBUG_SYNC_C("row_ins_sec_index_unique");
- if (row_ins_sec_mtr_start_trx_and_check_if_aborted(
- &mtr, trx, index, check, search_mode)) {
+ if (row_ins_sec_mtr_start_and_check_if_aborted(
+ &mtr, index, check, search_mode)) {
goto func_exit;
}
@@ -2838,8 +2836,8 @@ row_ins_sec_index_entry_low(
return(err);
}
- if (row_ins_sec_mtr_start_trx_and_check_if_aborted(
- &mtr, trx, index, check, search_mode)) {
+ if (row_ins_sec_mtr_start_and_check_if_aborted(
+ &mtr, index, check, search_mode)) {
goto func_exit;
}
@@ -3042,6 +3040,10 @@ row_ins_sec_index_entry(
mem_heap_t* offsets_heap;
mem_heap_t* heap;
+ DBUG_EXECUTE_IF("row_ins_sec_index_entry_timeout", {
+ DBUG_SET("-d,row_ins_sec_index_entry_timeout");
+ return(DB_LOCK_WAIT);});
+
if (!index->table->foreign_set.empty()) {
err = row_ins_check_foreign_constraints(index->table, index,
entry, thr);
@@ -3144,7 +3146,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*>(
diff --git a/storage/xtradb/row/row0log.cc b/storage/xtradb/row/row0log.cc
index 2cd663fd600..040fb37ee30 100644
--- a/storage/xtradb/row/row0log.cc
+++ b/storage/xtradb/row/row0log.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 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
@@ -197,8 +197,14 @@ struct row_log_t {
row_log_buf_t tail; /*!< writer context;
protected by mutex and index->lock S-latch,
or by index->lock X-latch only */
+ byte* crypt_tail; /*!< writer context;
+ temporary buffer used in encryption,
+ decryption or NULL*/
row_log_buf_t head; /*!< reader context; protected by MDL only;
modifiable by row_log_apply_ops() */
+ byte* crypt_head; /*!< reader context;
+ temporary buffer used in encryption,
+ decryption or NULL */
const char* path; /*!< where to create temporary file during
log operation */
};
@@ -349,6 +355,7 @@ row_log_online_op(
= (os_offset_t) log->tail.blocks
* srv_sort_buf_size;
ibool ret;
+ byte * buf = log->tail.block;
if (byte_offset + srv_sort_buf_size >= srv_online_max_size) {
goto write_failed;
@@ -368,11 +375,29 @@ row_log_online_op(
goto err_exit;
}
+ /* If encryption is enabled encrypt buffer before writing it
+ to file system. */
+ if (log_tmp_is_encrypted()) {
+ if (!log_tmp_block_encrypt(log->tail.block,
+ srv_sort_buf_size,
+ log->crypt_tail,
+ byte_offset,
+ index->table->space)) {
+ log->error = DB_DECRYPTION_FAILED;
+ goto write_failed;
+ }
+
+ srv_stats.n_rowlog_blocks_encrypted.inc();
+ buf = log->crypt_tail;
+ }
+
ret = os_file_write_int_fd(
"(modification log)",
log->fd,
- log->tail.block, byte_offset, srv_sort_buf_size);
+ buf, byte_offset, srv_sort_buf_size);
+
log->tail.blocks++;
+
if (!ret) {
write_failed:
/* We set the flag directly instead of invoking
@@ -380,7 +405,9 @@ write_failed:
because the index is not "public" yet. */
index->type |= DICT_CORRUPT;
}
+
UNIV_MEM_INVALID(log->tail.block, srv_sort_buf_size);
+
memcpy(log->tail.block, log->tail.buf + avail_size,
mrec_size - avail_size);
log->tail.bytes = mrec_size - avail_size;
@@ -451,13 +478,15 @@ static MY_ATTRIBUTE((nonnull))
void
row_log_table_close_func(
/*=====================*/
- row_log_t* log, /*!< in/out: online rebuild log */
+ dict_index_t* index, /*!< in/out: online rebuilt index */
#ifdef UNIV_DEBUG
const byte* b, /*!< in: end of log record */
#endif /* UNIV_DEBUG */
ulint size, /*!< in: size of log record */
ulint avail) /*!< in: available size for log record */
{
+ row_log_t* log = index->online_log;
+
ut_ad(mutex_own(&log->mutex));
if (size >= avail) {
@@ -465,6 +494,7 @@ row_log_table_close_func(
= (os_offset_t) log->tail.blocks
* srv_sort_buf_size;
ibool ret;
+ byte * buf = log->tail.block;
if (byte_offset + srv_sort_buf_size >= srv_online_max_size) {
goto write_failed;
@@ -484,11 +514,29 @@ row_log_table_close_func(
goto err_exit;
}
+ /* If encryption is enabled encrypt buffer before writing it
+ to file system. */
+ if (log_tmp_is_encrypted()) {
+ if (!log_tmp_block_encrypt(log->tail.block,
+ srv_sort_buf_size,
+ log->crypt_tail,
+ byte_offset,
+ index->table->space)) {
+ log->error = DB_DECRYPTION_FAILED;
+ goto err_exit;
+ }
+
+ srv_stats.n_rowlog_blocks_encrypted.inc();
+ buf = log->crypt_tail;
+ }
+
ret = os_file_write_int_fd(
"(modification log)",
log->fd,
- log->tail.block, byte_offset, srv_sort_buf_size);
+ buf, byte_offset, srv_sort_buf_size);
+
log->tail.blocks++;
+
if (!ret) {
write_failed:
log->error = DB_ONLINE_LOG_TOO_BIG;
@@ -512,11 +560,11 @@ err_exit:
}
#ifdef UNIV_DEBUG
-# define row_log_table_close(log, b, size, avail) \
- row_log_table_close_func(log, b, size, avail)
+# define row_log_table_close(index, b, size, avail) \
+ row_log_table_close_func(index, b, size, avail)
#else /* UNIV_DEBUG */
# define row_log_table_close(log, b, size, avail) \
- row_log_table_close_func(log, size, avail)
+ row_log_table_close_func(index, size, avail)
#endif /* UNIV_DEBUG */
/******************************************************//**
@@ -688,8 +736,7 @@ row_log_table_delete(
b += ext_size;
}
- row_log_table_close(
- index->online_log, b, mrec_size, avail_size);
+ row_log_table_close(index, b, mrec_size, avail_size);
}
func_exit:
@@ -812,8 +859,7 @@ row_log_table_low_redundant(
b + extra_size, index, tuple->fields, tuple->n_fields);
b += size;
- row_log_table_close(
- index->online_log, b, mrec_size, avail_size);
+ row_log_table_close(index, b, mrec_size, avail_size);
}
mem_heap_free(heap);
@@ -922,8 +968,7 @@ row_log_table_low(
memcpy(b, rec, rec_offs_data_size(offsets));
b += rec_offs_data_size(offsets);
- row_log_table_close(
- index->online_log, b, mrec_size, avail_size);
+ row_log_table_close(index, b, mrec_size, avail_size);
}
}
@@ -1019,7 +1064,7 @@ row_log_table_get_pk_col(
mem_heap_alloc(heap, field_len));
len = btr_copy_externally_stored_field_prefix(
- blob_field, field_len, zip_size, field, len, NULL);
+ blob_field, field_len, zip_size, field, len);
if (len >= max_len + 1) {
return(DB_TOO_BIG_INDEX_COL);
}
@@ -1138,7 +1183,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);
@@ -1167,7 +1212,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
@@ -1177,7 +1223,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;
}
@@ -1186,7 +1233,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*>(
@@ -1410,7 +1457,7 @@ row_log_table_apply_convert_mrec(
data = btr_rec_copy_externally_stored_field(
mrec, offsets,
dict_table_zip_size(index->table),
- i, &len, heap, NULL);
+ i, &len, heap);
ut_a(data);
dfield_set_data(dfield, data, len);
blob_done:
@@ -1528,13 +1575,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;
}
@@ -1544,12 +1588,13 @@ row_log_table_apply_insert_low(
flags, BTR_MODIFY_TREE,
index, offsets_heap, heap, entry, trx_id, thr);
- /* 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);
}
@@ -2128,17 +2173,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;
@@ -2619,10 +2663,29 @@ all_done:
goto func_exit;
}
+ byte * buf = index->online_log->head.block;
+
success = os_file_read_no_error_handling_int_fd(
index->online_log->fd,
- index->online_log->head.block, ofs,
+ buf, ofs,
srv_sort_buf_size);
+
+ /* If encryption is enabled decrypt buffer after reading it
+ from file system. */
+ if (success && log_tmp_is_encrypted()) {
+ if (!log_tmp_block_decrypt(buf,
+ srv_sort_buf_size,
+ index->online_log->crypt_head,
+ ofs,
+ index->table->space)) {
+ error = DB_DECRYPTION_FAILED;
+ goto func_exit;
+ }
+
+ srv_stats.n_rowlog_blocks_decrypted.inc();
+ memcpy(buf, index->online_log->crypt_head, srv_sort_buf_size);
+ }
+
if (!success) {
fprintf(stderr, "InnoDB: unable to read temporary file"
" for table %s\n", index->table_name);
@@ -2929,9 +2992,21 @@ row_log_allocate(
log->head.blocks = log->head.bytes = 0;
log->head.total = 0;
log->path = path;
+ log->crypt_tail = log->crypt_head = NULL;
dict_index_set_online_status(index, ONLINE_INDEX_CREATION);
index->online_log = log;
+ if (log_tmp_is_encrypted()) {
+ ulint size = srv_sort_buf_size;
+ log->crypt_head = static_cast<byte *>(os_mem_alloc_large(&size));
+ log->crypt_tail = static_cast<byte *>(os_mem_alloc_large(&size));
+
+ if (!log->crypt_head || !log->crypt_tail) {
+ row_log_free(log);
+ DBUG_RETURN(false);
+ }
+ }
+
/* While we might be holding an exclusive data dictionary lock
here, in row_log_abort_sec() we will not always be holding it. Use
atomic operations in both cases. */
@@ -2954,6 +3029,15 @@ row_log_free(
row_log_block_free(log->tail);
row_log_block_free(log->head);
row_merge_file_destroy_low(log->fd);
+
+ if (log->crypt_head) {
+ os_mem_free_large(log->crypt_head, srv_sort_buf_size);
+ }
+
+ if (log->crypt_tail) {
+ os_mem_free_large(log->crypt_tail, srv_sort_buf_size);
+ }
+
mutex_free(&log->mutex);
ut_free(log);
log = 0;
@@ -3445,11 +3529,29 @@ all_done:
goto func_exit;
}
+ byte* buf = index->online_log->head.block;
+
success = os_file_read_no_error_handling_int_fd(
index->online_log->fd,
- index->online_log->head.block, ofs,
+ buf, ofs,
srv_sort_buf_size);
+ /* If encryption is enabled decrypt buffer after reading it
+ from file system. */
+ if (success && log_tmp_is_encrypted()) {
+ if (!log_tmp_block_decrypt(buf,
+ srv_sort_buf_size,
+ index->online_log->crypt_head,
+ ofs,
+ index->table->space)) {
+ error = DB_DECRYPTION_FAILED;
+ goto func_exit;
+ }
+
+ srv_stats.n_rowlog_blocks_decrypted.inc();
+ memcpy(buf, index->online_log->crypt_head, srv_sort_buf_size);
+ }
+
if (!success) {
fprintf(stderr, "InnoDB: unable to read temporary file"
" for index %s\n", index->name + 1);
diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc
index 408e94b3997..d9585818577 100644
--- a/storage/xtradb/row/row0merge.cc
+++ b/storage/xtradb/row/row0merge.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2017, MariaDB Corporation.
+Copyright (c) 2005, 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
@@ -79,88 +79,6 @@ UNIV_INTERN char srv_disable_sort_file_cache;
/* Maximum pending doc memory limit in bytes for a fts tokenization thread */
#define FTS_PENDING_DOC_MEMORY_LIMIT 1000000
-
-/******************************************************//**
-Encrypt a merge block. */
-static
-void
-row_merge_encrypt_buf(
-/*==================*/
- fil_space_crypt_t* crypt_data, /*!< in: table crypt data */
- ulint offset, /*!< in: offset where to
- write */
- ulint space, /*!< in: tablespace id */
- const byte* input_buf, /*!< in: input buffer */
- byte* crypted_buf) /*!< out: crypted buffer */
-{
- uint key_version;
- uint dstlen=0;
- os_offset_t ofs = (os_offset_t)srv_sort_buf_size * (os_offset_t)offset;
-
- key_version = encryption_key_get_latest_version(crypt_data->key_id);
-
- /* Store key_version at the begining of the input buffer */
- mach_write_to_4((byte *)crypted_buf, key_version);
-
- int rc = encryption_scheme_encrypt(input_buf+ROW_MERGE_RESERVE_SIZE,
- srv_sort_buf_size-ROW_MERGE_RESERVE_SIZE,
- crypted_buf+ROW_MERGE_RESERVE_SIZE, &dstlen,
- crypt_data, key_version,
- space, ofs, 0);
-
- if (! ((rc == MY_AES_OK) && ((ulint)dstlen == srv_sort_buf_size-ROW_MERGE_RESERVE_SIZE))) {
- ib_logf(IB_LOG_LEVEL_FATAL,
- "Unable to encrypt data-block "
- " src: %p srclen: %lu buf: %p buflen: %d."
- " return-code: %d. Can't continue!\n",
- input_buf, srv_sort_buf_size,
- crypted_buf, dstlen, rc);
- }
-}
-
-/******************************************************//**
-Decrypt a merge block. */
-static
-bool
-row_merge_decrypt_buf(
-/*==================*/
- fil_space_crypt_t* crypt_data, /*!< in: table crypt data */
- ulint offset, /*!< in: offset where to
- write */
- ulint space, /*!< in: tablespace id */
- const byte* input_buf, /*!< in: input buffer */
- byte* crypted_buf) /*!< out: crypted buffer */
-{
- uint key_version;
- uint dstlen=0;
- os_offset_t ofs = (os_offset_t)srv_sort_buf_size * (os_offset_t)offset;
-
- /* Read key_version from begining of the buffer */
- key_version = mach_read_from_4((byte *)input_buf);
-
- if (key_version == 0) {
- /* block not encrypted */
- return false;
- }
-
- int rc = encryption_scheme_decrypt(input_buf+ROW_MERGE_RESERVE_SIZE,
- srv_sort_buf_size-ROW_MERGE_RESERVE_SIZE,
- crypted_buf+ROW_MERGE_RESERVE_SIZE, &dstlen,
- crypt_data, key_version,
- space, ofs, 0);
-
- if (! ((rc == MY_AES_OK) && ((ulint)dstlen == srv_sort_buf_size-ROW_MERGE_RESERVE_SIZE))) {
- ib_logf(IB_LOG_LEVEL_FATAL,
- "Unable to encrypt data-block "
- " src: %p srclen: %lu buf: %p buflen: %d."
- " return-code: %d. Can't continue!\n",
- input_buf, srv_sort_buf_size,
- crypted_buf, dstlen, rc);
- }
-
- return (true);
-}
-
#ifdef UNIV_DEBUG
/******************************************************//**
Display a merge tuple. */
@@ -279,7 +197,7 @@ row_merge_buf_create(
ulint buf_size;
mem_heap_t* heap;
- max_tuples = (srv_sort_buf_size - ROW_MERGE_RESERVE_SIZE)
+ max_tuples = (srv_sort_buf_size)
/ ut_max(1, dict_index_get_min_size(index));
buf_size = (sizeof *buf);
@@ -350,8 +268,8 @@ row_merge_buf_redundant_convert(
mem_heap_t* heap,
trx_t* trx)
{
- 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;
@@ -367,7 +285,7 @@ row_merge_buf_redundant_convert(
field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE));
byte* data = btr_copy_externally_stored_field(
- &ext_len, field_data, zip_size, field_len, heap, trx);
+ &ext_len, field_data, zip_size, field_len, heap);
ut_ad(ext_len < len);
@@ -478,7 +396,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 {
row_field = dtuple_get_nth_field(row, col_no);
@@ -613,7 +532,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)));
@@ -628,8 +547,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
@@ -639,14 +557,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 */
@@ -702,7 +617,7 @@ row_merge_buf_add(
ut_ad(data_size < srv_sort_buf_size);
/* Reserve bytes for the end marker of row_merge_block_t. */
- if (buf->total_size + data_size >= (srv_sort_buf_size - ROW_MERGE_RESERVE_SIZE)) {
+ if (buf->total_size + data_size >= srv_sort_buf_size) {
DBUG_RETURN(0);
}
@@ -823,7 +738,7 @@ UT_SORT_FUNCTION_BODY().
/**********************************************************************//**
Merge sort the tuple buffer in main memory. */
-static MY_ATTRIBUTE((nonnull(4,5)))
+static
void
row_merge_tuple_sort(
/*=================*/
@@ -874,7 +789,7 @@ row_merge_buf_write(
{
const dict_index_t* index = buf->index;
ulint n_fields= dict_index_get_n_fields(index);
- byte* b = &block[ROW_MERGE_RESERVE_SIZE];
+ byte* b = &block[0];
for (ulint i = 0; i < buf->n_tuples; i++) {
const mtuple_t* entry = &buf->tuples[i];
@@ -893,7 +808,7 @@ row_merge_buf_write(
/* Write an "end-of-chunk" marker. */
ut_a(b < &block[srv_sort_buf_size]);
- ut_a(b == &block[0] + buf->total_size + ROW_MERGE_RESERVE_SIZE);
+ ut_a(b == &block[0] + buf->total_size);
*b++ = 0;
#ifdef UNIV_DEBUG_VALGRIND
/* The rest of the block is uninitialized. Initialize it
@@ -943,7 +858,7 @@ row_merge_heap_create(
Read a merge block from the file system.
@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
-ibool
+bool
row_merge_read(
/*===========*/
int fd, /*!< in: file descriptor */
@@ -951,12 +866,11 @@ row_merge_read(
in number of row_merge_block_t
elements */
row_merge_block_t* buf, /*!< out: data */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_buf, /*!< in: crypt buf or NULL */
- ulint space) /*!< in: space id */
+ ulint space) /*!< in: space id */
{
os_offset_t ofs = ((os_offset_t) offset) * srv_sort_buf_size;
- ibool success;
+ bool success;
DBUG_EXECUTE_IF("row_merge_read_failure", return(FALSE););
@@ -970,11 +884,15 @@ row_merge_read(
success = os_file_read_no_error_handling_int_fd(fd, buf,
ofs, srv_sort_buf_size);
- /* For encrypted tables, decrypt data after reading and copy data */
- if (crypt_data && crypt_buf) {
- if( row_merge_decrypt_buf(crypt_data, offset, space, buf, crypt_buf)) {
- memcpy(buf, crypt_buf, srv_sort_buf_size);
+ /* If encryption is enabled decrypt buffer */
+ if (success && log_tmp_is_encrypted()) {
+ if (!log_tmp_block_decrypt(buf, srv_sort_buf_size,
+ crypt_buf, ofs, space)) {
+ return (FALSE);
}
+
+ srv_stats.n_merge_blocks_decrypted.inc();
+ memcpy(buf, crypt_buf, srv_sort_buf_size);
}
#ifdef POSIX_FADV_DONTNEED
@@ -996,31 +914,32 @@ row_merge_read(
Write a merge block to the file system.
@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
-ibool
+bool
row_merge_write(
/*============*/
int fd, /*!< in: file descriptor */
ulint offset, /*!< in: offset where to write,
in number of row_merge_block_t elements */
const void* buf, /*!< in: data */
- fil_space_crypt_t* crypt_data, /*!< in: table crypt data */
void* crypt_buf, /*!< in: crypt buf or NULL */
ulint space) /*!< in: space id */
{
size_t buf_len = srv_sort_buf_size;
os_offset_t ofs = buf_len * (os_offset_t) offset;
- ibool ret;
+ bool ret;
void* out_buf = (void *)buf;
DBUG_EXECUTE_IF("row_merge_write_failure", return(FALSE););
/* For encrypted tables, encrypt data before writing */
- if (crypt_data && crypt_buf) {
- row_merge_encrypt_buf(crypt_data, offset, space, (const byte *)buf, (byte *)crypt_buf);
+ if (log_tmp_is_encrypted()) {
+ if (!log_tmp_block_encrypt((const byte *)buf, buf_len,
+ (byte *)crypt_buf, ofs, space)) {
+ return (FALSE);
+ }
+
+ srv_stats.n_merge_blocks_encrypted.inc();
out_buf = crypt_buf;
- } else {
- /* Mark block unencrypted */
- mach_write_to_4((byte *)out_buf, 0);
}
ret = os_file_write_int_fd("(merge)", fd, out_buf, ofs, buf_len);
@@ -1058,9 +977,8 @@ row_merge_read_rec(
or NULL on end of list
(non-NULL on I/O error) */
ulint* offsets,/*!< out: offsets of mrec */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
- ulint space) /*!< in: space id */
+ ulint space) /*!< in: space id */
{
ulint extra_size;
ulint data_size;
@@ -1072,10 +990,6 @@ row_merge_read_rec(
ut_ad(*offsets == 1 + REC_OFFS_HEADER_SIZE
+ dict_index_get_n_fields(index));
- if (b == &block[0]) {
- b+= ROW_MERGE_RESERVE_SIZE;
- }
-
extra_size = *b++;
if (UNIV_UNLIKELY(!extra_size)) {
@@ -1097,7 +1011,8 @@ row_merge_read_rec(
if (UNIV_UNLIKELY(b >= &block[srv_sort_buf_size])) {
if (!row_merge_read(fd, ++(*foffs), block,
- crypt_data, crypt_block, space)) {
+ crypt_block,
+ space)) {
err_exit:
/* Signal I/O error. */
*mrec = b;
@@ -1105,7 +1020,7 @@ err_exit:
}
/* Wrap around to the beginning of the buffer. */
- b = &block[ROW_MERGE_RESERVE_SIZE];
+ b = &block[0];
}
extra_size = (extra_size & 0x7f) << 8;
@@ -1127,13 +1042,14 @@ err_exit:
memcpy(*buf, b, avail_size);
if (!row_merge_read(fd, ++(*foffs), block,
- crypt_data, crypt_block, space)) {
+ crypt_block,
+ space)) {
goto err_exit;
}
/* Wrap around to the beginning of the buffer. */
- b = &block[ROW_MERGE_RESERVE_SIZE];
+ b = &block[0];
/* Copy the record. */
memcpy(*buf + avail_size, b, extra_size - avail_size);
@@ -1189,13 +1105,14 @@ err_exit:
#endif /* UNIV_DEBUG */
if (!row_merge_read(fd, ++(*foffs), block,
- crypt_data, crypt_block, space)) {
+ crypt_block,
+ space)) {
goto err_exit;
}
/* Wrap around to the beginning of the buffer. */
- b = &block[ROW_MERGE_RESERVE_SIZE];
+ b = &block[0];
/* Copy the rest of the record. */
memcpy(*buf + avail_size, b, extra_size + data_size - avail_size);
@@ -1272,9 +1189,8 @@ row_merge_write_rec(
ulint* foffs, /*!< in/out: file offset */
const mrec_t* mrec, /*!< in: record to write */
const ulint* offsets,/*!< in: offsets of mrec */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
- ulint space) /*!< in: space id */
+ ulint space) /*!< in: space id */
{
ulint extra_size;
ulint size;
@@ -1295,10 +1211,6 @@ row_merge_write_rec(
size = extra_size + (extra_size >= 0x80)
+ rec_offs_data_size(offsets);
- if (b == &block[0]) {
- b+= ROW_MERGE_RESERVE_SIZE;
- }
-
if (UNIV_UNLIKELY(b + size >= &block[srv_sort_buf_size])) {
/* The record spans two blocks.
Copy it to the temporary buffer first. */
@@ -1314,14 +1226,15 @@ row_merge_write_rec(
memcpy(b, buf[0], avail_size);
if (!row_merge_write(fd, (*foffs)++, block,
- crypt_data, crypt_block, space)) {
+ crypt_block,
+ space)) {
return(NULL);
}
UNIV_MEM_INVALID(&block[0], srv_sort_buf_size);
/* Copy the rest. */
- b = &block[ROW_MERGE_RESERVE_SIZE];
+ b = &block[0];
memcpy(b, buf[0] + avail_size, size - avail_size);
b += size - avail_size;
} else {
@@ -1344,7 +1257,6 @@ row_merge_write_eof(
byte* b, /*!< in: pointer to end of block */
int fd, /*!< in: file descriptor */
ulint* foffs, /*!< in/out: file offset */
- fil_space_crypt_t* crypt_data, /*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
ulint space) /*!< in: space id */
{
@@ -1359,10 +1271,6 @@ row_merge_write_eof(
}
#endif /* UNIV_DEBUG */
- if (b == &block[0]) {
- b+= ROW_MERGE_RESERVE_SIZE;
- }
-
*b++ = 0;
UNIV_MEM_ASSERT_RW(&block[0], b - &block[0]);
UNIV_MEM_ASSERT_W(&block[0], srv_sort_buf_size);
@@ -1374,7 +1282,8 @@ row_merge_write_eof(
#endif /* UNIV_DEBUG_VALGRIND */
if (!row_merge_write(fd, (*foffs)++, block,
- crypt_data, crypt_block, space)) {
+ crypt_block,
+ space)) {
return(NULL);
}
@@ -1451,8 +1360,10 @@ containing the index entries for the indexes to be built.
@param[in,out] sequence autoinc sequence
@param[in,out] block file buffer
@param[in,out] tmpfd temporary file handle
-return DB_SUCCESS or error */
-static MY_ATTRIBUTE((nonnull(1,2,3,4,6,9,10,16), warn_unused_result))
+@param[in] pct_cost percent of task weight out of total alter job
+@param[in,out] crypt_block crypted file buffer
+@return DB_SUCCESS or error */
+static MY_ATTRIBUTE((warn_unused_result))
dberr_t
row_merge_read_clustered_index(
trx_t* trx,
@@ -1472,11 +1383,8 @@ row_merge_read_clustered_index(
ib_sequence_t& sequence,
row_merge_block_t* block,
int* tmpfd,
- float pct_cost, /*!< in: percent of task weight
- out of total alter job */
- fil_space_crypt_t* crypt_data,/*!< in: crypt data or NULL */
- row_merge_block_t* crypt_block)/*!< in: in/out: crypted file
- buffer */
+ float pct_cost,
+ row_merge_block_t* crypt_block)
{
dict_index_t* clust_index; /* Clustered index */
mem_heap_t* row_heap; /* Heap memory to create
@@ -1627,6 +1535,8 @@ row_merge_read_clustered_index(
goto func_exit;
}
+ mem_heap_empty(row_heap);
+
page_cur_move_to_next(cur);
if (page_cur_is_after_last(cur)) {
@@ -2014,7 +1924,7 @@ write_buffers:
row_merge_buf_write(buf, file, block);
if (!row_merge_write(file->fd, file->offset++,
- block, crypt_data, crypt_block,
+ block, crypt_block,
new_table->space)) {
err = DB_TEMP_FILE_WRITE_FAILURE;
trx->error_key_num = i;
@@ -2059,14 +1969,12 @@ write_buffers:
goto func_exit;
}
- mem_heap_empty(row_heap);
-
/* Increment innodb_onlineddl_pct_progress status variable */
read_rows++;
if(read_rows % 1000 == 0) {
/* Update progress for each 1000 rows */
curr_progress = (read_rows >= table_total_rows) ?
- pct_cost :
+ pct_cost :
((pct_cost * read_rows) / table_total_rows);
/* presenting 10.12% as 1012 integer */
onlineddl_pct_progress = curr_progress * 100;
@@ -2195,9 +2103,8 @@ wait_again:
&buf[2], b2, \
of->fd, &of->offset, \
mrec##N, offsets##N, \
- crypt_data, \
crypt_block ? &crypt_block[2 * srv_sort_buf_size] : NULL , \
- space); \
+ space); \
if (UNIV_UNLIKELY(!b2 || ++of->n_rec > file->n_rec)) { \
goto corrupt; \
} \
@@ -2205,7 +2112,6 @@ wait_again:
&buf[N], b##N, INDEX, \
file->fd, foffs##N, \
&mrec##N, offsets##N, \
- crypt_data, \
crypt_block ? &crypt_block[N * srv_sort_buf_size] : NULL, \
space); \
\
@@ -2220,7 +2126,7 @@ wait_again:
/*************************************************************//**
Merge two blocks of records on disk and write a bigger block.
@return DB_SUCCESS or error code */
-static __attribute__((nonnull(1,2,3,4,5,6), warn_unused_result))
+static __attribute__((warn_unused_result))
dberr_t
row_merge_blocks(
/*=============*/
@@ -2234,7 +2140,6 @@ row_merge_blocks(
ulint* foffs1, /*!< in/out: offset of second
source list in the file */
merge_file_t* of, /*!< in/out: output file */
- fil_space_crypt_t* crypt_data,/*!< in: crypt data or NULL */
row_merge_block_t* crypt_block,/*!< in: in/out: crypted file
buffer */
ulint space) /*!< in: space id */
@@ -2270,9 +2175,11 @@ row_merge_blocks(
file in two halves, which can be merged on the following pass. */
if (!row_merge_read(file->fd, *foffs0, &block[0],
- crypt_data, crypt_block ? &crypt_block[0] : NULL, space)
- || !row_merge_read(file->fd, *foffs1, &block[srv_sort_buf_size],
- crypt_data, crypt_block ? &crypt_block[srv_sort_buf_size] : NULL, space)) {
+ crypt_block ? &crypt_block[0] : NULL,
+ space) ||
+ !row_merge_read(file->fd, *foffs1, &block[srv_sort_buf_size],
+ crypt_block ? &crypt_block[srv_sort_buf_size] : NULL,
+ space)) {
corrupt:
mem_heap_free(heap);
return(DB_CORRUPTION);
@@ -2285,13 +2192,15 @@ corrupt:
b0 = row_merge_read_rec(
&block[0], &buf[0], b0, dup->index,
file->fd, foffs0, &mrec0, offsets0,
- crypt_data, crypt_block ? &crypt_block[0] : NULL, space);
+ crypt_block ? &crypt_block[0] : NULL,
+ space);
b1 = row_merge_read_rec(
&block[srv_sort_buf_size],
&buf[srv_sort_buf_size], b1, dup->index,
file->fd, foffs1, &mrec1, offsets1,
- crypt_data, crypt_block ? &crypt_block[srv_sort_buf_size] : NULL, space);
+ crypt_block ? &crypt_block[srv_sort_buf_size] : NULL,
+ space);
if (UNIV_UNLIKELY(!b0 && mrec0)
|| UNIV_UNLIKELY(!b1 && mrec1)) {
@@ -2337,7 +2246,8 @@ done1:
b2 = row_merge_write_eof(&block[2 * srv_sort_buf_size],
b2, of->fd, &of->offset,
- crypt_data, crypt_block ? &crypt_block[2 * srv_sort_buf_size] : NULL, space);
+ crypt_block ? &crypt_block[2 * srv_sort_buf_size] : NULL,
+ space);
return(b2 ? DB_SUCCESS : DB_CORRUPTION);
}
@@ -2345,8 +2255,8 @@ done1:
/*************************************************************//**
Copy a block of index entries.
@return TRUE on success, FALSE on failure */
-static __attribute__((nonnull(1,2,3,4,5), warn_unused_result))
-ibool
+static __attribute__((warn_unused_result))
+bool
row_merge_blocks_copy(
/*==================*/
const dict_index_t* index, /*!< in: index being created */
@@ -2354,9 +2264,8 @@ row_merge_blocks_copy(
row_merge_block_t* block, /*!< in/out: 3 buffers */
ulint* foffs0, /*!< in/out: input file offset */
merge_file_t* of, /*!< in/out: output file */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
- ulint space) /*!< in: space id */
+ ulint space) /*!< in: space id */
{
mem_heap_t* heap; /*!< memory heap for offsets0, offsets1 */
@@ -2384,7 +2293,8 @@ row_merge_blocks_copy(
file in two halves, which can be merged on the following pass. */
if (!row_merge_read(file->fd, *foffs0, &block[0],
- crypt_data, crypt_block ? &crypt_block[0] : NULL, space)) {
+ crypt_block ? &crypt_block[0] : NULL,
+ space)) {
corrupt:
mem_heap_free(heap);
return(FALSE);
@@ -2396,7 +2306,8 @@ corrupt:
b0 = row_merge_read_rec(&block[0], &buf[0], b0, index,
file->fd, foffs0, &mrec0, offsets0,
- crypt_data, crypt_block ? &crypt_block[0] : NULL, space);
+ crypt_block ? &crypt_block[0] : NULL,
+ space);
if (UNIV_UNLIKELY(!b0 && mrec0)) {
@@ -2419,15 +2330,15 @@ done0:
return(row_merge_write_eof(&block[2 * srv_sort_buf_size],
b2, of->fd, &of->offset,
- crypt_data,
- crypt_block ? &crypt_block[2 * srv_sort_buf_size] : NULL, space)
+ crypt_block ? &crypt_block[2 * srv_sort_buf_size] : NULL,
+ space)
!= NULL);
}
/*************************************************************//**
Merge disk files.
@return DB_SUCCESS or error code */
-static __attribute__((nonnull(1,2,3,4,5,6,7)))
+static
dberr_t
row_merge(
/*======*/
@@ -2443,9 +2354,8 @@ row_merge(
ulint* run_offset, /*!< in/out: Array contains the
first offset number for each merge
run */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
- ulint space) /*!< in: space id */
+ ulint space) /*!< in: space id */
{
ulint foffs0; /*!< first input offset */
ulint foffs1; /*!< second input offset */
@@ -2493,7 +2403,8 @@ row_merge(
error = row_merge_blocks(dup, file, block,
&foffs0, &foffs1, &of,
- crypt_data, crypt_block, space);
+ crypt_block,
+ space);
if (error != DB_SUCCESS) {
return(error);
@@ -2514,7 +2425,8 @@ row_merge(
if (!row_merge_blocks_copy(dup->index, file, block,
&foffs0, &of,
- crypt_data, crypt_block, space)) {
+ crypt_block,
+ space)) {
return(DB_CORRUPTION);
}
}
@@ -2532,7 +2444,8 @@ row_merge(
if (!row_merge_blocks_copy(dup->index, file, block,
&foffs1, &of,
- crypt_data, crypt_block, space)) {
+ crypt_block,
+ space)) {
return(DB_CORRUPTION);
}
}
@@ -2588,9 +2501,8 @@ row_merge_sort(
/*!< in: total progress percent
until now */
const float pct_cost, /*!< in: current progress percent */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
- ulint space) /*!< in: space id */
+ ulint space) /*!< in: space id */
{
const ulint half = file->offset / 2;
ulint num_runs;
@@ -2650,7 +2562,8 @@ row_merge_sort(
error = row_merge(trx, dup, file, block, tmpfd,
&num_runs, run_offset,
- crypt_data, crypt_block, space);
+ crypt_block,
+ space);
if(update_progress) {
merge_count++;
@@ -2710,7 +2623,7 @@ row_merge_copy_blobs(
BLOB pointers are read (row_merge_read_clustered_index())
and dereferenced (below). */
data = btr_rec_copy_externally_stored_field(
- mrec, offsets, zip_size, i, &len, heap, NULL);
+ mrec, offsets, zip_size, i, &len, heap);
/* Because we have locked the table, any records
written by incomplete transactions must have been
rolled back already. There must not be any incomplete
@@ -2725,7 +2638,7 @@ row_merge_copy_blobs(
Read sorted file containing index data tuples and insert these data
tuples to the index
@return DB_SUCCESS or error number */
-static __attribute__((nonnull(2,3,5), warn_unused_result))
+static __attribute__((warn_unused_result))
dberr_t
row_merge_insert_index_tuples(
/*==========================*/
@@ -2738,9 +2651,8 @@ row_merge_insert_index_tuples(
const float pct_progress, /*!< in: total progress percent until now */
const float pct_cost, /*!< in: current progress percent
*/
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
- ulint space) /*!< in: space id */
+ ulint space) /*!< in: space id */
{
const byte* b;
mem_heap_t* heap;
@@ -2774,7 +2686,8 @@ row_merge_insert_index_tuples(
b = &block[0];
if (!row_merge_read(fd, foffs, block,
- crypt_data, crypt_block, space)) {
+ crypt_block,
+ space)) {
error = DB_CORRUPTION;
} else {
buf = static_cast<mrec_buf_t*>(
@@ -2791,7 +2704,9 @@ row_merge_insert_index_tuples(
b = row_merge_read_rec(block, buf, b, index,
fd, &foffs, &mrec, offsets,
- crypt_data, crypt_block, space);
+ crypt_block,
+ space);
+
if (UNIV_UNLIKELY(!b)) {
/* End of list, or I/O error */
if (mrec) {
@@ -3818,11 +3733,7 @@ row_merge_create_index(
/*===================*/
trx_t* trx, /*!< in/out: trx (sets error_state) */
dict_table_t* table, /*!< in: the index is on this table */
- const index_def_t* index_def,
- /*!< in: the index definition */
- const char** col_names)
- /*! in: column names if columns are
- renamed or NULL */
+ const index_def_t* index_def) /*!< in: the index definition */
{
dict_index_t* index;
dberr_t err;
@@ -3842,28 +3753,10 @@ row_merge_create_index(
for (i = 0; i < n_fields; i++) {
index_field_t* ifield = &index_def->fields[i];
- const char * col_name;
-
- /*
- Alter table renaming a column and then adding a index
- to this new name e.g ALTER TABLE t
- CHANGE COLUMN b c INT NOT NULL, ADD UNIQUE INDEX (c);
- requires additional check as column names are not yet
- changed when new index definitions are created. Table's
- new column names are on a array of column name pointers
- if any of the column names are changed. */
-
- if (col_names && col_names[i]) {
- col_name = col_names[i];
- } else {
- col_name = ifield->col_name ?
- dict_table_get_col_name_for_mysql(table, ifield->col_name) :
- dict_table_get_col_name(table, ifield->col_no);
- }
dict_mem_index_add_field(
index,
- col_name,
+ dict_table_get_col_name(table, ifield->col_no),
ifield->prefix_len);
}
@@ -3976,7 +3869,6 @@ row_merge_build_indexes(
fts_psort_t* merge_info = NULL;
ib_int64_t sig_count = 0;
bool fts_psort_initiated = false;
- fil_space_crypt_t * crypt_data = NULL;
float total_static_cost = 0;
float total_dynamic_cost = 0;
@@ -4001,29 +3893,15 @@ row_merge_build_indexes(
DBUG_RETURN(DB_OUT_OF_MEMORY);
}
- /* Get crypt data from tablespace if present. We should be protected
- from concurrent DDL (e.g. drop table) by MDL-locks. */
- fil_space_t* space = fil_space_acquire(new_table->space);
-
- if (space) {
- crypt_data = space->crypt_data;
- } else {
- DBUG_RETURN(DB_TABLESPACE_NOT_FOUND);
- }
-
- /* If tablespace is encrypted, allocate additional buffer for
+ /* If temporary log file is encrypted allocate memory for
encryption/decryption. */
- if (crypt_data && crypt_data->should_encrypt()) {
+ if (log_tmp_is_encrypted()) {
crypt_block = static_cast<row_merge_block_t*>(
- os_mem_alloc_large(&block_size));
+ os_mem_alloc_large(&block_size));
if (crypt_block == NULL) {
- fil_space_release(space);
DBUG_RETURN(DB_OUT_OF_MEMORY);
}
- } else {
- /* Not needed */
- crypt_data = NULL;
}
trx_start_if_not_started_xa(trx);
@@ -4105,7 +3983,7 @@ row_merge_build_indexes(
fts_sort_idx, psort_info, merge_files, key_numbers,
n_indexes, add_cols, col_map,
add_autoinc, sequence, block, &tmpfd, pct_cost,
- crypt_data, crypt_block);
+ crypt_block);
pct_progress += pct_cost;
@@ -4128,10 +4006,6 @@ row_merge_build_indexes(
/* Now we have files containing index entries ready for
sorting and inserting. */
- DBUG_EXECUTE_IF(
- "ib_merge_wait_after_read",
- os_thread_sleep(20000000);); /* 20 sec */
-
for (i = 0; i < n_indexes; i++) {
dict_index_t* sort_idx = indexes[i];
@@ -4242,7 +4116,8 @@ wait_again:
trx, &dup, &merge_files[i],
block, &tmpfd, true,
pct_progress, pct_cost,
- crypt_data, crypt_block, new_table->space);
+ crypt_block,
+ new_table->space);
pct_progress += pct_cost;
@@ -4280,7 +4155,8 @@ wait_again:
trx->id, sort_idx, old_table,
merge_files[i].fd, block,
merge_files[i].n_rec, pct_progress, pct_cost,
- crypt_data, crypt_block, new_table->space);
+ crypt_block, new_table->space);
+
pct_progress += pct_cost;
if (global_system_variables.log_warnings > 2) {
@@ -4403,9 +4279,5 @@ func_exit:
}
}
- if (space) {
- fil_space_release(space);
- }
-
DBUG_RETURN(error);
}
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index 0079fc79a0e..ce4fe7f53ea 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2000, 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
@@ -58,6 +58,7 @@ Created 9/17/2000 Heikki Tuuri
#include "btr0sea.h"
#include "btr0defragment.h"
#include "fil0fil.h"
+#include "srv0srv.h"
#include "fil0crypt.h"
#include "ibuf0ibuf.h"
#include "fts0fts.h"
@@ -74,7 +75,7 @@ UNIV_INTERN 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 */
};
@@ -137,19 +138,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 */
-
/*******************************************************************//**
Delays an INSERT, DELETE or UPDATE operation if the purge is lagging. */
static
@@ -569,11 +557,33 @@ next_column:
/* If there is a FTS doc id column and it is not user supplied (
generated by server) then assign it a new doc id. */
- if (prebuilt->table->fts) {
+ if (!prebuilt->table->fts) {
+ return;
+ }
+
+ ut_a(prebuilt->table->fts->doc_col != ULINT_UNDEFINED);
- ut_a(prebuilt->table->fts->doc_col != ULINT_UNDEFINED);
+ doc_id_t doc_id;
- fts_create_doc_id(prebuilt->table, row, prebuilt->heap);
+ if (!DICT_TF2_FLAG_IS_SET(prebuilt->table, DICT_TF2_FTS_HAS_DOC_ID)) {
+ if (prebuilt->table->fts->cache->first_doc_id
+ == FTS_NULL_DOC_ID) {
+ fts_get_next_doc_id(prebuilt->table, &doc_id);
+ }
+ return;
+ }
+
+ dfield_t* fts_doc_id = dtuple_get_nth_field(
+ row, prebuilt->table->fts->doc_col);
+
+ if (fts_get_next_doc_id(prebuilt->table, &doc_id) == DB_SUCCESS) {
+ ut_a(doc_id != FTS_NULL_DOC_ID);
+ ut_ad(sizeof(doc_id) == fts_doc_id->type.len);
+ dfield_set_data(fts_doc_id, prebuilt->ins_upd_rec_buff
+ + prebuilt->mysql_row_len, 8);
+ fts_write_doc_id(fts_doc_id->data, doc_id);
+ } else {
+ dfield_set_null(fts_doc_id);
}
}
@@ -1048,7 +1058,10 @@ row_get_prebuilt_insert_row(
prebuilt->ins_upd_rec_buff = static_cast<byte*>(
mem_heap_alloc(
prebuilt->heap,
- prebuilt->mysql_row_len));
+ DICT_TF2_FLAG_IS_SET(prebuilt->table,
+ DICT_TF2_FTS_HAS_DOC_ID)
+ ? prebuilt->mysql_row_len + 8/* FTS_DOC_ID */
+ : prebuilt->mysql_row_len));
}
dtuple_t* row;
@@ -1986,7 +1999,7 @@ row_unlock_for_mysql(
trx_id_t rec_trx_id;
mtr_t mtr;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* Restore the cursor position and find the record */
@@ -2469,10 +2482,7 @@ err_exit:
/* We already have .ibd file here. it should be deleted. */
if (table->space
- && fil_delete_tablespace(
- table->space,
- BUF_REMOVE_FLUSH_NO_WRITE)
- != DB_SUCCESS) {
+ && fil_delete_tablespace(table->space) != DB_SUCCESS) {
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -2765,7 +2775,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);
@@ -2778,62 +2788,39 @@ 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 */
+ table = dict_table_open_on_id(drop->table_id, FALSE,
+ DICT_TABLE_OP_NORMAL);
- goto already_dropped;
+ if (!table) {
+ n_tables_dropped++;
+ mutex_enter(&row_drop_list_mutex);
+ UT_LIST_REMOVE(row_mysql_drop_list, 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, row_mysql_drop_list, drop);
+ UT_LIST_ADD_LAST(row_mysql_drop_list, 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)) {
/* 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, row_mysql_drop_list, drop);
-
- MONITOR_DEC(MONITOR_BACKGROUND_DROP_TABLE);
-
- ut_print_timestamp(stderr);
- fputs(" InnoDB: Dropped table ", stderr);
- ut_print_name(stderr, NULL, TRUE, drop->table_name);
- fputs(" in background drop queue.\n", stderr);
-
- mem_free(drop->table_name);
-
- mem_free(drop);
-
- mutex_exit(&row_drop_list_mutex);
-
goto loop;
}
@@ -2865,14 +2852,13 @@ 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);
@@ -2883,37 +2869,27 @@ 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*>(
- mem_alloc(sizeof(row_mysql_drop_t)));
-
- drop->table_name = mem_strdup(name);
+ drop = static_cast<row_mysql_drop_t*>(ut_malloc(sizeof *drop));
+ drop->table_id = table_id;
UT_LIST_ADD_LAST(row_mysql_drop_list, row_mysql_drop_list, drop);
MONITOR_INC(MONITOR_BACKGROUND_DROP_TABLE);
-
- /* fputs("InnoDB: Adding table ", stderr);
- ut_print_name(stderr, trx, TRUE, drop->table_name);
- fputs(" to background drop list\n", stderr); */
-
+func_exit:
mutex_exit(&row_drop_list_mutex);
-
- return(TRUE);
+ return added;
}
/*********************************************************************//**
Reassigns the table identifier of a table.
@return error code or DB_SUCCESS */
-UNIV_INTERN
+static
dberr_t
row_mysql_table_id_reassign(
/*========================*/
@@ -3107,9 +3083,6 @@ row_discard_tablespace(
4) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0,
we do not allow the discard. */
- /* Play safe and remove all insert buffer entries, though we should
- have removed them already when DISCARD TABLESPACE was called */
-
ibuf_delete_for_discarded_space(table->space);
table_id_t new_id;
@@ -3613,7 +3586,7 @@ row_truncate_table_for_mysql(
index = dict_table_get_next_index(index);
} while (index);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
fsp_header_init(space_id,
FIL_IBD_FILE_INITIAL_SIZE, &mtr);
mtr_commit(&mtr);
@@ -3642,7 +3615,7 @@ row_truncate_table_for_mysql(
sys_index = dict_table_get_first_index(dict_sys->sys_indexes);
dict_index_copy_types(tuple, sys_index, 1);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
BTR_MODIFY_LEAF, &pcur, &mtr);
for (;;) {
@@ -3689,7 +3662,7 @@ row_truncate_table_for_mysql(
a page in this mini-transaction, and the rest of
this loop could latch another index page. */
mtr_commit(&mtr);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
btr_pcur_restore_position(BTR_MODIFY_LEAF,
&pcur, &mtr);
}
@@ -4031,6 +4004,16 @@ row_drop_table_for_mysql(
ut_ad(!table->fts->add_wq);
ut_ad(lock_trx_has_sys_table_locks(trx) == 0);
+ for (;;) {
+ bool retry = false;
+ if (dict_fts_index_syncing(table)) {
+ retry = true;
+ }
+ if (!retry) {
+ break;
+ }
+ DICT_BG_YIELD(trx);
+ }
row_mysql_unlock_data_dictionary(trx);
fts_optimize_remove_table(table);
row_mysql_lock_data_dictionary(trx);
@@ -4131,7 +4114,7 @@ row_drop_table_for_mysql(
DBUG_EXECUTE_IF("row_drop_table_add_to_background",
- row_add_table_to_background_drop_list(table->name);
+ row_add_table_to_background_drop_list(table->id);
err = DB_SUCCESS;
goto funct_exit;
);
@@ -4143,33 +4126,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;
- ibool added;
-
- added = row_add_table_to_background_drop_list(save_tablename);
-
- if (added) {
+ if (row_add_table_to_background_drop_list(table->id)) {
ut_print_timestamp(stderr);
fputs(" InnoDB: You are trying to drop table ",
stderr);
- ut_print_name(stderr, trx, TRUE, save_tablename);
+ ut_print_name(stderr, trx, TRUE, table->name);
fputs("\n"
"InnoDB: though there is a"
" foreign key check running on it.\n"
"InnoDB: Adding the table to"
" the background drop queue.\n",
stderr);
-
- /* 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;
}
+ /* We return DB_SUCCESS to MySQL though the drop will
+ happen lazily later */
+ err = DB_SUCCESS;
goto funct_exit;
}
@@ -4194,11 +4166,7 @@ row_drop_table_for_mysql(
lock_remove_all_on_table(table, TRUE);
ut_a(table->n_rec_locks == 0);
} else if (table->n_ref_count > 0 || table->n_rec_locks > 0) {
- ibool added;
-
- added = row_add_table_to_background_drop_list(table->name);
-
- if (added) {
+ if (row_add_table_to_background_drop_list(table->id)) {
ut_print_timestamp(stderr);
fputs(" InnoDB: Warning: MySQL is"
" trying to drop table ", stderr);
@@ -4491,9 +4459,7 @@ row_drop_table_for_mysql(
fil_delete_file(filepath);
- } else if (fil_delete_tablespace(
- space_id,
- BUF_REMOVE_FLUSH_NO_WRITE)
+ } else if (fil_delete_tablespace(space_id)
!= DB_SUCCESS) {
fprintf(stderr,
"InnoDB: We removed now the InnoDB"
@@ -5406,6 +5372,7 @@ end:
trx_rollback_to_savepoint(trx, NULL);
trx->error_state = DB_SUCCESS;
}
+ table->data_dir_path= NULL;
}
funct_exit:
diff --git a/storage/xtradb/row/row0purge.cc b/storage/xtradb/row/row0purge.cc
index 333677edf21..0cd0941987d 100644
--- a/storage/xtradb/row/row0purge.cc
+++ b/storage/xtradb/row/row0purge.cc
@@ -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
@@ -823,7 +823,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);
}
diff --git a/storage/xtradb/row/row0quiesce.cc b/storage/xtradb/row/row0quiesce.cc
index 583fbe60fb3..53b4040f74e 100644
--- a/storage/xtradb/row/row0quiesce.cc
+++ b/storage/xtradb/row/row0quiesce.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, 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
@@ -236,7 +237,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);
@@ -542,8 +547,7 @@ row_quiesce_table_start(
}
if (!trx_is_interrupted(trx)) {
- buf_LRU_flush_or_remove_pages(
- table->space, BUF_REMOVE_FLUSH_WRITE, trx);
+ buf_LRU_flush_or_remove_pages(table->space, trx);
if (trx_is_interrupted(trx)) {
diff --git a/storage/xtradb/row/row0row.cc b/storage/xtradb/row/row0row.cc
index 96d25e15777..9bf9e7182ca 100644
--- a/storage/xtradb/row/row0row.cc
+++ b/storage/xtradb/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
@@ -173,7 +174,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);
@@ -588,7 +589,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));
}
@@ -702,7 +704,8 @@ notfound:
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));
}
diff --git a/storage/xtradb/row/row0sel.cc b/storage/xtradb/row/row0sel.cc
index 8e3ed3d1a4e..03ae6822fb7 100644
--- a/storage/xtradb/row/row0sel.cc
+++ b/storage/xtradb/row/row0sel.cc
@@ -1,8 +1,8 @@
/*****************************************************************************
-Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
+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
@@ -98,8 +98,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
@@ -138,8 +140,7 @@ row_sel_sec_rec_is_for_blob(
len = btr_copy_externally_stored_field_prefix(buf, prefix_len,
zip_size,
- clust_field, clust_len,
- NULL);
+ clust_field, clust_len);
if (UNIV_UNLIKELY(len == 0)) {
/* The BLOB was being deleted as the server crashed.
@@ -150,7 +151,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));
@@ -234,14 +235,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,
@@ -458,7 +459,7 @@ row_sel_fetch_columns(
data = btr_rec_copy_externally_stored_field(
rec, offsets,
dict_table_zip_size(index->table),
- field_no, &len, heap, NULL);
+ field_no, &len, heap);
/* data == NULL means that the
externally stored field was not
@@ -1406,7 +1407,7 @@ table_loop:
/* Open a cursor to index, or restore an open cursor position */
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
if (consistent_read && plan->unique_search && !plan->pcur_is_open
&& !plan->must_get_clust
@@ -1447,7 +1448,7 @@ table_loop:
plan_reset_cursor(plan);
mtr_commit(&mtr);
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
}
if (search_latch_locked) {
@@ -1545,6 +1546,7 @@ rec_loop:
switch (err) {
case DB_SUCCESS_LOCKED_REC:
err = DB_SUCCESS;
+ /* fall through */
case DB_SUCCESS:
break;
default:
@@ -1603,6 +1605,7 @@ skip_lock:
switch (err) {
case DB_SUCCESS_LOCKED_REC:
err = DB_SUCCESS;
+ /* fall through */
case DB_SUCCESS:
break;
default:
@@ -2569,31 +2572,30 @@ row_sel_store_row_id_to_prebuilt(
(dest,templ,src,len)
#endif /* UNIV_DEBUG */
-/**************************************************************//**
-Stores a non-SQL-NULL field in the MySQL format. The counterpart of this
-function is row_mysql_store_col_in_innobase_format() in row0mysql.cc. */
+/** Stores a non-SQL-NULL field in the MySQL format. The counterpart of this
+function is row_mysql_store_col_in_innobase_format() in row0mysql.cc.
+@param[in,out] dest buffer where to store; NOTE
+ that BLOBs are not in themselves stored
+ here: the caller must allocate and copy
+ the BLOB into buffer before, and pass
+ the pointer to the BLOB in 'data'
+@param[in] templ MySQL column template. Its following fields
+ are referenced: type, is_unsigned, mysql_col_len,
+ mbminlen, mbmaxlen
+@param[in] index InnoDB index
+@param[in] field_no templ->rec_field_no or templ->clust_rec_field_no
+ or templ->icp_rec_field_no
+@param[in] data data to store
+@param[in] len length of the data
+*/
static MY_ATTRIBUTE((nonnull))
void
row_sel_field_store_in_mysql_format_func(
-/*=====================================*/
- byte* dest, /*!< in/out: buffer where to store; NOTE
- that BLOBs are not in themselves
- stored here: the caller must allocate
- and copy the BLOB into buffer before,
- and pass the pointer to the BLOB in
- 'data' */
+ byte* dest,
const mysql_row_templ_t* templ,
- /*!< in: MySQL column template.
- Its following fields are referenced:
- type, is_unsigned, mysql_col_len,
- mbminlen, mbmaxlen */
#ifdef UNIV_DEBUG
const dict_index_t* index,
- /*!< in: InnoDB index */
ulint field_no,
- /*!< in: templ->rec_field_no or
- templ->clust_rec_field_no or
- templ->icp_rec_field_no */
#endif /* UNIV_DEBUG */
const byte* data, /*!< in: data to store */
ulint len) /*!< in: length of the data */
@@ -2736,6 +2738,7 @@ row_sel_field_store_in_mysql_format_func(
case DATA_SYS:
/* These column types should never be shipped to MySQL. */
ut_ad(0);
+ /* fall through */
case DATA_CHAR:
case DATA_FIXBINARY:
@@ -2746,7 +2749,7 @@ row_sel_field_store_in_mysql_format_func(
#endif /* UNIV_DEBUG */
ut_ad(field->prefix_len
? field->prefix_len == len
- : templ->mysql_col_len == len);
+ : (templ->mysql_col_len == len));
memcpy(dest, data, len);
}
}
@@ -2770,8 +2773,6 @@ row_sel_field_store_in_mysql_format_func(
@param[in] field_no templ->rec_field_no or
templ->clust_rec_field_no
or templ->icp_rec_field_no
- or sec field no if clust_templ_for_sec
- is TRUE
@param[in] templ row template
*/
static MY_ATTRIBUTE((warn_unused_result))
@@ -2828,7 +2829,7 @@ row_sel_store_mysql_field_func(
data = btr_rec_copy_externally_stored_field(
rec, offsets,
dict_table_zip_size(prebuilt->table),
- field_no, &len, heap, NULL);
+ field_no, &len, heap);
if (UNIV_UNLIKELY(!data)) {
/* The externally stored field was not written
@@ -2953,6 +2954,7 @@ row_sel_store_mysql_rec(
= rec_clust
? templ->clust_rec_field_no
: templ->rec_field_no;
+
/* We should never deliver column prefixes to MySQL,
except for evaluating innobase_index_cond() and if the prefix
index is longer than the actual row data. */
@@ -3110,7 +3112,7 @@ row_sel_get_clust_rec_for_mysql(
trx_print(stderr, trx, 600);
fputs("\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n", stderr);
+ " to https://jira.mariadb.org/\n", stderr);
ut_ad(0);
}
@@ -3351,6 +3353,36 @@ row_sel_copy_cached_field_for_mysql(
ut_memcpy(buf, cache, len);
}
+/** Copy used fields from cached row.
+Copy cache record field by field, don't touch fields that
+are not covered by current key.
+@param[out] buf Where to copy the MySQL row.
+@param[in] cached_rec What to copy (in MySQL row format).
+@param[in] prebuilt prebuilt struct. */
+void
+row_sel_copy_cached_fields_for_mysql(
+ byte* buf,
+ const byte* cached_rec,
+ row_prebuilt_t* prebuilt)
+{
+ const mysql_row_templ_t*templ;
+ ulint i;
+ for (i = 0; i < prebuilt->n_template; i++) {
+ templ = prebuilt->mysql_template + i;
+
+ row_sel_copy_cached_field_for_mysql(
+ buf, cached_rec, templ);
+ /* Copy NULL bit of the current field from cached_rec
+ to buf */
+ if (templ->mysql_null_bit_mask) {
+ buf[templ->mysql_null_byte_offset]
+ ^= (buf[templ->mysql_null_byte_offset]
+ ^ cached_rec[templ->mysql_null_byte_offset])
+ & (byte) templ->mysql_null_bit_mask;
+ }
+ }
+}
+
/********************************************************************//**
Pops a cached row for MySQL from the fetch cache. */
UNIV_INLINE
@@ -3902,7 +3934,7 @@ row_search_for_mysql(
}
}
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/*-------------------------------------------------------------*/
/* PHASE 2: Try fast adaptive hash index search if possible */
@@ -4186,6 +4218,7 @@ wait_table_again:
switch (err) {
case DB_SUCCESS_LOCKED_REC:
err = DB_SUCCESS;
+ /* fall through */
case DB_SUCCESS:
break;
default:
@@ -4281,6 +4314,7 @@ rec_loop:
switch (err) {
case DB_SUCCESS_LOCKED_REC:
err = DB_SUCCESS;
+ /* fall through */
case DB_SUCCESS:
break;
default:
@@ -4323,8 +4357,7 @@ wrong_offs:
if ((srv_force_recovery == 0 || moves_up == FALSE)
&& srv_pass_corrupt_table <= 1) {
ut_print_timestamp(stderr);
- buf_page_print(page_align(rec), 0,
- BUF_PAGE_PRINT_NO_CRASH);
+ buf_page_print(page_align(rec), 0);
fprintf(stderr,
"\nInnoDB: rec address %p,"
" buf block fix count %lu\n",
@@ -4569,6 +4602,7 @@ no_gap_lock:
prebuilt->new_rec_locks = 1;
}
err = DB_SUCCESS;
+ /* fall through */
case DB_SUCCESS:
break;
case DB_LOCK_WAIT:
@@ -5126,7 +5160,7 @@ next_rec:
mtr_commit(&mtr);
mtr_has_extra_clust_latch = FALSE;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
if (sel_restore_position_for_mysql(&same_user_rec,
BTR_SEARCH_LEAF,
pcur, moves_up, &mtr)) {
@@ -5193,7 +5227,7 @@ lock_table_wait:
/* It was a lock wait, and it ended */
thr->lock_state = QUE_THR_LOCK_NOLOCK;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* Table lock waited, go try to obtain table lock
again */
diff --git a/storage/xtradb/row/row0umod.cc b/storage/xtradb/row/row0umod.cc
index f23d7e9dc68..bb2fc536616 100644
--- a/storage/xtradb/row/row0umod.cc
+++ b/storage/xtradb/row/row0umod.cc
@@ -269,7 +269,7 @@ row_undo_mod_clust(
pcur = &node->pcur;
index = btr_cur_get_index(btr_pcur_get_btr_cur(pcur));
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
online = dict_index_is_online_ddl(index);
if (online) {
@@ -298,7 +298,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(&mtr);
err = row_undo_mod_clust_low(
node, &offsets, &offsets_heap,
@@ -350,7 +350,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(&mtr);
/* It is not necessary to call row_log_table,
because the record is delete-marked and would thus
@@ -363,7 +363,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(&mtr);
err = row_undo_mod_remove_clust_low(node, thr, &mtr,
BTR_MODIFY_TREE);
@@ -410,7 +410,7 @@ row_undo_mod_del_mark_or_remove_sec_low(
enum row_search_result search_result;
log_free_check();
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
if (mode == BTR_MODIFY_TREE
&& index->space == IBUF_SPACE_ID
&& !dict_index_is_unique(index)) {
@@ -471,7 +471,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_start(&mtr_vers);
success = btr_pcur_restore_position(BTR_SEARCH_LEAF, &(node->pcur),
&mtr_vers);
@@ -587,7 +587,7 @@ row_undo_mod_del_unmark_sec_and_undo_update(
ut_ad(trx->id);
log_free_check();
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
if (mode == BTR_MODIFY_TREE
&& index->space == IBUF_SPACE_ID
&& !dict_index_is_unique(index)) {
@@ -653,7 +653,7 @@ row_undo_mod_del_unmark_sec_and_undo_update(
trx_print(stderr, trx, 0);
fputs("\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n", stderr);
+ " to https://jira.mariadb.org/\n", stderr);
ib_logf(IB_LOG_LEVEL_WARN,
"record in index %s was not found"
diff --git a/storage/xtradb/row/row0undo.cc b/storage/xtradb/row/row0undo.cc
index 82b1ab049fa..552b99ab4d4 100644
--- a/storage/xtradb/row/row0undo.cc
+++ b/storage/xtradb/row/row0undo.cc
@@ -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
@@ -348,6 +349,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/xtradb/row/row0upd.cc b/storage/xtradb/row/row0upd.cc
index 2679e9a1c8a..9ac72f8d068 100644
--- a/storage/xtradb/row/row0upd.cc
+++ b/storage/xtradb/row/row0upd.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
@@ -261,7 +262,7 @@ row_upd_check_references_constraints(
DEBUG_SYNC_C("foreign_constraint_check_for_update");
- mtr_start_trx(mtr, trx);
+ mtr_start(mtr);
if (trx->dict_operation_lock_mode == 0) {
got_s_lock = TRUE;
@@ -1155,7 +1156,7 @@ row_upd_ext_fetch(
byte* buf = static_cast<byte*>(mem_heap_alloc(heap, *len));
*len = btr_copy_externally_stored_field_prefix(
- buf, *len, zip_size, data, local_len, NULL);
+ buf, *len, zip_size, data, local_len);
/* We should never update records containing a half-deleted BLOB. */
ut_a(*len);
@@ -1207,7 +1208,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);
@@ -1855,7 +1856,7 @@ row_upd_sec_index_entry(
}
#endif /* UNIV_DEBUG */
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
if (*index->name == TEMP_INDEX_PREFIX) {
/* The index->online_status may change if the
@@ -1958,7 +1959,7 @@ row_upd_sec_index_entry(
trx_print(stderr, trx, 0);
fputs("\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n", stderr);
+ " to https://jira.mariadb.org/\n", stderr);
ut_ad(0);
break;
case ROW_FOUND:
@@ -1988,9 +1989,9 @@ row_upd_sec_index_entry(
index, offsets, thr, &mtr);
}
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
+ if (err == DB_SUCCESS && !referenced &&
+ wsrep_on_trx(trx) &&
!wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
- err == DB_SUCCESS && !referenced &&
!(parent && que_node_get_type(parent) ==
QUE_NODE_UPDATE &&
((upd_node_t*)parent)->cascade_node == node) &&
@@ -2279,7 +2280,7 @@ err_exit:
}
}
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) && !referenced &&
+ if (!referenced && wsrep_on_trx(trx) &&
!(parent && que_node_get_type(parent) == QUE_NODE_UPDATE &&
((upd_node_t*)parent)->cascade_node == node) &&
foreign
@@ -2398,7 +2399,7 @@ 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_start(mtr);
/* NOTE: this transaction has an s-lock or x-lock on the record and
therefore other transactions cannot modify the record when we have no
@@ -2548,8 +2549,7 @@ row_upd_del_mark_clust_rec(
}
#ifdef WITH_WSREP
trx_t* trx = thr_get_trx(thr) ;
-
- if (err == DB_SUCCESS && !referenced && trx && wsrep_on(trx->mysql_thd) &&
+ if (err == DB_SUCCESS && !referenced && wsrep_on_trx(trx) &&
!(parent && que_node_get_type(parent) == QUE_NODE_UPDATE &&
((upd_node_t*)parent)->cascade_node == node) &&
foreign
@@ -2614,7 +2614,7 @@ row_upd_clust_step(
/* We have to restore the cursor to its position */
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
/* If the restoration does not succeed, then the same
transaction has deleted the record on which the cursor was,
@@ -2687,7 +2687,7 @@ row_upd_clust_step(
mtr_commit(&mtr);
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
success = btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur,
&mtr);
diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc
index 1f1fef6bea6..02314db6b07 100644
--- a/storage/xtradb/srv/srv0srv.cc
+++ b/storage/xtradb/srv/srv0srv.cc
@@ -82,10 +82,6 @@ Created 10/8/1995 Heikki Tuuri
/* prototypes for new functions added to ha_innodb.cc */
ibool innobase_get_slow_log();
-#ifdef WITH_WSREP
-extern int wsrep_debug;
-extern int wsrep_trx_is_aborting(void *thd_ptr);
-#endif
/* The following counter is incremented whenever there is some user activity
in the server */
UNIV_INTERN ulint srv_activity_count = 0;
@@ -479,6 +475,9 @@ UNIV_INTERN my_bool srv_print_all_deadlocks = FALSE;
/* Produce a stacktrace on long semaphore wait */
UNIV_INTERN my_bool srv_use_stacktrace = FALSE;
+/** Print lock wait timeout info to mysqld stderr */
+my_bool srv_print_lock_wait_timeout_info = FALSE;
+
/** Enable INFORMATION_SCHEMA.innodb_cmp_per_index */
UNIV_INTERN my_bool srv_cmp_per_index_enabled = FALSE;
@@ -2060,6 +2059,10 @@ srv_export_innodb_status(void)
export_vars.innodb_pages_page_compression_error = srv_stats.pages_page_compression_error;
export_vars.innodb_pages_decrypted = srv_stats.pages_decrypted;
export_vars.innodb_pages_encrypted = srv_stats.pages_encrypted;
+ export_vars.innodb_n_merge_blocks_encrypted = srv_stats.n_merge_blocks_encrypted;
+ export_vars.innodb_n_merge_blocks_decrypted = srv_stats.n_merge_blocks_decrypted;
+ export_vars.innodb_n_rowlog_blocks_encrypted = srv_stats.n_rowlog_blocks_encrypted;
+ export_vars.innodb_n_rowlog_blocks_decrypted = srv_stats.n_rowlog_blocks_decrypted;
export_vars.innodb_defragment_compression_failures =
btr_defragment_compression_failures;
@@ -2133,6 +2136,9 @@ srv_export_innodb_status(void)
scrub_stat.page_split_failures_unknown;
}
+ export_vars.innodb_buffered_aio_submitted =
+ srv_stats.n_aio_submitted;
+
mutex_exit(&srv_innodb_monitor_mutex);
}
@@ -2357,7 +2363,7 @@ loop:
" was greater\n"
"InnoDB: than the new log sequence number " LSN_PF "!\n"
"InnoDB: Please submit a bug report"
- " to http://bugs.mysql.com\n",
+ " to https://jira.mariadb.org\n",
old_lsn, new_lsn);
ut_ad(0);
}
@@ -2466,7 +2472,7 @@ srv_get_active_thread_type(void)
{
srv_thread_type ret = SRV_NONE;
- if (srv_read_only_mode) {
+ if (srv_read_only_mode || srv_apply_log_only) {
return(SRV_NONE);
}
diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc
index bd31f229dc0..2aa2426ca9c 100644
--- a/storage/xtradb/srv/srv0start.cc
+++ b/storage/xtradb/srv/srv0start.cc
@@ -73,8 +73,7 @@ Created 2/16/1996 Heikki Tuuri
#include "btr0defragment.h"
#include "ut0timer.h"
#include "btr0scrub.h"
-
-#include <mysql/service_wsrep.h>
+#include "mysql/service_wsrep.h" /* wsrep_recovery */
#ifndef UNIV_HOTBACKUP
# include "trx0rseg.h"
@@ -768,7 +767,7 @@ create_log_files(
/* Create a log checkpoint. */
mutex_enter(&log_sys->mutex);
- ut_d(recv_no_log_write = FALSE);
+ ut_d(recv_no_log_write = srv_apply_log_only);
recv_reset_logs(
#ifdef UNIV_LOG_ARCHIVE
UT_LIST_GET_FIRST(log_sys->log_groups)->archived_file_no,
@@ -2749,6 +2748,11 @@ files_checked:
recv_recovery_from_checkpoint_finish();
+ if (srv_apply_log_only) {
+ ut_ad(IS_XTRABACKUP());
+ goto skip_processes;
+ }
+
if (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE) {
/* The following call is necessary for the insert
buffer to work with multiple tablespaces. We must
@@ -3147,18 +3151,17 @@ files_checked:
#endif /* WITH_WSREP */
/* Create thread(s) that handles key rotation */
fil_system_enter();
+ btr_scrub_init();
fil_crypt_threads_init();
fil_system_exit();
- /* Init data for datafile scrub threads */
- btr_scrub_init();
-
/* Initialize online defragmentation. */
btr_defragment_init();
btr_defragment_thread_active = true;
os_thread_create(btr_defragment_thread, NULL, NULL);
}
+skip_processes:
srv_was_started = TRUE;
return(DB_SUCCESS);
@@ -3321,7 +3324,7 @@ innodb_shutdown()
srv_misc_tmpfile = 0;
}
- if (!srv_read_only_mode) {
+ if (!srv_read_only_mode && !srv_apply_log_only) {
dict_stats_thread_deinit();
fil_crypt_threads_cleanup();
btr_scrub_cleanup();
diff --git a/storage/xtradb/trx/trx0purge.cc b/storage/xtradb/trx/trx0purge.cc
index df4a3217820..cbf783628f9 100644
--- a/storage/xtradb/trx/trx0purge.cc
+++ b/storage/xtradb/trx/trx0purge.cc
@@ -584,32 +584,6 @@ trx_purge_rseg_get_next_history_log(
mutex_exit(&(rseg->mutex));
mtr_commit(&mtr);
-
- mutex_enter(&trx_sys->mutex);
-
- /* 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) {
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Warning: purge reached the"
- " head of the history list,\n"
- "InnoDB: but its length is still"
- " reported as %lu! Make a detailed bug\n"
- "InnoDB: report, and submit it"
- " to http://bugs.mysql.com\n",
- (ulong) trx_sys->rseg_history_len);
- ut_ad(0);
- }
-
- mutex_exit(&trx_sys->mutex);
-
return;
}
diff --git a/storage/xtradb/trx/trx0rec.cc b/storage/xtradb/trx/trx0rec.cc
index 8c0904dd57b..dc9b0829925 100644
--- a/storage/xtradb/trx/trx0rec.cc
+++ b/storage/xtradb/trx/trx0rec.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, 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
@@ -466,7 +467,7 @@ trx_undo_page_fetch_ext(
{
/* Fetch the BLOB. */
ulint ext_len = btr_copy_externally_stored_field_prefix(
- ext_buf, prefix_len, zip_size, field, *len, NULL);
+ ext_buf, prefix_len, zip_size, field, *len);
/* BLOBs should always be nonempty. */
ut_a(ext_len);
/* Append the BLOB pointer to the prefix. */
@@ -771,7 +772,25 @@ trx_undo_page_report_modify(
const dict_col_t* col
= dict_table_get_nth_col(table, col_no);
- if (col->ord_part) {
+ if (!col->ord_part) {
+ continue;
+ }
+
+ if (update) {
+ for (i = 0; i < update->n_fields; i++) {
+ const dict_field_t* f
+ = dict_index_get_nth_field(
+ index,
+ upd_get_nth_field(
+ update, i)
+ ->field_no);
+ if (f->col == col) {
+ goto already_logged;
+ }
+ }
+ }
+
+ if (TRUE) {
ulint pos;
/* Write field number to undo log */
@@ -822,6 +841,9 @@ trx_undo_page_report_modify(
ptr += flen;
}
}
+
+already_logged:
+ continue;
}
mach_write_to_2(old_ptr, ptr - old_ptr);
@@ -1000,7 +1022,7 @@ trx_undo_update_rec_get_update(
fprintf(stderr, "\n"
"InnoDB: but index has only %lu fields\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com\n"
+ " to https://jira.mariadb.org/\n"
"InnoDB: Run also CHECK TABLE ",
(ulong) dict_index_get_n_fields(index));
ut_print_name(stderr, trx, TRUE, index->table_name);
@@ -1054,6 +1076,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
@@ -1081,6 +1104,13 @@ trx_undo_rec_get_partial_row(
->mtype = DATA_MISSING;
}
+ for (const upd_field_t* uf = update->fields, * const ue
+ = update->fields + update->n_fields;
+ uf != ue; uf++) {
+ 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;
@@ -1101,6 +1131,10 @@ trx_undo_rec_get_partial_row(
ptr = trx_undo_rec_get_col_val(ptr, &field, &len, &orig_len);
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);
dict_col_copy_type(
dict_table_get_nth_col(index->table, col_no),
dfield_get_type(dfield));
@@ -1199,10 +1233,8 @@ trx_undo_report_row_operation(
marking, the record in the clustered
index, otherwise NULL */
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;
trx_undo_t* undo;
@@ -1236,7 +1268,7 @@ trx_undo_report_row_operation(
rseg = trx->rseg;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
mutex_enter(&trx->undo_mutex);
/* If the undo log is not assigned yet, assign one */
@@ -1313,7 +1345,7 @@ trx_undo_report_row_operation(
latches, such as SYNC_FSP and SYNC_FSP_PAGE. */
mtr_commit(&mtr);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
mutex_enter(&rseg->mutex);
trx_undo_free_last_page(trx, undo, &mtr);
@@ -1350,7 +1382,7 @@ trx_undo_report_row_operation(
/* We have to extend the undo log by one page */
ut_ad(++loop_count < 2);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* When we add a page to an undo log, this is analogous to
a pessimistic insert in a B-tree, and we must reserve the
diff --git a/storage/xtradb/trx/trx0roll.cc b/storage/xtradb/trx/trx0roll.cc
index 335ef8859c4..1075064a2d6 100644
--- a/storage/xtradb/trx/trx0roll.cc
+++ b/storage/xtradb/trx/trx0roll.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 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,6 +24,9 @@ Transaction rollback
Created 3/26/1996 Heikki Tuuri
*******************************************************/
+#include "my_config.h"
+#include <my_systemd.h>
+
#include "trx0roll.h"
#ifdef UNIV_NONINL
@@ -60,14 +63,7 @@ rollback */
bool trx_rollback_or_clean_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. */
@@ -564,8 +560,6 @@ trx_rollback_active(
que_thr_t* thr;
roll_node_t* roll_node;
dict_table_t* table;
- ib_int64_t rows_to_undo;
- const char* unit = "";
ibool dictionary_locked = FALSE;
heap = mem_heap_create(512);
@@ -584,30 +578,8 @@ trx_rollback_active(
ut_a(thr == que_fork_start_command(fork));
- mutex_enter(&trx_sys->mutex);
-
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;
-
- mutex_exit(&trx_sys->mutex);
-
- if (rows_to_undo > 1000000000) {
- rows_to_undo = rows_to_undo / 1000000;
- unit = "M";
- }
-
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Rolling back trx with id " TRX_ID_FMT ", %lu%s"
- " rows to undo\n",
- trx->id,
- (ulong) rows_to_undo, unit);
-
if (trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) {
row_mysql_lock_data_dictionary(trx);
dictionary_locked = TRUE;
@@ -618,6 +590,16 @@ 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_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 */
@@ -662,13 +644,14 @@ trx_rollback_active(
}
}
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Rollback of trx with id " TRX_ID_FMT " completed", trx->id);
+
+func_exit:
if (dictionary_locked) {
row_mysql_unlock_data_dictionary(trx);
}
- ib_logf(IB_LOG_LEVEL_INFO,
- "Rollback of trx with id " TRX_ID_FMT " completed", trx->id);
-
mem_heap_free(heap);
trx_roll_crash_recv_trx = NULL;
@@ -685,7 +668,7 @@ ibool
trx_rollback_resurrected(
/*=====================*/
trx_t* trx, /*!< in: transaction to rollback or clean */
- ibool all) /*!< in: FALSE=roll back dictionary transactions;
+ ibool* all) /*!< in/out: FALSE=roll back dictionary transactions;
TRUE=roll back all non-PREPARED transactions */
{
ut_ad(mutex_own(&trx_sys->mutex));
@@ -696,16 +679,15 @@ trx_rollback_resurrected(
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) {
+ if (!trx->is_recovered) {
+func_exit:
+ trx_mutex_exit(trx);
return(FALSE);
}
- switch (state) {
+ switch (trx->state) {
case TRX_STATE_COMMITTED_IN_MEMORY:
+ trx_mutex_exit(trx);
mutex_exit(&trx_sys->mutex);
fprintf(stderr,
"InnoDB: Cleaning up trx with id " TRX_ID_FMT "\n",
@@ -714,21 +696,84 @@ trx_rollback_resurrected(
trx_free_for_background(trx);
return(TRUE);
case TRX_STATE_ACTIVE:
- if (all || trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) {
+ if (!srv_undo_sources && srv_fast_shutdown) {
+fake_prepared:
+ trx->state = TRX_STATE_PREPARED;
+ trx_sys->n_prepared_trx++;
+ trx_sys->n_prepared_recovered_trx++;
+ *all = FALSE;
+ goto func_exit;
+ }
+ trx_mutex_exit(trx);
+
+ if (*all || trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) {
mutex_exit(&trx_sys->mutex);
trx_rollback_active(trx);
+ if (trx->error_state != DB_SUCCESS) {
+ ut_ad(trx->error_state == DB_INTERRUPTED);
+ ut_ad(!srv_undo_sources);
+ ut_ad(srv_fast_shutdown);
+ mutex_enter(&trx_sys->mutex);
+ trx_mutex_enter(trx);
+ goto fake_prepared;
+ }
trx_free_for_background(trx);
return(TRUE);
}
return(FALSE);
case TRX_STATE_PREPARED:
- return(FALSE);
+ goto func_exit;
case TRX_STATE_NOT_STARTED:
break;
}
ut_error;
- return(FALSE);
+ goto func_exit;
+}
+
+/** Report progress when rolling back a row of a recovered transaction.
+@return whether the rollback should be aborted due to pending shutdown */
+UNIV_INTERN
+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));
+
+ if (trx_get_dict_operation(trx) == TRX_DICT_OP_NONE
+ && !srv_undo_sources && srv_fast_shutdown) {
+ return true;
+ }
+
+ ib_time_t time = ut_time();
+ mutex_enter(&trx_sys->mutex);
+ mutex_enter(&recv_sys->mutex);
+
+ if (recv_sys->report(time)) {
+ ulint n_trx = 0;
+ ulonglong n_rows = 0;
+ for (const trx_t* t = UT_LIST_GET_FIRST(trx_sys->rw_trx_list);
+ t != NULL;
+ t = UT_LIST_GET_NEXT(trx_list, t)) {
+
+ assert_trx_in_rw_list(t);
+ if (t->is_recovered
+ && trx_state_eq(t, TRX_STATE_ACTIVE)) {
+ n_trx++;
+ n_rows += t->undo_no;
+ }
+ }
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "To roll back: " ULINTPF " transactions, "
+ "%llu rows", n_trx, n_rows);
+ sd_notifyf(0, "STATUS=To roll back: " ULINTPF " transactions, "
+ "%llu rows", n_trx, n_rows);
+ }
+
+ mutex_exit(&recv_sys->mutex);
+ mutex_exit(&trx_sys->mutex);
+ return false;
}
/*******************************************************************//**
@@ -775,17 +820,11 @@ trx_rollback_or_clean_recovered(
assert_trx_in_rw_list(trx);
- if (srv_shutdown_state != SRV_SHUTDOWN_NONE
- && srv_fast_shutdown != 0) {
- all = FALSE;
- break;
- }
-
/* 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)) {
+ if (trx_rollback_resurrected(trx, &all)) {
mutex_enter(&trx_sys->mutex);
@@ -1118,7 +1157,6 @@ trx_roll_pop_top_rec_of_trx(
undo_no_t undo_no;
ibool is_insert;
trx_rseg_t* rseg;
- ulint progress_pct;
mtr_t mtr;
rseg = trx->rseg;
@@ -1176,27 +1214,6 @@ try_again:
ut_ad(undo_no + 1 == trx->undo_no);
- /* 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) {
-
- 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;
if (!trx_undo_arr_store_info(trx, undo_no)) {
diff --git a/storage/xtradb/trx/trx0rseg.cc b/storage/xtradb/trx/trx0rseg.cc
index 16fa334872b..38719a1c771 100644
--- a/storage/xtradb/trx/trx0rseg.cc
+++ b/storage/xtradb/trx/trx0rseg.cc
@@ -122,9 +122,11 @@ trx_rseg_mem_free(
mutex_free(&rseg->mutex);
+ if (!srv_apply_log_only) {
/* There can't be any active transactions. */
ut_a(UT_LIST_GET_LEN(rseg->update_undo_list) == 0);
ut_a(UT_LIST_GET_LEN(rseg->insert_undo_list) == 0);
+ }
for (undo = UT_LIST_GET_FIRST(rseg->update_undo_cached);
undo != NULL;
diff --git a/storage/xtradb/trx/trx0sys.cc b/storage/xtradb/trx/trx0sys.cc
index 063a43b177c..6108ab7ab94 100644
--- a/storage/xtradb/trx/trx0sys.cc
+++ b/storage/xtradb/trx/trx0sys.cc
@@ -184,12 +184,7 @@ 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(mutex_own(&trx_sys->mutex));
-#endif /* WITH_WSREP */
if (!srv_read_only_mode) {
mtr_start(&mtr);
@@ -348,6 +343,7 @@ static inline void read_wsrep_xid_uuid(const XID* xid, unsigned char* buf)
@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,
@@ -406,8 +402,9 @@ trx_sys_update_wsrep_checkpoint(
}
/** Read WSREP XID from sys_header of TRX_SYS_PAGE_NO = 5.
-@param[out] xid Transaction XID
+@param[out] xid Transaction XID
@retval true if found, false if not */
+UNIV_INTERN
bool
trx_sys_read_wsrep_checkpoint(XID* xid)
{
@@ -1344,8 +1341,7 @@ trx_sys_close(void)
ut_a(UT_LIST_GET_LEN(trx_sys->rw_trx_list) == trx_sys->n_prepared_trx
|| srv_read_only_mode
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO
- || (IS_XTRABACKUP() && srv_apply_log_only));
-
+ || srv_apply_log_only);
while ((trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list)) != NULL) {
trx_free_prepared(trx);
@@ -1376,7 +1372,7 @@ trx_sys_close(void)
UT_LIST_REMOVE(view_list, trx_sys->view_list, prev_view);
}
- if (!IS_XTRABACKUP() || !srv_apply_log_only) {
+ if (!srv_apply_log_only) {
ut_a(UT_LIST_GET_LEN(trx_sys->view_list) == 0);
ut_a(UT_LIST_GET_LEN(trx_sys->ro_trx_list) == 0);
ut_a(UT_LIST_GET_LEN(trx_sys->rw_trx_list) == 0);
@@ -1428,7 +1424,7 @@ ulint
trx_sys_any_active_transactions(void)
/*=================================*/
{
- if (IS_XTRABACKUP() && srv_apply_log_only) {
+ if (srv_apply_log_only) {
return(0);
}
mutex_enter(&trx_sys->mutex);
diff --git a/storage/xtradb/trx/trx0trx.cc b/storage/xtradb/trx/trx0trx.cc
index cfc1f83053a..b3d709ccf8a 100644
--- a/storage/xtradb/trx/trx0trx.cc
+++ b/storage/xtradb/trx/trx0trx.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 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
@@ -480,9 +480,11 @@ trx_free_prepared(
trx_t* trx) /*!< in, own: trx object */
{
ut_a(trx_state_eq(trx, TRX_STATE_PREPARED)
- || (trx_state_eq(trx, TRX_STATE_ACTIVE)
- && trx->is_recovered
+ || (trx->is_recovered
+ && (trx_state_eq(trx, TRX_STATE_ACTIVE)
+ || trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY))
&& (srv_read_only_mode
+ || srv_apply_log_only
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO)));
ut_a(trx->magic_n == TRX_MAGIC_N);
@@ -1470,6 +1472,8 @@ trx_commit_in_memory(
if (lsn) {
ulint flush_log_at_trx_commit;
+ DEBUG_SYNC_C("after_trx_committed_in_memory");
+
if (trx->insert_undo != NULL) {
trx_undo_insert_cleanup(trx);
diff --git a/storage/xtradb/trx/trx0undo.cc b/storage/xtradb/trx/trx0undo.cc
index 220589dd9ff..594416ba34d 100644
--- a/storage/xtradb/trx/trx0undo.cc
+++ b/storage/xtradb/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. 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
@@ -1070,9 +1070,11 @@ Truncates an undo log from the end. This function is used during a rollback
to free space from an undo log. */
UNIV_INTERN
void
-trx_undo_truncate_end(
+trx_undo_truncate_end_func(
/*=======================*/
- trx_t* trx, /*!< in: transaction whose undo log it is */
+#ifdef UNIV_DEBUG
+ const trx_t* trx, /*!< in: transaction whose undo log it is */
+#endif /* UNIV_DEBUG */
trx_undo_t* undo, /*!< in: undo log */
undo_no_t limit) /*!< in: all undo records with undo number
>= this value should be truncated */
@@ -1087,7 +1089,7 @@ trx_undo_truncate_end(
ut_ad(mutex_own(&(trx->rseg->mutex)));
for (;;) {
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
trunc_here = NULL;
@@ -1774,7 +1776,7 @@ trx_undo_assign_undo(
ut_ad(mutex_own(&(trx->undo_mutex)));
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
mutex_enter(&rseg->mutex);
@@ -1987,7 +1989,9 @@ trx_undo_insert_cleanup(
mutex_exit(&(rseg->mutex));
- trx_undo_seg_free(undo);
+ if (!srv_read_only_mode) {
+ trx_undo_seg_free(undo);
+ }
mutex_enter(&(rseg->mutex));
@@ -2015,11 +2019,22 @@ trx_undo_free_prepared(
switch (trx->update_undo->state) {
case TRX_UNDO_PREPARED:
break;
+ case TRX_UNDO_CACHED:
+ case TRX_UNDO_TO_FREE:
+ case TRX_UNDO_TO_PURGE:
+ ut_ad(trx_state_eq(trx,
+ TRX_STATE_COMMITTED_IN_MEMORY));
+ /* fall through */
case TRX_UNDO_ACTIVE:
/* lock_trx_release_locks() assigns
- trx->is_recovered=false */
+ trx->is_recovered=false and
+ trx->state = TRX_STATE_COMMITTED_IN_MEMORY,
+ also for transactions that we faked
+ to TRX_STATE_PREPARED in trx_rollback_resurrected(). */
ut_a(srv_read_only_mode
- || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
+ || srv_apply_log_only
+ || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO
+ || srv_fast_shutdown);
break;
default:
ut_error;
@@ -2033,11 +2048,22 @@ trx_undo_free_prepared(
switch (trx->insert_undo->state) {
case TRX_UNDO_PREPARED:
break;
+ case TRX_UNDO_CACHED:
+ case TRX_UNDO_TO_FREE:
+ case TRX_UNDO_TO_PURGE:
+ ut_ad(trx_state_eq(trx,
+ TRX_STATE_COMMITTED_IN_MEMORY));
+ /* fall through */
case TRX_UNDO_ACTIVE:
/* lock_trx_release_locks() assigns
- trx->is_recovered=false */
+ trx->is_recovered=false and
+ trx->state = TRX_STATE_COMMITTED_IN_MEMORY,
+ also for transactions that we faked
+ to TRX_STATE_PREPARED in trx_rollback_resurrected(). */
ut_a(srv_read_only_mode
- || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
+ || srv_apply_log_only
+ || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO
+ || srv_fast_shutdown);
break;
default:
ut_error;
diff --git a/storage/xtradb/ut/ut0dbg.cc b/storage/xtradb/ut/ut0dbg.cc
index a1cad144da4..a0bd82b385a 100644
--- a/storage/xtradb/ut/ut0dbg.cc
+++ b/storage/xtradb/ut/ut0dbg.cc
@@ -63,7 +63,7 @@ ut_dbg_assertion_failed(
fputs("InnoDB: We intentionally generate a memory trap.\n"
"InnoDB: Submit a detailed bug report"
- " to http://bugs.mysql.com.\n"
+ " to https://jira.mariadb.org/\n"
"InnoDB: If you get repeated assertion failures"
" or crashes, even\n"
"InnoDB: immediately after the mysqld startup, there may be\n"
diff --git a/strings/CMakeLists.txt b/strings/CMakeLists.txt
index 1e364bc951b..2a7f0b71cc8 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)
@@ -34,8 +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)
-
-IF(MSVC)
- INSTALL_DEBUG_TARGET(strings DESTINATION ${INSTALL_LIBDIR}/debug)
-ENDIF()
+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-tis620.c b/strings/ctype-tis620.c
index bd8efeff1ec..5284109b816 100644
--- a/strings/ctype-tis620.c
+++ b/strings/ctype-tis620.c
@@ -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;
}
@@ -555,7 +555,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);
@@ -604,7 +604,7 @@ int my_strnncollsp_tis620(CHARSET_INFO * cs __attribute__((unused)),
ret:
if (alloced)
- my_str_free(alloced);
+ my_free(alloced);
return res;
}
diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c
index f7170a53a2c..b324a18e358 100644
--- a/strings/ctype-utf8.c
+++ b/strings/ctype-utf8.c
@@ -5035,7 +5035,6 @@ static int my_uni_utf8_no_range(CHARSET_INFO *cs __attribute__((unused)),
switch (count)
{
- /* Fall through all cases!!! */
case 3: r[2]= (uchar) (0x80 | (wc & 0x3f)); wc= wc >> 6; wc |= 0x800;
/* fall through */
case 2: r[1]= (uchar) (0x80 | (wc & 0x3f)); wc= wc >> 6; wc |= 0xc0;
@@ -7443,7 +7442,6 @@ my_wc_mb_utf8mb4(CHARSET_INFO *cs __attribute__((unused)),
return MY_CS_TOOSMALLN(count);
switch (count) {
- /* Fall through all cases!!! */
case 4: r[3] = (uchar) (0x80 | (wc & 0x3f)); wc = wc >> 6; wc |= 0x10000;
/* fall through */
case 3: r[2] = (uchar) (0x80 | (wc & 0x3f)); wc = wc >> 6; wc |= 0x800;
@@ -7478,7 +7476,6 @@ my_wc_mb_utf8mb4_no_range(CHARSET_INFO *cs __attribute__((unused)),
switch (count)
{
- /* Fall through all cases!!! */
case 4: r[3]= (uchar) (0x80 | (wc & 0x3f)); wc= wc >> 6; wc |= 0x10000;
/* fall through */
case 3: r[2]= (uchar) (0x80 | (wc & 0x3f)); wc= wc >> 6; wc |= 0x800;
diff --git a/strings/dtoa.c b/strings/dtoa.c
index e66db5fed3d..3dba0da7485 100644
--- a/strings/dtoa.c
+++ b/strings/dtoa.c
@@ -1466,11 +1466,9 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s
esign= 0;
if (++s < end)
switch (c= *s) {
- case '-':
- esign= 1;
- /* fall through */
- case '+':
- c= *++s;
+ case '-': esign= 1;
+ /* fall through */
+ case '+': c= *++s;
}
if (s < end && c >= '0' && c <= '9')
{
diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c
index 4178b20789d..134fdfc57b8 100644
--- a/strings/my_vsnprintf.c
+++ b/strings/my_vsnprintf.c
@@ -755,14 +755,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;
}
@@ -770,7 +770,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 71e9b3fad3d..3b6e86030ab 100644
--- a/support-files/CMakeLists.txt
+++ b/support-files/CMakeLists.txt
@@ -104,6 +104,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/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 ed0da3ccddb..c9ea270a781 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/unittest/mysys/base64-t.c b/unittest/mysys/base64-t.c
index 4561606936a..a3a37976da6 100644
--- a/unittest/mysys/base64-t.c
+++ b/unittest/mysys/base64-t.c
@@ -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/vio/CMakeLists.txt b/vio/CMakeLists.txt
index 2fb82ef9dd2..cdb28799ada 100644
--- a/vio/CMakeLists.txt
+++ b/vio/CMakeLists.txt
@@ -20,7 +20,3 @@ ADD_DEFINITIONS(${SSL_DEFINES})
SET(VIO_SOURCES vio.c viosocket.c viossl.c viopipe.c vioshm.c viosslfactories.c)
ADD_CONVENIENCE_LIBRARY(vio ${VIO_SOURCES})
TARGET_LINK_LIBRARIES(vio ${LIBSOCKET})
-
-IF(MSVC)
- INSTALL_DEBUG_TARGET(vio DESTINATION ${INSTALL_LIBDIR}/debug)
-ENDIF()
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 9281ce27d34..c0062ddcdd1 100644
--- a/win/packaging/ca/CustomAction.cpp
+++ b/win/packaging/ca/CustomAction.cpp
@@ -767,6 +767,49 @@ extern "C" UINT __stdcall PresetDatabaseProperties(MSIHANDLE hInstall)
LExit:
return WcaFinalize(er);
}
+
+static BOOL FindErrorLog(const wchar_t *dir, wchar_t * ErrorLogFile, size_t ErrorLogLen)
+{
+ WIN32_FIND_DATA FindFileData;
+ HANDLE hFind;
+ wchar_t name[MAX_PATH];
+ wcsncpy_s(name,dir, MAX_PATH);
+ wcsncat_s(name,L"\\*.err", MAX_PATH);
+ hFind = FindFirstFileW(name,&FindFileData);
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ _snwprintf(ErrorLogFile, ErrorLogLen,
+ L"%s\\%s",dir, FindFileData.cFileName);
+ FindClose(hFind);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void DumpErrorLog(const wchar_t *dir)
+{
+ wchar_t filepath[MAX_PATH];
+ if (!FindErrorLog(dir, filepath, MAX_PATH))
+ return;
+ FILE *f= _wfopen(filepath, L"r");
+ if (!f)
+ return;
+ char buf[2048];
+ WcaLog(LOGMSG_STANDARD,"=== dumping error log %S === ",filepath);
+ while (fgets(buf, sizeof(buf), f))
+ {
+ /* Strip off EOL chars. */
+ size_t len = strlen(buf);
+ if (len > 0 && buf[len-1] == '\n')
+ buf[--len]= 0;
+ if (len > 0 && buf[len-1] == '\r')
+ buf[--len]= 0;
+ WcaLog(LOGMSG_STANDARD,"%s",buf);
+ }
+ fclose(f);
+ WcaLog(LOGMSG_STANDARD,"=== end of error log ===");
+}
+
/* Remove service and data directory created by CreateDatabase operation */
extern "C" UINT __stdcall CreateDatabaseRollback(MSIHANDLE hInstall)
{
@@ -774,7 +817,6 @@ extern "C" UINT __stdcall CreateDatabaseRollback(MSIHANDLE hInstall)
UINT er = ERROR_SUCCESS;
wchar_t* service= 0;
wchar_t* dir= 0;
-
hr = WcaInitialize(hInstall, __FUNCTION__);
ExitOnFailure(hr, "Failed to initialize");
WcaLog(LOGMSG_STANDARD, "Initialized.");
@@ -804,6 +846,7 @@ extern "C" UINT __stdcall CreateDatabaseRollback(MSIHANDLE hInstall)
}
if(dir)
{
+ DumpErrorLog(dir);
ExecRemoveDataDirectory(dir);
}
LExit:
diff --git a/zlib/CMakeLists.txt b/zlib/CMakeLists.txt
index 7668ce723b8..dd1e45d4acf 100644
--- a/zlib/CMakeLists.txt
+++ b/zlib/CMakeLists.txt
@@ -22,8 +22,3 @@ SET(ZLIB_SOURCES adler32.c compress.c crc32.c crc32.h deflate.c deflate.h gzio.
zutil.c zutil.h)
ADD_CONVENIENCE_LIBRARY(zlib ${ZLIB_SOURCES})
RESTRICT_SYMBOL_EXPORTS(zlib)
-
-IF(MSVC)
- INSTALL_DEBUG_TARGET(zlib DESTINATION ${INSTALL_LIBDIR}/debug)
-ENDIF()
-