summaryrefslogtreecommitdiffstats
path: root/storage/mroonga/vendor/groonga/lib
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 18:07:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 18:07:14 +0000
commita175314c3e5827eb193872241446f2f8f5c9d33c (patch)
treecd3d60ca99ae00829c52a6ca79150a5b6e62528b /storage/mroonga/vendor/groonga/lib
parentInitial commit. (diff)
downloadmariadb-10.5-upstream.tar.xz
mariadb-10.5-upstream.zip
Adding upstream version 1:10.5.12.upstream/1%10.5.12upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'storage/mroonga/vendor/groonga/lib')
-rw-r--r--storage/mroonga/vendor/groonga/lib/CMakeLists.txt185
-rw-r--r--storage/mroonga/vendor/groonga/lib/Makefile.am99
-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.am112
-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.c1202
-rw-r--r--storage/mroonga/vendor/groonga/lib/command.c201
-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.c1873
-rw-r--r--storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c324
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat.cpp1338
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/Makefile.am11
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/array.hpp98
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/base.hpp67
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/block.hpp94
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/check.hpp149
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/cursor-factory.cpp92
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/cursor-factory.hpp44
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/cursor.hpp46
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/dat.hpp248
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/entry.hpp59
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/file-impl.cpp279
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/file-impl.hpp73
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/file.cpp73
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/file.hpp60
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/header.hpp179
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/id-cursor.cpp184
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/id-cursor.hpp83
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/key-cursor.cpp349
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/key-cursor.hpp88
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/key.hpp110
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/node.hpp127
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/predictive-cursor.cpp206
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/predictive-cursor.hpp84
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/prefix-cursor.cpp175
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/prefix-cursor.hpp78
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/sources.am29
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/string.hpp173
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/trie.cpp1225
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/trie.hpp285
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/vector.hpp191
-rw-r--r--storage/mroonga/vendor/groonga/lib/db.c14054
-rw-r--r--storage/mroonga/vendor/groonga/lib/dump.c112
-rw-r--r--storage/mroonga/vendor/groonga/lib/error.c454
-rw-r--r--storage/mroonga/vendor/groonga/lib/expr.c9294
-rw-r--r--storage/mroonga/vendor/groonga/lib/expr_code.c55
-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.c2788
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn.h759
-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.h250
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_config.h37
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ctx.h501
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ctx_impl.h237
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ctx_impl_mrb.h35
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_dat.h95
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_db.h493
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ecmascript.c2542
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ecmascript.h74
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ecmascript.lemon581
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_error.h34
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_expr.h86
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_expr_code.h33
-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.h200
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_hash.h378
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ii.h192
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_index_column.h34
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_io.h487
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_load.h47
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_logger.h35
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_mrb.h42
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_msgpack.h46
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_nfkc.h39
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_normalizer.h42
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_obj.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_output.h127
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_pat.h129
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_plugin.h62
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_proc.h152
-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.h28
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_request_timer.h28
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_rset.h114
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_scanner.h40
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_scorer.h49
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_scorers.h31
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_snip.h125
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_store.h216
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_str.h116
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_string.h51
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_time.h40
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_token_cursor.h81
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_tokenizers.h38
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ts.h48
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_util.h49
-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.c3720
-rw-r--r--storage/mroonga/vendor/groonga/lib/icudump.c298
-rw-r--r--storage/mroonga/vendor/groonga/lib/id.c36
-rw-r--r--storage/mroonga/vendor/groonga/lib/ii.c12816
-rw-r--r--storage/mroonga/vendor/groonga/lib/index_column.c194
-rw-r--r--storage/mroonga/vendor/groonga/lib/io.c2201
-rw-r--r--storage/mroonga/vendor/groonga/lib/load.c1229
-rw-r--r--storage/mroonga/vendor/groonga/lib/logger.c810
-rw-r--r--storage/mroonga/vendor/groonga/lib/metadata.rc.in28
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb.c220
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/Makefile.am21
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.c121
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.h33
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c92
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_array.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c373
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.h41
-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.c173
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_column.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_command.c196
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_command.h34
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.c139
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.h32
-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.c49
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_content_type.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c350
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.h64
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.c838
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.h33
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_database.c206
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_database.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_double_array_trie.c60
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_double_array_trie.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_error.c202
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_error.h32
-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.c1079
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.h43
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_fixed_size_column.c59
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_fixed_size_column.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.c117
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_id.c79
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_id.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c199
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.c245
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.h32
-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.c99
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_logger.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c346
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_object.h34
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.c96
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.c155
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.h34
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_options.c39
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_options.h38
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_patricia_trie.c59
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_patricia_trie.h32
-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.c108
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_procedure.h32
-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.c493
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.c208
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor_flags.c60
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor_flags.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_flags.c48
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_flags.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.c254
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.h31
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.c42
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.h31
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.c159
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.h32
-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.c60
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_type.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_variable_size_column.c60
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_variable_size_column.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_void.c59
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_void.h32
-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.c253
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.h32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/Makefile.am16
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/accessor.rb5
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/backtrace_entry.rb28
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/command.rb64
-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/Makefile.am9
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/grndb.rb452
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/sources.am2
-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.rb85
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/context/Makefile.am9
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/context/error_level.rb30
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/context/rc.rb205
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/context/sources.am3
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/database.rb65
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/error.rb16
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/eval_context.rb18
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression.rb68
-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.rb54
-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/index_column.rb39
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/index_cursor.rb18
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/index_info.rb10
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/Makefile.am9
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb28
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/pre.rb3
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/sources.am3
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/logger.rb34
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/Makefile.am9
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/level.rb40
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/sources.am2
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/object.rb18
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/operator.rb22
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/plugin_loader.rb14
-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.rb71
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info.rb38
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_builder.rb577
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data.rb324
-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/scan_info_search_index.rb9
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am37
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/table.rb144
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/table_cursor.rb28
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/variable_size_column.rb5
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/writer.rb21
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/sources.am93
-rw-r--r--storage/mroonga/vendor/groonga/lib/nfkc-custom-rules.txt1
-rw-r--r--storage/mroonga/vendor/groonga/lib/nfkc.c45
-rwxr-xr-xstorage/mroonga/vendor/groonga/lib/nfkc.rb897
-rw-r--r--storage/mroonga/vendor/groonga/lib/nfkc50.c77784
-rw-r--r--storage/mroonga/vendor/groonga/lib/normalizer.c1193
-rw-r--r--storage/mroonga/vendor/groonga/lib/obj.c689
-rw-r--r--storage/mroonga/vendor/groonga/lib/operator.c1362
-rw-r--r--storage/mroonga/vendor/groonga/lib/output.c2880
-rw-r--r--storage/mroonga/vendor/groonga/lib/pat.c3674
-rw-r--r--storage/mroonga/vendor/groonga/lib/plugin.c1396
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc.c4211
-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.c3809
-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.c176
-rw-r--r--storage/mroonga/vendor/groonga/lib/request_timer.c88
-rw-r--r--storage/mroonga/vendor/groonga/lib/rset.c324
-rw-r--r--storage/mroonga/vendor/groonga/lib/scanner.c73
-rw-r--r--storage/mroonga/vendor/groonga/lib/scorer.c189
-rw-r--r--storage/mroonga/vendor/groonga/lib/scorers.c96
-rw-r--r--storage/mroonga/vendor/groonga/lib/snip.c841
-rw-r--r--storage/mroonga/vendor/groonga/lib/store.c2864
-rw-r--r--storage/mroonga/vendor/groonga/lib/str.c3276
-rw-r--r--storage/mroonga/vendor/groonga/lib/string.c416
-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.c386
-rw-r--r--storage/mroonga/vendor/groonga/lib/token_filter.c59
-rw-r--r--storage/mroonga/vendor/groonga/lib/tokenizer.c375
-rw-r--r--storage/mroonga/vendor/groonga/lib/tokenizers.c890
-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.c5325
-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.c1643
-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
359 files changed, 218537 insertions, 0 deletions
diff --git a/storage/mroonga/vendor/groonga/lib/CMakeLists.txt b/storage/mroonga/vendor/groonga/lib/CMakeLists.txt
new file mode 100644
index 00000000..8c71563f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/CMakeLists.txt
@@ -0,0 +1,185 @@
+# 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 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-1335 USA
+
+add_definitions(
+ -DGRN_DAT_EXPORT
+ )
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/dat
+ ${ONIGMO_INCLUDE_DIRS}
+ ${MRUBY_INCLUDE_DIRS}
+ ${LIBLZ4_INCLUDE_DIRS}
+ ${LIBZSTD_INCLUDE_DIRS}
+ ${MESSAGE_PACK_INCLUDE_DIRS})
+
+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_C_SOURCES}
+ ${LIBGRNMRB_SOURCES}
+ ${LIBGRNPROC_SOURCES}
+ ${LIBGRNTS_SOURCES}
+ PROPERTIES
+ COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
+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_C_SOURCES}
+ ${LIBGROONGA_CPP_SOURCES}
+ ${LIBGRNDAT_SOURCES}
+ ${LIBGRNMRB_SOURCES}
+ ${LIBGRNPROC_SOURCES}
+ ${LIBGRNTS_SOURCES}
+ ${LIBGROONGA_METADATA_SOURCES})
+if(GRN_EMBED)
+ add_library(libgroonga STATIC ${GRN_ALL_SOURCES})
+ set_target_properties(
+ libgroonga
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+else()
+ add_library(libgroonga SHARED ${GRN_ALL_SOURCES})
+endif()
+set_target_properties(libgroonga PROPERTIES OUTPUT_NAME "groonga")
+
+set(GRN_ALL_LIBRARIES
+ ${EXECINFO_LIBS}
+ ${RT_LIBS}
+ ${PTHREAD_LIBS}
+ ${Z_LIBS}
+ ${LZ4_LIBS}
+ ${LIBZSTD_LIBS}
+ ${MESSAGE_PACK_LIBS}
+ ${CMAKE_DL_LIBS}
+ ${M_LIBS}
+ ${WS2_32_LIBS}
+ ${MRUBY_LIBS}
+ ${ONIGMO_LIBS})
+if(GRN_EMBED)
+ set(GRN_EMBEDDED_PLUGIN_LIBRARIES "")
+ if(GRN_WITH_MECAB)
+ list(APPEND GRN_EMBEDDED_PLUGIN_LIBRARIES mecab_tokenizer)
+ endif()
+ target_link_libraries(libgroonga
+ ${GRN_ALL_LIBRARIES}
+ ${STDCPP_LIBS}
+ ${GRN_EMBEDDED_PLUGIN_LIBRARIES})
+else()
+ target_link_libraries(libgroonga
+ ${GRN_ALL_LIBRARIES})
+ install(TARGETS libgroonga
+ ARCHIVE DESTINATION "${LIB_DIR}"
+ LIBRARY DESTINATION "${LIB_DIR}"
+ RUNTIME DESTINATION "${BIN_DIR}")
+endif()
+
+if(GRN_WITH_MRUBY)
+ read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/mrb/scripts/sources.am
+ RUBY_SCRIPTS)
+ string(REGEX REPLACE "([^;]+)" "mrb/scripts/\\1"
+ RUBY_SCRIPTS "${RUBY_SCRIPTS}")
+ install(
+ FILES ${RUBY_SCRIPTS}
+ DESTINATION "${GRN_RELATIVE_RUBY_SCRIPTS_DIR}")
+
+ read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/mrb/scripts/command_line/sources.am
+ COMMANE_LINE_RUBY_SCRIPTS)
+ string(REGEX REPLACE "([^;]+)" "mrb/scripts/command_line/\\1"
+ COMMANE_LINE_RUBY_SCRIPTS "${COMMANE_LINE_RUBY_SCRIPTS}")
+ install(
+ FILES ${COMMANE_LINE_RUBY_SCRIPTS}
+ DESTINATION "${GRN_RELATIVE_RUBY_SCRIPTS_DIR}/command_line")
+
+ read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/mrb/scripts/context/sources.am
+ CONTEXT_RUBY_SCRIPTS)
+ string(REGEX REPLACE "([^;]+)" "mrb/scripts/context/\\1"
+ CONTEXT_RUBY_SCRIPTS "${CONTEXT_RUBY_SCRIPTS}")
+ install(
+ FILES ${CONTEXT_RUBY_SCRIPTS}
+ DESTINATION "${GRN_RELATIVE_RUBY_SCRIPTS_DIR}/context")
+
+ read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/mrb/scripts/initialize/sources.am
+ INITIALIZE_RUBY_SCRIPTS)
+ string(REGEX REPLACE "([^;]+)" "mrb/scripts/initialize/\\1"
+ INITIALIZE_RUBY_SCRIPTS "${INITIALIZE_RUBY_SCRIPTS}")
+ install(
+ FILES ${INITIALIZE_RUBY_SCRIPTS}
+ DESTINATION "${GRN_RELATIVE_RUBY_SCRIPTS_DIR}/initialize")
+
+ read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/mrb/scripts/logger/sources.am
+ LOGGER_RUBY_SCRIPTS)
+ string(REGEX REPLACE "([^;]+)" "mrb/scripts/logger/\\1"
+ LOGGER_RUBY_SCRIPTS "${LOGGER_RUBY_SCRIPTS}")
+ 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" AND
+ CMAKE_C_COMPILER_VERSION VERSION_GREATER "5")
+ 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
new file mode 100644
index 00000000..9a2217ee
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/Makefile.am
@@ -0,0 +1,99 @@
+SUBDIRS = \
+ dat \
+ 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) \
+ $(LIBZSTD_CFLAGS)
+
+AM_CXXFLAGS = \
+ $(NO_STRICT_ALIASING_CFLAGS) \
+ $(COVERAGE_CFLAGS) \
+ $(GRN_CXXFLAGS) \
+ $(ARROW_CFLAGS)
+
+BUNDLED_LIBRARIES_CFLAGS = \
+ $(MRUBY_CFLAGS) \
+ $(ONIGMO_CFLAGS)
+
+DEFAULT_INCLUDES = \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/include \
+ $(BUNDLED_LIBRARIES_CFLAGS)
+
+DEFS += -D_REENTRANT $(GRN_DEFS) -DGRN_DAT_EXPORT
+
+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) \
+ -no-undefined \
+ $(WINDOWS_LDFLAGS)
+
+libgroonga_la_LIBADD = \
+ dat/libgrndat.la \
+ mrb/libgrnmrb.la \
+ proc/libgrnproc.la \
+ ts/libgrnts.la \
+ $(MESSAGE_PACK_LIBS)
+
+if WITH_MRUBY
+libgroonga_la_LIBADD += \
+ ../vendor/mruby/libmruby.la
+endif
+
+libgroonga_la_LIBADD += \
+ $(ONIGMO_LIBS) \
+ $(LIBLZ4_LIBS) \
+ $(LIBZSTD_LIBS) \
+ $(ATOMIC_LIBS) \
+ $(ARROW_LIBS)
+
+if WITH_LEMON
+BUILT_SOURCES = \
+ grn_ecmascript.c
+
+SUFFIXES = .lemon .c
+
+.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 \
+ grn_ecmascript.lemon \
+ CMakeLists.txt
+
+CLEANFILES = *.gcno *.gcda
diff --git a/storage/mroonga/vendor/groonga/lib/alloc.c b/storage/mroonga/vendor/groonga/lib/alloc.c
new file mode 100644
index 00000000..5e556b83
--- /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-1335 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 (1U <<22)
+#define GRN_CTX_SEGMENT_MASK (GRN_CTX_SEGMENT_SIZE - 1)
+
+#define GRN_CTX_SEGMENT_WORD (1U <<31)
+#define GRN_CTX_SEGMENT_VLEN (1U <<30)
+#define GRN_CTX_SEGMENT_LIFO (1U <<29)
+#define GRN_CTX_SEGMENT_DIRTY (1U <<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 {
+ if ((i = ctx->impl->currseg) >= 0)
+ 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 defined(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 00000000..5f022ed1
--- /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-1335 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/c_sources.am b/storage/mroonga/vendor/groonga/lib/c_sources.am
new file mode 100644
index 00000000..3b76e693
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/c_sources.am
@@ -0,0 +1,112 @@
+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 \
+ grn_dat.h \
+ db.c \
+ grn_db.h \
+ 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 \
+ pat.c \
+ grn_pat.h \
+ plugin.c \
+ 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 \
+ grn_scorers.h \
+ snip.c \
+ grn_snip.h \
+ store.c \
+ grn_store.h \
+ str.c \
+ 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 \
+ tokenizers.c \
+ grn_tokenizers.h \
+ token_filter.c \
+ util.c \
+ 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 00000000..79a2c678
--- /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-1335 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 00000000..ecfc71b7
--- /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-1335 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
new file mode 100644
index 00000000..7761f483
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/com.c
@@ -0,0 +1,1202 @@
+/* -*- c-basic-offset: 2 -*- */
+/* Copyright(C) 2009-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-1335 USA
+*/
+
+#include "grn.h"
+
+#include <stdio.h>
+#include <string.h>
+#include "grn_ctx_impl.h"
+
+#ifdef WIN32
+# include <ws2tcpip.h>
+#else
+# ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+# endif /* HAVE_SYS_SOCKET_H */
+# include <netinet/in.h>
+# include <netinet/tcp.h>
+# ifdef HAVE_SIGNAL_H
+# include <signal.h>
+# endif /* HAVE_SIGNAL_H */
+# include <sys/uio.h>
+#endif /* WIN32 */
+
+#include "grn_ctx.h"
+#include "grn_com.h"
+
+#ifndef PF_INET
+#define PF_INET AF_INET
+#endif /* PF_INET */
+
+#ifndef SOL_TCP
+# ifdef IPPROTO_TCP
+# define SOL_TCP IPPROTO_TCP
+# else
+# define SOL_TCP 6
+# endif /* IPPROTO_TCP */
+#endif /* SOL_TCP */
+
+#ifndef USE_MSG_MORE
+# ifdef MSG_MORE
+# undef MSG_MORE
+# endif
+# define MSG_MORE 0
+#endif /* USE_MSG_MORE */
+
+
+#ifndef USE_MSG_NOSIGNAL
+# ifdef MSG_NOSIGNAL
+# undef MSG_NOSIGNAL
+# endif
+# define MSG_NOSIGNAL 0
+#endif /* USE_MSG_NOSIGNAL */
+/******* grn_com_queue ********/
+
+grn_rc
+grn_com_queue_enque(grn_ctx *ctx, grn_com_queue *q, grn_com_queue_entry *e)
+{
+ CRITICAL_SECTION_ENTER(q->cs);
+ e->next = NULL;
+ *q->tail = e;
+ q->tail = &e->next;
+ CRITICAL_SECTION_LEAVE(q->cs);
+ /*
+ uint8_t i = q->last + 1;
+ e->next = NULL;
+ if (q->first == i || q->next) {
+ CRITICAL_SECTION_ENTER(q->cs);
+ if (q->first == i || q->next) {
+ *q->tail = e;
+ q->tail = &e->next;
+ } else {
+ q->bins[q->last] = e;
+ q->last = i;
+ }
+ CRITICAL_SECTION_LEAVE(q->cs);
+ } else {
+ q->bins[q->last] = e;
+ q->last = i;
+ }
+ */
+ return GRN_SUCCESS;
+}
+
+grn_com_queue_entry *
+grn_com_queue_deque(grn_ctx *ctx, grn_com_queue *q)
+{
+ grn_com_queue_entry *e = NULL;
+
+ CRITICAL_SECTION_ENTER(q->cs);
+ if (q->next) {
+ e = q->next;
+ if (!(q->next = e->next)) { q->tail = &q->next; }
+ }
+ CRITICAL_SECTION_LEAVE(q->cs);
+
+ /*
+ if (q->first == q->last) {
+ if (q->next) {
+ CRITICAL_SECTION_ENTER(q->cs);
+ e = q->next;
+ if (!(q->next = e->next)) { q->tail = &q->next; }
+ CRITICAL_SECTION_LEAVE(q->cs);
+ }
+ } else {
+ e = q->bins[q->first++];
+ }
+ */
+ return e;
+}
+
+/******* grn_msg ********/
+
+grn_obj *
+grn_msg_open(grn_ctx *ctx, grn_com *com, grn_com_queue *old)
+{
+ grn_msg *msg = NULL;
+ if (old && (msg = (grn_msg *)grn_com_queue_deque(ctx, old))) {
+ if (msg->ctx != ctx) {
+ ERR(GRN_INVALID_ARGUMENT, "ctx unmatch");
+ return NULL;
+ }
+ GRN_BULK_REWIND(&msg->qe.obj);
+ } else if ((msg = GRN_MALLOCN(grn_msg, 1))) {
+ GRN_OBJ_INIT(&msg->qe.obj, GRN_MSG, 0, GRN_DB_TEXT);
+ msg->qe.obj.header.impl_flags |= GRN_OBJ_ALLOCATED;
+ msg->ctx = ctx;
+ }
+ msg->qe.next = NULL;
+ msg->u.peer = com;
+ msg->old = old;
+ memset(&msg->header, 0, sizeof(grn_com_header));
+ return (grn_obj *)msg;
+}
+
+grn_obj *
+grn_msg_open_for_reply(grn_ctx *ctx, grn_obj *query, grn_com_queue *old)
+{
+ grn_msg *req = (grn_msg *)query, *msg = NULL;
+ if (req && (msg = (grn_msg *)grn_msg_open(ctx, req->u.peer, old))) {
+ msg->edge_id = req->edge_id;
+ msg->header.proto = req->header.proto == GRN_COM_PROTO_MBREQ
+ ? GRN_COM_PROTO_MBRES : req->header.proto;
+ }
+ return (grn_obj *)msg;
+}
+
+grn_rc
+grn_msg_close(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_msg *msg = (grn_msg *)obj;
+ if (ctx == msg->ctx) { return grn_obj_close(ctx, obj); }
+ return grn_com_queue_enque(ctx, msg->old, (grn_com_queue_entry *)msg);
+}
+
+grn_rc
+grn_msg_set_property(grn_ctx *ctx, grn_obj *obj,
+ uint16_t status, uint32_t key_size, uint8_t extra_size)
+{
+ grn_com_header *header = &((grn_msg *)obj)->header;
+ header->status = htons(status);
+ header->keylen = htons(key_size);
+ header->level = extra_size;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_msg_send(grn_ctx *ctx, grn_obj *msg, int flags)
+{
+ grn_rc rc;
+ grn_msg *m = (grn_msg *)msg;
+ grn_com *peer = m->u.peer;
+ grn_com_header *header = &m->header;
+ if (GRN_COM_QUEUE_EMPTYP(&peer->new_)) {
+ switch (header->proto) {
+ case GRN_COM_PROTO_HTTP :
+ {
+ ssize_t ret;
+ ret = send(peer->fd, GRN_BULK_HEAD(msg), GRN_BULK_VSIZE(msg), MSG_NOSIGNAL);
+ if (ret == -1) { SOERR("send"); }
+ if (ctx->rc != GRN_OPERATION_WOULD_BLOCK) {
+ grn_com_queue_enque(ctx, m->old, (grn_com_queue_entry *)msg);
+ return ctx->rc;
+ }
+ }
+ break;
+ case GRN_COM_PROTO_GQTP :
+ {
+ 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->keylen = 0;
+ header->level = 0;
+ header->flags = flags;
+ header->status = htons((uint16_t)ctx->rc);
+ header->opaque = 0;
+ header->cas = 0;
+ //todo : MSG_DONTWAIT
+ rc = grn_com_send(ctx, peer, header,
+ GRN_BULK_HEAD(msg), GRN_BULK_VSIZE(msg), 0);
+ if (rc != GRN_OPERATION_WOULD_BLOCK) {
+ grn_com_queue_enque(ctx, m->old, (grn_com_queue_entry *)msg);
+ return rc;
+ }
+ }
+ break;
+ case GRN_COM_PROTO_MBREQ :
+ return GRN_FUNCTION_NOT_IMPLEMENTED;
+ case GRN_COM_PROTO_MBRES :
+ rc = grn_com_send(ctx, peer, header,
+ GRN_BULK_HEAD(msg), GRN_BULK_VSIZE(msg),
+ (flags & GRN_CTX_MORE) ? MSG_MORE :0);
+ if (rc != GRN_OPERATION_WOULD_BLOCK) {
+ grn_com_queue_enque(ctx, m->old, (grn_com_queue_entry *)msg);
+ return rc;
+ }
+ break;
+ default :
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+ MUTEX_LOCK(peer->ev->mutex);
+ rc = grn_com_queue_enque(ctx, &peer->new_, (grn_com_queue_entry *)msg);
+ COND_SIGNAL(peer->ev->cond);
+ MUTEX_UNLOCK(peer->ev->mutex);
+ return rc;
+}
+
+/******* grn_com ********/
+
+grn_rc
+grn_com_init(void)
+{
+#ifdef WIN32
+ WSADATA wd;
+ if (WSAStartup(MAKEWORD(2, 0), &wd) != 0) {
+ grn_ctx *ctx = &grn_gctx;
+ SOERR("WSAStartup");
+ }
+#else /* WIN32 */
+#ifndef USE_MSG_NOSIGNAL
+ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
+ grn_ctx *ctx = &grn_gctx;
+ SERR("signal");
+ }
+#endif /* USE_MSG_NOSIGNAL */
+#endif /* WIN32 */
+ return grn_gctx.rc;
+}
+
+void
+grn_com_fin(void)
+{
+#ifdef WIN32
+ WSACleanup();
+#endif /* WIN32 */
+}
+
+grn_rc
+grn_com_event_init(grn_ctx *ctx, grn_com_event *ev, int max_nevents, int data_size)
+{
+ ev->max_nevents = max_nevents;
+ if ((ev->hash = grn_hash_create(ctx, NULL, sizeof(grn_sock), data_size, 0))) {
+ 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))) {
+ if ((ev->epfd = epoll_create(max_nevents)) != -1) {
+ goto exit;
+ } else {
+ SERR("epoll_create");
+ }
+ GRN_FREE(ev->events);
+ }
+# else /* USE_EPOLL */
+# ifdef USE_KQUEUE
+ if ((ev->events = GRN_MALLOC(sizeof(struct kevent) * max_nevents))) {
+ if ((ev->kqfd = kqueue()) != -1) {
+ goto exit;
+ } else {
+ SERR("kqueue");
+ }
+ GRN_FREE(ev->events);
+ }
+# else /* USE_KQUEUE */
+ if ((ev->events = GRN_MALLOC(sizeof(struct pollfd) * max_nevents))) {
+ goto exit;
+ }
+# endif /* USE_KQUEUE*/
+# endif /* USE_EPOLL */
+ grn_hash_close(ctx, ev->hash);
+ ev->hash = NULL;
+ ev->events = NULL;
+#else /* USE_SELECT */
+ goto exit;
+#endif /* USE_SELECT */
+ }
+exit :
+ return ctx->rc;
+}
+
+grn_rc
+grn_com_event_fin(grn_ctx *ctx, grn_com_event *ev)
+{
+ grn_obj *msg;
+ while ((msg = (grn_obj *)grn_com_queue_deque(ctx, &ev->recv_old))) {
+ grn_msg_close(ctx, msg);
+ }
+ if (ev->hash) { grn_hash_close(ctx, ev->hash); }
+#ifndef USE_SELECT
+ if (ev->events) { GRN_FREE(ev->events); }
+# ifdef USE_EPOLL
+ grn_close(ev->epfd);
+# endif /* USE_EPOLL */
+# ifdef USE_KQUEUE
+ grn_close(ev->kqfd);
+# endif /* USE_KQUEUE*/
+#endif /* USE_SELECT */
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_com_event_add(grn_ctx *ctx, grn_com_event *ev, grn_sock fd, int events, grn_com **com)
+{
+ grn_com *c;
+ /* todo : expand events */
+ if (!ev || *ev->hash->n_entries == (uint32_t) ev->max_nevents) {
+ if (ev) { GRN_LOG(ctx, GRN_LOG_ERROR, "too many connections (%d)", ev->max_nevents); }
+ return GRN_INVALID_ARGUMENT;
+ }
+#ifdef USE_EPOLL
+ {
+ struct epoll_event e;
+ memset(&e, 0, sizeof(struct epoll_event));
+ e.data.fd = (fd);
+ e.events = (uint32_t) events;
+ if (epoll_ctl(ev->epfd, EPOLL_CTL_ADD, (fd), &e) == -1) {
+ SERR("epoll_ctl");
+ return ctx->rc;
+ }
+ }
+#endif /* USE_EPOLL*/
+#ifdef USE_KQUEUE
+ {
+ struct kevent e;
+ /* todo: udata should have fd */
+ EV_SET(&e, (fd), events, EV_ADD, 0, 0, NULL);
+ if (kevent(ev->kqfd, &e, 1, NULL, 0, NULL) == -1) {
+ SERR("kevent");
+ return ctx->rc;
+ }
+ }
+#endif /* USE_KQUEUE */
+ {
+ if (grn_hash_add(ctx, ev->hash, &fd, sizeof(grn_sock), (void **)&c, NULL)) {
+ c->ev = ev;
+ c->fd = fd;
+ c->events = events;
+ if (com) { *com = c; }
+ }
+ }
+ return ctx->rc;
+}
+
+grn_rc
+grn_com_event_mod(grn_ctx *ctx, grn_com_event *ev, grn_sock fd, int events, grn_com **com)
+{
+ grn_com *c;
+ if (!ev) { return GRN_INVALID_ARGUMENT; }
+ if (grn_hash_get(ctx, ev->hash, &fd, sizeof(grn_sock), (void **)&c)) {
+ if (c->fd != fd) {
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "grn_com_event_mod fd unmatch "
+ "%" GRN_FMT_SOCKET " != %" GRN_FMT_SOCKET,
+ c->fd, fd);
+ return GRN_OBJECT_CORRUPT;
+ }
+ if (com) { *com = c; }
+ if (c->events != events) {
+#ifdef USE_EPOLL
+ struct epoll_event e;
+ memset(&e, 0, sizeof(struct epoll_event));
+ e.data.fd = (fd);
+ e.events = (uint32_t) events;
+ if (epoll_ctl(ev->epfd, EPOLL_CTL_MOD, (fd), &e) == -1) {
+ SERR("epoll_ctl");
+ return ctx->rc;
+ }
+#endif /* USE_EPOLL*/
+#ifdef USE_KQUEUE
+ // experimental
+ struct kevent e[2];
+ EV_SET(&e[0], (fd), GRN_COM_POLLIN|GRN_COM_POLLOUT, EV_DELETE, 0, 0, NULL);
+ EV_SET(&e[1], (fd), events, EV_ADD, 0, 0, NULL);
+ if (kevent(ev->kqfd, e, 2, NULL, 0, NULL) == -1) {
+ SERR("kevent");
+ return ctx->rc;
+ }
+#endif /* USE_KQUEUE */
+ c->events = events;
+ }
+ return GRN_SUCCESS;
+ }
+ return GRN_INVALID_ARGUMENT;
+}
+
+grn_rc
+grn_com_event_del(grn_ctx *ctx, grn_com_event *ev, grn_sock fd)
+{
+ if (!ev) { return GRN_INVALID_ARGUMENT; }
+ {
+ grn_com *c;
+ grn_id id = grn_hash_get(ctx, ev->hash, &fd, sizeof(grn_sock), (void **)&c);
+ if (id) {
+#ifdef USE_EPOLL
+ if (!c->closed) {
+ struct epoll_event e;
+ memset(&e, 0, sizeof(struct epoll_event));
+ e.data.fd = fd;
+ e.events = c->events;
+ if (epoll_ctl(ev->epfd, EPOLL_CTL_DEL, fd, &e) == -1) {
+ SERR("epoll_ctl");
+ return ctx->rc;
+ }
+ }
+#endif /* USE_EPOLL*/
+#ifdef USE_KQUEUE
+ struct kevent e;
+ EV_SET(&e, (fd), c->events, EV_DELETE, 0, 0, NULL);
+ if (kevent(ev->kqfd, &e, 1, NULL, 0, NULL) == -1) {
+ SERR("kevent");
+ return ctx->rc;
+ }
+#endif /* USE_KQUEUE */
+ return grn_hash_delete_by_id(ctx, ev->hash, id, NULL);
+ } else {
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "%04x| fd(%" GRN_FMT_SOCKET ") not found in ev(%p)",
+ grn_getpid(), fd, ev);
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+}
+
+#define LISTEN_BACKLOG 0x1000
+
+grn_rc
+grn_com_event_start_accept(grn_ctx *ctx, grn_com_event *ev)
+{
+ grn_com *com = ev->acceptor;
+
+ if (com->accepting) {return ctx->rc;}
+
+ GRN_API_ENTER;
+ if (!grn_com_event_mod(ctx, ev, com->fd, GRN_COM_POLLIN, NULL)) {
+ if (listen(com->fd, LISTEN_BACKLOG) == 0) {
+ com->accepting = GRN_TRUE;
+ } else {
+ SOERR("listen - start accept");
+ }
+ }
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_rc
+grn_com_event_stop_accept(grn_ctx *ctx, grn_com_event *ev)
+{
+ grn_com *com = ev->acceptor;
+
+ if (!com->accepting) {return ctx->rc;}
+
+ GRN_API_ENTER;
+ if (!grn_com_event_mod(ctx, ev, com->fd, 0, NULL)) {
+ if (listen(com->fd, 0) == 0) {
+ com->accepting = GRN_FALSE;
+ } else {
+ SOERR("listen - disable accept");
+ }
+ }
+ GRN_API_RETURN(ctx->rc);
+}
+
+static void
+grn_com_receiver(grn_ctx *ctx, grn_com *com)
+{
+ grn_com_event *ev = com->ev;
+ ERRCLR(ctx);
+ if (ev->acceptor == com) {
+ grn_com *ncs;
+ grn_sock fd = accept(com->fd, NULL, NULL);
+ if (fd == -1) {
+ if (errno == EMFILE) {
+ grn_com_event_stop_accept(ctx, ev);
+ } else {
+ SOERR("accept");
+ }
+ return;
+ }
+ if (grn_com_event_add(ctx, ev, fd, GRN_COM_POLLIN, (grn_com **)&ncs)) {
+ grn_sock_close(fd);
+ return;
+ }
+ ncs->has_sid = 0;
+ ncs->closed = 0;
+ ncs->opaque = NULL;
+ GRN_COM_QUEUE_INIT(&ncs->new_);
+ // GRN_LOG(ctx, GRN_LOG_NOTICE, "accepted (%d)", fd);
+ return;
+ } else {
+ grn_msg *msg = (grn_msg *)grn_msg_open(ctx, com, &ev->recv_old);
+ grn_com_recv(ctx, msg->u.peer, &msg->header, (grn_obj *)msg);
+ if (msg->u.peer /* is_edge_request(msg)*/) {
+ grn_memcpy(&msg->edge_id, &ev->curr_edge_id, sizeof(grn_com_addr));
+ if (!com->has_sid) {
+ com->has_sid = 1;
+ com->sid = ev->curr_edge_id.sid++;
+ }
+ msg->edge_id.sid = com->sid;
+ }
+ msg->acceptor = ev->acceptor;
+ ev->msg_handler(ctx, (grn_obj *)msg);
+ }
+}
+
+grn_rc
+grn_com_event_poll(grn_ctx *ctx, grn_com_event *ev, int timeout)
+{
+ int nevents;
+ grn_com *com;
+#ifdef USE_SELECT
+ uint32_t dummy;
+ grn_sock *pfd;
+ int nfds = 0;
+ fd_set rfds;
+ fd_set wfds;
+ struct timeval tv;
+ if (timeout >= 0) {
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+ }
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
+ ctx->errlvl = GRN_OK;
+ ctx->rc = GRN_SUCCESS;
+ {
+ grn_hash_cursor *cursor;
+ cursor = grn_hash_cursor_open(ctx, ev->hash, NULL, 0, NULL, 0, 0, -1, 0);
+ if (cursor) {
+ grn_id id;
+ while ((id = grn_hash_cursor_next(ctx, cursor))) {
+ grn_hash_cursor_get_key_value(ctx,
+ cursor,
+ (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); }
+# ifndef WIN32
+ if (*pfd > nfds) { nfds = *pfd; }
+# endif /* WIN32 */
+ }
+ grn_hash_cursor_close(ctx, cursor);
+ }
+ }
+ nevents = select(nfds + 1, &rfds, &wfds, NULL, (timeout >= 0) ? &tv : NULL);
+ if (nevents < 0) {
+ SOERR("select");
+ if (ctx->rc == GRN_INTERRUPTED_FUNCTION_CALL) { ERRCLR(ctx); }
+ return ctx->rc;
+ }
+ if (timeout < 0 && !nevents) { GRN_LOG(ctx, GRN_LOG_NOTICE, "select returns 0 events"); }
+ GRN_HASH_EACH(ctx, ev->hash, eh, &pfd, &dummy, &com, {
+ if (FD_ISSET(*pfd, &rfds)) { grn_com_receiver(ctx, com); }
+ });
+#else /* USE_SELECT */
+# ifdef USE_EPOLL
+ struct epoll_event *ep;
+ ctx->errlvl = GRN_OK;
+ ctx->rc = GRN_SUCCESS;
+ nevents = epoll_wait(ev->epfd, ev->events, ev->max_nevents, timeout);
+ if (nevents < 0) {
+ SERR("epoll_wait");
+ }
+# else /* USE_EPOLL */
+# ifdef USE_KQUEUE
+ struct kevent *ep;
+ struct timespec tv;
+ if (timeout >= 0) {
+ tv.tv_sec = timeout / 1000;
+ tv.tv_nsec = (timeout % 1000) * 1000;
+ }
+ nevents = kevent(ev->kqfd, NULL, 0, ev->events, ev->max_nevents, &tv);
+ if (nevents < 0) {
+ SERR("kevent");
+ }
+# else /* USE_KQUEUE */
+ uint32_t dummy;
+ int nfd = 0, *pfd;
+ struct pollfd *ep = ev->events;
+ ctx->errlvl = GRN_OK;
+ ctx->rc = GRN_SUCCESS;
+ GRN_HASH_EACH(ctx, ev->hash, eh, &pfd, &dummy, &com, {
+ ep->fd = *pfd;
+ // ep->events =(short) com->events;
+ ep->events = POLLIN;
+ ep->revents = 0;
+ ep++;
+ nfd++;
+ });
+ nevents = poll(ev->events, nfd, timeout);
+ if (nevents < 0) {
+ SERR("poll");
+ }
+# endif /* USE_KQUEUE */
+# endif /* USE_EPOLL */
+ if (ctx->rc != GRN_SUCCESS) {
+ if (ctx->rc == GRN_INTERRUPTED_FUNCTION_CALL) {
+ ERRCLR(ctx);
+ }
+ return ctx->rc;
+ }
+ if (timeout < 0 && !nevents) { GRN_LOG(ctx, GRN_LOG_NOTICE, "poll returns 0 events"); }
+ for (ep = ev->events; nevents; ep++) {
+ int efd;
+# ifdef USE_EPOLL
+ efd = ep->data.fd;
+ nevents--;
+ // todo : com = ep->data.ptr;
+ if (!grn_hash_get(ctx, ev->hash, &efd, sizeof(grn_sock), (void *)&com)) {
+ struct epoll_event e;
+ GRN_LOG(ctx, GRN_LOG_ERROR, "fd(%d) not found in ev->hash", efd);
+ memset(&e, 0, sizeof(struct epoll_event));
+ e.data.fd = efd;
+ e.events = ep->events;
+ if (epoll_ctl(ev->epfd, EPOLL_CTL_DEL, efd, &e) == -1) { SERR("epoll_ctl"); }
+ if (grn_sock_close(efd) == -1) { SOERR("close"); }
+ continue;
+ }
+ if (ep->events & GRN_COM_POLLIN) { grn_com_receiver(ctx, com); }
+# else /* USE_EPOLL */
+# ifdef USE_KQUEUE
+ efd = ep->ident;
+ nevents--;
+ // todo : com = ep->udata;
+ if (!grn_hash_get(ctx, ev->hash, &efd, sizeof(grn_sock), (void *)&com)) {
+ struct kevent e;
+ GRN_LOG(ctx, GRN_LOG_ERROR, "fd(%d) not found in ev->set", efd);
+ EV_SET(&e, efd, ep->filter, EV_DELETE, 0, 0, NULL);
+ if (kevent(ev->kqfd, &e, 1, NULL, 0, NULL) == -1) { SERR("kevent"); }
+ if (grn_sock_close(efd) == -1) { SOERR("close"); }
+ continue;
+ }
+ if (ep->filter == GRN_COM_POLLIN) { grn_com_receiver(ctx, com); }
+# else
+ efd = ep->fd;
+ if (!(ep->events & ep->revents)) { continue; }
+ nevents--;
+ if (!grn_hash_get(ctx, ev->hash, &efd, sizeof(grn_sock), (void *)&com)) {
+ GRN_LOG(ctx, GRN_LOG_ERROR, "fd(%d) not found in ev->hash", efd);
+ if (grn_sock_close(efd) == -1) { SOERR("close"); }
+ continue;
+ }
+ if (ep->revents & GRN_COM_POLLIN) { grn_com_receiver(ctx, com); }
+# endif /* USE_KQUEUE */
+# endif /* USE_EPOLL */
+ }
+#endif /* USE_SELECT */
+ /* todo :
+ while (!(msg = (grn_com_msg *)grn_com_queue_deque(&recv_old))) {
+ grn_msg_close(ctx, msg);
+ }
+ */
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_com_send_http(grn_ctx *ctx, grn_com *cs, const char *path, uint32_t path_len, int flags)
+{
+ ssize_t ret;
+ grn_obj buf;
+ GRN_TEXT_INIT(&buf, 0);
+ GRN_TEXT_PUTS(ctx, &buf, "GET ");
+ grn_bulk_write(ctx, &buf, path, path_len);
+ GRN_TEXT_PUTS(ctx, &buf, " HTTP/1.0\r\n\r\n");
+ // todo : refine
+ if ((ret = send(cs->fd, GRN_BULK_HEAD(&buf), GRN_BULK_VSIZE(&buf), MSG_NOSIGNAL|flags)) == -1) {
+ SOERR("send");
+ }
+ if (ret != GRN_BULK_VSIZE(&buf)) {
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "send %d != %d", (int)ret, (int)GRN_BULK_VSIZE(&buf));
+ }
+ grn_obj_close(ctx, &buf);
+ return ctx->rc;
+}
+
+grn_rc
+grn_com_send(grn_ctx *ctx, grn_com *cs,
+ grn_com_header *header, const char *body, uint32_t size, int flags)
+{
+ grn_rc rc = GRN_SUCCESS;
+ size_t whole_size = sizeof(grn_com_header) + size;
+ ssize_t ret;
+ header->size = htonl(size);
+ GRN_LOG(ctx, GRN_LOG_INFO, "send (%d,%x,%d,%02x,%02x,%04x)", size, header->flags, header->proto, header->qtype, header->level, header->status);
+
+ if (size) {
+#ifdef WIN32
+ WSABUF wsabufs[2];
+ DWORD n_sent;
+ wsabufs[0].buf = (char *)header;
+ wsabufs[0].len = sizeof(grn_com_header);
+ wsabufs[1].buf = (char *)body;
+ wsabufs[1].len = size;
+ if (WSASend(cs->fd, wsabufs, 2, &n_sent, 0, NULL, NULL) == SOCKET_ERROR) {
+ SOERR("WSASend");
+ }
+ ret = n_sent;
+#else /* WIN32 */
+ struct iovec msg_iov[2];
+ struct msghdr msg;
+ memset(&msg, 0, sizeof(struct msghdr));
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = msg_iov;
+ msg.msg_iovlen = 2;
+ msg_iov[0].iov_base = (char*) header;
+ msg_iov[0].iov_len = sizeof(grn_com_header);
+ msg_iov[1].iov_base = (char *)body;
+ msg_iov[1].iov_len = size;
+ if ((ret = sendmsg(cs->fd, &msg, MSG_NOSIGNAL|flags)) == -1) {
+ SOERR("sendmsg");
+ rc = ctx->rc;
+ }
+#endif /* WIN32 */
+ } else {
+ if ((ret = send(cs->fd, (const void *)header, whole_size, MSG_NOSIGNAL|flags)) == -1) {
+ SOERR("send");
+ rc = ctx->rc;
+ }
+ }
+ if ((size_t) ret != whole_size) {
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "sendmsg(%" GRN_FMT_SOCKET "): %" GRN_FMT_LLD " < %" GRN_FMT_LLU,
+ cs->fd, (long long int)ret, (unsigned long long int)whole_size);
+ rc = ctx->rc;
+ }
+ return rc;
+}
+
+#define RETRY_MAX 10
+
+static const char *
+scan_delimiter(const char *p, const char *e)
+{
+ while (p + 4 <= e) {
+ if (p[3] == '\n') {
+ if (p[2] == '\r') {
+ if (p[1] == '\n') {
+ if (p[0] == '\r') { return p + 4; } else { p += 2; }
+ } else { p += 2; }
+ } else { p += 4; }
+ } else { p += p[3] == '\r' ? 1 : 4; }
+ }
+ return NULL;
+}
+
+#define BUFSIZE 4096
+
+static grn_rc
+grn_com_recv_text(grn_ctx *ctx, grn_com *com,
+ grn_com_header *header, grn_obj *buf, ssize_t ret)
+{
+ const char *p;
+ int retry = 0;
+ grn_bulk_write(ctx, buf, (char *)header, ret);
+ if ((p = scan_delimiter(GRN_BULK_HEAD(buf), GRN_BULK_CURR(buf)))) {
+ header->qtype = *GRN_BULK_HEAD(buf);
+ header->proto = GRN_COM_PROTO_HTTP;
+ header->size = GRN_BULK_VSIZE(buf);
+ goto exit;
+ }
+ for (;;) {
+ if (grn_bulk_reserve(ctx, buf, BUFSIZE)) { return ctx->rc; }
+ if ((ret = recv(com->fd, GRN_BULK_CURR(buf), BUFSIZE, 0)) < 0) {
+ SOERR("recv text");
+ if (ctx->rc == GRN_OPERATION_WOULD_BLOCK ||
+ ctx->rc == GRN_INTERRUPTED_FUNCTION_CALL) {
+ ERRCLR(ctx);
+ continue;
+ }
+ goto exit;
+ }
+ if (ret) {
+ off_t o = GRN_BULK_VSIZE(buf);
+ p = GRN_BULK_CURR(buf);
+ GRN_BULK_INCR_LEN(buf, ret);
+ if (scan_delimiter(p - (o > 3 ? 3 : o), p + ret)) {
+ break;
+ }
+ } else {
+ if (++retry > RETRY_MAX) {
+ // ERR(GRN_RETRY_MAX, "retry max in recv text");
+ goto exit;
+ }
+ }
+ }
+ header->qtype = *GRN_BULK_HEAD(buf);
+ header->proto = GRN_COM_PROTO_HTTP;
+ header->size = GRN_BULK_VSIZE(buf);
+exit :
+ if (header->qtype == 'H') {
+ //todo : refine
+ /*
+ GRN_BULK_REWIND(buf);
+ grn_bulk_reserve(ctx, buf, BUFSIZE);
+ if ((ret = recv(com->fd, GRN_BULK_CURR(buf), BUFSIZE, 0)) < 0) {
+ SOERR("recv text body");
+ } else {
+ GRN_BULK_CURR(buf) += ret;
+ }
+ */
+ }
+ return ctx->rc;
+}
+
+grn_rc
+grn_com_recv(grn_ctx *ctx, grn_com *com, grn_com_header *header, grn_obj *buf)
+{
+ ssize_t ret;
+ int retry = 0;
+ byte *p = (byte *)header;
+ size_t rest = sizeof(grn_com_header);
+ do {
+ if ((ret = recv(com->fd, p, rest, 0)) < 0) {
+ SOERR("recv size");
+ GRN_LOG(ctx, GRN_LOG_ERROR, "recv error (%" GRN_FMT_SOCKET ")", com->fd);
+ if (ctx->rc == GRN_OPERATION_WOULD_BLOCK ||
+ ctx->rc == GRN_INTERRUPTED_FUNCTION_CALL) {
+ ERRCLR(ctx);
+ continue;
+ }
+ goto exit;
+ }
+ if (ret) {
+ if (header->proto < 0x80) {
+ return grn_com_recv_text(ctx, com, header, buf, ret);
+ }
+ rest -= ret, p += ret;
+ } else {
+ if (++retry > RETRY_MAX) {
+ // ERR(GRN_RETRY_MAX, "retry max in recv header (%d)", com->fd);
+ goto exit;
+ }
+ }
+ } while (rest);
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "recv (%u,%x,%d,%02x,%02x,%04x)",
+ (uint32_t)ntohl(header->size),
+ header->flags,
+ header->proto,
+ header->qtype,
+ header->level,
+ header->status);
+ {
+ uint8_t proto = header->proto;
+ size_t value_size = ntohl(header->size);
+ GRN_BULK_REWIND(buf);
+ switch (proto) {
+ 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)) {
+ goto exit;
+ }
+ }
+ retry = 0;
+ for (rest = value_size; rest;) {
+ if ((ret = recv(com->fd, GRN_BULK_CURR(buf), rest, MSG_WAITALL)) < 0) {
+ SOERR("recv body");
+ if (ctx->rc == GRN_OPERATION_WOULD_BLOCK ||
+ ctx->rc == GRN_INTERRUPTED_FUNCTION_CALL) {
+ ERRCLR(ctx);
+ continue;
+ }
+ goto exit;
+ }
+ if (ret) {
+ rest -= ret;
+ GRN_BULK_INCR_LEN(buf, ret);
+ } else {
+ if (++retry > RETRY_MAX) {
+ // ERR(GRN_RETRY_MAX, "retry max in recv body");
+ goto exit;
+ }
+ }
+ }
+ break;
+ default :
+ GRN_LOG(ctx, GRN_LOG_ERROR, "illegal header: %d", proto);
+ ctx->rc = GRN_INVALID_FORMAT;
+ goto exit;
+ }
+ }
+exit :
+ return ctx->rc;
+}
+
+grn_com *
+grn_com_copen(grn_ctx *ctx, grn_com_event *ev, const char *dest, int port)
+{
+ grn_sock fd = -1;
+ grn_com *cs = NULL;
+
+ struct addrinfo hints, *addrinfo_list, *addrinfo_ptr;
+ char port_string[16];
+ int getaddrinfo_result;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+#ifdef AI_NUMERICSERV
+ hints.ai_flags = AI_NUMERICSERV;
+#endif
+ grn_snprintf(port_string, sizeof(port_string), sizeof(port_string),
+ "%d", port);
+
+ getaddrinfo_result = getaddrinfo(dest, port_string, &hints, &addrinfo_list);
+ if (getaddrinfo_result != 0) {
+ switch (getaddrinfo_result) {
+#ifdef EAI_MEMORY
+ case EAI_MEMORY:
+ ERR(GRN_NO_MEMORY_AVAILABLE, "getaddrinfo: <%s:%s>: %s",
+ dest, port_string, gai_strerror(getaddrinfo_result));
+ break;
+#endif
+#ifdef EAI_SYSTEM
+ case EAI_SYSTEM:
+ SOERR("getaddrinfo");
+ break;
+#endif
+ default:
+ ERR(GRN_INVALID_ARGUMENT, "getaddrinfo: <%s:%s>: %s",
+ dest, port_string, gai_strerror(getaddrinfo_result));
+ break;
+ }
+ return NULL;
+ }
+
+ for (addrinfo_ptr = addrinfo_list; addrinfo_ptr;
+ addrinfo_ptr = addrinfo_ptr->ai_next) {
+ fd = socket(addrinfo_ptr->ai_family, addrinfo_ptr->ai_socktype,
+ addrinfo_ptr->ai_protocol);
+ if (fd == -1) {
+ SOERR("socket");
+ 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);
+ continue;
+ }
+
+ break;
+ }
+
+ freeaddrinfo(addrinfo_list);
+
+ if (!addrinfo_ptr) {
+ return NULL;
+ }
+ ctx->errlvl = GRN_OK;
+ ctx->rc = GRN_SUCCESS;
+
+ if (ev) {
+ grn_com_event_add(ctx, ev, fd, GRN_COM_POLLIN, &cs);
+ } else {
+ cs = GRN_CALLOC(sizeof(grn_com));
+ if (cs) {
+ cs->fd = fd;
+ }
+ }
+ if (!cs) {
+ grn_sock_close(fd);
+ }
+ return cs;
+}
+
+void
+grn_com_close_(grn_ctx *ctx, grn_com *com)
+{
+ grn_sock fd = com->fd;
+ if (shutdown(fd, SHUT_RDWR) == -1) { /* SOERR("shutdown"); */ }
+ if (grn_sock_close(fd) == -1) {
+ SOERR("close");
+ } else {
+ com->closed = 1;
+ }
+}
+
+grn_rc
+grn_com_close(grn_ctx *ctx, grn_com *com)
+{
+ grn_sock fd = com->fd;
+ grn_com_event *ev = com->ev;
+ if (ev) {
+ grn_com *acceptor = ev->acceptor;
+ grn_com_event_del(ctx, ev, fd);
+ if (acceptor) { grn_com_event_start_accept(ctx, ev); }
+ }
+ if (!com->closed) { grn_com_close_(ctx, com); }
+ if (!ev) { GRN_FREE(com); }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_com_sopen(grn_ctx *ctx, grn_com_event *ev,
+ const char *bind_address, int port, grn_msg_handler *func,
+ struct hostent *he)
+{
+ grn_sock lfd = -1;
+ grn_com *cs = NULL;
+ int getaddrinfo_result;
+ struct addrinfo *bind_address_info = NULL;
+ struct addrinfo hints;
+ char port_string[6]; /* ceil(log10(65535)) + 1 ('\0')*/
+
+ GRN_API_ENTER;
+ if (!bind_address) {
+ bind_address = "0.0.0.0";
+ }
+ grn_snprintf(port_string, sizeof(port_string), sizeof(port_string),
+ "%d", port);
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+#ifdef AI_NUMERICSERV
+ hints.ai_flags = AI_NUMERICSERV;
+#endif
+ getaddrinfo_result = getaddrinfo(bind_address, port_string,
+ &hints, &bind_address_info);
+ if (getaddrinfo_result != 0) {
+ switch (getaddrinfo_result) {
+#ifdef EAI_MEMORY
+ case EAI_MEMORY:
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "getaddrinfo: <%s:%s>: %s",
+ bind_address, port_string, gai_strerror(getaddrinfo_result));
+ break;
+#endif
+#ifdef EAI_SYSTEM
+ case EAI_SYSTEM:
+ SOERR("getaddrinfo");
+ break;
+#endif
+ default:
+ ERR(GRN_INVALID_ARGUMENT,
+ "getaddrinfo: <%s:%s>: %s",
+ bind_address, port_string, gai_strerror(getaddrinfo_result));
+ break;
+ }
+ goto exit;
+ }
+ if ((lfd = socket(bind_address_info->ai_family, SOCK_STREAM, 0)) == -1) {
+ SOERR("socket");
+ goto exit;
+ }
+ grn_memcpy(&ev->curr_edge_id.addr, he->h_addr, he->h_length);
+ ev->curr_edge_id.port = htons(port);
+ 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;
+ }
+ }
+ if (bind(lfd, bind_address_info->ai_addr, bind_address_info->ai_addrlen) < 0) {
+ SOERR("bind");
+ goto exit;
+ }
+ if (listen(lfd, LISTEN_BACKLOG) < 0) {
+ SOERR("listen");
+ goto exit;
+ }
+ if (ev) {
+ if (grn_com_event_add(ctx, ev, lfd, GRN_COM_POLLIN, &cs)) { goto exit; }
+ ev->acceptor = cs;
+ ev->msg_handler = func;
+ cs->has_sid = 0;
+ cs->closed = 0;
+ cs->opaque = NULL;
+ GRN_COM_QUEUE_INIT(&cs->new_);
+ } else {
+ if (!(cs = GRN_MALLOC(sizeof(grn_com)))) { goto exit; }
+ cs->fd = lfd;
+ }
+ cs->accepting = GRN_TRUE;
+exit :
+ if (!cs && lfd != 1) { grn_sock_close(lfd); }
+ if (bind_address_info) { freeaddrinfo(bind_address_info); }
+ GRN_API_RETURN(ctx->rc);
+}
+
+
+grn_hash *grn_edges = NULL;
+void (*grn_dispatcher)(grn_ctx *ctx, grn_edge *edge);
+
+void
+grn_edges_init(grn_ctx *ctx, void (*dispatcher)(grn_ctx *ctx, grn_edge *edge))
+{
+ grn_edges = grn_hash_create(ctx, NULL, sizeof(grn_com_addr), sizeof(grn_edge), 0);
+ grn_dispatcher = dispatcher;
+}
+
+void
+grn_edges_fin(grn_ctx *ctx)
+{
+ grn_hash_close(ctx, grn_edges);
+}
+
+grn_edge *
+grn_edges_add(grn_ctx *ctx, grn_com_addr *addr, int *added)
+{
+ if (grn_io_lock(ctx, grn_edges->io, grn_lock_timeout)) {
+ return NULL;
+ } else {
+ grn_edge *edge;
+ grn_id id = grn_hash_add(ctx, grn_edges, addr, sizeof(grn_com_addr),
+ (void **)&edge, added);
+ grn_io_unlock(grn_edges->io);
+ if (id) { edge->id = id; }
+ return edge;
+ }
+}
+
+void
+grn_edges_delete(grn_ctx *ctx, grn_edge *edge)
+{
+ if (!grn_io_lock(ctx, grn_edges->io, grn_lock_timeout)) {
+ grn_hash_delete_by_id(ctx, grn_edges, edge->id, NULL);
+ grn_io_unlock(grn_edges->io);
+ }
+}
+
+grn_edge *
+grn_edges_add_communicator(grn_ctx *ctx, grn_com_addr *addr)
+{
+ int added;
+ grn_edge *edge = grn_edges_add(ctx, addr, &added);
+ if (added) {
+ grn_ctx_init(&edge->ctx, 0);
+ GRN_COM_QUEUE_INIT(&edge->recv_new);
+ GRN_COM_QUEUE_INIT(&edge->send_old);
+ edge->com = NULL;
+ edge->stat = 0 /*EDGE_IDLE*/;
+ edge->flags = GRN_EDGE_COMMUNICATOR;
+ }
+ return edge;
+}
+
+void
+grn_edge_dispatch(grn_ctx *ctx, grn_edge *edge, grn_obj *msg)
+{
+ grn_com_queue_enque(ctx, &edge->recv_new, (grn_com_queue_entry *)msg);
+ grn_dispatcher(ctx, edge);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/command.c b/storage/mroonga/vendor/groonga/lib/command.c
new file mode 100644
index 00000000..3da5871b
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/command.c
@@ -0,0 +1,201 @@
+/* -*- 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-1335 USA
+*/
+
+#include <string.h>
+
+#include "grn.h"
+#include "grn_db.h"
+#include "grn_ctx_impl.h"
+
+struct _grn_command_input {
+ grn_obj *command;
+ grn_hash *arguments;
+};
+
+grn_command_input *
+grn_command_input_open(grn_ctx *ctx, grn_obj *command)
+{
+ grn_command_input *input = NULL;
+
+ GRN_API_ENTER;
+ input = GRN_MALLOC(sizeof(grn_command_input));
+ if (!input) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[command-input] failed to allocate grn_command_input");
+ goto exit;
+ }
+
+ input->command = command;
+ /* TODO: Allocate by self. */
+ {
+ uint32_t n;
+ input->arguments = grn_expr_get_vars(ctx, input->command, &n);
+ }
+
+exit :
+ GRN_API_RETURN(input);
+}
+
+grn_rc
+grn_command_input_close(grn_ctx *ctx, grn_command_input *input)
+{
+ GRN_API_ENTER;
+
+ /* TODO: Free input->arguments by self. */
+ /* grn_expr_clear_vars(ctx, input->command); */
+ GRN_FREE(input);
+
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_obj *
+grn_command_input_add(grn_ctx *ctx,
+ grn_command_input *input,
+ const char *name,
+ int name_size,
+ grn_bool *added)
+{
+ grn_obj *argument = NULL;
+ /* TODO: Use grn_bool */
+ int internal_added = GRN_FALSE;
+
+ GRN_API_ENTER;
+
+ if (name_size == -1) {
+ name_size = strlen(name);
+ }
+ if (input->arguments) {
+ grn_hash_add(ctx, input->arguments, name, name_size, (void **)&argument,
+ &internal_added);
+ if (internal_added) {
+ GRN_TEXT_INIT(argument, 0);
+ }
+ }
+ if (added) {
+ *added = internal_added;
+ }
+
+ GRN_API_RETURN(argument);
+}
+
+grn_obj *
+grn_command_input_get(grn_ctx *ctx,
+ grn_command_input *input,
+ const char *name,
+ int name_size)
+{
+ grn_obj *argument = NULL;
+
+ GRN_API_ENTER;
+
+ if (name_size == -1) {
+ name_size = strlen(name);
+ }
+ if (input->arguments) {
+ grn_hash_get(ctx, input->arguments, name, name_size, (void **)&argument);
+ }
+
+ GRN_API_RETURN(argument);
+}
+
+grn_obj *
+grn_command_input_at(grn_ctx *ctx,
+ grn_command_input *input,
+ unsigned int offset)
+{
+ grn_obj *argument = NULL;
+
+ GRN_API_ENTER;
+ if (input->arguments) {
+ argument = (grn_obj *)grn_hash_get_value_(ctx, input->arguments,
+ offset + 1, NULL);
+ }
+ GRN_API_RETURN(argument);
+}
+
+grn_obj *
+grn_command_input_get_arguments(grn_ctx *ctx,
+ grn_command_input *input)
+{
+ GRN_API_ENTER;
+ GRN_API_RETURN((grn_obj *)(input->arguments));
+}
+
+grn_rc
+grn_command_register(grn_ctx *ctx,
+ const char *command_name,
+ int command_name_size,
+ grn_command_run_func *run,
+ grn_expr_var *vars,
+ unsigned int n_vars,
+ void *user_data)
+{
+ GRN_API_ENTER;
+
+ if (command_name_size == -1) {
+ command_name_size = strlen(command_name);
+ }
+
+ {
+ grn_obj *command_object;
+ command_object = grn_proc_create(ctx,
+ command_name,
+ command_name_size,
+ GRN_PROC_COMMAND,
+ NULL, NULL, NULL, n_vars, vars);
+ if (!command_object) {
+ GRN_PLUGIN_ERROR(ctx, GRN_COMMAND_ERROR,
+ "[command][%.*s] failed to grn_proc_create()",
+ command_name_size, command_name);
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ {
+ grn_proc *command = (grn_proc *)command_object;
+ command->callbacks.command.run = run;
+ command->user_data = user_data;
+ }
+ }
+
+ GRN_API_RETURN(GRN_SUCCESS);
+}
+
+grn_rc
+grn_command_run(grn_ctx *ctx,
+ grn_obj *command,
+ grn_command_input *input)
+{
+ grn_proc *proc;
+
+ GRN_API_ENTER;
+
+ proc = (grn_proc *)command;
+ if (proc->callbacks.command.run) {
+ proc->callbacks.command.run(ctx, command, input, proc->user_data);
+ } else {
+ /* TODO: REMOVE ME. For backward compatibility. */
+ uint32_t stack_curr = ctx->impl->stack_curr;
+ grn_proc_call(ctx, command, 0, command);
+ if (ctx->impl->stack_curr > stack_curr) {
+ grn_ctx_pop(ctx);
+ }
+ }
+
+ GRN_API_RETURN(ctx->rc);
+}
+
diff --git a/storage/mroonga/vendor/groonga/lib/config.c b/storage/mroonga/vendor/groonga/lib/config.c
new file mode 100644
index 00000000..6664e127
--- /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-1335 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 > (int32_t) 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 00000000..c1d09a97
--- /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
new file mode 100644
index 00000000..1fd912d4
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ctx.c
@@ -0,0 +1,1873 @@
+/* -*- 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-1335 USA
+*/
+
+#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"
+#include "grn_output.h"
+#include "grn_normalizer.h"
+#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 */
+
+#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, \
+ {NULL, NULL,NULL, NULL,NULL, NULL,NULL, NULL,NULL, NULL,NULL, NULL,NULL, NULL,NULL, NULL}, ""}
+
+#define GRN_CTX_CLOSED(ctx) ((ctx)->stat == GRN_CTX_FIN)
+
+grn_ctx grn_gctx = GRN_CTX_INITIALIZER(GRN_ENC_DEFAULT);
+int grn_pagesize;
+grn_critical_section grn_glock;
+uint32_t grn_gtick;
+int grn_lock_timeout = GRN_LOCK_TIMEOUT;
+
+#ifdef USE_UYIELD
+int grn_uyield_count = 0;
+#endif
+
+static grn_bool grn_ctx_per_db = GRN_FALSE;
+
+static void
+grn_init_from_env(void)
+{
+ {
+ char grn_ctx_per_db_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_CTX_PER_DB",
+ grn_ctx_per_db_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_ctx_per_db_env[0] && strcmp(grn_ctx_per_db_env, "yes") == 0) {
+ grn_ctx_per_db = GRN_TRUE;
+ }
+ }
+
+ 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)
+{
+#ifdef WIN32
+ Sleep(seconds * 1000);
+#else // WIN32
+ sleep(seconds);
+#endif // WIN32
+}
+
+void
+grn_nanosleep(uint64_t nanoseconds)
+{
+#ifdef WIN32
+ Sleep((DWORD)(nanoseconds / 1000000));
+#else // WIN32
+ struct timespec interval;
+ interval.tv_sec = (time_t)(nanoseconds / 1000000000);
+ interval.tv_nsec = (long)(nanoseconds % 1000000000);
+ nanosleep(&interval, NULL);
+#endif // WIN32
+}
+
+const char *
+grn_get_global_error_message(void)
+{
+ return grn_gctx.errbuf;
+}
+
+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;
+ loader->ifexists = NULL;
+ loader->each = NULL;
+ 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
+grn_ctx_loader_clear(grn_ctx *ctx)
+{
+ grn_loader *loader = &ctx->impl->loader;
+ grn_obj *v = (grn_obj *)(GRN_BULK_HEAD(&loader->values));
+ grn_obj *ve = (grn_obj *)(GRN_BULK_CURR(&loader->values));
+ grn_obj **p = (grn_obj **)GRN_BULK_HEAD(&loader->columns);
+ uint32_t i = GRN_BULK_VSIZE(&loader->columns) / sizeof(grn_obj *);
+ if (ctx->impl->db) { while (i--) { grn_obj_unlink(ctx, *p++); } }
+ if (loader->ifexists) { grn_obj_unlink(ctx, loader->ifexists); }
+ if (loader->each) { grn_obj_unlink(ctx, loader->each); }
+ while (v < ve) { GRN_OBJ_FIN(ctx, v++); }
+ 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);
+}
+
+#define IMPL_SIZE ((sizeof(struct _grn_ctx_impl) + (grn_pagesize - 1)) & ~(grn_pagesize - 1))
+
+#ifdef GRN_WITH_MESSAGE_PACK
+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->output.buf, buf, len);
+}
+#endif
+
+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))) {
+ return ctx->rc;
+ }
+ grn_alloc_init_ctx_impl(ctx);
+ ctx->impl->encoding = ctx->encoding;
+ ctx->impl->lifoseg = -1;
+ ctx->impl->currseg = -1;
+ CRITICAL_SECTION_INIT(ctx->impl->lock);
+ if (!(ctx->impl->values = grn_array_create(ctx, NULL, sizeof(grn_db_obj *),
+ GRN_ARRAY_TINY))) {
+ CRITICAL_SECTION_FIN(ctx->impl->lock);
+ grn_io_anon_unmap(ctx, &mi, IMPL_SIZE);
+ ctx->impl = NULL;
+ 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 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;
+ 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->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;
+ } else {
+ 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 =
+ GRN_DEFAULT_MATCH_ESCALATION_THRESHOLD;
+ } else {
+ ctx->impl->match_escalation_threshold =
+ grn_get_default_match_escalation_threshold();
+ }
+
+ ctx->impl->finalizer = NULL;
+
+ ctx->impl->com = 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;
+ grn_loader_init(&ctx->impl->loader);
+ ctx->impl->plugin_path = NULL;
+
+ GRN_TEXT_INIT(&ctx->impl->query_log_buf, 0);
+
+ ctx->impl->previous_errbuf[0] = '\0';
+ ctx->impl->n_same_error_messages = 0;
+
+ 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_keep_command(grn_ctx *ctx, grn_obj *command)
+{
+ ctx->impl->command.keep.command = command;
+ ctx->impl->command.keep.version = ctx->impl->command.version;
+}
+
+static void
+grn_ctx_impl_clear_n_same_error_messagges(grn_ctx *ctx)
+{
+ if (ctx->impl->n_same_error_messages == 0) {
+ return;
+ }
+
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "(%u same messages are truncated)",
+ ctx->impl->n_same_error_messages);
+ ctx->impl->n_same_error_messages = 0;
+}
+
+grn_bool
+grn_ctx_impl_should_log(grn_ctx *ctx)
+{
+ if (!ctx->impl) {
+ return GRN_TRUE;
+ }
+
+ if (strcmp(ctx->errbuf, ctx->impl->previous_errbuf) == 0) {
+ ctx->impl->n_same_error_messages++;
+ return GRN_FALSE;
+ }
+
+ return GRN_TRUE;
+}
+
+void
+grn_ctx_impl_set_current_error_message(grn_ctx *ctx)
+{
+ if (!ctx->impl) {
+ return;
+ }
+
+ grn_ctx_impl_clear_n_same_error_messagges(ctx);
+ grn_strcpy(ctx->impl->previous_errbuf, GRN_CTX_MSGSIZE, ctx->errbuf);
+}
+
+static grn_rc
+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;
+ }
+ ctx->stat = GRN_CTX_INITED;
+ ctx->encoding = grn_gctx.encoding;
+ ctx->seqno = 0;
+ ctx->seqno2 = 0;
+ ctx->subno = 0;
+ ctx->impl = NULL;
+ ctx->user_data.ptr = NULL;
+ CRITICAL_SECTION_ENTER(grn_glock);
+ ctx->next = grn_gctx.next;
+ ctx->prev = &grn_gctx;
+ grn_gctx.next->prev = ctx;
+ grn_gctx.next = ctx;
+ CRITICAL_SECTION_LEAVE(grn_glock);
+ ctx->errline = 0;
+ ctx->errfile = "";
+ ctx->errfunc = "";
+ ctx->trace[0] = NULL;
+ ctx->errbuf[0] = '\0';
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ctx_init(grn_ctx *ctx, int flags)
+{
+ grn_rc rc;
+
+ rc = grn_ctx_init_internal(ctx, 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;
+}
+
+grn_ctx *
+grn_ctx_open(int flags)
+{
+ grn_ctx *ctx = GRN_GMALLOCN(grn_ctx, 1);
+ if (ctx) {
+ grn_ctx_init(ctx, flags|GRN_CTX_ALLOCATED);
+ if (ERRP(ctx, GRN_ERROR)) {
+ GRN_GFREE(ctx);
+ ctx = NULL;
+ }
+ }
+ return ctx;
+}
+
+grn_rc
+grn_ctx_fin(grn_ctx *ctx)
+{
+ grn_rc rc = GRN_SUCCESS;
+ if (!ctx) { return GRN_INVALID_ARGUMENT; }
+ if (ctx->stat == GRN_CTX_FIN) { return GRN_INVALID_ARGUMENT; }
+ if (!(ctx->flags & GRN_CTX_ALLOCATED)) {
+ CRITICAL_SECTION_ENTER(grn_glock);
+ ctx->next->prev = ctx->prev;
+ ctx->prev->next = ctx->next;
+ CRITICAL_SECTION_LEAVE(grn_glock);
+ }
+ if (ctx->impl) {
+ grn_ctx_impl_clear_n_same_error_messagges(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;
+ GRN_ARRAY_EACH(ctx, ctx->impl->values, 0, 0, id, &o, {
+ grn_obj_close(ctx, *((grn_obj **)o));
+ });
+#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);
+ }
+ if (ctx->impl->com) {
+ if (ctx->stat != GRN_CTX_QUIT) {
+ int flags;
+ char *str;
+ unsigned int str_len;
+ grn_ctx_send(ctx, "quit", 4, GRN_CTX_HEAD);
+ grn_ctx_recv(ctx, &str, &str_len, &flags);
+ }
+ grn_ctx_send(ctx, "ACK", 3, GRN_CTX_HEAD);
+ rc = grn_com_close(ctx, ctx->impl->com);
+ }
+ GRN_OBJ_FIN(ctx, &ctx->impl->query_log_buf);
+ 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;
+ GRN_HASH_EACH(ctx, ctx->impl->expr_vars, eid, NULL, NULL, &vp, {
+ if (*vp) {
+ GRN_HASH_EACH(ctx, *vp, id, NULL, NULL, &value, {
+ GRN_OBJ_FIN(ctx, value);
+ });
+ }
+ grn_hash_close(ctx, *vp);
+ });
+ }
+ grn_hash_close(ctx, ctx->impl->expr_vars);
+ if (ctx->impl->db && ctx->flags & GRN_CTX_PER_DB) {
+ grn_obj *db = ctx->impl->db;
+ ctx->impl->db = NULL;
+ grn_obj_close(ctx, db);
+ }
+ grn_alloc_fin_ctx_impl(ctx);
+ grn_alloc_info_dump(ctx);
+ grn_alloc_info_free(ctx);
+ CRITICAL_SECTION_FIN(ctx->impl->lock);
+ {
+ grn_io_mapinfo mi;
+ mi.map = (void *)ctx->impl;
+ grn_io_anon_unmap(ctx, &mi, IMPL_SIZE);
+ }
+ ctx->impl = NULL;
+ }
+ ctx->stat = GRN_CTX_FIN;
+ return rc;
+}
+
+grn_rc
+grn_ctx_set_finalizer(grn_ctx *ctx, grn_proc_func *finalizer)
+{
+ if (!ctx) { return GRN_INVALID_ARGUMENT; }
+ if (!ctx->impl) {
+ if (ERRP(ctx, GRN_ERROR)) { return ctx->rc; }
+ }
+ ctx->impl->finalizer = finalizer;
+ return GRN_SUCCESS;
+}
+
+grn_timeval grn_starttime;
+
+static void
+check_overcommit_memory(grn_ctx *ctx)
+{
+ FILE *file;
+ int value;
+ file = grn_fopen("/proc/sys/vm/overcommit_memory", "r");
+ if (!file) { return; }
+ value = fgetc(file);
+ if (value != '1') {
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
+ "vm.overcommit_memory kernel parameter should be 1: <%c>: "
+ "See INFO level log to resolve this",
+ value);
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "Some processings with vm.overcommit_memory != 1 "
+ "may break DB under low memory condition.");
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "To set vm.overcommit_memory to 1");
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and "
+ "restart your system or");
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "run 'sudo /sbin/sysctl vm.overcommit_memory=1' command.");
+ }
+ fclose(file);
+}
+
+grn_rc
+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;
+ rc = grn_ctx_init_internal(ctx, 0);
+ if (rc) {
+ goto fail_ctx_init_internal;
+ }
+ ctx->encoding = grn_encoding_parse(GRN_DEFAULT_ENCODING);
+ rc = grn_timeval_now(ctx, &grn_starttime);
+ if (rc) {
+ goto fail_start_time;
+ }
+#ifdef WIN32
+ {
+ SYSTEM_INFO si;
+ GetSystemInfo(&si);
+ grn_pagesize = si.dwAllocationGranularity;
+ }
+#else /* WIN32 */
+ if ((grn_pagesize = sysconf(_SC_PAGESIZE)) == -1) {
+ SERR("_SC_PAGESIZE");
+ 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();
+ if ((rc = grn_com_init())) {
+ GRN_LOG(ctx, GRN_LOG_ALERT, "grn_com_init failed (%d)", 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;
+ }
+ if ((rc = grn_plugins_init())) {
+ GRN_LOG(ctx, GRN_LOG_ALERT, "grn_plugins_init failed (%d)", rc);
+ goto fail_plugins;
+ }
+ if ((rc = grn_normalizer_init())) {
+ GRN_LOG(ctx, GRN_LOG_ALERT, "grn_normalizer_init failed (%d)", rc);
+ goto fail_normalizer;
+ }
+ if ((rc = grn_tokenizers_init())) {
+ GRN_LOG(ctx, GRN_LOG_ALERT, "grn_tokenizers_init failed (%d)", rc);
+ goto fail_tokenizer;
+ }
+ grn_cache_init();
+ if (!grn_request_canceler_init()) {
+ rc = ctx->rc;
+ GRN_LOG(ctx, GRN_LOG_ALERT,
+ "failed to initialize request canceler (%d)", rc);
+ goto fail_request_canceler;
+ }
+ 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
+grn_get_default_encoding(void)
+{
+ return grn_gctx.encoding;
+}
+
+grn_rc
+grn_set_default_encoding(grn_encoding encoding)
+{
+ switch (encoding) {
+ case GRN_ENC_DEFAULT :
+ grn_gctx.encoding = grn_encoding_parse(GRN_DEFAULT_ENCODING);
+ return GRN_SUCCESS;
+ case GRN_ENC_NONE :
+ case GRN_ENC_EUC_JP :
+ case GRN_ENC_UTF8 :
+ case GRN_ENC_SJIS :
+ case GRN_ENC_LATIN1 :
+ case GRN_ENC_KOI8R :
+ grn_gctx.encoding = encoding;
+ return GRN_SUCCESS;
+ default :
+ return GRN_INVALID_ARGUMENT;
+ }
+}
+
+grn_command_version
+grn_get_default_command_version(void)
+{
+ return grn_ctx_get_command_version(&grn_gctx);
+}
+
+grn_rc
+grn_set_default_command_version(grn_command_version version)
+{
+ return grn_ctx_set_command_version(&grn_gctx, version);
+}
+
+long long int
+grn_get_default_match_escalation_threshold(void)
+{
+ return grn_ctx_get_match_escalation_threshold(&grn_gctx);
+}
+
+grn_rc
+grn_set_default_match_escalation_threshold(long long int threshold)
+{
+ return grn_ctx_set_match_escalation_threshold(&grn_gctx, threshold);
+}
+
+int
+grn_get_lock_timeout(void)
+{
+ return grn_lock_timeout;
+}
+
+grn_rc
+grn_set_lock_timeout(int timeout)
+{
+ grn_lock_timeout = timeout;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_fin(void)
+{
+ grn_ctx *ctx, *ctx_;
+ if (grn_gctx.stat == GRN_CTX_FIN) { return GRN_INVALID_ARGUMENT; }
+ for (ctx = grn_gctx.next; ctx != &grn_gctx; ctx = ctx_) {
+ ctx_ = ctx->next;
+ if (ctx->stat != GRN_CTX_FIN) { grn_ctx_fin(ctx); }
+ if (ctx->flags & GRN_CTX_ALLOCATED) {
+ ctx->next->prev = ctx->prev;
+ ctx->prev->next = ctx->next;
+ GRN_GFREE(ctx);
+ }
+ }
+ grn_query_logger_fin(ctx);
+ grn_request_timer_fin();
+ grn_request_canceler_fin();
+ grn_cache_fin();
+ grn_tokenizers_fin();
+ grn_normalizer_fin();
+ grn_plugins_fin();
+ grn_ctx_fin(ctx);
+ grn_com_fin();
+ 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;
+}
+
+grn_rc
+grn_ctx_connect(grn_ctx *ctx, const char *host, int port, int flags)
+{
+ GRN_API_ENTER;
+ if (!ctx->impl) { goto exit; }
+ {
+ grn_com *com = grn_com_copen(ctx, NULL, host, port);
+ if (com) {
+ ctx->impl->com = com;
+ }
+ }
+exit :
+ GRN_API_RETURN(ctx->rc);
+}
+
+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;
+}
+
+grn_command_version
+grn_ctx_get_command_version(grn_ctx *ctx)
+{
+ if (ctx->impl) {
+ return ctx->impl->command.version;
+ } else {
+ return GRN_COMMAND_VERSION_STABLE;
+ }
+}
+
+grn_rc
+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;
+ return GRN_SUCCESS;
+ default :
+ if (GRN_COMMAND_VERSION_MIN <= version &&
+ version <= GRN_COMMAND_VERSION_MAX) {
+ ctx->impl->command.version = version;
+ return GRN_SUCCESS;
+ } else {
+ return GRN_UNSUPPORTED_COMMAND_VERSION;
+ }
+ }
+}
+
+grn_content_type
+grn_ctx_get_output_type(grn_ctx *ctx)
+{
+ if (ctx->impl) {
+ return ctx->impl->output.type;
+ } else {
+ return GRN_CONTENT_NONE;
+ }
+}
+
+grn_rc
+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) {
+ case GRN_CONTENT_NONE :
+ ctx->impl->output.mime_type = "application/octet-stream";
+ break;
+ case GRN_CONTENT_TSV :
+ ctx->impl->output.mime_type = "text/tab-separated-values";
+ break;
+ case GRN_CONTENT_JSON :
+ ctx->impl->output.mime_type = "application/json";
+ break;
+ case GRN_CONTENT_XML :
+ ctx->impl->output.mime_type = "text/xml";
+ break;
+ case GRN_CONTENT_MSGPACK :
+ ctx->impl->output.mime_type = "application/x-msgpack";
+ break;
+ case GRN_CONTENT_GROONGA_COMMAND_LIST :
+ ctx->impl->output.mime_type = "text/x-groonga-command-list";
+ break;
+ }
+ } else {
+ rc = GRN_INVALID_ARGUMENT;
+ }
+
+ return rc;
+}
+
+const char *
+grn_ctx_get_mime_type(grn_ctx *ctx)
+{
+ if (ctx->impl) {
+ return ctx->impl->output.mime_type;
+ } else {
+ return NULL;
+ }
+}
+
+long long int
+grn_ctx_get_match_escalation_threshold(grn_ctx *ctx)
+{
+ if (ctx->impl) {
+ return ctx->impl->match_escalation_threshold;
+ } else {
+ return GRN_DEFAULT_MATCH_ESCALATION_THRESHOLD;
+ }
+}
+
+grn_rc
+grn_ctx_set_match_escalation_threshold(grn_ctx *ctx, long long int threshold)
+{
+ ctx->impl->match_escalation_threshold = threshold;
+ return GRN_SUCCESS;
+}
+
+grn_content_type
+grn_get_ctype(grn_obj *var)
+{
+ 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)) {
+ switch (*(GRN_TEXT_VALUE(var))) {
+ case 't' :
+ case 'T' :
+ ct = GRN_CONTENT_TSV;
+ break;
+ case 'j' :
+ case 'J' :
+ ct = GRN_CONTENT_JSON;
+ break;
+ case 'x' :
+ case 'X' :
+ ct = GRN_CONTENT_XML;
+ break;
+ }
+ }
+ return ct;
+}
+
+static void
+get_content_mime_type(grn_ctx *ctx, const char *p, const char *pe)
+{
+ 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->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->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->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->output.mime_type = "text/javascript";
+ } else if (p + 4 == pe && !memcmp(p + 2, "on", 2)) {
+ 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->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->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->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->output.mime_type = "text/plain";
+ } else if (p + 3 == pe && !memcmp(p, "tsv", 3)) {
+ 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->output.mime_type = "text/xml";
+ }
+ break;
+ }
+ }
+}
+
+static void
+grn_str_get_mime_type(grn_ctx *ctx, const char *p, const char *pe,
+ const char **key_end, const char **filename_end)
+{
+ const char *pd = NULL;
+ for (; p < pe && *p != '?' && *p != '#'; p++) {
+ if (*p == '.') { pd = p; }
+ }
+ *filename_end = p;
+ if (pd && pd < p) {
+ get_content_mime_type(ctx, pd + 1, p);
+ *key_end = pd;
+ } else {
+ *key_end = pe;
+ }
+}
+
+static void
+get_command_version(grn_ctx *ctx, const char *p, const char *pe)
+{
+ grn_command_version version;
+ const char *rest;
+
+ version = grn_atoui(p, pe, &rest);
+ if (pe == rest) {
+ grn_rc rc;
+ rc = grn_ctx_set_command_version(ctx, version);
+ if (rc == GRN_UNSUPPORTED_COMMAND_VERSION) {
+ ERR(rc,
+ "unsupported command version is specified: %d: "
+ "stable command version: %d: "
+ "available command versions: %d-%d",
+ version,
+ GRN_COMMAND_VERSION_STABLE,
+ GRN_COMMAND_VERSION_MIN, GRN_COMMAND_VERSION_MAX);
+ }
+ }
+}
+
+#define INDEX_HTML "index.html"
+#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 "&;"
+
+static inline int
+command_proc_p(grn_obj *expr)
+{
+ return (expr->header.type == GRN_PROC &&
+ ((grn_proc *)expr)->type == GRN_PROC_COMMAND);
+}
+
+grn_obj *
+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, '?');
+ if (!GRN_TEXT_LEN(&buf)) { GRN_TEXT_SETS(ctx, &buf, INDEX_HTML); }
+ v = GRN_TEXT_VALUE(&buf);
+ grn_str_get_mime_type(ctx, v, GRN_BULK_CURR(&buf), &key_end, &filename_end);
+ if ((GRN_TEXT_LEN(&buf) >= 2 && v[0] == 'd' && v[1] == '/')) {
+ const char *command_name = v + 2;
+ int command_name_size = key_end - command_name;
+ expr = grn_ctx_get(ctx, command_name, command_name_size);
+ if (expr && command_proc_p(expr)) {
+ while (p < e) {
+ int l;
+ GRN_BULK_REWIND(&buf);
+ p = grn_text_cgidec(ctx, &buf, p, e, HTTP_QUERY_PAIR_DELIMITER);
+ v = GRN_TEXT_VALUE(&buf);
+ l = GRN_TEXT_LEN(&buf);
+ if (l == OUTPUT_TYPE_LEN && !memcmp(v, OUTPUT_TYPE, OUTPUT_TYPE_LEN)) {
+ GRN_BULK_REWIND(&buf);
+ p = grn_text_cgidec(ctx, &buf, p, e, HTTP_QUERY_PAIRS_DELIMITERS);
+ v = GRN_TEXT_VALUE(&buf);
+ get_content_mime_type(ctx, v, GRN_BULK_CURR(&buf));
+ } else if (l == COMMAND_VERSION_LEN &&
+ !memcmp(v, COMMAND_VERSION, COMMAND_VERSION_LEN)) {
+ GRN_BULK_REWIND(&buf);
+ p = grn_text_cgidec(ctx, &buf, p, e, HTTP_QUERY_PAIRS_DELIMITERS);
+ get_command_version(ctx, GRN_TEXT_VALUE(&buf), GRN_BULK_CURR(&buf));
+ if (ctx->rc) { goto exit; }
+ } else if (l == REQUEST_ID_LEN &&
+ !memcmp(v, REQUEST_ID, REQUEST_ID_LEN)) {
+ GRN_BULK_REWIND(&request_id);
+ p = grn_text_cgidec(ctx, &request_id, p, e,
+ HTTP_QUERY_PAIRS_DELIMITERS);
+ } 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;
+ }
+ grn_obj_reinit(ctx, val, GRN_DB_TEXT, 0);
+ 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);
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "invalid command name: %.*s",
+ command_name_size, command_name);
+ }
+ } else if ((expr = grn_ctx_get(ctx, GRN_EXPR_MISSING_NAME,
+ strlen(GRN_EXPR_MISSING_NAME)))) {
+ if ((val = grn_expr_get_var_by_offset(ctx, expr, 0))) {
+ grn_obj_reinit(ctx, val, GRN_DB_TEXT, 0);
+ GRN_TEXT_SET(ctx, val, v, filename_end - v);
+ }
+ ctx->impl->curr_expr = expr;
+ grn_expr_exec(ctx, expr, 0);
+ }
+exit :
+ GRN_OBJ_FIN(ctx, &request_id);
+ GRN_OBJ_FIN(ctx, &buf);
+
+ return expr;
+}
+
+grn_obj *
+grn_ctx_qe_exec(grn_ctx *ctx, const char *str, uint32_t str_len)
+{
+ char tok_type;
+ 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);
+ expr = grn_ctx_get(ctx, GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf));
+ while (p < e) {
+ GRN_BULK_REWIND(&buf);
+ p = grn_text_unesc_tok(ctx, &buf, p, e, &tok_type);
+ v = GRN_TEXT_VALUE(&buf);
+ switch (tok_type) {
+ case GRN_TOK_VOID :
+ p = e;
+ break;
+ case GRN_TOK_SYMBOL :
+ if (GRN_TEXT_LEN(&buf) > 2 && v[0] == '-' && v[1] == '-') {
+ int l = GRN_TEXT_LEN(&buf) - 2;
+ v += 2;
+ if (l == OUTPUT_TYPE_LEN && !memcmp(v, OUTPUT_TYPE, OUTPUT_TYPE_LEN)) {
+ GRN_BULK_REWIND(&buf);
+ p = grn_text_unesc_tok(ctx, &buf, p, e, &tok_type);
+ v = GRN_TEXT_VALUE(&buf);
+ get_content_mime_type(ctx, v, GRN_BULK_CURR(&buf));
+ } else if (l == COMMAND_VERSION_LEN &&
+ !memcmp(v, COMMAND_VERSION, COMMAND_VERSION_LEN)) {
+ GRN_BULK_REWIND(&buf);
+ p = grn_text_unesc_tok(ctx, &buf, p, e, &tok_type);
+ get_command_version(ctx, GRN_TEXT_VALUE(&buf), GRN_BULK_CURR(&buf));
+ if (ctx->rc) { goto exit; }
+ } else if (l == REQUEST_ID_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);
+ } 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);
+ } else {
+ p = e;
+ }
+ break;
+ }
+ // fallthru
+ case GRN_TOK_STRING :
+ case GRN_TOK_QUOTE :
+ if (expr && (val = grn_expr_get_var_by_offset(ctx, expr, offset++))) {
+ grn_obj_reinit(ctx, val, GRN_DB_TEXT, 0);
+ GRN_TEXT_PUT(ctx, val, GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf));
+ } else {
+ p = e;
+ }
+ 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)) {
+ grn_expr_exec(ctx, expr, 0);
+ } else {
+ GRN_BULK_REWIND(&buf);
+ grn_text_unesc_tok(ctx, &buf, str, str + str_len, &tok_type);
+ if (GRN_TEXT_LEN(&buf)) {
+ ERR(GRN_INVALID_ARGUMENT, "invalid command name: %.*s",
+ (int)GRN_TEXT_LEN(&buf), GRN_TEXT_VALUE(&buf));
+ }
+ }
+exit :
+ GRN_OBJ_FIN(ctx, &request_id);
+ GRN_OBJ_FIN(ctx, &buf);
+
+ return expr;
+}
+
+grn_rc
+grn_ctx_sendv(grn_ctx *ctx, int argc, char **argv, int flags)
+{
+ grn_obj buf;
+ GRN_API_ENTER;
+ GRN_TEXT_INIT(&buf, 0);
+ while (argc--) {
+ // todo : encode into json like syntax
+ GRN_TEXT_PUTS(ctx, &buf, *argv);
+ argv++;
+ if (argc) { GRN_TEXT_PUTC(ctx, &buf, ' '); }
+ }
+ grn_ctx_send(ctx, GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf), flags);
+ GRN_OBJ_FIN(ctx, &buf);
+ GRN_API_RETURN(ctx->rc);
+}
+
+static int
+comment_command_p(const char *command, unsigned int length)
+{
+ const char *p, *e;
+
+ e = command + length;
+ for (p = command; p < e; p++) {
+ switch (*p) {
+ case '#' :
+ return GRN_TRUE;
+ case ' ' :
+ case '\t' :
+ break;
+ default :
+ return GRN_FALSE;
+ }
+ }
+ return GRN_FALSE;
+}
+
+unsigned int
+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);
+ sheader.proto = GRN_COM_PROTO_GQTP;
+ sheader.qtype = 0;
+ sheader.keylen = 0;
+ sheader.level = 0;
+ sheader.flags = flags;
+ sheader.status = 0;
+ sheader.opaque = 0;
+ sheader.cas = 0;
+ if ((rc = grn_com_send(ctx, ctx->impl->com, &sheader, (char *)str, str_len, 0))) {
+ ERR(rc, "grn_com_send failed");
+ }
+ goto exit;
+ } else {
+ grn_command_version command_version;
+ grn_obj *expr = NULL;
+
+ command_version = grn_ctx_get_command_version(ctx);
+ if (ctx->impl->command.keep.command) {
+ grn_obj *val;
+ 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);
+ }
+ grn_expr_exec(ctx, expr, 0);
+ } else {
+ if (comment_command_p(str, str_len)) { goto output; };
+ 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);
+ if (str_len && *str == '/') {
+ expr = grn_ctx_qe_exec_uri(ctx, str + 1, str_len - 1);
+ } else {
+ expr = grn_ctx_qe_exec(ctx, str, str_len);
+ }
+ }
+ if (ctx->stat == GRN_CTX_QUITTING) { ctx->stat = GRN_CTX_QUIT; }
+ 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 (!(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;
+ }
+ }
+ ERR(GRN_INVALID_ARGUMENT, "invalid ctx assigned");
+exit :
+ GRN_API_RETURN(0);
+}
+
+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) {
+ 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->output.buf)) {
+ *str = NULL;
+ *str_len = 0;
+ *flags = 0;
+ } else {
+ *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;
+ } else {
+ if (!(header.flags & GRN_CTX_TAIL)) {
+ *flags |= GRN_CTX_MORE;
+ }
+ }
+ ctx->impl->output.type = header.qtype;
+ ctx->rc = (int16_t)ntohs(header.status);
+ ctx->errbuf[0] = '\0';
+ ctx->errline = 0;
+ ctx->errfile = NULL;
+ ctx->errfunc = NULL;
+ }
+ goto exit;
+ } else {
+ 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->output.buf);
+ goto exit;
+ }
+ }
+ ERR(GRN_INVALID_ARGUMENT, "invalid ctx assigned");
+exit :
+ GRN_API_RETURN(0);
+}
+
+void
+grn_ctx_stream_out_func(grn_ctx *ctx, int flags, void *stream)
+{
+ if (ctx && ctx->impl) {
+ 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)) {
+ fputc('\n', (FILE *)stream);
+ fflush((FILE *)stream);
+ }
+ GRN_BULK_REWIND(buf);
+ }
+ }
+}
+
+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 = func;
+ ctx->impl->output.data.ptr = func_arg;
+ }
+}
+
+grn_rc
+grn_ctx_info_get(grn_ctx *ctx, grn_ctx_info *info)
+{
+ if (!ctx || !ctx->impl) { return GRN_INVALID_ARGUMENT; }
+ if (ctx->impl->com) {
+ info->fd = ctx->impl->com->fd;
+ info->com_status = ctx->impl->com_status;
+ info->outbuf = ctx->impl->output.buf;
+ info->stat = ctx->stat;
+ } else {
+ info->fd = -1;
+ info->com_status = 0;
+ info->outbuf = ctx->impl->output.buf;
+ info->stat = ctx->stat;
+ }
+ return GRN_SUCCESS;
+}
+
+#define DB_P(s) ((s) && (s)->header.type == GRN_DB)
+
+grn_rc
+grn_ctx_use(grn_ctx *ctx, grn_obj *db)
+{
+ GRN_API_ENTER;
+ if (db && !DB_P(db)) {
+ ctx->rc = GRN_INVALID_ARGUMENT;
+ } else {
+ if (!ctx->rc) {
+ ctx->impl->db = db;
+ if (db) {
+ grn_obj buf;
+ GRN_TEXT_INIT(&buf, 0);
+ grn_obj_get_info(ctx, db, GRN_INFO_ENCODING, &buf);
+ ctx->encoding = *(grn_encoding *)GRN_BULK_HEAD(&buf);
+ grn_obj_close(ctx, &buf);
+ }
+ }
+ }
+ GRN_API_RETURN(ctx->rc);
+}
+
+/* don't handle error inside logger functions */
+
+void
+grn_ctx_log(grn_ctx *ctx, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ grn_ctx_logv(ctx, fmt, ap);
+ va_end(ap);
+}
+
+void
+grn_ctx_logv(grn_ctx *ctx, const char *fmt, va_list ap)
+{
+ char buffer[GRN_CTX_MSGSIZE];
+ grn_vsnprintf(buffer, GRN_CTX_MSGSIZE, fmt, ap);
+ grn_strcpy(ctx->errbuf, GRN_CTX_MSGSIZE, buffer);
+}
+
+void
+grn_assert(grn_ctx *ctx, int cond, const char* file, int line, const char* func)
+{
+ if (!cond) {
+ GRN_LOG(ctx, GRN_LOG_WARNING, "ASSERT fail on %s %s:%d", func, file, line);
+ }
+}
+
+const char *
+grn_get_version(void)
+{
+ return GRN_VERSION;
+}
+
+const char *
+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
+segv_handler(int signal_number, siginfo_t *info, void *context)
+{
+ grn_ctx *ctx = &grn_gctx;
+
+ if (segv_received) {
+ GRN_LOG(ctx, GRN_LOG_CRIT, "SEGV received in SEGV handler.");
+ exit(EXIT_FAILURE);
+ }
+ segv_received = 1;
+
+ GRN_LOG(ctx, GRN_LOG_CRIT, "-- CRASHED!!! --");
+#ifdef HAVE_BACKTRACE
+# define N_TRACE_LEVEL 1024
+ {
+ static void *trace[N_TRACE_LEVEL];
+ int n = backtrace(trace, N_TRACE_LEVEL);
+ char **symbols = backtrace_symbols(trace, n);
+ int i;
+
+ if (symbols) {
+ for (i = 0; i < n; i++) {
+ GRN_LOG(ctx, GRN_LOG_CRIT, "%s", symbols[i]);
+ }
+ free(symbols);
+ }
+ }
+#else /* HAVE_BACKTRACE */
+ GRN_LOG(ctx, GRN_LOG_CRIT, "backtrace() isn't available.");
+#endif /* HAVE_BACKTRACE */
+ GRN_LOG(ctx, GRN_LOG_CRIT, "----------------");
+ abort();
+}
+#endif /* defined(HAVE_SIGNAL_H) && !defined(WIN32) */
+
+grn_rc
+grn_set_segv_handler(void)
+{
+ grn_rc rc = GRN_SUCCESS;
+#if defined(HAVE_SIGNAL_H) && !defined(WIN32)
+ grn_ctx *ctx = &grn_gctx;
+ struct sigaction action;
+
+ sigemptyset(&action.sa_mask);
+ action.sa_sigaction = segv_handler;
+ action.sa_flags = SA_SIGINFO | SA_ONSTACK;
+
+ if (sigaction(SIGSEGV, &action, NULL)) {
+ SERR("failed to set SIGSEGV action");
+ rc = ctx->rc;
+ };
+#endif
+ return rc;
+}
+
+#if defined(HAVE_SIGNAL_H) && !defined(WIN32)
+static struct sigaction old_int_handler;
+static void
+int_handler(int signal_number, siginfo_t *info, void *context)
+{
+ grn_gctx.stat = GRN_CTX_QUIT;
+ sigaction(signal_number, &old_int_handler, NULL);
+}
+
+static struct sigaction old_term_handler;
+static void
+term_handler(int signal_number, siginfo_t *info, void *context)
+{
+ grn_gctx.stat = GRN_CTX_QUIT;
+ sigaction(signal_number, &old_term_handler, NULL);
+}
+#endif /* defined(HAVE_SIGNAL_H) && !defined(WIN32) */
+
+grn_rc
+grn_set_int_handler(void)
+{
+ grn_rc rc = GRN_SUCCESS;
+#if defined(HAVE_SIGNAL_H) && !defined(WIN32)
+ grn_ctx *ctx = &grn_gctx;
+ struct sigaction action;
+
+ sigemptyset(&action.sa_mask);
+ action.sa_sigaction = int_handler;
+ action.sa_flags = SA_SIGINFO;
+
+ if (sigaction(SIGINT, &action, &old_int_handler)) {
+ SERR("failed to set SIGINT action");
+ rc = ctx->rc;
+ }
+#endif
+ return rc;
+}
+
+grn_rc
+grn_set_term_handler(void)
+{
+ grn_rc rc = GRN_SUCCESS;
+#if defined(HAVE_SIGNAL_H) && !defined(WIN32)
+ grn_ctx *ctx = &grn_gctx;
+ struct sigaction action;
+
+ sigemptyset(&action.sa_mask);
+ action.sa_sigaction = term_handler;
+ action.sa_flags = SA_SIGINFO;
+
+ if (sigaction(SIGTERM, &action, &old_term_handler)) {
+ SERR("failed to set SIGTERM action");
+ rc = ctx->rc;
+ }
+#endif
+ return rc;
+}
+
+void
+grn_ctx_output_flush(grn_ctx *ctx, int flags)
+{
+ if (flags & GRN_CTX_QUIET) {
+ return;
+ }
+ if (!ctx->impl->output.func) {
+ return;
+ }
+ 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->output.buf,
+ ctx->impl->output.type,
+ name, nelements);
+}
+
+void
+grn_ctx_output_array_close(grn_ctx *ctx)
+{
+ 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->output.buf,
+ ctx->impl->output.type,
+ name, nelements);
+}
+
+void
+grn_ctx_output_map_close(grn_ctx *ctx)
+{
+ 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->output.buf,
+ ctx->impl->output.type,
+ value);
+}
+
+void
+grn_ctx_output_int64(grn_ctx *ctx, int64_t 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->output.buf,
+ ctx->impl->output.type,
+ value);
+}
+
+void
+grn_ctx_output_cstr(grn_ctx *ctx, const char *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->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->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->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->output.buf,
+ ctx->impl->output.type,
+ table,
+ format);
+}
+
+void
+grn_ctx_output_table_records(grn_ctx *ctx, grn_obj *table,
+ grn_obj_format *format)
+{
+ grn_output_table_records(ctx,
+ 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
new file mode 100644
index 00000000..7f554f3f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c
@@ -0,0 +1,324 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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 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-1335 USA
+*/
+
+#include "grn_ctx_impl.h"
+
+#include <string.h>
+
+#ifdef GRN_WITH_MRUBY
+# include "grn_ctx_impl_mrb.h"
+
+# include "grn_mrb.h"
+# include "mrb/mrb_converter.h"
+# 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"
+# include "mrb/mrb_patricia_trie.h"
+# include "mrb/mrb_double_array_trie.h"
+# include "mrb/mrb_table_group_flags.h"
+# 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"
+# include "mrb/mrb_index_column.h"
+# include "mrb/mrb_index_cursor.h"
+# include "mrb/mrb_type.h"
+# include "mrb/mrb_expr.h"
+# include "mrb/mrb_accessor.h"
+# include "mrb/mrb_procedure.h"
+# include "mrb/mrb_command.h"
+# include "mrb/mrb_command_input.h"
+# include "mrb/mrb_table_cursor.h"
+# 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 */
+
+static grn_bool grn_ctx_impl_mrb_mruby_enabled = GRN_TRUE;
+
+void
+grn_ctx_impl_mrb_init_from_env(void)
+{
+ {
+ char grn_mruby_enabled_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_MRUBY_ENABLED",
+ grn_mruby_enabled_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_mruby_enabled_env[0] &&
+ strcmp(grn_mruby_enabled_env, "no") == 0) {
+ grn_ctx_impl_mrb_mruby_enabled = GRN_FALSE;
+ }
+ }
+}
+
+#ifdef GRN_WITH_MRUBY
+static mrb_value
+mrb_kernel_load(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ char *path;
+
+ mrb_get_args(mrb, "z", &path);
+
+ grn_mrb_load(ctx, path);
+ if (mrb->exc) {
+ mrb_exc_raise(mrb, mrb_obj_value(mrb->exc));
+ }
+
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_true_value();
+}
+
+static mrb_value
+mrb_groonga_init(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = mrb->ud;
+
+ 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,
+ "load", mrb_kernel_load, MRB_ARGS_REQ(1));
+
+ {
+ mrb_value load_path;
+ const char *plugins_dir;
+ const char *system_ruby_scripts_dir;
+
+ load_path = mrb_ary_new(mrb);
+ plugins_dir = grn_plugin_get_system_plugins_dir();
+ mrb_ary_push(mrb, load_path,
+ mrb_str_new_cstr(mrb, plugins_dir));
+ system_ruby_scripts_dir = grn_mrb_get_system_ruby_scripts_dir(ctx);
+ mrb_ary_push(mrb, load_path,
+ mrb_str_new_cstr(mrb, system_ruby_scripts_dir));
+ mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$LOAD_PATH"), load_path);
+ }
+
+ grn_mrb_load(ctx, "require.rb");
+ grn_mrb_load(ctx, "initialize/pre.rb");
+
+ grn_mrb_converter_init(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);
+ grn_mrb_patricia_trie_init(ctx);
+ grn_mrb_double_array_trie_init(ctx);
+ grn_mrb_table_group_flags_init(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);
+ grn_mrb_index_column_init(ctx);
+ grn_mrb_index_cursor_init(ctx);
+ grn_mrb_type_init(ctx);
+ grn_mrb_expr_init(ctx);
+ grn_mrb_accessor_init(ctx);
+ grn_mrb_procedure_init(ctx);
+ grn_mrb_command_init(ctx);
+ grn_mrb_command_input_init(ctx);
+ grn_mrb_table_cursor_init(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();
+}
+
+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;
+ ctx->impl->mrb.base_directory[0] = '\0';
+ ctx->impl->mrb.module = NULL;
+ ctx->impl->mrb.object_class = NULL;
+ ctx->impl->mrb.checked_procs = NULL;
+ ctx->impl->mrb.registered_plugins = NULL;
+ ctx->impl->mrb.builtin.time_class = NULL;
+ 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);
+ if (ctx->impl->mrb.state->exc) {
+ 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");
+ }
+ }
+}
+
+static void
+grn_ctx_impl_mrb_fin_real(grn_ctx *ctx)
+{
+ if (ctx->impl->mrb.state) {
+ mrb_close(ctx->impl->mrb.state);
+ ctx->impl->mrb.state = NULL;
+ grn_hash_close(ctx, ctx->impl->mrb.checked_procs);
+ grn_hash_close(ctx, ctx->impl->mrb.registered_plugins);
+ GRN_OBJ_FIN(ctx, &(ctx->impl->mrb.buffer.from));
+ GRN_OBJ_FIN(ctx, &(ctx->impl->mrb.buffer.to));
+ }
+}
+#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);
+ }
+}
diff --git a/storage/mroonga/vendor/groonga/lib/dat.cpp b/storage/mroonga/vendor/groonga/lib/dat.cpp
new file mode 100644
index 00000000..1446be7c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat.cpp
@@ -0,0 +1,1338 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+#include "grn.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <cstring>
+#include <new>
+#include "grn_str.h"
+#include "grn_io.h"
+#include "grn_dat.h"
+#include "grn_util.h"
+#include "grn_normalizer.h"
+
+#include "dat/trie.hpp"
+#include "dat/cursor-factory.hpp"
+
+namespace {
+
+const uint32_t FILE_ID_LENGTH = 3;
+
+class CriticalSection {
+ public:
+ CriticalSection() : lock_(NULL) {}
+ explicit CriticalSection(grn_critical_section *lock) : lock_(lock) {
+ CRITICAL_SECTION_ENTER(*lock_);
+ }
+ ~CriticalSection() {
+ leave();
+ }
+
+ void enter(grn_critical_section *lock) {
+ leave();
+ lock_ = lock;
+ }
+ void leave() {
+ if (lock_ != NULL) {
+ CRITICAL_SECTION_LEAVE(*lock_);
+ lock_ = NULL;
+ }
+ }
+
+ private:
+ grn_critical_section *lock_;
+
+ // Disallows copy and assignment.
+ CriticalSection(const CriticalSection &);
+ CriticalSection &operator=(const CriticalSection &);
+};
+
+/*
+ grn_dat_remove_file() removes a file specified by `path' and then returns
+ true on success, false on failure. Note that grn_dat_remove_file() does not
+ change `ctx->rc'.
+ */
+bool
+grn_dat_remove_file(grn_ctx *ctx, const char *path)
+{
+ struct stat stat;
+
+ 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
+grn_dat_translate_error_code(grn::dat::ErrorCode error_code) {
+ switch (error_code) {
+ case grn::dat::PARAM_ERROR: {
+ return GRN_INVALID_ARGUMENT;
+ }
+ case grn::dat::IO_ERROR: {
+ return GRN_INPUT_OUTPUT_ERROR;
+ }
+ case grn::dat::FORMAT_ERROR: {
+ return GRN_INVALID_FORMAT;
+ }
+ case grn::dat::MEMORY_ERROR: {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ case grn::dat::SIZE_ERROR:
+ case grn::dat::UNEXPECTED_ERROR: {
+ return GRN_UNKNOWN_ERROR;
+ }
+ case grn::dat::STATUS_ERROR: {
+ return GRN_FILE_CORRUPT;
+ }
+ default: {
+ return GRN_UNKNOWN_ERROR;
+ }
+ }
+}
+
+void
+grn_dat_init(grn_ctx *, grn_dat *dat)
+{
+ GRN_DB_OBJ_SET_TYPE(dat, GRN_TABLE_DAT_KEY);
+ dat->io = NULL;
+ dat->header = NULL;
+ dat->file_id = 0;
+ dat->encoding = GRN_ENC_DEFAULT;
+ dat->trie = NULL;
+ dat->old_trie = NULL;
+ dat->tokenizer = NULL;
+ 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
+grn_dat_fin(grn_ctx *ctx, grn_dat *dat)
+{
+ CRITICAL_SECTION_FIN(dat->lock);
+ delete static_cast<grn::dat::Trie *>(dat->old_trie);
+ delete static_cast<grn::dat::Trie *>(dat->trie);
+ 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;
+ }
+ GRN_OBJ_FIN(ctx, &(dat->token_filters));
+}
+
+/*
+ grn_dat_generate_trie_path() generates the path from `base_path' and
+ `file_id'. The generated path is stored in `trie_path'.
+ */
+void
+grn_dat_generate_trie_path(const char *base_path, char *trie_path, uint32_t file_id)
+{
+ if (!base_path || !base_path[0]) {
+ trie_path[0] = '\0';
+ return;
+ }
+ const size_t len = std::strlen(base_path);
+ grn_memcpy(trie_path, base_path, len);
+ trie_path[len] = '.';
+ grn_itoh(file_id % (1U << (4 * FILE_ID_LENGTH)),
+ trie_path + len + 1, FILE_ID_LENGTH);
+ trie_path[len + 1 + FILE_ID_LENGTH] = '\0';
+}
+
+bool
+grn_dat_open_trie_if_needed(grn_ctx *ctx, grn_dat *dat)
+{
+ if (!dat) {
+ ERR(GRN_INVALID_ARGUMENT, "dat is null");
+ return false;
+ }
+
+ const uint32_t file_id = dat->header->file_id;
+ if (!file_id || (dat->trie && (file_id <= dat->file_id))) {
+ /*
+ There is no need to open file when no trie file is available or the
+ current trie file is the latest one.
+ */
+ return true;
+ }
+
+ CriticalSection critical_section(&dat->lock);
+
+ if (dat->trie && (file_id <= dat->file_id)) {
+ /*
+ There is no need to open file if the latest file has been opened by
+ another thread.
+ */
+ return true;
+ }
+
+ char trie_path[PATH_MAX];
+ grn_dat_generate_trie_path(grn_io_path(dat->io), trie_path, file_id);
+ grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ grn::dat::Trie * const old_trie = static_cast<grn::dat::Trie *>(dat->old_trie);
+ grn::dat::Trie * const new_trie = new (std::nothrow) grn::dat::Trie;
+ if (!new_trie) {
+ MERR("new grn::dat::Trie failed");
+ 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;
+ dat->trie = new_trie;
+ dat->file_id = file_id;
+
+ critical_section.leave();
+
+ delete old_trie;
+ if (file_id >= 3) {
+ grn_dat_generate_trie_path(grn_io_path(dat->io), trie_path, file_id - 2);
+ grn_dat_remove_file(ctx, trie_path);
+ }
+ return true;
+}
+
+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");
+ return false;
+ }
+
+ const uint32_t file_id = dat->header->file_id;
+ 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);
+ dat->old_trie = dat->trie;
+ dat->trie = new_trie;
+ dat->header->file_id = dat->file_id = file_id + 1;
+
+ delete old_trie;
+ if (file_id >= 2) {
+ char trie_path[PATH_MAX];
+ grn_dat_generate_trie_path(grn_io_path(dat->io), trie_path, file_id - 1);
+ grn_dat_remove_file(ctx, trie_path);
+ }
+ return true;
+}
+
+void grn_dat_cursor_init(grn_ctx *, grn_dat_cursor *cursor) {
+ GRN_DB_OBJ_SET_TYPE(cursor, GRN_CURSOR_TABLE_DAT_KEY);
+ cursor->dat = NULL;
+ cursor->cursor = NULL;
+ cursor->key = &grn::dat::Key::invalid_key();
+ cursor->curr_rec = GRN_ID_NIL;
+}
+
+void grn_dat_cursor_fin(grn_ctx *, grn_dat_cursor *cursor) {
+ delete static_cast<grn::dat::Cursor *>(cursor->cursor);
+ cursor->dat = NULL;
+ cursor->cursor = NULL;
+ cursor->key = &grn::dat::Key::invalid_key();
+ cursor->curr_rec = GRN_ID_NIL;
+}
+
+} // namespace
+
+extern "C" {
+
+grn_dat *
+grn_dat_create(grn_ctx *ctx, const char *path, uint32_t,
+ uint32_t, uint32_t flags)
+{
+ if (path) {
+ if (path[0] == '\0') {
+ path = NULL;
+ } else if (std::strlen(path) >= (PATH_MAX - (FILE_ID_LENGTH + 1))) {
+ ERR(GRN_FILENAME_TOO_LONG, "too long path");
+ return NULL;
+ }
+ }
+
+ grn_dat * const dat = static_cast<grn_dat *>(GRN_CALLOC(sizeof(grn_dat)));
+ if (!dat) {
+ return NULL;
+ }
+ grn_dat_init(ctx, dat);
+
+ dat->io = grn_io_create(ctx, path, sizeof(struct grn_dat_header),
+ 4096, 0, grn_io_auto, GRN_IO_EXPIRE_SEGMENT);
+ if (!dat->io) {
+ GRN_FREE(dat);
+ return NULL;
+ }
+ grn_io_set_type(dat->io, GRN_TABLE_DAT_KEY);
+
+ dat->header = static_cast<struct grn_dat_header *>(grn_io_header(dat->io));
+ if (!dat->header) {
+ grn_io_close(ctx, dat->io);
+ grn_dat_remove_file(ctx, path);
+ GRN_FREE(dat);
+ return NULL;
+ }
+ const grn_encoding encoding = (ctx->encoding != GRN_ENC_DEFAULT) ?
+ ctx->encoding : grn_gctx.encoding;
+ dat->header->flags = flags;
+ dat->header->encoding = encoding;
+ dat->header->tokenizer = GRN_ID_NIL;
+ dat->header->file_id = 0;
+ if (dat->header->flags & GRN_OBJ_KEY_NORMALIZE) {
+ dat->header->flags &= ~GRN_OBJ_KEY_NORMALIZE;
+ dat->normalizer = grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1);
+ dat->header->normalizer = grn_obj_id(ctx, dat->normalizer);
+ } else {
+ dat->normalizer = NULL;
+ dat->header->normalizer = GRN_ID_NIL;
+ }
+ dat->encoding = encoding;
+ dat->tokenizer = NULL;
+ GRN_PTR_INIT(&(dat->token_filters), GRN_OBJ_VECTOR, GRN_ID_NIL);
+
+ dat->obj.header.flags = dat->header->flags;
+
+ return dat;
+}
+
+grn_dat *
+grn_dat_open(grn_ctx *ctx, const char *path)
+{
+ if (path && (std::strlen(path) >= (PATH_MAX - (FILE_ID_LENGTH + 1)))) {
+ ERR(GRN_FILENAME_TOO_LONG, "too long path");
+ return NULL;
+ }
+
+ grn_dat * const dat = static_cast<grn_dat *>(GRN_MALLOC(sizeof(grn_dat)));
+ if (!dat) {
+ return NULL;
+ }
+
+ grn_dat_init(ctx, dat);
+ dat->io = grn_io_open(ctx, path, grn_io_auto);
+ if (!dat->io) {
+ GRN_FREE(dat);
+ return NULL;
+ }
+
+ dat->header = (struct grn_dat_header *)grn_io_header(dat->io);
+ if (!dat->header) {
+ grn_io_close(ctx, dat->io);
+ GRN_FREE(dat);
+ return NULL;
+ }
+ dat->file_id = dat->header->file_id;
+ dat->encoding = dat->header->encoding;
+ dat->tokenizer = grn_ctx_at(ctx, dat->header->tokenizer);
+ if (dat->header->flags & GRN_OBJ_KEY_NORMALIZE) {
+ dat->header->flags &= ~GRN_OBJ_KEY_NORMALIZE;
+ dat->normalizer = grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1);
+ dat->header->normalizer = grn_obj_id(ctx, dat->normalizer);
+ } else {
+ dat->normalizer = grn_ctx_at(ctx, dat->header->normalizer);
+ }
+ GRN_PTR_INIT(&(dat->token_filters), GRN_OBJ_VECTOR, GRN_ID_NIL);
+ dat->obj.header.flags = dat->header->flags;
+ return dat;
+}
+
+grn_rc
+grn_dat_close(grn_ctx *ctx, grn_dat *dat)
+{
+ if (dat) {
+ grn_dat_fin(ctx, dat);
+ GRN_FREE(dat);
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_dat_remove(grn_ctx *ctx, const char *path)
+{
+ if (!path) {
+ ERR(GRN_INVALID_ARGUMENT, "path is null");
+ return GRN_INVALID_ARGUMENT;
+ }
+
+ grn_dat * const dat = grn_dat_open(ctx, path);
+ if (!dat) {
+ return ctx->rc;
+ }
+ const uint32_t file_id = dat->header->file_id;
+ grn_dat_close(ctx, dat);
+
+ /*
+ grn_dat_remove() tries to remove (file_id + 1)th trie file because
+ grn::dat::Trie::create() might leave an incomplete file on failure.
+ */
+ char trie_path[PATH_MAX];
+ grn_dat_generate_trie_path(path, trie_path, file_id + 1);
+ grn_dat_remove_file(ctx, trie_path);
+ for (uint32_t i = file_id; i > 0; --i) {
+ grn_dat_generate_trie_path(path, trie_path, i);
+ if (!grn_dat_remove_file(ctx, trie_path)) {
+ break;
+ }
+ }
+
+ /*
+ grn_io_remove() reports an error when it fails to remove `path'.
+ */
+ return grn_io_remove(ctx, path);
+}
+
+grn_id
+grn_dat_get(grn_ctx *ctx, grn_dat *dat, const void *key,
+ unsigned int key_size, void **)
+{
+ if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ return GRN_ID_NIL;
+ }
+ const grn::dat::Trie * const trie = static_cast<const grn::dat::Trie *>(dat->trie);
+ if (!trie) {
+ return GRN_ID_NIL;
+ }
+ grn::dat::UInt32 key_pos;
+ try {
+ if (trie->search(key, key_size, &key_pos)) {
+ return trie->get_key(key_pos).id();
+ }
+ } catch (const grn::dat::Exception &ex) {
+ ERR(grn_dat_translate_error_code(ex.code()),
+ "grn::dat::Trie::search failed: %s",
+ ex.what());
+ }
+ return GRN_ID_NIL;
+}
+
+grn_id
+grn_dat_add(grn_ctx *ctx, grn_dat *dat, const void *key,
+ unsigned int key_size, void **, int *added)
+{
+ if (!key_size) {
+ return GRN_ID_NIL;
+ } else if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ return GRN_ID_NIL;
+ }
+
+ if (!dat->trie) {
+ char trie_path[PATH_MAX];
+ grn_dat_generate_trie_path(grn_io_path(dat->io), trie_path, 1);
+ grn::dat::Trie * const new_trie = new (std::nothrow) grn::dat::Trie;
+ if (!new_trie) {
+ MERR("new grn::dat::Trie failed");
+ return GRN_ID_NIL;
+ }
+ 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 GRN_ID_NIL;
+ }
+ dat->trie = new_trie;
+ dat->file_id = dat->header->file_id = 1;
+ }
+
+ grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ try {
+ grn::dat::UInt32 key_pos;
+ const bool res = trie->insert(key, key_size, &key_pos);
+ if (added) {
+ *added = res ? 1 : 0;
+ }
+ return trie->get_key(key_pos).id();
+ } catch (const grn::dat::SizeError &) {
+ if (!grn_dat_rebuild_trie(ctx, dat)) {
+ return GRN_ID_NIL;
+ }
+ grn::dat::Trie * const new_trie = static_cast<grn::dat::Trie *>(dat->trie);
+ grn::dat::UInt32 key_pos;
+ const bool res = new_trie->insert(key, key_size, &key_pos);
+ if (added) {
+ *added = res ? 1 : 0;
+ }
+ 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: %s",
+ ex.what());
+ return GRN_ID_NIL;
+ }
+}
+
+int
+grn_dat_get_key(grn_ctx *ctx, grn_dat *dat, grn_id id, void *keybuf, int bufsize)
+{
+ if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ return 0;
+ }
+ const grn::dat::Trie * const trie = static_cast<const grn::dat::Trie *>(dat->trie);
+ if (!trie) {
+ return 0;
+ }
+ const grn::dat::Key &key = trie->ith_key(id);
+ if (!key.is_valid()) {
+ return 0;
+ }
+ if (keybuf && (bufsize >= (int)key.length())) {
+ grn_memcpy(keybuf, key.ptr(), key.length());
+ }
+ return (int)key.length();
+}
+
+int
+grn_dat_get_key2(grn_ctx *ctx, grn_dat *dat, grn_id id, grn_obj *bulk)
+{
+ if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ return 0;
+ }
+ const grn::dat::Trie * const trie = static_cast<const grn::dat::Trie *>(dat->trie);
+ if (!trie) {
+ return 0;
+ }
+ const grn::dat::Key &key = trie->ith_key(id);
+ if (!key.is_valid()) {
+ return 0;
+ }
+ if (bulk->header.impl_flags & GRN_OBJ_REFER) {
+ bulk->u.b.head = static_cast<char *>(const_cast<void *>(key.ptr()));
+ bulk->u.b.curr = bulk->u.b.head + key.length();
+ } else {
+ grn_bulk_write(ctx, bulk, static_cast<const char *>(key.ptr()), key.length());
+ }
+ return (int)key.length();
+}
+
+grn_rc
+grn_dat_delete_by_id(grn_ctx *ctx, grn_dat *dat, grn_id id,
+ grn_table_delete_optarg *optarg)
+{
+ if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ return ctx->rc;
+ } else if (!dat->trie || (id == GRN_ID_NIL)) {
+ return GRN_INVALID_ARGUMENT;
+ }
+
+ if (optarg && optarg->func) {
+ const grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ if (!trie->ith_entry(id).is_valid()) {
+ return GRN_INVALID_ARGUMENT;
+ } else if (!optarg->func(ctx, reinterpret_cast<grn_obj *>(dat), id, optarg->func_arg)) {
+ return GRN_SUCCESS;
+ }
+ }
+
+ try {
+ grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ if (!trie->remove(id)) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ } catch (const grn::dat::Exception &ex) {
+ ERR(grn_dat_translate_error_code(ex.code()),
+ "grn::dat::Trie::remove failed: %s",
+ ex.what());
+ return ctx->rc;
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_dat_delete(grn_ctx *ctx, grn_dat *dat, const void *key, unsigned int key_size,
+ grn_table_delete_optarg *optarg)
+{
+ if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ return ctx->rc;
+ } else if (!dat->trie || !key || !key_size) {
+ return GRN_INVALID_ARGUMENT;
+ }
+
+ if (optarg && optarg->func) {
+ try {
+ const grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ grn::dat::UInt32 key_pos;
+ if (!trie->search(key, key_size, &key_pos)) {
+ return GRN_INVALID_ARGUMENT;
+ } else if (!optarg->func(ctx, reinterpret_cast<grn_obj *>(dat),
+ trie->get_key(key_pos).id(), optarg->func_arg)) {
+ return GRN_SUCCESS;
+ }
+ } catch (const grn::dat::Exception &ex) {
+ ERR(grn_dat_translate_error_code(ex.code()),
+ "grn::dat::Trie::search failed: %s",
+ ex.what());
+ return ctx->rc;
+ }
+ }
+
+ try {
+ grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ if (!trie->remove(key, key_size)) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ } catch (const grn::dat::Exception &ex) {
+ ERR(grn_dat_translate_error_code(ex.code()),
+ "grn::dat::Trie::remove failed: %s",
+ ex.what());
+ return ctx->rc;
+ }
+ return GRN_SUCCESS;
+}
+
+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)
+{
+ if (!dest_key_size) {
+ return GRN_INVALID_ARGUMENT;
+ } else if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ return ctx->rc;
+ } else if (!dat->trie) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ try {
+ try {
+ grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ if (!trie->update(src_key_id, dest_key, dest_key_size)) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ } catch (const grn::dat::SizeError &) {
+ if (!grn_dat_rebuild_trie(ctx, dat)) {
+ return ctx->rc;
+ }
+ grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ if (!trie->update(src_key_id, dest_key, dest_key_size)) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+ } catch (const grn::dat::Exception &ex) {
+ ERR(grn_dat_translate_error_code(ex.code()),
+ "grn::dat::Trie::update failed: %s",
+ ex.what());
+ return ctx->rc;
+ }
+ return GRN_SUCCESS;
+}
+
+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)
+{
+ if (!dest_key_size) {
+ return GRN_INVALID_ARGUMENT;
+ } else if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ return ctx->rc;
+ } else if (!dat->trie) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ try {
+ try {
+ grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ if (!trie->update(src_key, src_key_size, dest_key, dest_key_size)) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ } catch (const grn::dat::SizeError &) {
+ if (!grn_dat_rebuild_trie(ctx, dat)) {
+ return ctx->rc;
+ }
+ grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ if (!trie->update(src_key, src_key_size, dest_key, dest_key_size)) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+ } catch (const grn::dat::Exception &ex) {
+ ERR(grn_dat_translate_error_code(ex.code()),
+ "grn::dat::Trie::update failed: %s",
+ ex.what());
+ return ctx->rc;
+ }
+ return GRN_SUCCESS;
+}
+
+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)
+{
+ if (!grn_dat_open_trie_if_needed(ctx, dat) || !str ||
+ !(dat->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) || !scan_hits) {
+ if (str_rest) {
+ *str_rest = str;
+ }
+ return -1;
+ }
+
+ grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ if (!trie) {
+ if (str_rest) {
+ *str_rest = str + str_size;
+ }
+ return 0;
+ }
+
+ if (!max_num_scan_hits || !str_size) {
+ if (str_rest) {
+ *str_rest = str;
+ }
+ return 0;
+ }
+
+ unsigned int num_scan_hits = 0;
+ try {
+ if (dat->normalizer) {
+ int flags = GRN_STRING_WITH_CHECKS;
+ grn_obj * const normalized_string = grn_string_open(ctx, str, str_size,
+ dat->normalizer,
+ flags);
+ if (!normalized_string) {
+ if (str_rest) {
+ *str_rest = str;
+ }
+ return -1;
+ }
+ grn_string_get_normalized(ctx, normalized_string, &str, &str_size, NULL);
+ const short *checks = grn_string_get_checks(ctx, normalized_string);
+ unsigned int offset = 0;
+ while (str_size) {
+ if (*checks) {
+ grn::dat::UInt32 key_pos;
+ if (trie->lcp_search(str, str_size, &key_pos)) {
+ const grn::dat::Key &key = trie->get_key(key_pos);
+ const grn::dat::UInt32 key_length = key.length();
+ if ((key_length == str_size) || (checks[key_length])) {
+ unsigned int length = 0;
+ for (grn::dat::UInt32 i = 0; i < key_length; ++i) {
+ if (checks[i] > 0) {
+ length += checks[i];
+ }
+ }
+ scan_hits[num_scan_hits].id = key.id();
+ scan_hits[num_scan_hits].offset = offset;
+ scan_hits[num_scan_hits].length = length;
+ offset += length;
+ str += key_length;
+ str_size -= key_length;
+ checks += key_length;
+ if (++num_scan_hits >= max_num_scan_hits) {
+ break;
+ }
+ continue;
+ }
+ }
+ if (*checks > 0) {
+ offset += *checks;
+ }
+ }
+ ++str;
+ --str_size;
+ ++checks;
+ }
+ if (str_rest) {
+ grn_string_get_original(ctx, normalized_string, str_rest, NULL);
+ *str_rest += offset;
+ }
+ grn_obj_close(ctx, normalized_string);
+ } else {
+ const char * const begin = str;
+ while (str_size) {
+ grn::dat::UInt32 key_pos;
+ if (trie->lcp_search(str, str_size, &key_pos)) {
+ const grn::dat::Key &key = trie->get_key(key_pos);
+ scan_hits[num_scan_hits].id = key.id();
+ scan_hits[num_scan_hits].offset = str - begin;
+ scan_hits[num_scan_hits].length = key.length();
+ str += key.length();
+ str_size -= key.length();
+ if (++num_scan_hits >= max_num_scan_hits) {
+ break;
+ }
+ } else {
+ const int char_length = grn_charlen(ctx, str, str + str_size);
+ if (char_length) {
+ str += char_length;
+ str_size -= char_length;
+ } else {
+ ++str;
+ --str_size;
+ }
+ }
+ }
+ if (str_rest) {
+ *str_rest = str;
+ }
+ }
+ } catch (const grn::dat::Exception &ex) {
+ ERR(grn_dat_translate_error_code(ex.code()),
+ "grn::dat::lcp_search failed: %s",
+ ex.what());
+ if (str_rest) {
+ *str_rest = str;
+ }
+ return -1;
+ }
+ return static_cast<int>(num_scan_hits);
+}
+
+grn_id
+grn_dat_lcp_search(grn_ctx *ctx, grn_dat *dat,
+ const void *key, unsigned int key_size)
+{
+ if (!grn_dat_open_trie_if_needed(ctx, dat) || !key ||
+ !(dat->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE)) {
+ return GRN_ID_NIL;
+ }
+
+ grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ if (!trie) {
+ return GRN_ID_NIL;
+ }
+
+ try {
+ grn::dat::UInt32 key_pos;
+ if (!trie->lcp_search(key, key_size, &key_pos)) {
+ return GRN_ID_NIL;
+ }
+ 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: %s",
+ ex.what());
+ return GRN_ID_NIL;
+ }
+}
+
+unsigned int
+grn_dat_size(grn_ctx *ctx, grn_dat *dat)
+{
+ if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ return 0;
+ }
+ const grn::dat::Trie * const trie = static_cast<const grn::dat::Trie *>(dat->trie);
+ if (trie) {
+ return trie->num_keys();
+ }
+ return 0;
+}
+
+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)
+{
+ if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ return NULL;
+ }
+
+ grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ if (!trie) {
+ grn_dat_cursor * const dc =
+ static_cast<grn_dat_cursor *>(GRN_MALLOC(sizeof(grn_dat_cursor)));
+ if (dc) {
+ grn_dat_cursor_init(ctx, dc);
+ }
+ return dc;
+ }
+
+ grn_dat_cursor * const dc =
+ static_cast<grn_dat_cursor *>(GRN_MALLOC(sizeof(grn_dat_cursor)));
+ if (!dc) {
+ return NULL;
+ }
+ grn_dat_cursor_init(ctx, dc);
+
+ try {
+ if ((flags & GRN_CURSOR_BY_ID) != 0) {
+ dc->cursor = grn::dat::CursorFactory::open(*trie,
+ min, min_size, max, max_size, offset, limit,
+ grn::dat::ID_RANGE_CURSOR |
+ ((flags & GRN_CURSOR_DESCENDING) ? grn::dat::DESCENDING_CURSOR : 0) |
+ ((flags & GRN_CURSOR_GT) ? grn::dat::EXCEPT_LOWER_BOUND : 0) |
+ ((flags & GRN_CURSOR_LT) ? grn::dat::EXCEPT_UPPER_BOUND : 0));
+ } else if ((flags & GRN_CURSOR_PREFIX) != 0) {
+ if (max && max_size) {
+ if ((dat->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) != 0) {
+ dc->cursor = grn::dat::CursorFactory::open(*trie,
+ NULL, min_size, max, max_size, offset, limit,
+ grn::dat::PREFIX_CURSOR | grn::dat::DESCENDING_CURSOR);
+ } else {
+ // TODO: near
+ }
+ } else if (min && min_size) {
+ if ((flags & GRN_CURSOR_RK) != 0) {
+ // TODO: rk search
+ } else {
+ dc->cursor = grn::dat::CursorFactory::open(*trie,
+ min, min_size, NULL, 0, offset, limit,
+ grn::dat::PREDICTIVE_CURSOR |
+ ((flags & GRN_CURSOR_DESCENDING) ? grn::dat::DESCENDING_CURSOR : 0) |
+ ((flags & GRN_CURSOR_GT) ? grn::dat::EXCEPT_EXACT_MATCH : 0));
+ }
+ }
+ } else {
+ dc->cursor = grn::dat::CursorFactory::open(*trie,
+ min, min_size, max, max_size, offset, limit,
+ grn::dat::KEY_RANGE_CURSOR |
+ ((flags & GRN_CURSOR_DESCENDING) ? grn::dat::DESCENDING_CURSOR : 0) |
+ ((flags & GRN_CURSOR_GT) ? grn::dat::EXCEPT_LOWER_BOUND : 0) |
+ ((flags & GRN_CURSOR_LT) ? grn::dat::EXCEPT_UPPER_BOUND : 0));
+ }
+ } catch (const grn::dat::Exception &ex) {
+ ERR(grn_dat_translate_error_code(ex.code()),
+ "grn::dat::CursorFactory::open failed: %s",
+ ex.what());
+ GRN_FREE(dc);
+ return NULL;
+ }
+ if (!dc->cursor) {
+ ERR(GRN_INVALID_ARGUMENT, "unsupported query");
+ GRN_FREE(dc);
+ return NULL;
+ }
+ dc->dat = dat;
+ return dc;
+}
+
+grn_id
+grn_dat_cursor_next(grn_ctx *ctx, grn_dat_cursor *c)
+{
+ if (!c || !c->cursor) {
+ return GRN_ID_NIL;
+ }
+ try {
+ grn::dat::Cursor * const cursor = static_cast<grn::dat::Cursor *>(c->cursor);
+ const grn::dat::Key &key = cursor->next();
+ c->key = &key;
+ 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: %s",
+ ex.what());
+ return GRN_ID_NIL;
+ }
+ return c->curr_rec;
+}
+
+void
+grn_dat_cursor_close(grn_ctx *ctx, grn_dat_cursor *c)
+{
+ if (c) {
+ grn_dat_cursor_fin(ctx, c);
+ GRN_FREE(c);
+ }
+}
+
+int
+grn_dat_cursor_get_key(grn_ctx *ctx, grn_dat_cursor *c, const void **key)
+{
+ if (c) {
+ const grn::dat::Key &key_ref = *static_cast<const grn::dat::Key *>(c->key);
+ if (key_ref.is_valid()) {
+ *key = key_ref.ptr();
+ return (int)key_ref.length();
+ }
+ }
+ return 0;
+}
+
+grn_rc
+grn_dat_cursor_delete(grn_ctx *ctx, grn_dat_cursor *c,
+ grn_table_delete_optarg *optarg)
+{
+ if (!c || !c->cursor) {
+ return GRN_INVALID_ARGUMENT;
+ } else if (!grn_dat_open_trie_if_needed(ctx, c->dat)) {
+ return ctx->rc;
+ }
+ grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(c->dat->trie);
+ if (!trie) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ try {
+ if (trie->remove(c->curr_rec)) {
+ return GRN_SUCCESS;
+ }
+ } catch (const grn::dat::Exception &ex) {
+ ERR(grn_dat_translate_error_code(ex.code()),
+ "grn::dat::Trie::remove failed: %s",
+ ex.what());
+ return GRN_INVALID_ARGUMENT;
+ }
+ return GRN_INVALID_ARGUMENT;
+}
+
+grn_id
+grn_dat_curr_id(grn_ctx *ctx, grn_dat *dat)
+{
+ if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ return GRN_ID_NIL;
+ }
+ const grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ if (trie) {
+ return trie->max_key_id();
+ }
+ return GRN_ID_NIL;
+}
+
+grn_rc
+grn_dat_truncate(grn_ctx *ctx, grn_dat *dat)
+{
+ if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ return ctx->rc;
+ }
+ const grn::dat::Trie * const trie = static_cast<const grn::dat::Trie *>(dat->trie);
+ if (!trie || !trie->max_key_id()) {
+ return GRN_SUCCESS;
+ }
+
+ char trie_path[PATH_MAX];
+ grn_dat_generate_trie_path(grn_io_path(dat->io), trie_path, dat->header->file_id + 1);
+ try {
+ 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: %s", ex.what());
+ return error_code;
+ }
+ ++dat->header->file_id;
+ if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ return ctx->rc;
+ }
+ return GRN_SUCCESS;
+}
+
+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();
+ return static_cast<const char *>(key.ptr());
+}
+
+grn_id
+grn_dat_next(grn_ctx *ctx, grn_dat *dat, grn_id id)
+{
+ if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ return GRN_ID_NIL;
+ }
+ const grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ if (!trie) {
+ return GRN_ID_NIL;
+ }
+ while (id < trie->max_key_id()) {
+ if (trie->ith_key(++id).is_valid()) {
+ return id;
+ }
+ }
+ return GRN_ID_NIL;
+}
+
+grn_id
+grn_dat_at(grn_ctx *ctx, grn_dat *dat, grn_id id)
+{
+ if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ return GRN_ID_NIL;
+ }
+ const grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ if (!trie) {
+ return GRN_ID_NIL;
+ }
+ const grn::dat::Key &key = trie->ith_key(id);
+ if (!key.is_valid()) {
+ return GRN_ID_NIL;
+ }
+ return id;
+}
+
+grn_rc
+grn_dat_clear_status_flags(grn_ctx *ctx, grn_dat *dat)
+{
+ if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ return ctx->rc;
+ }
+ grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ if (!trie) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ trie->clear_status_flags();
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_dat_repair(grn_ctx *ctx, grn_dat *dat)
+{
+ if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ return ctx->rc;
+ }
+ const grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ if (!trie) {
+ return GRN_INVALID_ARGUMENT;
+ }
+
+ char trie_path[PATH_MAX];
+ grn_dat_generate_trie_path(grn_io_path(dat->io), trie_path, dat->header->file_id + 1);
+ try {
+ 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: %s", ex.what());
+ return error_code;
+ }
+ ++dat->header->file_id;
+ if (!grn_dat_open_trie_if_needed(ctx, dat)) {
+ return ctx->rc;
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_dat_flush(grn_ctx *ctx, grn_dat *dat)
+{
+ if (!dat->io) {
+ return GRN_SUCCESS;
+ }
+
+ grn_rc rc = grn_io_flush(ctx, dat->io);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+
+ if (dat->trie) {
+ grn::dat::Trie * const trie = static_cast<grn::dat::Trie *>(dat->trie);
+ try {
+ trie->flush();
+ } 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: %s", ex.what());
+ } else {
+ ERR(error_code, "grn::dat::Trie::flush failed: %s", ex.what());
+ }
+ return error_code;
+ }
+ }
+
+ 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/Makefile.am b/storage/mroonga/vendor/groonga/lib/dat/Makefile.am
new file mode 100644
index 00000000..0a58629c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/Makefile.am
@@ -0,0 +1,11 @@
+DEFS += -D_REENTRANT $(GRN_DEFS) -DGRN_DAT_EXPORT
+
+DEFAULT_INCLUDES = \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/include
+
+noinst_LTLIBRARIES = libgrndat.la
+
+include sources.am
+
+CLEANFILES = *.gcno *.gcda
diff --git a/storage/mroonga/vendor/groonga/lib/dat/array.hpp b/storage/mroonga/vendor/groonga/lib/dat/array.hpp
new file mode 100644
index 00000000..de60e3bd
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/array.hpp
@@ -0,0 +1,98 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "dat.hpp"
+
+namespace grn {
+namespace dat {
+
+// This class is used to detect an out-of-range access in debug mode.
+template <typename T>
+class GRN_DAT_API Array {
+ public:
+ Array() : ptr_(NULL), size_(0) {}
+ Array(void *ptr, UInt32 size) : ptr_(static_cast<T *>(ptr)), size_(size) {
+ GRN_DAT_DEBUG_THROW_IF((ptr == NULL) && (size != 0));
+ }
+ template <UInt32 U>
+ explicit Array(T (&array)[U]) : ptr_(array), size_(U) {}
+ ~Array() {}
+
+ const T &operator[](UInt32 i) const {
+ GRN_DAT_DEBUG_THROW_IF(i >= size_);
+ return ptr_[i];
+ }
+ T &operator[](UInt32 i) {
+ GRN_DAT_DEBUG_THROW_IF(i >= size_);
+ return ptr_[i];
+ }
+
+ const T *begin() const {
+ return ptr();
+ }
+ T *begin() {
+ return ptr();
+ }
+
+ const T *end() const {
+ return ptr() + size();
+ }
+ T *end() {
+ return ptr() + size();
+ }
+
+ void assign(void *ptr, UInt32 size) {
+ GRN_DAT_DEBUG_THROW_IF((ptr == NULL) && (size != 0));
+ ptr_ = static_cast<T *>(ptr);
+ size_ = size;
+ }
+ template <UInt32 U>
+ void assign(T (&array)[U]) {
+ assign(array, U);
+ }
+
+ void swap(Array *rhs) {
+ T * const temp_ptr = ptr_;
+ ptr_ = rhs->ptr_;
+ rhs->ptr_ = temp_ptr;
+
+ const UInt32 temp_size = size_;
+ size_ = rhs->size_;
+ rhs->size_ = temp_size;
+ }
+
+ T *ptr() const {
+ return ptr_;
+ }
+ UInt32 size() const {
+ return size_;
+ }
+
+ private:
+ T *ptr_;
+ UInt32 size_;
+
+ // Disallows copy and assignment.
+ Array(const Array &);
+ Array &operator=(const Array &);
+};
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/base.hpp b/storage/mroonga/vendor/groonga/lib/dat/base.hpp
new file mode 100644
index 00000000..51ec6f2f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/base.hpp
@@ -0,0 +1,67 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "dat.hpp"
+
+namespace grn {
+namespace dat {
+
+// The most significant bit represents whether or not the node is a linker.
+// BASE of a linker represents the position of its associated key and BASE of
+// a non-linker represents the offset to its child nodes.
+class GRN_DAT_API Base {
+ public:
+ Base() : value_(0) {}
+
+ bool operator==(const Base &rhs) const {
+ return value_ == rhs.value_;
+ }
+
+ bool is_linker() const {
+ return (value_ & IS_LINKER_FLAG) == IS_LINKER_FLAG;
+ }
+ UInt32 offset() const {
+ GRN_DAT_DEBUG_THROW_IF(is_linker());
+ return value_;
+ }
+ UInt32 key_pos() const {
+ GRN_DAT_DEBUG_THROW_IF(!is_linker());
+ return value_ & ~IS_LINKER_FLAG;
+ }
+
+ void set_offset(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF((x & IS_LINKER_FLAG) != 0);
+ GRN_DAT_DEBUG_THROW_IF(x > MAX_OFFSET);
+ value_ = x;
+ }
+ void set_key_pos(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF((x & IS_LINKER_FLAG) != 0);
+ GRN_DAT_DEBUG_THROW_IF(x > MAX_OFFSET);
+ value_ = IS_LINKER_FLAG | x;
+ }
+
+ private:
+ UInt32 value_;
+
+ static const UInt32 IS_LINKER_FLAG = 0x80000000U;
+};
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/block.hpp b/storage/mroonga/vendor/groonga/lib/dat/block.hpp
new file mode 100644
index 00000000..34e3620a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/block.hpp
@@ -0,0 +1,94 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "dat.hpp"
+
+namespace grn {
+namespace dat {
+
+class GRN_DAT_API Block {
+ public:
+ Block() : next_(0), prev_(0), first_phantom_(0), num_phantoms_(0) {}
+
+ // Blocks in the same level are stored in a doubly-linked list which is
+ // represented by the following next() and prev().
+ UInt32 next() const {
+ return next_ / BLOCK_SIZE;
+ }
+ UInt32 prev() const {
+ return prev_ / BLOCK_SIZE;
+ }
+
+ // A level indicates how easyily find_offset() can find a good offset in that
+ // block. It is easier in lower level blocks.
+ UInt32 level() const {
+ return next_ & BLOCK_MASK;
+ }
+ // A block level rises when find_offset() fails to find a good offset
+ // MAX_FAILURE_COUNT times in that block.
+ UInt32 failure_count() const {
+ return prev_ & BLOCK_MASK;
+ }
+
+ UInt32 first_phantom() const {
+ return first_phantom_;
+ }
+ UInt32 num_phantoms() const {
+ return num_phantoms_;
+ }
+
+ void set_next(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(x > MAX_BLOCK_ID);
+ next_ = (next_ & BLOCK_MASK) | (x * BLOCK_SIZE);
+ }
+ void set_prev(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(x > MAX_BLOCK_ID);
+ prev_ = (prev_ & BLOCK_MASK) | (x * BLOCK_SIZE);
+ }
+
+ void set_level(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(x > MAX_BLOCK_LEVEL);
+ GRN_DAT_DEBUG_THROW_IF(x > BLOCK_MASK);
+ next_ = (next_ & ~BLOCK_MASK) | x;
+ }
+ void set_failure_count(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(x > MAX_FAILURE_COUNT);
+ GRN_DAT_DEBUG_THROW_IF(x > BLOCK_MASK);
+ prev_ = (prev_ & ~BLOCK_MASK) | x;
+ }
+
+ void set_first_phantom(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(x >= BLOCK_SIZE);
+ first_phantom_ = (UInt16)x;
+ }
+ void set_num_phantoms(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(x > BLOCK_SIZE);
+ num_phantoms_ = (UInt16)x;
+ }
+
+ private:
+ UInt32 next_;
+ UInt32 prev_;
+ UInt16 first_phantom_;
+ UInt16 num_phantoms_;
+};
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/check.hpp b/storage/mroonga/vendor/groonga/lib/dat/check.hpp
new file mode 100644
index 00000000..f77148c6
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/check.hpp
@@ -0,0 +1,149 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "dat.hpp"
+
+namespace grn {
+namespace dat {
+
+class GRN_DAT_API Check {
+ public:
+ Check() : value_(0) {}
+
+ bool operator==(const Check &rhs) const {
+ return value_ == rhs.value_;
+ }
+
+ // The most significant bit represents whether or not the node ID is used as
+ // an offset. Note that the MSB is independent of the other bits.
+ bool is_offset() const {
+ return (value_ & IS_OFFSET_FLAG) == IS_OFFSET_FLAG;
+ }
+
+ UInt32 except_is_offset() const {
+ GRN_DAT_DEBUG_THROW_IF(is_phantom());
+ return value_ & ~IS_OFFSET_FLAG;
+ }
+
+ // A phantom node is a node that has never been used, and such a node is also
+ // called an empty element. Phantom nodes form a doubly linked list in each
+ // block, and the linked list is represented by next() and prev().
+ bool is_phantom() const {
+ return (value_ & IS_PHANTOM_FLAG) == IS_PHANTOM_FLAG;
+ }
+
+ UInt32 next() const {
+ GRN_DAT_DEBUG_THROW_IF(!is_phantom());
+ return (value_ >> NEXT_SHIFT) & BLOCK_MASK;
+ }
+ UInt32 prev() const {
+ GRN_DAT_DEBUG_THROW_IF(!is_phantom());
+ return (value_ >> PREV_SHIFT) & BLOCK_MASK;
+ }
+
+ // A label is attached to each non-phantom node. A label is represented by
+ // a byte except for a terminal label '\256'. Note that a phantom node always
+ // returns an invalid label with its phantom bit flag so as to reject invalid
+ // transitions.
+ UInt32 label() const {
+ return value_ & (IS_PHANTOM_FLAG | LABEL_MASK);
+ }
+
+ // A non-phantom node has the labels of the first child and the next sibling.
+ // Note that INVALID_LABEL is stored if the node has no child nodes or has
+ // no more siblings.
+ UInt32 child() const {
+ return (value_ >> CHILD_SHIFT) & LABEL_MASK;
+ }
+ UInt32 sibling() const {
+ return (value_ >> SIBLING_SHIFT) & LABEL_MASK;
+ }
+
+ void set_is_offset(bool x) {
+ if (x) {
+ GRN_DAT_DEBUG_THROW_IF(is_offset());
+ value_ |= IS_OFFSET_FLAG;
+ } else {
+ GRN_DAT_DEBUG_THROW_IF(!is_offset());
+ value_ &= ~IS_OFFSET_FLAG;
+ }
+ }
+
+ void set_except_is_offset(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(is_phantom());
+ GRN_DAT_DEBUG_THROW_IF((x & IS_OFFSET_FLAG) == IS_OFFSET_FLAG);
+ value_ = (value_ & IS_OFFSET_FLAG) | x;
+ }
+
+ // To reject a transition to an incomplete node, set_is_phantom() invalidates
+ // its label and links when it becomes non-phantom.
+ void set_is_phantom(bool x) {
+ if (x) {
+ GRN_DAT_DEBUG_THROW_IF(is_phantom());
+ value_ |= IS_PHANTOM_FLAG;
+ } else {
+ GRN_DAT_DEBUG_THROW_IF(!is_phantom());
+ value_ = (value_ & IS_OFFSET_FLAG) | (INVALID_LABEL << CHILD_SHIFT) |
+ (INVALID_LABEL << SIBLING_SHIFT) | INVALID_LABEL;
+ }
+ }
+
+ void set_next(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(!is_phantom());
+ GRN_DAT_DEBUG_THROW_IF(x > BLOCK_MASK);
+ value_ = (value_ & ~(BLOCK_MASK << NEXT_SHIFT)) | (x << NEXT_SHIFT);
+ }
+ void set_prev(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(!is_phantom());
+ GRN_DAT_DEBUG_THROW_IF(x > BLOCK_MASK);
+ value_ = (value_ & ~(BLOCK_MASK << PREV_SHIFT)) | (x << PREV_SHIFT);
+ }
+
+ void set_label(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(is_phantom());
+ GRN_DAT_DEBUG_THROW_IF(x > MAX_LABEL);
+ value_ = (value_ & ~LABEL_MASK) | x;
+ }
+
+ void set_child(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(is_phantom());
+ GRN_DAT_DEBUG_THROW_IF(x > MAX_LABEL);
+ value_ = (value_ & ~(LABEL_MASK << CHILD_SHIFT)) | (x << CHILD_SHIFT);
+ }
+ void set_sibling(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(is_phantom());
+ GRN_DAT_DEBUG_THROW_IF(label() > MAX_LABEL);
+ GRN_DAT_DEBUG_THROW_IF((sibling() != INVALID_LABEL) && (x == INVALID_LABEL));
+ value_ = (value_ & ~(LABEL_MASK << SIBLING_SHIFT)) | (x << SIBLING_SHIFT);
+ }
+
+ private:
+ UInt32 value_;
+
+ static const UInt32 IS_OFFSET_FLAG = 1U << 31;
+ static const UInt32 IS_PHANTOM_FLAG = 1U << 30;
+ static const UInt32 NEXT_SHIFT = 9;
+ static const UInt32 PREV_SHIFT = 18;
+ static const UInt32 CHILD_SHIFT = 9;
+ static const UInt32 SIBLING_SHIFT = 18;
+};
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/cursor-factory.cpp b/storage/mroonga/vendor/groonga/lib/dat/cursor-factory.cpp
new file mode 100644
index 00000000..0e97e527
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/cursor-factory.cpp
@@ -0,0 +1,92 @@
+/* -*- c-basic-offset: 2 -*- */
+/* Copyright(C) 2011 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-1335 USA
+*/
+
+#include "cursor-factory.hpp"
+#include "id-cursor.hpp"
+#include "key-cursor.hpp"
+#include "prefix-cursor.hpp"
+#include "predictive-cursor.hpp"
+
+#include <new>
+
+namespace grn {
+namespace dat {
+
+Cursor *CursorFactory::open(const Trie &trie,
+ const void *min_ptr, UInt32 min_length,
+ const void *max_ptr, UInt32 max_length,
+ UInt32 offset,
+ UInt32 limit,
+ UInt32 flags) {
+ const UInt32 cursor_type = flags & CURSOR_TYPE_MASK;
+ switch (cursor_type) {
+ case ID_RANGE_CURSOR: {
+ IdCursor *cursor = new (std::nothrow) IdCursor;
+ GRN_DAT_THROW_IF(MEMORY_ERROR, cursor == NULL);
+ try {
+ cursor->open(trie, String(min_ptr, min_length),
+ String(max_ptr, max_length), offset, limit, flags);
+ } catch (...) {
+ delete cursor;
+ throw;
+ }
+ return cursor;
+ }
+ case KEY_RANGE_CURSOR: {
+ KeyCursor *cursor = new (std::nothrow) KeyCursor;
+ GRN_DAT_THROW_IF(MEMORY_ERROR, cursor == NULL);
+ try {
+ cursor->open(trie, String(min_ptr, min_length),
+ String(max_ptr, max_length), offset, limit, flags);
+ } catch (...) {
+ delete cursor;
+ throw;
+ }
+ return cursor;
+ }
+ case PREFIX_CURSOR: {
+ PrefixCursor *cursor = new (std::nothrow) PrefixCursor;
+ GRN_DAT_THROW_IF(MEMORY_ERROR, cursor == NULL);
+ try {
+ cursor->open(trie, String(max_ptr, max_length), min_length,
+ offset, limit, flags);
+ } catch (...) {
+ delete cursor;
+ throw;
+ }
+ return cursor;
+ }
+ case PREDICTIVE_CURSOR: {
+ PredictiveCursor *cursor = new (std::nothrow) PredictiveCursor;
+ GRN_DAT_THROW_IF(MEMORY_ERROR, cursor == NULL);
+ try {
+ cursor->open(trie, String(min_ptr, min_length),
+ offset, limit, flags);
+ } catch (...) {
+ delete cursor;
+ throw;
+ }
+ return cursor;
+ }
+ default: {
+ GRN_DAT_THROW(PARAM_ERROR, "unknown cursor type");
+ }
+ }
+}
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/cursor-factory.hpp b/storage/mroonga/vendor/groonga/lib/dat/cursor-factory.hpp
new file mode 100644
index 00000000..d48ab16d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/cursor-factory.hpp
@@ -0,0 +1,44 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "cursor.hpp"
+
+namespace grn {
+namespace dat {
+
+class Trie;
+
+class GRN_DAT_API CursorFactory {
+ public:
+ static Cursor *open(const Trie &trie,
+ const void *min_ptr, UInt32 min_length,
+ const void *max_ptr, UInt32 max_length,
+ UInt32 offset = 0,
+ UInt32 limit = MAX_UINT32,
+ UInt32 flags = 0);
+
+ private:
+ // Disallows copy and assignment.
+ CursorFactory(const CursorFactory &);
+ CursorFactory &operator=(const CursorFactory &);
+};
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/cursor.hpp b/storage/mroonga/vendor/groonga/lib/dat/cursor.hpp
new file mode 100644
index 00000000..357b5250
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/cursor.hpp
@@ -0,0 +1,46 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "key.hpp"
+
+namespace grn {
+namespace dat {
+
+class GRN_DAT_API Cursor {
+ public:
+ Cursor() {}
+ virtual ~Cursor() {}
+
+ virtual void close() = 0;
+
+ virtual const Key &next() = 0;
+
+ virtual UInt32 offset() const = 0;
+ virtual UInt32 limit() const = 0;
+ virtual UInt32 flags() const = 0;
+
+ private:
+ // Disallows copy and assignment.
+ Cursor(const Cursor &);
+ Cursor &operator=(const Cursor &);
+};
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/dat.hpp b/storage/mroonga/vendor/groonga/lib/dat/dat.hpp
new file mode 100644
index 00000000..1afbd095
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/dat.hpp
@@ -0,0 +1,248 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#ifndef _MSC_VER
+# include <stddef.h>
+# include <stdint.h>
+#endif // _MSC_VER
+
+#include <cstddef>
+#include <exception>
+
+#ifdef _DEBUG
+# include <iostream>
+#endif // _DEBUG
+
+#ifndef GRN_DAT_API
+# ifdef WIN32
+# ifdef GRN_DAT_EXPORT
+# define GRN_DAT_API __declspec(dllexport)
+# else // GRN_DAT_EXPORT
+# define GRN_DAT_API __declspec(dllimport)
+# endif // GRN_DAT_EXPORT
+# else // WIN32
+# define GRN_DAT_API
+# endif // WIN32
+#endif // GRN_DAT_API
+
+#ifdef WIN32
+# define grn_memcpy(dest, src, n) ::memcpy_s((dest), (n), (src), (n))
+#else // WIN32
+# define grn_memcpy(dest, src, n) std::memcpy((dest), (src), (n))
+#endif // WIN32
+
+namespace grn {
+namespace dat {
+
+#ifdef _MSC_VER
+typedef unsigned __int8 UInt8;
+typedef unsigned __int16 UInt16;
+typedef unsigned __int32 UInt32;
+typedef unsigned __int64 UInt64;
+#else // _MSC_VER
+typedef ::uint8_t UInt8;
+typedef ::uint16_t UInt16;
+typedef ::uint32_t UInt32;
+typedef ::uint64_t UInt64;
+#endif // _MSC_VER
+
+const UInt8 MAX_UINT8 = static_cast<UInt8>(0xFFU);
+const UInt16 MAX_UINT16 = static_cast<UInt16>(0xFFFFU);
+const UInt32 MAX_UINT32 = static_cast<UInt32>(0xFFFFFFFFU);
+const UInt64 MAX_UINT64 = static_cast<UInt64>(0xFFFFFFFFFFFFFFFFULL);
+
+// If a key is a prefix of another key, such a key is associated with a special
+// terminal node which has TERMINAL_LABEL.
+const UInt16 TERMINAL_LABEL = 0x100;
+const UInt16 MIN_LABEL = '\0';
+const UInt16 MAX_LABEL = TERMINAL_LABEL;
+const UInt32 INVALID_LABEL = 0x1FF;
+const UInt32 LABEL_MASK = 0x1FF;
+
+// The MSB of BASE is used to represent whether the node is a linker node or
+// not and the other 31 bits represent the offset to its child nodes. So, the
+// number of nodes is limited to 2^31.
+const UInt32 ROOT_NODE_ID = 0;
+const UInt32 MAX_NODE_ID = 0x7FFFFFFF;
+const UInt32 MAX_NUM_NODES = MAX_NODE_ID + 1;
+const UInt32 INVALID_NODE_ID = MAX_NODE_ID + 1;
+
+// 0 is reserved for non-linker leaf nodes. For example, the root node of an
+// initial double-array is a non-linker leaf node.
+const UInt32 MAX_OFFSET = MAX_NODE_ID;
+const UInt32 INVALID_OFFSET = 0;
+
+// Phantom nodes are managed in each block because siblings are always put in
+// the same block.
+const UInt32 BLOCK_SIZE = 0x200;
+const UInt32 BLOCK_MASK = 0x1FF;
+const UInt32 MAX_BLOCK_ID = MAX_NODE_ID / BLOCK_SIZE;
+const UInt32 MAX_NUM_BLOCKS = MAX_BLOCK_ID + 1;
+
+// Blocks are divided by their levels, which indicate how easily update
+// operations can find a good offset in them. The level of a block rises when
+// find_offset() fails in that block many times. MAX_FAILURE_COUNT is the
+// threshold. Also, in order to limit the time cost, find_offset() scans at
+// most MAX_BLOCK_COUNT blocks.
+// Larger parameters bring more chances of finding good offsets but it leads to
+// more node renumberings, which are costly operations, and thus results in
+// a degradation of space/time efficiencies.
+const UInt32 MAX_FAILURE_COUNT = 4;
+const UInt32 MAX_BLOCK_COUNT = 16;
+const UInt32 MAX_BLOCK_LEVEL = 5;
+
+// Blocks in the same level compose a doubly linked list. The entry block of
+// a linked list is called a leader. INVALID_LEADER means that a linked list is
+// empty and there exists no leader.
+const UInt32 INVALID_LEADER = 0x7FFFFFFF;
+
+const UInt32 MIN_KEY_ID = 1;
+const UInt32 MAX_KEY_ID = MAX_NODE_ID;
+const UInt32 INVALID_KEY_ID = 0;
+
+// A key length is represented as a 12-bit unsigned integer in Key.
+// A key ID is represented as a 28-bit unsigned integer in Key.
+const UInt32 MAX_KEY_LENGTH = (1U << 12) - 1;
+const UInt32 MAX_NUM_KEYS = (1U << 28) - 1;
+
+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;
+
+const UInt32 ID_RANGE_CURSOR = 0x00001;
+const UInt32 KEY_RANGE_CURSOR = 0x00002;
+const UInt32 PREFIX_CURSOR = 0x00004;
+const UInt32 PREDICTIVE_CURSOR = 0x00008;
+const UInt32 CURSOR_TYPE_MASK = 0x000FF;
+
+const UInt32 ASCENDING_CURSOR = 0x00100;
+const UInt32 DESCENDING_CURSOR = 0x00200;
+const UInt32 CURSOR_ORDER_MASK = 0x00F00;
+
+const UInt32 EXCEPT_LOWER_BOUND = 0x01000;
+const UInt32 EXCEPT_UPPER_BOUND = 0x02000;
+const UInt32 EXCEPT_EXACT_MATCH = 0x04000;
+const UInt32 CURSOR_OPTIONS_MASK = 0xFF000;
+
+const UInt32 REMOVING_FLAG = 1U << 0;
+const UInt32 INSERTING_FLAG = 1U << 1;
+const UInt32 UPDATING_FLAG = 1U << 2;
+const UInt32 CHANGING_MASK = REMOVING_FLAG | INSERTING_FLAG | UPDATING_FLAG;
+
+const UInt32 MKQ_SORT_THRESHOLD = 10;
+
+enum ErrorCode {
+ PARAM_ERROR = -1,
+ IO_ERROR = -2,
+ FORMAT_ERROR = -3,
+ MEMORY_ERROR = -4,
+ SIZE_ERROR = -5,
+ UNEXPECTED_ERROR = -6,
+ STATUS_ERROR = -7
+};
+
+class Exception : public std::exception {
+ public:
+ Exception() throw()
+ : std::exception(),
+ file_(""),
+ line_(-1),
+ what_("") {}
+ Exception(const char *file, int line, const char *what) throw()
+ : std::exception(),
+ file_(file),
+ line_(line),
+ what_((what != NULL) ? what : "") {}
+ Exception(const Exception &ex) throw()
+ : std::exception(ex),
+ file_(ex.file_),
+ line_(ex.line_),
+ what_(ex.what_) {}
+ virtual ~Exception() throw() {}
+
+ virtual ErrorCode code() const throw() = 0;
+ virtual const char *file() const throw() {
+ return file_;
+ }
+ virtual int line() const throw() {
+ return line_;
+ }
+ virtual const char *what() const throw() {
+ return what_;
+ }
+
+ private:
+ const char *file_;
+ int line_;
+ const char *what_;
+};
+
+template <ErrorCode T>
+class Error : public Exception {
+ public:
+ Error() throw()
+ : Exception() {}
+ Error(const char *file, int line, const char *what) throw()
+ : Exception(file, line, what) {}
+ Error(const Error &ex) throw()
+ : Exception(ex) {}
+ virtual ~Error() throw() {}
+
+ virtual ErrorCode code() const throw() {
+ return T;
+ }
+};
+
+typedef Error<PARAM_ERROR> ParamError;
+typedef Error<IO_ERROR> IOError;
+typedef Error<FORMAT_ERROR> FormatError;
+typedef Error<MEMORY_ERROR> MemoryError;
+typedef Error<SIZE_ERROR> SizeError;
+typedef Error<UNEXPECTED_ERROR> UnexpectedError;
+typedef Error<STATUS_ERROR> StatusError;
+
+#define GRN_DAT_INT_TO_STR(value) #value
+#define GRN_DAT_LINE_TO_STR(line) GRN_DAT_INT_TO_STR(line)
+#define GRN_DAT_LINE_STR GRN_DAT_LINE_TO_STR(__LINE__)
+
+#define GRN_DAT_THROW(code, msg)\
+ (throw grn::dat::Error<code>(__FILE__, __LINE__,\
+ __FILE__ ":" GRN_DAT_LINE_STR ": " #code ": " msg))
+#define GRN_DAT_THROW_IF(code, cond)\
+ (void)((!(cond)) || (GRN_DAT_THROW(code, #cond), 0))
+
+#ifdef _DEBUG
+ #define GRN_DAT_DEBUG_THROW_IF(cond)\
+ GRN_DAT_THROW_IF(grn::dat::UNEXPECTED_ERROR, cond)
+ #define GRN_DAT_DEBUG_LOG(var)\
+ (std::clog << __FILE__ ":" GRN_DAT_LINE_STR ": " #var ": "\
+ << (var) << std::endl)
+#else // _DEBUG
+ #define GRN_DAT_DEBUG_THROW_IF(cond)
+ #define GRN_DAT_DEBUG_LOG(var)
+#endif // _DEBUG
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/entry.hpp b/storage/mroonga/vendor/groonga/lib/dat/entry.hpp
new file mode 100644
index 00000000..ecb9b53e
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/entry.hpp
@@ -0,0 +1,59 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "dat.hpp"
+
+namespace grn {
+namespace dat {
+
+// The most significant bit represents whether or not the entry is valid.
+// A valid entry stores the position of its associated key and an invalid entry
+// stores the index of the next invalid entry.
+class GRN_DAT_API Entry {
+ public:
+ Entry() : value_(0) {}
+
+ bool is_valid() const {
+ return (value_ & IS_VALID_FLAG) == IS_VALID_FLAG;
+ }
+ UInt32 key_pos() const {
+ GRN_DAT_DEBUG_THROW_IF(!is_valid());
+ return value_ & ~IS_VALID_FLAG;
+ }
+ UInt32 next() const {
+ GRN_DAT_DEBUG_THROW_IF(is_valid());
+ return value_;
+ }
+
+ void set_key_pos(UInt32 x) {
+ value_ = IS_VALID_FLAG | x;
+ }
+ void set_next(UInt32 x) {
+ value_ = x;
+ }
+
+ private:
+ UInt32 value_;
+
+ static const UInt32 IS_VALID_FLAG = 0x80000000U;
+};
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/file-impl.cpp b/storage/mroonga/vendor/groonga/lib/dat/file-impl.cpp
new file mode 100644
index 00000000..7032eff3
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/file-impl.cpp
@@ -0,0 +1,279 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#include "file-impl.hpp"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef WIN32
+# ifdef min
+# undef min
+# endif // min
+# ifdef max
+# undef max
+# endif // max
+#else // WIN32
+# include <fcntl.h>
+# include <sys/mman.h>
+# include <unistd.h>
+#endif // WIN32
+
+#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 0640
+#endif /* WIN32 */
+
+namespace grn {
+namespace dat {
+
+#ifdef WIN32
+
+FileImpl::FileImpl()
+ : ptr_(NULL),
+ size_(0),
+ file_(INVALID_HANDLE_VALUE),
+ map_(INVALID_HANDLE_VALUE),
+ addr_(NULL) {}
+
+FileImpl::~FileImpl() {
+ if (addr_ != NULL) {
+ ::UnmapViewOfFile(addr_);
+ }
+
+ if (map_ != INVALID_HANDLE_VALUE) {
+ ::CloseHandle(map_);
+ }
+
+ if (file_ != INVALID_HANDLE_VALUE) {
+ ::CloseHandle(file_);
+ }
+}
+
+#else // WIN32
+
+FileImpl::FileImpl()
+ : ptr_(NULL),
+ size_(0),
+ fd_(-1),
+ addr_(MAP_FAILED),
+ length_(0) {}
+
+FileImpl::~FileImpl() {
+ if (addr_ != MAP_FAILED) {
+ ::munmap(addr_, length_);
+ }
+
+ if (fd_ != -1) {
+ ::close(fd_);
+ }
+}
+
+#endif // WIN32
+
+void FileImpl::create(const char *path, UInt64 size) {
+ GRN_DAT_THROW_IF(PARAM_ERROR, size == 0);
+ GRN_DAT_THROW_IF(PARAM_ERROR,
+ size > static_cast<UInt64>(std::numeric_limits< ::size_t>::max()));
+
+ FileImpl new_impl;
+ new_impl.create_(path, size);
+ new_impl.swap(this);
+}
+
+void FileImpl::open(const char *path) {
+ GRN_DAT_THROW_IF(PARAM_ERROR, path == NULL);
+ GRN_DAT_THROW_IF(PARAM_ERROR, path[0] == '\0');
+
+ FileImpl new_impl;
+ new_impl.open_(path);
+ new_impl.swap(this);
+}
+
+void FileImpl::close() {
+ FileImpl new_impl;
+ new_impl.swap(this);
+}
+
+#ifdef WIN32
+
+void FileImpl::swap(FileImpl *rhs) {
+ std::swap(ptr_, rhs->ptr_);
+ std::swap(size_, rhs->size_);
+ std::swap(file_, rhs->file_);
+ std::swap(map_, rhs->map_);
+ std::swap(addr_, rhs->addr_);
+}
+
+void FileImpl::flush() {
+ if (!addr_) {
+ return;
+ }
+
+ 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_DELETE,
+ NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ GRN_DAT_THROW_IF(IO_ERROR, file_ == INVALID_HANDLE_VALUE);
+
+ const LONG size_low = static_cast<LONG>(size & 0xFFFFFFFFU);
+ LONG size_high = static_cast<LONG>(size >> 32);
+ const DWORD file_pos = ::SetFilePointer(file_, size_low, &size_high,
+ FILE_BEGIN);
+ GRN_DAT_THROW_IF(IO_ERROR, (file_pos == INVALID_SET_FILE_POINTER) &&
+ (::GetLastError() != 0));
+ GRN_DAT_THROW_IF(IO_ERROR, ::SetEndOfFile(file_) == 0);
+
+ map_ = ::CreateFileMapping(file_, NULL, PAGE_READWRITE, 0, 0, NULL);
+ GRN_DAT_THROW_IF(IO_ERROR, map_ == INVALID_HANDLE_VALUE);
+ } else {
+ const DWORD size_low = static_cast<DWORD>(size & 0xFFFFFFFFU);
+ const DWORD size_high = static_cast<DWORD>(size >> 32);
+
+ map_ = ::CreateFileMapping(file_, NULL, PAGE_READWRITE,
+ size_high, size_low, NULL);
+ GRN_DAT_THROW_IF(IO_ERROR, map_ == INVALID_HANDLE_VALUE);
+ }
+
+ addr_ = ::MapViewOfFile(map_, FILE_MAP_WRITE, 0, 0, 0);
+ GRN_DAT_THROW_IF(IO_ERROR, addr_ == NULL);
+
+ ptr_ = addr_;
+ size_ = static_cast< ::size_t>(size);
+}
+
+void FileImpl::open_(const char *path) {
+#ifdef _MSC_VER
+ struct __stat64 st;
+ GRN_DAT_THROW_IF(IO_ERROR, ::_stat64(path, &st) == -1);
+#else // _MSC_VER
+ struct _stat st;
+ GRN_DAT_THROW_IF(IO_ERROR, ::_stat(path, &st) == -1);
+#endif // _MSC_VER
+ GRN_DAT_THROW_IF(IO_ERROR, st.st_size == 0);
+ GRN_DAT_THROW_IF(IO_ERROR,
+ 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_DELETE,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ GRN_DAT_THROW_IF(IO_ERROR, file_ == NULL);
+
+ map_ = ::CreateFileMapping(file_, NULL, PAGE_READWRITE, 0, 0, NULL);
+ GRN_DAT_THROW_IF(IO_ERROR, map_ == NULL);
+
+ addr_ = ::MapViewOfFile(map_, FILE_MAP_WRITE, 0, 0, 0);
+ GRN_DAT_THROW_IF(IO_ERROR, addr_ == NULL);
+
+ ptr_ = addr_;
+ size_ = static_cast< ::size_t>(st.st_size);
+}
+
+#else // WIN32
+
+void FileImpl::swap(FileImpl *rhs) {
+ std::swap(ptr_, rhs->ptr_);
+ std::swap(size_, rhs->size_);
+ std::swap(fd_, rhs->fd_);
+ std::swap(addr_, rhs->addr_);
+ std::swap(length_, rhs->length_);
+}
+
+void FileImpl::flush() {
+ if (!addr_) {
+ return;
+ }
+
+ int result = ::msync(addr_, length_, MS_SYNC);
+ GRN_DAT_THROW_IF(IO_ERROR, result != 0);
+}
+
+void FileImpl::create_(const char *path, UInt64 size) {
+ GRN_DAT_THROW_IF(PARAM_ERROR,
+ size > static_cast<UInt64>(std::numeric_limits< ::off_t>::max()));
+
+ if ((path != NULL) && (path[0] != '\0')) {
+ fd_ = ::open(path, O_RDWR | O_CREAT | O_TRUNC, GRN_IO_FILE_CREATE_MODE);
+ GRN_DAT_THROW_IF(IO_ERROR, fd_ == -1);
+
+ const ::off_t file_size = static_cast< ::off_t>(size);
+ GRN_DAT_THROW_IF(IO_ERROR, ::ftruncate(fd_, file_size) == -1);
+ }
+
+#ifdef MAP_ANONYMOUS
+ const int flags = (fd_ == -1) ? (MAP_PRIVATE | MAP_ANONYMOUS) : MAP_SHARED;
+#else // MAP_ANONYMOUS
+ const int flags = (fd_ == -1) ? (MAP_PRIVATE | MAP_ANON) : MAP_SHARED;
+#endif // MAP_ANONYMOUS
+
+ length_ = static_cast< ::size_t>(size);
+#ifdef USE_MAP_HUGETLB
+ addr_ = ::mmap(NULL, length_, PROT_READ | PROT_WRITE,
+ flags | MAP_HUGETLB, fd_, 0);
+#endif // USE_MAP_HUGETLB
+ if (addr_ == MAP_FAILED) {
+ addr_ = ::mmap(NULL, length_, PROT_READ | PROT_WRITE, flags, fd_, 0);
+ GRN_DAT_THROW_IF(IO_ERROR, addr_ == MAP_FAILED);
+ }
+
+ ptr_ = addr_;
+ size_ = length_;
+}
+
+void FileImpl::open_(const char *path) {
+ struct stat st;
+ GRN_DAT_THROW_IF(IO_ERROR, ::stat(path, &st) == -1);
+ GRN_DAT_THROW_IF(IO_ERROR, (st.st_mode & S_IFMT) != S_IFREG);
+ GRN_DAT_THROW_IF(IO_ERROR, st.st_size == 0);
+ GRN_DAT_THROW_IF(IO_ERROR,
+ static_cast<UInt64>(st.st_size) > std::numeric_limits< ::size_t>::max());
+
+ fd_ = ::open(path, O_RDWR);
+ GRN_DAT_THROW_IF(IO_ERROR, fd_ == -1);
+
+ length_ = static_cast<std::size_t>(st.st_size);
+ addr_ = ::mmap(NULL, length_, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0);
+ GRN_DAT_THROW_IF(IO_ERROR, addr_ == MAP_FAILED);
+
+ ptr_ = addr_;
+ size_ = length_;
+}
+
+#endif // WIN32
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/file-impl.hpp b/storage/mroonga/vendor/groonga/lib/dat/file-impl.hpp
new file mode 100644
index 00000000..7b9c8c76
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/file-impl.hpp
@@ -0,0 +1,73 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#ifdef WIN32
+# include <windows.h>
+#endif // WIN32
+
+#include "dat.hpp"
+
+namespace grn {
+namespace dat {
+
+class FileImpl {
+ public:
+ FileImpl();
+ ~FileImpl();
+
+ void create(const char *path, UInt64 size);
+ void open(const char *path);
+ void close();
+
+ void *ptr() const {
+ return ptr_;
+ }
+ UInt64 size() const {
+ return size_;
+ }
+
+ void swap(FileImpl *rhs);
+
+ void flush();
+
+ private:
+ void *ptr_;
+ UInt64 size_;
+
+#ifdef WIN32
+ HANDLE file_;
+ HANDLE map_;
+ LPVOID addr_;
+#else // WIN32
+ int fd_;
+ void *addr_;
+ ::size_t length_;
+#endif // WIN32
+
+ void create_(const char *path, UInt64 size);
+ void open_(const char *path);
+
+ // Disallows copy and assignment.
+ FileImpl(const FileImpl &);
+ FileImpl &operator=(const FileImpl &);
+};
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/file.cpp b/storage/mroonga/vendor/groonga/lib/dat/file.cpp
new file mode 100644
index 00000000..84f2a1fb
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/file.cpp
@@ -0,0 +1,73 @@
+/* -*- c-basic-offset: 2 -*- */
+/* Copyright(C) 2011-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-1335 USA
+*/
+
+#include "file.hpp"
+#include "file-impl.hpp"
+
+#include <new>
+
+namespace grn {
+namespace dat {
+
+File::File() : impl_(NULL) {}
+
+File::~File() {
+ delete impl_;
+}
+
+void File::create(const char *path, UInt64 size) {
+ File new_file;
+ new_file.impl_ = new (std::nothrow) FileImpl;
+ GRN_DAT_THROW_IF(MEMORY_ERROR, new_file.impl_ == NULL);
+ new_file.impl_->create(path, size);
+ new_file.swap(this);
+}
+
+void File::open(const char *path) {
+ File new_file;
+ new_file.impl_ = new (std::nothrow) FileImpl;
+ GRN_DAT_THROW_IF(MEMORY_ERROR, new_file.impl_ == NULL);
+ new_file.impl_->open(path);
+ new_file.swap(this);
+}
+
+void File::close() {
+ File().swap(this);
+}
+
+void *File::ptr() const {
+ return (impl_ != NULL) ? impl_->ptr() : NULL;
+}
+
+UInt64 File::size() const {
+ return (impl_ != NULL) ? impl_->size() : 0;
+}
+
+void File::swap(File *rhs) {
+ FileImpl * const temp = impl_;
+ impl_ = rhs->impl_;
+ rhs->impl_ = temp;
+}
+
+void File::flush() {
+ if (impl_) {
+ impl_->flush();
+ }
+}
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/file.hpp b/storage/mroonga/vendor/groonga/lib/dat/file.hpp
new file mode 100644
index 00000000..722b93dd
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/file.hpp
@@ -0,0 +1,60 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "dat.hpp"
+
+namespace grn {
+namespace dat {
+
+// This implementation class hides environment dependent codes required for
+// memory-mapped I/O.
+class FileImpl;
+
+class GRN_DAT_API File {
+ public:
+ File();
+ ~File();
+
+ // This function creates a file and maps the entire file to a certain range
+ // of the address space. Note that a file is truncated if exists.
+ void create(const char *path, UInt64 size);
+
+ // This function opens a file and maps the entire file to a certain range of
+ // the address space.
+ void open(const char *path);
+ void close();
+
+ void *ptr() const;
+ UInt64 size() const;
+
+ void swap(File *rhs);
+
+ void flush();
+
+ private:
+ FileImpl *impl_;
+
+ // Disallows copy and assignment.
+ File(const File &);
+ File &operator=(const File &);
+};
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/header.hpp b/storage/mroonga/vendor/groonga/lib/dat/header.hpp
new file mode 100644
index 00000000..dbbb1efd
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/header.hpp
@@ -0,0 +1,179 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "dat.hpp"
+
+namespace grn {
+namespace dat {
+
+class GRN_DAT_API Header {
+ public:
+ Header()
+ : file_size_(0),
+ total_key_length_(0),
+ next_key_id_(grn::dat::MIN_KEY_ID),
+ max_key_id_(0),
+ num_keys_(0),
+ max_num_keys_(0),
+ num_phantoms_(0),
+ num_zombies_(0),
+ num_blocks_(0),
+ max_num_blocks_(0),
+ next_key_pos_(0),
+ key_buf_size_(0),
+ status_flags_(0) {
+ for (UInt32 i = 0; i <= MAX_BLOCK_LEVEL; ++i) {
+ leaders_[i] = INVALID_LEADER;
+ }
+ for (UInt32 i = 0; i < (sizeof(reserved_) / sizeof(*reserved_)); ++i) {
+ reserved_[i] = 0;
+ }
+ }
+
+ UInt64 file_size() const {
+ return file_size_;
+ }
+ UInt32 total_key_length() const {
+ return total_key_length_;
+ }
+ UInt32 min_key_id() const {
+ return MIN_KEY_ID;
+ }
+ UInt32 next_key_id() const {
+ return next_key_id_;
+ }
+ UInt32 max_key_id() const {
+ return max_key_id_;
+ }
+ UInt32 num_keys() const {
+ return num_keys_;
+ }
+ UInt32 max_num_keys() const {
+ return max_num_keys_;
+ }
+ UInt32 num_nodes() const {
+ return num_blocks() * BLOCK_SIZE;
+ }
+ UInt32 num_phantoms() const {
+ return num_phantoms_;
+ }
+ UInt32 num_zombies() const {
+ return num_zombies_;
+ }
+ UInt32 max_num_nodes() const {
+ return max_num_blocks() * BLOCK_SIZE;
+ }
+ UInt32 num_blocks() const {
+ return num_blocks_;
+ }
+ UInt32 max_num_blocks() const {
+ return max_num_blocks_;
+ }
+ UInt32 next_key_pos() const {
+ return next_key_pos_;
+ }
+ UInt32 key_buf_size() const {
+ return key_buf_size_;
+ }
+ UInt32 status_flags() const {
+ return status_flags_;
+ }
+ UInt32 ith_leader(UInt32 i) const {
+ GRN_DAT_DEBUG_THROW_IF(i > MAX_BLOCK_LEVEL);
+ return leaders_[i];
+ }
+
+ void set_file_size(UInt64 x) {
+ GRN_DAT_DEBUG_THROW_IF(x > MAX_FILE_SIZE);
+ file_size_ = x;
+ }
+ void set_total_key_length(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(x > MAX_TOTAL_KEY_LENGTH);
+ total_key_length_ = x;
+ }
+ void set_next_key_id(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF((x - 1) > MAX_KEY_ID);
+ next_key_id_ = x;
+ }
+ void set_max_key_id(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(x > MAX_KEY_ID);
+ max_key_id_ = x;
+ }
+ void set_num_keys(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(x > MAX_NUM_KEYS);
+ num_keys_ = x;
+ }
+ void set_max_num_keys(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(x > MAX_NUM_KEYS);
+ max_num_keys_ = x;
+ }
+ void set_num_phantoms(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(x > max_num_nodes());
+ num_phantoms_ = x;
+ }
+ void set_num_zombies(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(x > max_num_nodes());
+ num_zombies_ = x;
+ }
+ void set_num_blocks(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(x > max_num_blocks());
+ num_blocks_ = x;
+ }
+ void set_max_num_blocks(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(x > MAX_NUM_BLOCKS);
+ max_num_blocks_ = x;
+ }
+ void set_next_key_pos(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(x > key_buf_size());
+ next_key_pos_ = x;
+ }
+ void set_key_buf_size(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(x > MAX_KEY_BUF_SIZE);
+ key_buf_size_ = x;
+ }
+ void set_status_flags(UInt32 x) {
+ status_flags_ = x;
+ }
+ void set_ith_leader(UInt32 i, UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(i > MAX_BLOCK_LEVEL);
+ GRN_DAT_DEBUG_THROW_IF((x != INVALID_LEADER) && (x >= num_blocks()));
+ leaders_[i] = x;
+ }
+
+ private:
+ UInt64 file_size_;
+ UInt32 total_key_length_;
+ UInt32 next_key_id_;
+ UInt32 max_key_id_;
+ UInt32 num_keys_;
+ UInt32 max_num_keys_;
+ UInt32 num_phantoms_;
+ UInt32 num_zombies_;
+ UInt32 num_blocks_;
+ UInt32 max_num_blocks_;
+ UInt32 next_key_pos_;
+ UInt32 key_buf_size_;
+ UInt32 leaders_[MAX_BLOCK_LEVEL + 1];
+ UInt32 status_flags_;
+ UInt32 reserved_[12];
+};
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/id-cursor.cpp b/storage/mroonga/vendor/groonga/lib/dat/id-cursor.cpp
new file mode 100644
index 00000000..de969839
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/id-cursor.cpp
@@ -0,0 +1,184 @@
+/* -*- c-basic-offset: 2 -*- */
+/* Copyright(C) 2011 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-1335 USA
+*/
+
+#include "id-cursor.hpp"
+
+#include <algorithm>
+
+#include "trie.hpp"
+
+namespace grn {
+namespace dat {
+
+IdCursor::IdCursor()
+ : trie_(NULL),
+ offset_(0),
+ limit_(MAX_UINT32),
+ flags_(ID_RANGE_CURSOR),
+ cur_(INVALID_KEY_ID),
+ end_(INVALID_KEY_ID),
+ count_(0) {}
+
+IdCursor::~IdCursor() {}
+
+void IdCursor::open(const Trie &trie,
+ const String &min_str,
+ const String &max_str,
+ UInt32 offset,
+ UInt32 limit,
+ UInt32 flags) {
+ UInt32 min_id = INVALID_KEY_ID;
+ if (min_str.ptr() != NULL) {
+ UInt32 key_pos;
+ GRN_DAT_THROW_IF(PARAM_ERROR,
+ !trie.search(min_str.ptr(), min_str.length(), &key_pos));
+ min_id = trie.get_key(key_pos).id();
+ }
+
+ UInt32 max_id = INVALID_KEY_ID;
+ if (max_str.ptr() != NULL) {
+ UInt32 key_pos;
+ GRN_DAT_THROW_IF(PARAM_ERROR,
+ !trie.search(max_str.ptr(), max_str.length(), &key_pos));
+ max_id = trie.get_key(key_pos).id();
+ }
+
+ open(trie, min_id, max_id, offset, limit, flags);
+}
+
+void IdCursor::open(const Trie &trie,
+ UInt32 min_id,
+ UInt32 max_id,
+ UInt32 offset,
+ UInt32 limit,
+ UInt32 flags) {
+ flags = fix_flags(flags);
+
+ IdCursor new_cursor(trie, offset, limit, flags);
+ new_cursor.init(min_id, max_id);
+ new_cursor.swap(this);
+}
+
+void IdCursor::close() {
+ IdCursor new_cursor;
+ new_cursor.swap(this);
+}
+
+const Key &IdCursor::next() {
+ if (count_ >= limit_) {
+ return Key::invalid_key();
+ }
+ while (cur_ != end_) {
+ const Key &key = trie_->ith_key(cur_);
+ if ((flags_ & ASCENDING_CURSOR) == ASCENDING_CURSOR) {
+ ++cur_;
+ } else {
+ --cur_;
+ }
+ if (key.is_valid()) {
+ ++count_;
+ return key;
+ }
+ }
+ return Key::invalid_key();
+}
+
+IdCursor::IdCursor(const Trie &trie,
+ UInt32 offset,
+ UInt32 limit,
+ UInt32 flags)
+ : trie_(&trie),
+ offset_(offset),
+ limit_(limit),
+ flags_(flags),
+ cur_(INVALID_KEY_ID),
+ end_(INVALID_KEY_ID),
+ count_(0) {}
+
+UInt32 IdCursor::fix_flags(UInt32 flags) const {
+ const UInt32 cursor_type = flags & CURSOR_TYPE_MASK;
+ GRN_DAT_THROW_IF(PARAM_ERROR, (cursor_type != 0) &&
+ (cursor_type != ID_RANGE_CURSOR));
+ flags |= ID_RANGE_CURSOR;
+
+ const UInt32 cursor_order = flags & CURSOR_ORDER_MASK;
+ GRN_DAT_THROW_IF(PARAM_ERROR, (cursor_order != 0) &&
+ (cursor_order != ASCENDING_CURSOR) &&
+ (cursor_order != DESCENDING_CURSOR));
+ if (cursor_order == 0) {
+ flags |= ASCENDING_CURSOR;
+ }
+
+ const UInt32 cursor_options = flags & CURSOR_OPTIONS_MASK;
+ GRN_DAT_THROW_IF(PARAM_ERROR,
+ cursor_options & ~(EXCEPT_LOWER_BOUND | EXCEPT_UPPER_BOUND));
+
+ return flags;
+}
+
+void IdCursor::init(UInt32 min_id, UInt32 max_id) {
+ if (min_id == INVALID_KEY_ID) {
+ min_id = trie_->min_key_id();
+ } else if ((flags_ & EXCEPT_LOWER_BOUND) == EXCEPT_LOWER_BOUND) {
+ ++min_id;
+ }
+
+ if (max_id == INVALID_KEY_ID) {
+ max_id = trie_->max_key_id();
+ } else if ((flags_ & EXCEPT_UPPER_BOUND) == EXCEPT_UPPER_BOUND) {
+ --max_id;
+ }
+
+ if ((max_id < min_id) || ((max_id - min_id) < offset_)) {
+ return;
+ }
+
+ if ((flags_ & ASCENDING_CURSOR) == ASCENDING_CURSOR) {
+ cur_ = min_id;
+ end_ = max_id + 1;
+ for (UInt32 i = 0; (i < offset_) && (cur_ != end_); ++i) {
+ while (cur_ != end_) {
+ if (trie_->ith_key(cur_++).is_valid()) {
+ break;
+ }
+ }
+ }
+ } else {
+ cur_ = max_id;
+ end_ = min_id - 1;
+ for (UInt32 i = 0; (i < offset_) && (cur_ != end_); ++i) {
+ while (cur_ != end_) {
+ if (trie_->ith_key(cur_--).is_valid()) {
+ break;
+ }
+ }
+ }
+ }
+}
+
+void IdCursor::swap(IdCursor *cursor) {
+ std::swap(trie_, cursor->trie_);
+ std::swap(offset_, cursor->offset_);
+ std::swap(limit_, cursor->limit_);
+ std::swap(flags_, cursor->flags_);
+ std::swap(cur_, cursor->cur_);
+ std::swap(end_, cursor->end_);
+ std::swap(count_, cursor->count_);
+}
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/id-cursor.hpp b/storage/mroonga/vendor/groonga/lib/dat/id-cursor.hpp
new file mode 100644
index 00000000..60953fae
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/id-cursor.hpp
@@ -0,0 +1,83 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "cursor.hpp"
+
+namespace grn {
+namespace dat {
+
+class Trie;
+
+class GRN_DAT_API IdCursor : public Cursor {
+ public:
+ IdCursor();
+ ~IdCursor();
+
+ void open(const Trie &trie,
+ const String &min_str,
+ const String &max_str,
+ UInt32 offset = 0,
+ UInt32 limit = MAX_UINT32,
+ UInt32 flags = 0);
+
+ void open(const Trie &trie,
+ UInt32 min_id,
+ UInt32 max_id,
+ UInt32 offset = 0,
+ UInt32 limit = MAX_UINT32,
+ UInt32 flags = 0);
+
+ void close();
+
+ const Key &next();
+
+ UInt32 offset() const {
+ return offset_;
+ }
+ UInt32 limit() const {
+ return limit_;
+ }
+ UInt32 flags() const {
+ return flags_;
+ }
+
+ private:
+ const Trie *trie_;
+ UInt32 offset_;
+ UInt32 limit_;
+ UInt32 flags_;
+
+ UInt32 cur_;
+ UInt32 end_;
+ UInt32 count_;
+
+ IdCursor(const Trie &trie, UInt32 offset, UInt32 limit, UInt32 flags);
+
+ UInt32 fix_flags(UInt32 flags) const;
+ void init(UInt32 min_id, UInt32 max_id);
+ void swap(IdCursor *cursor);
+
+ // Disallows copy and assignment.
+ IdCursor(const IdCursor &);
+ IdCursor &operator=(const IdCursor &);
+};
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/key-cursor.cpp b/storage/mroonga/vendor/groonga/lib/dat/key-cursor.cpp
new file mode 100644
index 00000000..2ce04fee
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/key-cursor.cpp
@@ -0,0 +1,349 @@
+/* -*- c-basic-offset: 2 -*- */
+/* Copyright(C) 2011 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-1335 USA
+*/
+
+#include "key-cursor.hpp"
+
+#include <algorithm>
+#include <cstring>
+
+#include "trie.hpp"
+
+namespace grn {
+namespace dat {
+
+KeyCursor::KeyCursor()
+ : trie_(NULL),
+ offset_(0),
+ limit_(MAX_UINT32),
+ flags_(KEY_RANGE_CURSOR),
+ buf_(),
+ count_(0),
+ max_count_(0),
+ finished_(false),
+ end_buf_(NULL),
+ end_str_() {}
+
+KeyCursor::~KeyCursor() {
+ if (end_buf_ != NULL) {
+ delete [] end_buf_;
+ }
+}
+
+void KeyCursor::open(const Trie &trie,
+ const String &min_str,
+ const String &max_str,
+ UInt32 offset,
+ UInt32 limit,
+ UInt32 flags) {
+ GRN_DAT_THROW_IF(PARAM_ERROR,
+ (min_str.ptr() == NULL) && (min_str.length() != 0));
+ GRN_DAT_THROW_IF(PARAM_ERROR,
+ (max_str.ptr() == NULL) && (max_str.length() != 0));
+
+ flags = fix_flags(flags);
+ KeyCursor new_cursor(trie, offset, limit, flags);
+ new_cursor.init(min_str, max_str);
+ new_cursor.swap(this);
+}
+
+void KeyCursor::close() {
+ KeyCursor new_cursor;
+ new_cursor.swap(this);
+}
+
+const Key &KeyCursor::next() {
+ if (finished_ || (count_ >= max_count_)) {
+ return Key::invalid_key();
+ }
+
+ if ((flags_ & ASCENDING_CURSOR) == ASCENDING_CURSOR) {
+ return ascending_next();
+ } else {
+ return descending_next();
+ }
+}
+
+KeyCursor::KeyCursor(const Trie &trie,
+ UInt32 offset, UInt32 limit, UInt32 flags)
+ : trie_(&trie),
+ offset_(offset),
+ limit_(limit),
+ flags_(flags),
+ buf_(),
+ count_(0),
+ max_count_(0),
+ finished_(false),
+ end_buf_(NULL),
+ end_str_() {}
+
+UInt32 KeyCursor::fix_flags(UInt32 flags) const {
+ const UInt32 cursor_type = flags & CURSOR_TYPE_MASK;
+ GRN_DAT_THROW_IF(PARAM_ERROR, (cursor_type != 0) &&
+ (cursor_type != KEY_RANGE_CURSOR));
+ flags |= KEY_RANGE_CURSOR;
+
+ const UInt32 cursor_order = flags & CURSOR_ORDER_MASK;
+ GRN_DAT_THROW_IF(PARAM_ERROR, (cursor_order != 0) &&
+ (cursor_order != ASCENDING_CURSOR) &&
+ (cursor_order != DESCENDING_CURSOR));
+ if (cursor_order == 0) {
+ flags |= ASCENDING_CURSOR;
+ }
+
+ const UInt32 cursor_options = flags & CURSOR_OPTIONS_MASK;
+ GRN_DAT_THROW_IF(PARAM_ERROR,
+ cursor_options & ~(EXCEPT_LOWER_BOUND | EXCEPT_UPPER_BOUND));
+
+ return flags;
+}
+
+void KeyCursor::init(const String &min_str, const String &max_str) {
+ if (offset_ > (MAX_UINT32 - limit_)) {
+ max_count_ = MAX_UINT32;
+ } else {
+ max_count_ = offset_ + limit_;
+ }
+
+ if (limit_ == 0) {
+ return;
+ }
+
+ if ((flags_ & ASCENDING_CURSOR) == ASCENDING_CURSOR) {
+ ascending_init(min_str, max_str);
+ } else {
+ descending_init(min_str, max_str);
+ }
+}
+
+void KeyCursor::ascending_init(const String &min_str, const String &max_str) {
+ if (max_str.ptr() != NULL) {
+ if (max_str.length() != 0) {
+ end_buf_ = new UInt8[max_str.length()];
+ grn_memcpy(end_buf_, max_str.ptr(), max_str.length());
+ end_str_.assign(end_buf_, max_str.length());
+ }
+ }
+
+ if ((min_str.ptr() == NULL) || (min_str.length() == 0)) {
+ buf_.push_back(ROOT_NODE_ID);
+ return;
+ }
+
+ UInt32 node_id = ROOT_NODE_ID;
+ Node node;
+ for (UInt32 i = 0; i < min_str.length(); ++i) {
+ node = trie_->ith_node(node_id);
+ if (node.is_linker()) {
+ const Key &key = trie_->get_key(node.key_pos());
+ const int result = key.str().compare(min_str, i);
+ if ((result > 0) || ((result == 0) &&
+ ((flags_ & EXCEPT_LOWER_BOUND) != EXCEPT_LOWER_BOUND))) {
+ buf_.push_back(node_id);
+ } else if (node.sibling() != INVALID_LABEL) {
+ buf_.push_back(node_id ^ node.label() ^ node.sibling());
+ }
+ return;
+ } else if (node.sibling() != INVALID_LABEL) {
+ buf_.push_back(node_id ^ node.label() ^ node.sibling());
+ }
+
+ node_id = node.offset() ^ min_str[i];
+ if (trie_->ith_node(node_id).label() != min_str[i]) {
+ UInt16 label = node.child();
+ if (label == TERMINAL_LABEL) {
+ label = trie_->ith_node(node.offset() ^ label).sibling();
+ }
+ while (label != INVALID_LABEL) {
+ if (label > min_str[i]) {
+ buf_.push_back(node.offset() ^ label);
+ break;
+ }
+ label = trie_->ith_node(node.offset() ^ label).sibling();
+ }
+ return;
+ }
+ }
+
+ node = trie_->ith_node(node_id);
+ if (node.is_linker()) {
+ const Key &key = trie_->get_key(node.key_pos());
+ if ((key.length() != min_str.length()) ||
+ ((flags_ & EXCEPT_LOWER_BOUND) != EXCEPT_LOWER_BOUND)) {
+ buf_.push_back(node_id);
+ } else if (node.sibling() != INVALID_LABEL) {
+ buf_.push_back(node_id ^ node.label() ^ node.sibling());
+ }
+ return;
+ } else if (node.sibling() != INVALID_LABEL) {
+ buf_.push_back(node_id ^ node.label() ^ node.sibling());
+ }
+
+ UInt16 label = node.child();
+ if ((label == TERMINAL_LABEL) &&
+ ((flags_ & EXCEPT_LOWER_BOUND) == EXCEPT_LOWER_BOUND)) {
+ label = trie_->ith_node(node.offset() ^ label).sibling();
+ }
+ if (label != INVALID_LABEL) {
+ buf_.push_back(node.offset() ^ label);
+ }
+}
+
+void KeyCursor::descending_init(const String &min_str, const String &max_str) {
+ if (min_str.ptr() != NULL) {
+ if (min_str.length() != 0) {
+ end_buf_ = new UInt8[min_str.length()];
+ grn_memcpy(end_buf_, min_str.ptr(), min_str.length());
+ end_str_.assign(end_buf_, min_str.length());
+ }
+ }
+
+ if ((max_str.ptr() == NULL) || (max_str.length() == 0)) {
+ buf_.push_back(ROOT_NODE_ID);
+ return;
+ }
+
+ UInt32 node_id = ROOT_NODE_ID;
+ for (UInt32 i = 0; i < max_str.length(); ++i) {
+ const Base base = trie_->ith_node(node_id).base();
+ if (base.is_linker()) {
+ const Key &key = trie_->get_key(base.key_pos());
+ const int result = key.str().compare(max_str, i);
+ if ((result < 0) || ((result == 0) &&
+ ((flags_ & EXCEPT_UPPER_BOUND) != EXCEPT_UPPER_BOUND))) {
+ buf_.push_back(node_id | POST_ORDER_FLAG);
+ }
+ return;
+ }
+
+ UInt32 label = trie_->ith_node(node_id).child();
+ if (label == TERMINAL_LABEL) {
+ node_id = base.offset() ^ label;
+ buf_.push_back(node_id | POST_ORDER_FLAG);
+ label = trie_->ith_node(node_id).sibling();
+ }
+ while (label != INVALID_LABEL) {
+ node_id = base.offset() ^ label;
+ if (label < max_str[i]) {
+ buf_.push_back(node_id);
+ } else if (label > max_str[i]) {
+ return;
+ } else {
+ break;
+ }
+ label = trie_->ith_node(node_id).sibling();
+ }
+ if (label == INVALID_LABEL) {
+ return;
+ }
+ }
+
+ const Base base = trie_->ith_node(node_id).base();
+ if (base.is_linker()) {
+ const Key &key = trie_->get_key(base.key_pos());
+ if ((key.length() == max_str.length()) &&
+ ((flags_ & EXCEPT_UPPER_BOUND) != EXCEPT_UPPER_BOUND)) {
+ buf_.push_back(node_id | POST_ORDER_FLAG);
+ }
+ return;
+ }
+
+ UInt16 label = trie_->ith_node(node_id).child();
+ if ((label == TERMINAL_LABEL) &&
+ ((flags_ & EXCEPT_UPPER_BOUND) != EXCEPT_UPPER_BOUND)) {
+ buf_.push_back((base.offset() ^ label) | POST_ORDER_FLAG);
+ }
+}
+
+void KeyCursor::swap(KeyCursor *cursor) {
+ std::swap(trie_, cursor->trie_);
+ std::swap(offset_, cursor->offset_);
+ std::swap(limit_, cursor->limit_);
+ std::swap(flags_, cursor->flags_);
+ buf_.swap(&cursor->buf_);
+ std::swap(count_, cursor->count_);
+ std::swap(max_count_, cursor->max_count_);
+ std::swap(finished_, cursor->finished_);
+ std::swap(end_buf_, cursor->end_buf_);
+ end_str_.swap(&cursor->end_str_);
+}
+
+const Key &KeyCursor::ascending_next() {
+ while (!buf_.empty()) {
+ const UInt32 node_id = buf_.back();
+ buf_.pop_back();
+
+ const Node node = trie_->ith_node(node_id);
+ if (node.sibling() != INVALID_LABEL) {
+ buf_.push_back(node_id ^ node.label() ^ node.sibling());
+ }
+
+ if (node.is_linker()) {
+ const Key &key = trie_->get_key(node.key_pos());
+ if (end_buf_ != NULL) {
+ const int result = key.str().compare(end_str_);
+ if ((result > 0) || ((result == 0) &&
+ ((flags_ & EXCEPT_UPPER_BOUND) == EXCEPT_UPPER_BOUND))) {
+ finished_ = true;
+ return Key::invalid_key();
+ }
+ }
+ if (count_++ >= offset_) {
+ return key;
+ }
+ } else if (node.child() != INVALID_LABEL) {
+ buf_.push_back(node.offset() ^ node.child());
+ }
+ }
+ return Key::invalid_key();
+}
+
+const Key &KeyCursor::descending_next() {
+ while (!buf_.empty()) {
+ const bool post_order = (buf_.back() & POST_ORDER_FLAG) == POST_ORDER_FLAG;
+ const UInt32 node_id = buf_.back() & ~POST_ORDER_FLAG;
+
+ const Base base = trie_->ith_node(node_id).base();
+ if (post_order) {
+ buf_.pop_back();
+ if (base.is_linker()) {
+ const Key &key = trie_->get_key(base.key_pos());
+ if (end_buf_ != NULL) {
+ const int result = key.str().compare(end_str_);
+ if ((result < 0) || ((result == 0) &&
+ ((flags_ & EXCEPT_LOWER_BOUND) == EXCEPT_LOWER_BOUND))) {
+ finished_ = true;
+ return Key::invalid_key();
+ }
+ }
+ if (count_++ >= offset_) {
+ return key;
+ }
+ }
+ } else {
+ buf_.back() |= POST_ORDER_FLAG;
+ UInt16 label = trie_->ith_node(node_id).child();
+ while (label != INVALID_LABEL) {
+ buf_.push_back(base.offset() ^ label);
+ label = trie_->ith_node(base.offset() ^ label).sibling();
+ }
+ }
+ }
+ return Key::invalid_key();
+}
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/key-cursor.hpp b/storage/mroonga/vendor/groonga/lib/dat/key-cursor.hpp
new file mode 100644
index 00000000..56392b63
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/key-cursor.hpp
@@ -0,0 +1,88 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "cursor.hpp"
+#include "vector.hpp"
+
+namespace grn {
+namespace dat {
+
+class Trie;
+
+class GRN_DAT_API KeyCursor : public Cursor {
+ public:
+ KeyCursor();
+ ~KeyCursor();
+
+ void open(const Trie &trie,
+ const String &min_str,
+ const String &max_str,
+ UInt32 offset = 0,
+ UInt32 limit = MAX_UINT32,
+ UInt32 flags = 0);
+
+ void close();
+
+ const Key &next();
+
+ UInt32 offset() const {
+ return offset_;
+ }
+ UInt32 limit() const {
+ return limit_;
+ }
+ UInt32 flags() const {
+ return flags_;
+ }
+
+ private:
+ const Trie *trie_;
+ UInt32 offset_;
+ UInt32 limit_;
+ UInt32 flags_;
+
+ Vector<UInt32> buf_;
+ UInt32 count_;
+ UInt32 max_count_;
+ bool finished_;
+ UInt8 *end_buf_;
+ String end_str_;
+
+ KeyCursor(const Trie &trie,
+ UInt32 offset, UInt32 limit, UInt32 flags);
+
+ UInt32 fix_flags(UInt32 flags) const;
+ void init(const String &min_str, const String &max_str);
+ void ascending_init(const String &min_str, const String &max_str);
+ void descending_init(const String &min_str, const String &max_str);
+ void swap(KeyCursor *cursor);
+
+ const Key &ascending_next();
+ const Key &descending_next();
+
+ static const UInt32 POST_ORDER_FLAG = 0x80000000U;
+
+ // Disallows copy and assignment.
+ KeyCursor(const KeyCursor &);
+ KeyCursor &operator=(const KeyCursor &);
+};
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/key.hpp b/storage/mroonga/vendor/groonga/lib/dat/key.hpp
new file mode 100644
index 00000000..eb0324cd
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/key.hpp
@@ -0,0 +1,110 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "string.hpp"
+
+namespace grn {
+namespace dat {
+
+class GRN_DAT_API Key {
+ public:
+ const UInt8 &operator[](UInt32 i) const {
+ GRN_DAT_DEBUG_THROW_IF(i >= length());
+ return buf_[i];
+ }
+
+ bool is_valid() const {
+ return id() != INVALID_KEY_ID;
+ }
+
+ String str() const {
+ return String(ptr(), length());
+ }
+
+ const void *ptr() const {
+ return buf_;
+ }
+ UInt32 length() const {
+ return (length_high_ << 4) | (id_and_length_low_ & 0x0F);
+ }
+ UInt32 id() const {
+ return id_and_length_low_ >> 4;
+ }
+
+ bool equals_to(const void *ptr, UInt32 length, UInt32 offset = 0) const {
+ if (length != this->length()) {
+ return false;
+ }
+ for ( ; offset < length; ++offset) {
+ if ((*this)[offset] != static_cast<const UInt8 *>(ptr)[offset]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // Creates an object of Key from given parameters. Then, the created object
+ // is embedded into a specified buffer.
+ static const Key &create(UInt32 *buf, UInt32 key_id,
+ const void *key_ptr, UInt32 key_length) {
+ GRN_DAT_DEBUG_THROW_IF(buf == NULL);
+ GRN_DAT_DEBUG_THROW_IF(key_id > MAX_KEY_ID);
+ GRN_DAT_DEBUG_THROW_IF((key_ptr == NULL) && (key_length != 0));
+ GRN_DAT_DEBUG_THROW_IF(key_length > MAX_KEY_LENGTH);
+
+ *buf = (key_id << 4) | (key_length & 0x0F);
+ UInt8 *ptr = reinterpret_cast<UInt8 *>(buf + 1);
+ *ptr++ = key_length >> 4;
+ for (UInt32 i = 0; i < key_length; ++i) {
+ ptr[i] = static_cast<const UInt8 *>(key_ptr)[i];
+ }
+ return *reinterpret_cast<const Key *>(buf);
+ }
+
+ // Calculates how many UInt32s are required for a string. It is guaranteed
+ // that the estimated size is not less than the actual size.
+ static UInt32 estimate_size(UInt32 length) {
+ return 2 + (length / sizeof(UInt32));
+ }
+
+ // Returns a reference to an invalid key.
+ static const Key &invalid_key() {
+ static const Key invalid_key;
+ return invalid_key;
+// static const UInt32 invalid_key_buf[2] = { INVALID_KEY_ID << 4, 0 };
+// return *reinterpret_cast<const Key *>(invalid_key_buf);
+ }
+
+ private:
+ UInt32 id_and_length_low_;
+ UInt8 length_high_;
+ UInt8 buf_[3];
+
+ // Disallows instantiation.
+ Key() : id_and_length_low_(INVALID_KEY_ID << 4), length_high_(0) {}
+ ~Key() {}
+
+ // Disallows copy and assignment.
+ Key(const Key &);
+ Key &operator=(const Key &);
+};
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/node.hpp b/storage/mroonga/vendor/groonga/lib/dat/node.hpp
new file mode 100644
index 00000000..29febc7d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/node.hpp
@@ -0,0 +1,127 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+// See base.hpp and check.hpp for details.
+#include "base.hpp"
+#include "check.hpp"
+
+namespace grn {
+namespace dat {
+
+class GRN_DAT_API Node {
+ public:
+ Node() : base_(), check_() {}
+
+ Base base() const {
+ return base_;
+ }
+ bool is_linker() const {
+ GRN_DAT_DEBUG_THROW_IF(is_phantom());
+ return base_.is_linker();
+ }
+ UInt32 offset() const {
+ GRN_DAT_DEBUG_THROW_IF(is_phantom());
+ return base_.offset();
+ }
+ UInt32 key_pos() const {
+ GRN_DAT_DEBUG_THROW_IF(is_phantom());
+ return base_.key_pos();
+ }
+
+ Check check() const {
+ return check_;
+ }
+ bool is_offset() const {
+ return check_.is_offset();
+ }
+ UInt32 except_is_offset() const {
+ return check_.except_is_offset();
+ }
+ bool is_phantom() const {
+ return check_.is_phantom();
+ }
+ UInt32 next() const {
+ return check_.next();
+ }
+ UInt32 prev() const {
+ return check_.prev();
+ }
+ UInt32 label() const {
+ return check_.label();
+ }
+ UInt32 child() const {
+ return check_.child();
+ }
+ UInt32 sibling() const {
+ return check_.sibling();
+ }
+
+ void set_base(Base x) {
+ GRN_DAT_DEBUG_THROW_IF(is_phantom());
+ base_ = x;
+ }
+ void set_offset(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(is_phantom());
+ base_.set_offset(x);
+ }
+ void set_key_pos(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(is_phantom());
+ base_.set_key_pos(x);
+ }
+
+ void set_check(Check x) {
+ check_ = x;
+ }
+ void set_is_offset(bool x) {
+ check_.set_is_offset(x);
+ }
+ void set_except_is_offset(UInt32 x) {
+ check_.set_except_is_offset(x);
+ }
+ void set_is_phantom(bool x) {
+ GRN_DAT_DEBUG_THROW_IF(base_.offset() != INVALID_OFFSET);
+ check_.set_is_phantom(x);
+ }
+ void set_next(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(base_.offset() != INVALID_OFFSET);
+ check_.set_next(x);
+ }
+ void set_prev(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(base_.offset() != INVALID_OFFSET);
+ check_.set_prev(x);
+ }
+ void set_label(UInt32 x) {
+ GRN_DAT_DEBUG_THROW_IF(offset() != INVALID_OFFSET);
+ check_.set_label(x);
+ }
+ void set_child(UInt32 x) {
+ check_.set_child(x);
+ }
+ void set_sibling(UInt32 x) {
+ check_.set_sibling(x);
+ }
+
+ private:
+ Base base_;
+ Check check_;
+};
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/predictive-cursor.cpp b/storage/mroonga/vendor/groonga/lib/dat/predictive-cursor.cpp
new file mode 100644
index 00000000..67520305
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/predictive-cursor.cpp
@@ -0,0 +1,206 @@
+/* -*- c-basic-offset: 2 -*- */
+/* Copyright(C) 2011 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-1335 USA
+*/
+
+#include "predictive-cursor.hpp"
+
+#include <algorithm>
+#include <cstring>
+
+#include "trie.hpp"
+
+namespace grn {
+namespace dat {
+
+PredictiveCursor::PredictiveCursor()
+ : trie_(NULL),
+ offset_(0),
+ limit_(MAX_UINT32),
+ flags_(PREDICTIVE_CURSOR),
+ buf_(),
+ cur_(0),
+ end_(0),
+ min_length_(0) {}
+
+PredictiveCursor::~PredictiveCursor() {}
+
+void PredictiveCursor::open(const Trie &trie,
+ const String &str,
+ UInt32 offset,
+ UInt32 limit,
+ UInt32 flags) {
+ GRN_DAT_THROW_IF(PARAM_ERROR, (str.ptr() == NULL) && (str.length() != 0));
+
+ flags = fix_flags(flags);
+ PredictiveCursor new_cursor(trie, offset, limit, flags);
+ new_cursor.init(str);
+ new_cursor.swap(this);
+}
+
+void PredictiveCursor::close() {
+ PredictiveCursor new_cursor;
+ new_cursor.swap(this);
+}
+
+const Key &PredictiveCursor::next() {
+ if (cur_ == end_) {
+ return Key::invalid_key();
+ }
+
+ if ((flags_ & ASCENDING_CURSOR) == ASCENDING_CURSOR) {
+ return ascending_next();
+ } else {
+ return descending_next();
+ }
+}
+
+PredictiveCursor::PredictiveCursor(const Trie &trie,
+ UInt32 offset, UInt32 limit, UInt32 flags)
+ : trie_(&trie),
+ offset_(offset),
+ limit_(limit),
+ flags_(flags),
+ buf_(),
+ cur_(0),
+ end_(0),
+ min_length_(0) {}
+
+UInt32 PredictiveCursor::fix_flags(UInt32 flags) const {
+ const UInt32 cursor_type = flags & CURSOR_TYPE_MASK;
+ GRN_DAT_THROW_IF(PARAM_ERROR, (cursor_type != 0) &&
+ (cursor_type != PREDICTIVE_CURSOR));
+ flags |= PREDICTIVE_CURSOR;
+
+ const UInt32 cursor_order = flags & CURSOR_ORDER_MASK;
+ GRN_DAT_THROW_IF(PARAM_ERROR, (cursor_order != 0) &&
+ (cursor_order != ASCENDING_CURSOR) &&
+ (cursor_order != DESCENDING_CURSOR));
+ if (cursor_order == 0) {
+ flags |= ASCENDING_CURSOR;
+ }
+
+ const UInt32 cursor_options = flags & CURSOR_OPTIONS_MASK;
+ GRN_DAT_THROW_IF(PARAM_ERROR, cursor_options & ~(EXCEPT_EXACT_MATCH));
+
+ return flags;
+}
+
+void PredictiveCursor::init(const String &str) {
+ if (limit_ == 0) {
+ return;
+ }
+
+ min_length_ = str.length();
+ if ((flags_ & EXCEPT_EXACT_MATCH) == EXCEPT_EXACT_MATCH) {
+ ++min_length_;
+ }
+ end_ = (offset_ > (MAX_UINT32 - limit_)) ? MAX_UINT32 : (offset_ + limit_);
+
+ UInt32 node_id = ROOT_NODE_ID;
+ for (UInt32 i = 0; i < str.length(); ++i) {
+ const Base base = trie_->ith_node(node_id).base();
+ if (base.is_linker()) {
+ if (offset_ == 0) {
+ const Key &key = trie_->get_key(base.key_pos());
+ if ((key.length() >= str.length()) &&
+ (key.str().substr(0, str.length()).compare(str, i) == 0)) {
+ if ((flags_ & ASCENDING_CURSOR) == ASCENDING_CURSOR) {
+ node_id |= IS_ROOT_FLAG;
+ }
+ buf_.push_back(node_id);
+ }
+ }
+ return;
+ }
+
+ node_id = base.offset() ^ str[i];
+ if (trie_->ith_node(node_id).label() != str[i]) {
+ return;
+ }
+ }
+
+ if ((flags_ & ASCENDING_CURSOR) == ASCENDING_CURSOR) {
+ node_id |= IS_ROOT_FLAG;
+ }
+ buf_.push_back(node_id);
+}
+
+void PredictiveCursor::swap(PredictiveCursor *cursor) {
+ std::swap(trie_, cursor->trie_);
+ std::swap(offset_, cursor->offset_);
+ std::swap(limit_, cursor->limit_);
+ std::swap(flags_, cursor->flags_);
+ buf_.swap(&cursor->buf_);
+ std::swap(cur_, cursor->cur_);
+ std::swap(end_, cursor->end_);
+ std::swap(min_length_, cursor->min_length_);
+}
+
+const Key &PredictiveCursor::ascending_next() {
+ while (!buf_.empty()) {
+ const bool is_root = (buf_.back() & IS_ROOT_FLAG) == IS_ROOT_FLAG;
+ const UInt32 node_id = buf_.back() & ~IS_ROOT_FLAG;
+ buf_.pop_back();
+
+ const Node node = trie_->ith_node(node_id);
+ if (!is_root && (node.sibling() != INVALID_LABEL)) {
+ buf_.push_back(node_id ^ node.label() ^ node.sibling());
+ }
+
+ if (node.is_linker()) {
+ const Key &key = trie_->get_key(node.key_pos());
+ if (key.length() >= min_length_) {
+ if (cur_++ >= offset_) {
+ return key;
+ }
+ }
+ } else if (node.child() != INVALID_LABEL) {
+ buf_.push_back(node.offset() ^ node.child());
+ }
+ }
+ return Key::invalid_key();
+}
+
+const Key &PredictiveCursor::descending_next() {
+ while (!buf_.empty()) {
+ const bool post_order = (buf_.back() & POST_ORDER_FLAG) == POST_ORDER_FLAG;
+ const UInt32 node_id = buf_.back() & ~POST_ORDER_FLAG;
+
+ const Base base = trie_->ith_node(node_id).base();
+ if (post_order) {
+ buf_.pop_back();
+ if (base.is_linker()) {
+ const Key &key = trie_->get_key(base.key_pos());
+ if (key.length() >= min_length_) {
+ if (cur_++ >= offset_) {
+ return key;
+ }
+ }
+ }
+ } else {
+ buf_.back() |= POST_ORDER_FLAG;
+ UInt16 label = trie_->ith_node(node_id).child();
+ while (label != INVALID_LABEL) {
+ buf_.push_back(base.offset() ^ label);
+ label = trie_->ith_node(base.offset() ^ label).sibling();
+ }
+ }
+ }
+ return Key::invalid_key();
+}
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/predictive-cursor.hpp b/storage/mroonga/vendor/groonga/lib/dat/predictive-cursor.hpp
new file mode 100644
index 00000000..88a950b8
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/predictive-cursor.hpp
@@ -0,0 +1,84 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "cursor.hpp"
+#include "vector.hpp"
+
+namespace grn {
+namespace dat {
+
+class Trie;
+
+class GRN_DAT_API PredictiveCursor : public Cursor {
+ public:
+ PredictiveCursor();
+ ~PredictiveCursor();
+
+ void open(const Trie &trie,
+ const String &str,
+ UInt32 offset = 0,
+ UInt32 limit = MAX_UINT32,
+ UInt32 flags = 0);
+
+ void close();
+
+ const Key &next();
+
+ UInt32 offset() const {
+ return offset_;
+ }
+ UInt32 limit() const {
+ return limit_;
+ }
+ UInt32 flags() const {
+ return flags_;
+ }
+
+ private:
+ const Trie *trie_;
+ UInt32 offset_;
+ UInt32 limit_;
+ UInt32 flags_;
+
+ Vector<UInt32> buf_;
+ UInt32 cur_;
+ UInt32 end_;
+ UInt32 min_length_;
+
+ PredictiveCursor(const Trie &trie,
+ UInt32 offset, UInt32 limit, UInt32 flags);
+
+ UInt32 fix_flags(UInt32 flags) const;
+ void init(const String &str);
+ void swap(PredictiveCursor *cursor);
+
+ const Key &ascending_next();
+ const Key &descending_next();
+
+ static const UInt32 IS_ROOT_FLAG = 0x80000000U;
+ static const UInt32 POST_ORDER_FLAG = 0x80000000U;
+
+ // Disallows copy and assignment.
+ PredictiveCursor(const PredictiveCursor &);
+ PredictiveCursor &operator=(const PredictiveCursor &);
+};
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/prefix-cursor.cpp b/storage/mroonga/vendor/groonga/lib/dat/prefix-cursor.cpp
new file mode 100644
index 00000000..83adeb37
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/prefix-cursor.cpp
@@ -0,0 +1,175 @@
+/* -*- c-basic-offset: 2 -*- */
+/* Copyright(C) 2011 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-1335 USA
+*/
+
+#include "prefix-cursor.hpp"
+
+#include <algorithm>
+
+#include "trie.hpp"
+
+namespace grn {
+namespace dat {
+
+PrefixCursor::PrefixCursor()
+ : trie_(NULL),
+ offset_(0),
+ limit_(MAX_UINT32),
+ flags_(PREFIX_CURSOR),
+ buf_(),
+ cur_(0),
+ end_(0) {}
+
+PrefixCursor::~PrefixCursor() {}
+
+void PrefixCursor::open(const Trie &trie,
+ const String &str,
+ UInt32 min_length,
+ UInt32 offset,
+ UInt32 limit,
+ UInt32 flags) {
+ GRN_DAT_THROW_IF(PARAM_ERROR, (str.ptr() == NULL) && (str.length() != 0));
+ GRN_DAT_THROW_IF(PARAM_ERROR, min_length > str.length());
+
+ flags = fix_flags(flags);
+ PrefixCursor new_cursor(trie, offset, limit, flags);
+ new_cursor.init(str, min_length);
+ new_cursor.swap(this);
+}
+
+void PrefixCursor::close() {
+ PrefixCursor new_cursor;
+ new_cursor.swap(this);
+}
+
+const Key &PrefixCursor::next() {
+ if (cur_ == end_) {
+ return Key::invalid_key();
+ }
+ if ((flags_ & ASCENDING_CURSOR) == ASCENDING_CURSOR) {
+ return trie_->get_key(buf_[cur_++]);
+ } else {
+ return trie_->get_key(buf_[--cur_]);
+ }
+}
+
+PrefixCursor::PrefixCursor(const Trie &trie,
+ UInt32 offset, UInt32 limit, UInt32 flags)
+ : trie_(&trie),
+ offset_(offset),
+ limit_(limit),
+ flags_(flags),
+ buf_(),
+ cur_(0),
+ end_(0) {}
+
+UInt32 PrefixCursor::fix_flags(UInt32 flags) const {
+ const UInt32 cursor_type = flags & CURSOR_TYPE_MASK;
+ GRN_DAT_THROW_IF(PARAM_ERROR, (cursor_type != 0) &&
+ (cursor_type != PREFIX_CURSOR));
+ flags |= PREFIX_CURSOR;
+
+ const UInt32 cursor_order = flags & CURSOR_ORDER_MASK;
+ GRN_DAT_THROW_IF(PARAM_ERROR, (cursor_order != 0) &&
+ (cursor_order != ASCENDING_CURSOR) &&
+ (cursor_order != DESCENDING_CURSOR));
+ if (cursor_order == 0) {
+ flags |= ASCENDING_CURSOR;
+ }
+
+ const UInt32 cursor_options = flags & CURSOR_OPTIONS_MASK;
+ GRN_DAT_THROW_IF(PARAM_ERROR, cursor_options & ~EXCEPT_EXACT_MATCH);
+
+ return flags;
+}
+
+void PrefixCursor::init(const String &str, UInt32 min_length) {
+ if ((limit_ == 0) || (offset_ > (str.length() - min_length))) {
+ return;
+ }
+
+ UInt32 node_id = ROOT_NODE_ID;
+ UInt32 i;
+ for (i = 0; i < str.length(); ++i) {
+ const Base base = trie_->ith_node(node_id).base();
+ if (base.is_linker()) {
+ const Key &key = trie_->get_key(base.key_pos());
+ if ((key.length() >= min_length) && (key.length() <= str.length()) &&
+ (str.substr(0, key.length()).compare(key.str(), i) == 0) &&
+ ((key.length() < str.length()) ||
+ ((flags_ & EXCEPT_EXACT_MATCH) != EXCEPT_EXACT_MATCH))) {
+ buf_.push_back(base.key_pos());
+ }
+ break;
+ }
+
+ if ((i >= min_length) &&
+ (trie_->ith_node(node_id).child() == TERMINAL_LABEL)) {
+ const Base linker_base =
+ trie_->ith_node(base.offset() ^ TERMINAL_LABEL).base();
+ if (linker_base.is_linker()) {
+ buf_.push_back(linker_base.key_pos());
+ }
+ }
+
+ node_id = base.offset() ^ str[i];
+ if (trie_->ith_node(node_id).label() != str[i]) {
+ break;
+ }
+ }
+
+ if ((i == str.length()) &&
+ ((flags_ & EXCEPT_EXACT_MATCH) != EXCEPT_EXACT_MATCH)) {
+ const Base base = trie_->ith_node(node_id).base();
+ if (base.is_linker()) {
+ const Key &key = trie_->get_key(base.key_pos());
+ if ((key.length() >= min_length) && (key.length() <= str.length())) {
+ buf_.push_back(base.key_pos());
+ }
+ } else if (trie_->ith_node(node_id).child() == TERMINAL_LABEL) {
+ const Base linker_base =
+ trie_->ith_node(base.offset() ^ TERMINAL_LABEL).base();
+ if (linker_base.is_linker()) {
+ buf_.push_back(linker_base.key_pos());
+ }
+ }
+ }
+
+ if (buf_.size() <= offset_) {
+ return;
+ }
+
+ if ((flags_ & ASCENDING_CURSOR) == ASCENDING_CURSOR) {
+ cur_ = offset_;
+ end_ = (limit_ < (buf_.size() - cur_)) ? (cur_ + limit_) : buf_.size();
+ } else {
+ cur_ = buf_.size() - offset_;
+ end_ = (limit_ < cur_) ? (cur_ - limit_) : 0;
+ }
+}
+
+void PrefixCursor::swap(PrefixCursor *cursor) {
+ std::swap(trie_, cursor->trie_);
+ std::swap(offset_, cursor->offset_);
+ std::swap(limit_, cursor->limit_);
+ std::swap(flags_, cursor->flags_);
+ buf_.swap(&cursor->buf_);
+ std::swap(cur_, cursor->cur_);
+ std::swap(end_, cursor->end_);
+}
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/prefix-cursor.hpp b/storage/mroonga/vendor/groonga/lib/dat/prefix-cursor.hpp
new file mode 100644
index 00000000..07a59186
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/prefix-cursor.hpp
@@ -0,0 +1,78 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "cursor.hpp"
+#include "vector.hpp"
+
+namespace grn {
+namespace dat {
+
+class Trie;
+
+class GRN_DAT_API PrefixCursor : public Cursor {
+ public:
+ PrefixCursor();
+ ~PrefixCursor();
+
+ void open(const Trie &trie,
+ const String &str,
+ UInt32 min_length = 0,
+ UInt32 offset = 0,
+ UInt32 limit = MAX_UINT32,
+ UInt32 flags = 0);
+
+ void close();
+
+ const Key &next();
+
+ UInt32 offset() const {
+ return offset_;
+ }
+ UInt32 limit() const {
+ return limit_;
+ }
+ UInt32 flags() const {
+ return flags_;
+ }
+
+ private:
+ const Trie *trie_;
+ UInt32 offset_;
+ UInt32 limit_;
+ UInt32 flags_;
+
+ Vector<UInt32> buf_;
+ UInt32 cur_;
+ UInt32 end_;
+
+ PrefixCursor(const Trie &trie,
+ UInt32 offset, UInt32 limit, UInt32 flags);
+
+ UInt32 fix_flags(UInt32 flags) const;
+ void init(const String &str, UInt32 min_length);
+ void swap(PrefixCursor *cursor);
+
+ // Disallows copy and assignment.
+ PrefixCursor(const PrefixCursor &);
+ PrefixCursor &operator=(const PrefixCursor &);
+};
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/sources.am b/storage/mroonga/vendor/groonga/lib/dat/sources.am
new file mode 100644
index 00000000..26c9f09f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/sources.am
@@ -0,0 +1,29 @@
+libgrndat_la_SOURCES = \
+ cursor-factory.cpp \
+ file-impl.cpp \
+ file.cpp \
+ id-cursor.cpp \
+ key-cursor.cpp \
+ predictive-cursor.cpp \
+ prefix-cursor.cpp \
+ trie.cpp \
+ array.hpp \
+ base.hpp \
+ block.hpp \
+ check.hpp \
+ cursor-factory.hpp \
+ cursor.hpp \
+ dat.hpp \
+ entry.hpp \
+ file-impl.hpp \
+ file.hpp \
+ header.hpp \
+ id-cursor.hpp \
+ key-cursor.hpp \
+ key.hpp \
+ node.hpp \
+ predictive-cursor.hpp \
+ prefix-cursor.hpp \
+ string.hpp \
+ trie.hpp \
+ vector.hpp
diff --git a/storage/mroonga/vendor/groonga/lib/dat/string.hpp b/storage/mroonga/vendor/groonga/lib/dat/string.hpp
new file mode 100644
index 00000000..aead21ca
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/string.hpp
@@ -0,0 +1,173 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "dat.hpp"
+
+namespace grn {
+namespace dat {
+
+class GRN_DAT_API String {
+ public:
+ String()
+ : ptr_(NULL),
+ length_(0) {}
+ String(const void *ptr, UInt32 length)
+ : ptr_(static_cast<const UInt8 *>(ptr)),
+ length_(length) {}
+ template <UInt32 T>
+ explicit String(const char (&str)[T])
+ : ptr_(reinterpret_cast<const UInt8 *>(str)),
+ length_(T - 1) {}
+ String(const String &rhs)
+ : ptr_(rhs.ptr_),
+ length_(rhs.length_) {}
+
+ String &operator=(const String &rhs) {
+ set_ptr(rhs.ptr());
+ set_length(rhs.length());
+ return *this;
+ }
+
+ const UInt8 &operator[](UInt32 i) const {
+ GRN_DAT_DEBUG_THROW_IF(i >= length_);
+ return ptr_[i];
+ }
+
+ const void *ptr() const {
+ return ptr_;
+ }
+ UInt32 length() const {
+ return length_;
+ }
+
+ void set_ptr(const void *x) {
+ ptr_ = static_cast<const UInt8 *>(x);
+ }
+ void set_length(UInt32 x) {
+ length_ = x;
+ }
+
+ void assign(const void *ptr, UInt32 length) {
+ set_ptr(ptr);
+ set_length(length);
+ }
+
+ String substr(UInt32 offset = 0) const {
+ return String(ptr_ + offset, length_ - offset);
+ }
+ String substr(UInt32 offset, UInt32 length) const {
+ return String(ptr_ + offset, length);
+ }
+
+ // This function returns an integer as follows:
+ // - a negative value if *this < rhs,
+ // - zero if *this == rhs,
+ // - a positive value if *this > rhs,
+ // but if the offset is too large, the result is undefined.
+ int compare(const String &rhs, UInt32 offset = 0) const {
+ GRN_DAT_DEBUG_THROW_IF(offset > length());
+ GRN_DAT_DEBUG_THROW_IF(offset > rhs.length());
+
+ for (UInt32 i = offset; i < length(); ++i) {
+ if (i >= rhs.length()) {
+ return 1;
+ } else if ((*this)[i] != rhs[i]) {
+ return (*this)[i] - rhs[i];
+ }
+ }
+ return (length() == rhs.length()) ? 0 : -1;
+ }
+
+ bool starts_with(const String &str) const {
+ if (length() < str.length()) {
+ return false;
+ }
+ for (UInt32 i = 0; i < str.length(); ++i) {
+ if ((*this)[i] != str[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool ends_with(const String &str) const {
+ if (length() < str.length()) {
+ return false;
+ }
+ UInt32 offset = length() - str.length();
+ for (UInt32 i = 0; i < str.length(); ++i) {
+ if ((*this)[offset + i] != str[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ void swap(String *rhs) {
+ const UInt8 * const ptr_temp = ptr_;
+ ptr_ = rhs->ptr_;
+ rhs->ptr_ = ptr_temp;
+
+ const UInt32 length_temp = length_;
+ length_ = rhs->length_;
+ rhs->length_ = length_temp;
+ }
+
+ private:
+ const UInt8 *ptr_;
+ UInt32 length_;
+};
+
+inline bool operator==(const String &lhs, const String &rhs) {
+ if (lhs.length() != rhs.length()) {
+ return false;
+ } else if (lhs.ptr() == rhs.ptr()) {
+ return true;
+ }
+ for (UInt32 i = 0; i < lhs.length(); ++i) {
+ if (lhs[i] != rhs[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+inline bool operator!=(const String &lhs, const String &rhs) {
+ return !(lhs == rhs);
+}
+
+inline bool operator<(const String &lhs, const String &rhs) {
+ return lhs.compare(rhs) < 0;
+}
+
+inline bool operator>(const String &lhs, const String &rhs) {
+ return rhs < lhs;
+}
+
+inline bool operator<=(const String &lhs, const String &rhs) {
+ return !(lhs > rhs);
+}
+
+inline bool operator>=(const String &lhs, const String &rhs) {
+ return !(lhs < rhs);
+}
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/trie.cpp b/storage/mroonga/vendor/groonga/lib/dat/trie.cpp
new file mode 100644
index 00000000..b2c6a84f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/trie.cpp
@@ -0,0 +1,1225 @@
+/* -*- c-basic-offset: 2 -*- */
+/* Copyright(C) 2011-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-1335 USA
+*/
+
+#include "trie.hpp"
+
+#include <algorithm>
+#include <cstring>
+
+#include "vector.hpp"
+
+namespace grn {
+namespace dat {
+namespace {
+
+class StatusFlagManager {
+ public:
+ StatusFlagManager(Header *header, UInt32 status_flag)
+ : header_(header), status_flag_(status_flag) {
+ header_->set_status_flags(header_->status_flags() | status_flag_);
+ }
+ ~StatusFlagManager() {
+ header_->set_status_flags(header_->status_flags() & ~status_flag_);
+ }
+
+ private:
+ Header *header_;
+ UInt32 status_flag_;
+
+ // Disallows copy and assignment.
+ StatusFlagManager(const StatusFlagManager &);
+ StatusFlagManager &operator=(const StatusFlagManager &);
+};
+
+} // namespace
+
+Trie::Trie()
+ : file_(),
+ header_(NULL),
+ nodes_(),
+ blocks_(),
+ entries_(),
+ key_buf_() {}
+
+Trie::~Trie() {}
+
+void Trie::create(const char *file_name,
+ UInt64 file_size,
+ UInt32 max_num_keys,
+ double num_nodes_per_key,
+ double average_key_length) {
+ GRN_DAT_THROW_IF(PARAM_ERROR, (file_size != 0) && (max_num_keys != 0));
+
+ 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;
+ }
+ GRN_DAT_THROW_IF(PARAM_ERROR, average_key_length < 1.0);
+ GRN_DAT_THROW_IF(PARAM_ERROR, average_key_length > MAX_KEY_LENGTH);
+
+ if (max_num_keys == 0) {
+ if (file_size == 0) {
+ file_size = DEFAULT_FILE_SIZE;
+ } else {
+ GRN_DAT_THROW_IF(PARAM_ERROR, file_size < MIN_FILE_SIZE);
+ GRN_DAT_THROW_IF(PARAM_ERROR, file_size > MAX_FILE_SIZE);
+ }
+ } else {
+ GRN_DAT_THROW_IF(PARAM_ERROR, max_num_keys > MAX_NUM_KEYS);
+ }
+
+ Trie new_trie;
+ new_trie.create_file(file_name, file_size, max_num_keys,
+ num_nodes_per_key, average_key_length);
+ new_trie.swap(this);
+}
+
+void Trie::create(const Trie &trie,
+ const char *file_name,
+ UInt64 file_size,
+ UInt32 max_num_keys,
+ double num_nodes_per_key,
+ double average_key_length) {
+ GRN_DAT_THROW_IF(PARAM_ERROR, (file_size != 0) && (max_num_keys != 0));
+
+ if (num_nodes_per_key < 1.0) {
+ if (trie.num_keys() == 0) {
+ 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) {
+ average_key_length = DEFAULT_AVERAGE_KEY_LENGTH;
+ } else {
+ average_key_length = 1.0 * trie.total_key_length() / trie.num_keys();
+ }
+ }
+ GRN_DAT_THROW_IF(PARAM_ERROR, average_key_length < 1.0);
+ GRN_DAT_THROW_IF(PARAM_ERROR, average_key_length > MAX_KEY_LENGTH);
+
+ if (max_num_keys == 0) {
+ if (file_size == 0) {
+ file_size = trie.file_size();
+ }
+ GRN_DAT_THROW_IF(PARAM_ERROR, file_size < MIN_FILE_SIZE);
+ GRN_DAT_THROW_IF(PARAM_ERROR, file_size > MAX_FILE_SIZE);
+ GRN_DAT_THROW_IF(PARAM_ERROR, file_size < trie.virtual_size());
+ } else {
+ GRN_DAT_THROW_IF(PARAM_ERROR, max_num_keys < trie.num_keys());
+ GRN_DAT_THROW_IF(PARAM_ERROR, max_num_keys < trie.max_key_id());
+ GRN_DAT_THROW_IF(PARAM_ERROR, max_num_keys > MAX_NUM_KEYS);
+ }
+
+ Trie new_trie;
+ new_trie.create_file(file_name, file_size, max_num_keys,
+ num_nodes_per_key, average_key_length);
+ new_trie.build_from_trie(trie);
+ new_trie.swap(this);
+}
+
+void Trie::repair(const Trie &trie, const char *file_name) {
+ Trie new_trie;
+ new_trie.create_file(file_name, trie.file_size(), trie.max_num_keys(),
+ trie.max_num_blocks(), trie.key_buf_size());
+ new_trie.repair_trie(trie);
+ new_trie.swap(this);
+}
+
+void Trie::open(const char *file_name) {
+ GRN_DAT_THROW_IF(PARAM_ERROR, file_name == NULL);
+
+ Trie new_trie;
+ new_trie.open_file(file_name);
+ new_trie.swap(this);
+}
+
+void Trie::close() {
+ Trie().swap(this);
+}
+
+void Trie::swap(Trie *trie) {
+ file_.swap(&trie->file_);
+ std::swap(header_, trie->header_);
+ nodes_.swap(&trie->nodes_);
+ blocks_.swap(&trie->blocks_);
+ entries_.swap(&trie->entries_);
+ key_buf_.swap(&trie->key_buf_);
+}
+
+void Trie::flush() {
+ file_.flush();
+}
+
+void Trie::create_file(const char *file_name,
+ UInt64 file_size,
+ UInt32 max_num_keys,
+ double num_nodes_per_key,
+ double average_key_length) {
+ GRN_DAT_THROW_IF(PARAM_ERROR, (file_size == 0) && (max_num_keys == 0));
+ GRN_DAT_THROW_IF(PARAM_ERROR, (file_size != 0) && (max_num_keys != 0));
+ if (max_num_keys == 0) {
+ const UInt64 avail = file_size - sizeof(Header);
+ const double num_bytes_per_key = (sizeof(Node) * num_nodes_per_key)
+ + (1.0 * sizeof(Block) / BLOCK_SIZE * num_nodes_per_key)
+ + sizeof(Entry)
+ + sizeof(UInt32) + sizeof(UInt8) + average_key_length + 1.5;
+ if ((avail / num_bytes_per_key) > MAX_NUM_KEYS) {
+ max_num_keys = MAX_NUM_KEYS;
+ } else {
+ max_num_keys = (UInt32)(avail / num_bytes_per_key);
+ }
+ GRN_DAT_THROW_IF(PARAM_ERROR, max_num_keys == 0);
+ }
+
+ UInt32 max_num_blocks;
+ {
+ const double max_num_nodes = num_nodes_per_key * max_num_keys;
+ GRN_DAT_THROW_IF(PARAM_ERROR, (max_num_nodes - 1.0) >= MAX_NUM_NODES);
+ max_num_blocks = ((UInt32)max_num_nodes + BLOCK_SIZE - 1) / BLOCK_SIZE;
+ GRN_DAT_THROW_IF(PARAM_ERROR, max_num_blocks == 0);
+ GRN_DAT_THROW_IF(PARAM_ERROR, max_num_blocks > MAX_NUM_BLOCKS);
+ }
+
+ UInt32 key_buf_size;
+ if (file_size == 0) {
+ const double total_key_length = average_key_length * max_num_keys;
+ GRN_DAT_THROW_IF(PARAM_ERROR,
+ (total_key_length - 1.0) >= MAX_TOTAL_KEY_LENGTH);
+
+ // The last term is the estimated number of bytes that will be used for
+ // 32-bit alignment.
+ const UInt64 total_num_bytes = (UInt64)(total_key_length)
+ + (UInt64)(sizeof(UInt32) + sizeof(UInt8)) * max_num_keys
+ + (UInt32)(max_num_keys * 1.5);
+ GRN_DAT_THROW_IF(PARAM_ERROR,
+ (total_num_bytes / sizeof(UInt32)) >= MAX_KEY_BUF_SIZE);
+ key_buf_size = (UInt32)(total_num_bytes / sizeof(UInt32));
+
+ file_size = sizeof(Header)
+ + (sizeof(Block) * max_num_blocks)
+ + (sizeof(Node) * BLOCK_SIZE * max_num_blocks)
+ + (sizeof(Entry) * max_num_keys)
+ + (sizeof(UInt32) * key_buf_size);
+ } else {
+ const UInt64 avail = file_size - sizeof(Header)
+ - (sizeof(Block) * max_num_blocks)
+ - (sizeof(Node) * BLOCK_SIZE * max_num_blocks)
+ - (sizeof(Entry) * max_num_keys);
+ GRN_DAT_THROW_IF(PARAM_ERROR, (avail / sizeof(UInt32)) > MAX_KEY_BUF_SIZE);
+ key_buf_size = (UInt32)(avail / sizeof(UInt32));
+ }
+
+ create_file(file_name, file_size, max_num_keys,
+ max_num_blocks, key_buf_size);
+}
+
+void Trie::create_file(const char *file_name,
+ UInt64 file_size,
+ UInt32 max_num_keys,
+ UInt32 max_num_blocks,
+ UInt32 key_buf_size) {
+ GRN_DAT_THROW_IF(PARAM_ERROR, file_size < (sizeof(Header)
+ + (sizeof(Block) * max_num_blocks)
+ + (sizeof(Node) * BLOCK_SIZE * max_num_blocks)
+ + (sizeof(Entry) * max_num_keys)
+ + (sizeof(UInt32) * key_buf_size)));
+
+ file_.create(file_name, file_size);
+
+ Header * const header = static_cast<Header *>(file_.ptr());
+ *header = Header();
+ header->set_file_size(file_size);
+ header->set_max_num_keys(max_num_keys);
+ header->set_max_num_blocks(max_num_blocks);
+ header->set_key_buf_size(key_buf_size);
+
+ map_address(file_.ptr());
+
+ reserve_node(ROOT_NODE_ID);
+ ith_node(INVALID_OFFSET).set_is_offset(true);
+}
+
+void Trie::open_file(const char *file_name) {
+ GRN_DAT_THROW_IF(PARAM_ERROR, file_name == NULL);
+
+ file_.open(file_name);
+ map_address(file_.ptr());
+ GRN_DAT_THROW_IF(FORMAT_ERROR, file_size() != file_.size());
+}
+
+void Trie::map_address(void *address) {
+ GRN_DAT_THROW_IF(PARAM_ERROR, address == NULL);
+
+ header_ = static_cast<Header *>(address);
+ nodes_.assign(header_ + 1, max_num_nodes());
+ blocks_.assign(nodes_.end(), max_num_blocks());
+ entries_.assign(reinterpret_cast<Entry *>(blocks_.end()) - 1,
+ max_num_keys() + 1);
+ key_buf_.assign(entries_.end(), key_buf_size());
+
+ GRN_DAT_THROW_IF(UNEXPECTED_ERROR, static_cast<void *>(key_buf_.end())
+ > static_cast<void *>(static_cast<char *>(address) + file_size()));
+}
+
+void Trie::build_from_trie(const Trie &trie) {
+ GRN_DAT_THROW_IF(SIZE_ERROR, max_num_keys() < trie.num_keys());
+ GRN_DAT_THROW_IF(SIZE_ERROR, max_num_keys() < trie.max_key_id());
+
+ header_->set_total_key_length(trie.total_key_length());
+ header_->set_num_keys(trie.num_keys());
+ header_->set_max_key_id(trie.max_key_id());
+ header_->set_next_key_id(trie.next_key_id());
+ for (UInt32 i = min_key_id(); i <= max_key_id(); ++i) {
+ ith_entry(i) = trie.ith_entry(i);
+ }
+ build_from_trie(trie, ROOT_NODE_ID, ROOT_NODE_ID);
+}
+
+void Trie::build_from_trie(const Trie &trie, UInt32 src, UInt32 dest) {
+ // Keys are sorted in lexicographic order.
+ if (trie.ith_node(src).is_linker()) {
+ const Key &key = trie.get_key(trie.ith_node(src).key_pos());
+ Key::create(key_buf_.ptr() + next_key_pos(),
+ key.id(), key.ptr(), key.length());
+ ith_node(dest).set_key_pos(next_key_pos());
+ ith_entry(key.id()).set_key_pos(next_key_pos());
+ header_->set_next_key_pos(
+ next_key_pos() + Key::estimate_size(key.length()));
+ return;
+ }
+
+ const UInt32 src_offset = trie.ith_node(src).offset();
+ UInt32 dest_offset;
+ {
+ UInt16 labels[MAX_LABEL + 1];
+ UInt32 num_labels = 0;
+
+ UInt32 label = trie.ith_node(src).child();
+ while (label != INVALID_LABEL) {
+ GRN_DAT_DEBUG_THROW_IF(label > MAX_LABEL);
+ const UInt32 child = src_offset ^ label;
+ if (trie.ith_node(child).is_linker() ||
+ (trie.ith_node(child).child() != INVALID_LABEL)) {
+ labels[num_labels++] = label;
+ }
+ label = trie.ith_node(child).sibling();
+ }
+ if (num_labels == 0) {
+ return;
+ }
+
+ dest_offset = find_offset(labels, num_labels);
+ for (UInt32 i = 0; i < num_labels; ++i) {
+ const UInt32 child = dest_offset ^ labels[i];
+ reserve_node(child);
+ ith_node(child).set_label(labels[i]);
+ if ((i + 1) < num_labels) {
+ ith_node(child).set_sibling(labels[i + 1]);
+ }
+ }
+
+ GRN_DAT_DEBUG_THROW_IF(ith_node(dest_offset).is_offset());
+ ith_node(dest_offset).set_is_offset(true);
+ ith_node(dest).set_offset(dest_offset);
+ ith_node(dest).set_child(labels[0]);
+ }
+
+ UInt32 label = ith_node(dest).child();
+ while (label != INVALID_LABEL) {
+ build_from_trie(trie, src_offset ^ label, dest_offset ^ label);
+ label = ith_node(dest_offset ^ label).sibling();
+ }
+}
+
+void Trie::repair_trie(const Trie &trie) {
+ Vector<UInt32> valid_ids;
+ header_->set_max_key_id(trie.max_key_id());
+ header_->set_next_key_id(trie.max_key_id() + 1);
+ UInt32 prev_invalid_key_id = INVALID_KEY_ID;
+ for (UInt32 i = min_key_id(); i <= max_key_id(); ++i) {
+ const Entry &entry = trie.ith_entry(i);
+ if (entry.is_valid()) {
+ valid_ids.push_back(i);
+ ith_entry(i) = entry;
+ const Key &key = trie.get_key(entry.key_pos());
+ Key::create(key_buf_.ptr() + next_key_pos(),
+ key.id(), key.ptr(), key.length());
+ ith_entry(i).set_key_pos(next_key_pos());
+ header_->set_next_key_pos(
+ next_key_pos() + Key::estimate_size(key.length()));
+ header_->set_total_key_length(
+ total_key_length() + key.length());
+ header_->set_num_keys(num_keys() + 1);
+ } else {
+ if (prev_invalid_key_id == INVALID_KEY_ID) {
+ header_->set_next_key_id(i);
+ } else {
+ ith_entry(prev_invalid_key_id).set_next(i);
+ }
+ prev_invalid_key_id = i;
+ }
+ }
+ if (prev_invalid_key_id != INVALID_KEY_ID) {
+ ith_entry(prev_invalid_key_id).set_next(max_key_id() + 1);
+ }
+ mkq_sort(valid_ids.begin(), valid_ids.end(), 0);
+ build_from_keys(valid_ids.begin(), valid_ids.end(), 0, ROOT_NODE_ID);
+}
+
+void Trie::build_from_keys(const UInt32 *begin, const UInt32 *end,
+ UInt32 depth, UInt32 node_id) {
+ if ((end - begin) == 1) {
+ ith_node(node_id).set_key_pos(ith_entry(*begin).key_pos());
+ return;
+ }
+
+ UInt32 offset;
+ {
+ UInt16 labels[MAX_LABEL + 2];
+ UInt32 num_labels = 0;
+
+ const UInt32 *it = begin;
+ if (ith_key(*it).length() == depth) {
+ labels[num_labels++] = TERMINAL_LABEL;
+ ++it;
+ }
+
+ labels[num_labels++] = (UInt8)ith_key(*it)[depth];
+ for (++it; it < end; ++it) {
+ const Key &key = ith_key(*it);
+ if ((UInt8)key[depth] != labels[num_labels - 1]) {
+ labels[num_labels++] = (UInt8)key[depth];
+ }
+ }
+ labels[num_labels] = INVALID_LABEL;
+
+ offset = find_offset(labels, num_labels);
+ ith_node(node_id).set_child(labels[0]);
+ for (UInt32 i = 0; i < num_labels; ++i) {
+ const UInt32 next = offset ^ labels[i];
+ reserve_node(next);
+ ith_node(next).set_label(labels[i]);
+ ith_node(next).set_sibling(labels[i + 1]);
+ }
+
+ if (offset >= num_nodes()) {
+ reserve_block(num_blocks());
+ }
+ ith_node(offset).set_is_offset(true);
+ ith_node(node_id).set_offset(offset);
+ }
+
+ if (ith_key(*begin).length() == depth) {
+ build_from_keys(begin, begin + 1, depth + 1, offset ^ TERMINAL_LABEL);
+ ++begin;
+ }
+
+ UInt16 label = ith_key(*begin)[depth];
+ for (const UInt32 *it = begin + 1; it < end; ++it) {
+ const Key &key = ith_key(*it);
+ if ((UInt8)key[depth] != label) {
+ build_from_keys(begin, it, depth + 1, offset ^ label);
+ label = (UInt8)key[depth];
+ begin = it;
+ }
+ }
+ build_from_keys(begin, end, depth + 1, offset ^ label);
+}
+
+void Trie::mkq_sort(UInt32 *l, UInt32 *r, UInt32 depth) {
+ while ((r - l) >= MKQ_SORT_THRESHOLD) {
+ UInt32 *pl = l;
+ UInt32 *pr = r;
+ UInt32 *pivot_l = l;
+ UInt32 *pivot_r = r;
+
+ const int pivot = get_median(*l, *(l + (r - l) / 2), *(r - 1), depth);
+ for ( ; ; ) {
+ while (pl < pr) {
+ const int label = get_label(*pl, depth);
+ if (label > pivot) {
+ break;
+ } else if (label == pivot) {
+ swap_ids(pl, pivot_l);
+ ++pivot_l;
+ }
+ ++pl;
+ }
+ while (pl < pr) {
+ const int label = get_label(*--pr, depth);
+ if (label < pivot) {
+ break;
+ } else if (label == pivot) {
+ swap_ids(pr, --pivot_r);
+ }
+ }
+ if (pl >= pr) {
+ break;
+ }
+ swap_ids(pl, pr);
+ ++pl;
+ }
+ while (pivot_l > l) {
+ swap_ids(--pivot_l, --pl);
+ }
+ while (pivot_r < r) {
+ swap_ids(pivot_r, pr);
+ ++pivot_r;
+ ++pr;
+ }
+
+ if (((pl - l) > (pr - pl)) || ((r - pr) > (pr - pl))) {
+ if ((pr - pl) > 1) {
+ mkq_sort(pl, pr, depth + 1);
+ }
+
+ if ((pl - l) < (r - pr)) {
+ if ((pl - l) > 1) {
+ mkq_sort(l, pl, depth);
+ }
+ l = pr;
+ } else {
+ if ((r - pr) > 1) {
+ mkq_sort(pr, r, depth);
+ }
+ r = pl;
+ }
+ } else {
+ if ((pl - l) > 1) {
+ mkq_sort(l, pl, depth);
+ }
+
+ if ((r - pr) > 1) {
+ mkq_sort(pr, r, depth);
+ }
+
+ l = pl, r = pr;
+ if ((pr - pl) > 1) {
+ ++depth;
+ }
+ }
+ }
+
+ if ((r - l) > 1) {
+ insertion_sort(l, r, depth);
+ }
+}
+
+void Trie::insertion_sort(UInt32 *l, UInt32 *r, UInt32 depth) {
+ for (UInt32 *i = l + 1; i < r; ++i) {
+ for (UInt32 *j = i; j > l; --j) {
+ if (less_than(*(j - 1), *j, depth)) {
+ break;
+ }
+ swap_ids(j - 1, j);
+ }
+ }
+}
+
+int Trie::get_median(UInt32 a, UInt32 b, UInt32 c, UInt32 depth) const {
+ const int x = get_label(a, depth);
+ const int y = get_label(b, depth);
+ const int z = get_label(c, depth);
+ if (x < y) {
+ if (y < z) {
+ return y;
+ } else if (x < z) {
+ return z;
+ }
+ return x;
+ } else if (x < z) {
+ return x;
+ } else if (y < z) {
+ return z;
+ }
+ return y;
+}
+
+int Trie::get_label(UInt32 key_id, UInt32 depth) const {
+ const Key &key = ith_key(key_id);
+ if (depth == key.length()) {
+ return -1;
+ } else {
+ return (UInt8)key[depth];
+ }
+}
+
+bool Trie::less_than(UInt32 lhs, UInt32 rhs, UInt32 depth) const {
+ const Key &lhs_key = ith_key(lhs);
+ const Key &rhs_key = ith_key(rhs);
+ const UInt32 length = (lhs_key.length() < rhs_key.length()) ?
+ lhs_key.length() : rhs_key.length();
+ for (UInt32 i = depth; i < length; ++i) {
+ if (lhs_key[i] != rhs_key[i]) {
+ return (UInt8)lhs_key[i] < (UInt8)rhs_key[i];
+ }
+ }
+ return lhs_key.length() < rhs_key.length();
+}
+
+void Trie::swap_ids(UInt32 *lhs, UInt32 *rhs) {
+ UInt32 temp = *lhs;
+ *lhs = *rhs;
+ *rhs = temp;
+}
+
+bool Trie::search_key(const UInt8 *ptr, UInt32 length, UInt32 *key_pos) const {
+ GRN_DAT_DEBUG_THROW_IF((ptr == NULL) && (length != 0));
+
+ UInt32 node_id = ROOT_NODE_ID;
+ UInt32 query_pos = 0;
+ if (!search_linker(ptr, length, node_id, query_pos)) {
+ return false;
+ }
+
+ const Base base = ith_node(node_id).base();
+ if (!base.is_linker()) {
+ return false;
+ }
+
+ if (get_key(base.key_pos()).equals_to(ptr, length, query_pos)) {
+ if (key_pos != NULL) {
+ *key_pos = base.key_pos();
+ }
+ return true;
+ }
+ return false;
+}
+
+bool Trie::search_linker(const UInt8 *ptr, UInt32 length,
+ UInt32 &node_id, UInt32 &query_pos) const {
+ GRN_DAT_DEBUG_THROW_IF((ptr == NULL) && (length != 0));
+
+ for ( ; query_pos < length; ++query_pos) {
+ const Base base = ith_node(node_id).base();
+ if (base.is_linker()) {
+ return true;
+ }
+
+ const UInt32 next = base.offset() ^ ptr[query_pos];
+ if (ith_node(next).label() != ptr[query_pos]) {
+ return false;
+ }
+ node_id = next;
+ }
+
+ const Base base = ith_node(node_id).base();
+ if (base.is_linker()) {
+ return true;
+ }
+
+ const UInt32 next = base.offset() ^ TERMINAL_LABEL;
+ if (ith_node(next).label() != TERMINAL_LABEL) {
+ return false;
+ }
+ node_id = next;
+ return ith_node(next).is_linker();
+}
+
+bool Trie::lcp_search_key(const UInt8 *ptr, UInt32 length,
+ UInt32 *key_pos) const {
+ GRN_DAT_DEBUG_THROW_IF((ptr == NULL) && (length != 0));
+
+ bool found = false;
+ UInt32 node_id = ROOT_NODE_ID;
+ UInt32 query_pos = 0;
+
+ for ( ; query_pos < length; ++query_pos) {
+ const Base base = ith_node(node_id).base();
+ if (base.is_linker()) {
+ const Key &key = get_key(base.key_pos());
+ if ((key.length() <= length) &&
+ key.equals_to(ptr, key.length(), query_pos)) {
+ if (key_pos != NULL) {
+ *key_pos = base.key_pos();
+ }
+ found = true;
+ }
+ return found;
+ }
+
+ if (ith_node(node_id).child() == TERMINAL_LABEL) {
+ const Base linker_base =
+ ith_node(base.offset() ^ TERMINAL_LABEL).base();
+ if (linker_base.is_linker()) {
+ if (key_pos != NULL) {
+ *key_pos = linker_base.key_pos();
+ }
+ found = true;
+ }
+ }
+
+ node_id = base.offset() ^ ptr[query_pos];
+ if (ith_node(node_id).label() != ptr[query_pos]) {
+ return found;
+ }
+ }
+
+ const Base base = ith_node(node_id).base();
+ if (base.is_linker()) {
+ const Key &key = get_key(base.key_pos());
+ if (key.length() <= length) {
+ if (key_pos != NULL) {
+ *key_pos = base.key_pos();
+ }
+ found = true;
+ }
+ } else if (ith_node(node_id).child() == TERMINAL_LABEL) {
+ const Base linker_base = ith_node(base.offset() ^ TERMINAL_LABEL).base();
+ if (linker_base.is_linker()) {
+ if (key_pos != NULL) {
+ *key_pos = linker_base.key_pos();
+ }
+ found = true;
+ }
+ }
+ return found;
+}
+
+bool Trie::remove_key(const UInt8 *ptr, UInt32 length) {
+ GRN_DAT_THROW_IF(STATUS_ERROR, (status_flags() & CHANGING_MASK) != 0);
+ StatusFlagManager status_flag_manager(header_, REMOVING_FLAG);
+
+ GRN_DAT_DEBUG_THROW_IF((ptr == NULL) && (length != 0));
+
+ UInt32 node_id = ROOT_NODE_ID;
+ UInt32 query_pos = 0;
+ if (!search_linker(ptr, length, node_id, query_pos)) {
+ return false;
+ }
+
+ const UInt32 key_pos = ith_node(node_id).key_pos();
+ if (!get_key(key_pos).equals_to(ptr, length, query_pos)) {
+ return false;
+ }
+
+ const UInt32 key_id = get_key(key_pos).id();
+ ith_node(node_id).set_offset(INVALID_OFFSET);
+ ith_entry(key_id).set_next(next_key_id());
+
+ header_->set_next_key_id(key_id);
+ header_->set_total_key_length(total_key_length() - length);
+ header_->set_num_keys(num_keys() - 1);
+ return true;
+}
+
+bool Trie::insert_key(const UInt8 *ptr, UInt32 length, UInt32 *key_pos) {
+ GRN_DAT_THROW_IF(STATUS_ERROR, (status_flags() & CHANGING_MASK) != 0);
+ StatusFlagManager status_flag_manager(header_, INSERTING_FLAG);
+
+ GRN_DAT_DEBUG_THROW_IF((ptr == NULL) && (length != 0));
+
+ UInt32 node_id = ROOT_NODE_ID;
+ UInt32 query_pos = 0;
+
+ search_linker(ptr, length, node_id, query_pos);
+ if (!insert_linker(ptr, length, node_id, query_pos)) {
+ if (key_pos != NULL) {
+ *key_pos = ith_node(node_id).key_pos();
+ }
+ return false;
+ }
+
+ const UInt32 new_key_id = next_key_id();
+ const UInt32 new_key_pos = append_key(ptr, length, new_key_id);
+
+ header_->set_total_key_length(total_key_length() + length);
+ header_->set_num_keys(num_keys() + 1);
+ if (new_key_id > max_key_id()) {
+ header_->set_max_key_id(new_key_id);
+ header_->set_next_key_id(new_key_id + 1);
+ } else {
+ header_->set_next_key_id(ith_entry(new_key_id).next());
+ }
+
+ ith_entry(new_key_id).set_key_pos(new_key_pos);
+ ith_node(node_id).set_key_pos(new_key_pos);
+ if (key_pos != NULL) {
+ *key_pos = new_key_pos;
+ }
+ return true;
+}
+
+bool Trie::insert_linker(const UInt8 *ptr, UInt32 length,
+ UInt32 &node_id, UInt32 query_pos) {
+ if (ith_node(node_id).is_linker()) {
+ const Key &key = get_key(ith_node(node_id).key_pos());
+ UInt32 i = query_pos;
+ while ((i < length) && (i < key.length())) {
+ if (ptr[i] != key[i]) {
+ break;
+ }
+ ++i;
+ }
+ if ((i == length) && (i == key.length())) {
+ return false;
+ }
+ GRN_DAT_THROW_IF(SIZE_ERROR, num_keys() >= max_num_keys());
+ GRN_DAT_DEBUG_THROW_IF(next_key_id() > max_num_keys());
+
+ for (UInt32 j = query_pos; j < i; ++j) {
+ node_id = insert_node(node_id, ptr[j]);
+ }
+ node_id = separate(ptr, length, node_id, i);
+ return true;
+ } else if (ith_node(node_id).label() == TERMINAL_LABEL) {
+ return true;
+ } else {
+ GRN_DAT_THROW_IF(SIZE_ERROR, num_keys() >= max_num_keys());
+ const UInt16 label = (query_pos < length) ?
+ (UInt16)ptr[query_pos] : (UInt16)TERMINAL_LABEL;
+ const Base base = ith_node(node_id).base();
+ if ((base.offset() == INVALID_OFFSET) ||
+ !ith_node(base.offset() ^ label).is_phantom()) {
+ resolve(node_id, label);
+ }
+ node_id = insert_node(node_id, label);
+ return true;
+ }
+}
+
+bool Trie::update_key(const Key &key, const UInt8 *ptr, UInt32 length,
+ UInt32 *key_pos) {
+ GRN_DAT_THROW_IF(STATUS_ERROR, (status_flags() & CHANGING_MASK) != 0);
+ StatusFlagManager status_flag_manager(header_, UPDATING_FLAG);
+
+ GRN_DAT_DEBUG_THROW_IF((ptr == NULL) && (length != 0));
+
+ if (!key.is_valid()) {
+ return false;
+ }
+
+ UInt32 node_id = ROOT_NODE_ID;
+ UInt32 query_pos = 0;
+
+ search_linker(ptr, length, node_id, query_pos);
+ if (!insert_linker(ptr, length, node_id, query_pos)) {
+ if (key_pos != NULL) {
+ *key_pos = ith_node(node_id).key_pos();
+ }
+ return false;
+ }
+
+ const UInt32 new_key_pos = append_key(ptr, length, key.id());
+ header_->set_total_key_length(total_key_length() + length - key.length());
+ ith_entry(key.id()).set_key_pos(new_key_pos);
+ ith_node(node_id).set_key_pos(new_key_pos);
+ if (key_pos != NULL) {
+ *key_pos = new_key_pos;
+ }
+
+ node_id = ROOT_NODE_ID;
+ query_pos = 0;
+ GRN_DAT_THROW_IF(UNEXPECTED_ERROR,
+ !search_linker(static_cast<const UInt8 *>(key.ptr()), key.length(),
+ node_id, query_pos));
+ ith_node(node_id).set_offset(INVALID_OFFSET);
+ return true;
+}
+
+UInt32 Trie::insert_node(UInt32 node_id, UInt16 label) {
+ GRN_DAT_DEBUG_THROW_IF(node_id >= num_nodes());
+ GRN_DAT_DEBUG_THROW_IF(label > MAX_LABEL);
+
+ const Base base = ith_node(node_id).base();
+ UInt32 offset;
+ if (base.is_linker() || (base.offset() == INVALID_OFFSET)) {
+ offset = find_offset(&label, 1);
+ } else {
+ offset = base.offset();
+ }
+
+ const UInt32 next = offset ^ label;
+ reserve_node(next);
+
+ ith_node(next).set_label(label);
+ if (base.is_linker()) {
+ GRN_DAT_DEBUG_THROW_IF(ith_node(offset).is_offset());
+ ith_node(offset).set_is_offset(true);
+ ith_node(next).set_key_pos(base.key_pos());
+ } else if (base.offset() == INVALID_OFFSET) {
+ GRN_DAT_DEBUG_THROW_IF(ith_node(offset).is_offset());
+ ith_node(offset).set_is_offset(true);
+ } else {
+ GRN_DAT_DEBUG_THROW_IF(!ith_node(offset).is_offset());
+ }
+ ith_node(node_id).set_offset(offset);
+
+ const UInt32 child_label = ith_node(node_id).child();
+ GRN_DAT_DEBUG_THROW_IF(child_label == label);
+ if (child_label == INVALID_LABEL) {
+ ith_node(node_id).set_child(label);
+ } else if ((label == TERMINAL_LABEL) ||
+ ((child_label != TERMINAL_LABEL) && (label < child_label))) {
+ GRN_DAT_DEBUG_THROW_IF(ith_node(offset ^ child_label).is_phantom());
+ GRN_DAT_DEBUG_THROW_IF(ith_node(offset ^ child_label).label() != child_label);
+ ith_node(next).set_sibling(child_label);
+ ith_node(node_id).set_child(label);
+ } else {
+ UInt32 prev = offset ^ child_label;
+ GRN_DAT_DEBUG_THROW_IF(ith_node(prev).label() != child_label);
+ UInt32 sibling_label = ith_node(prev).sibling();
+ while (label > sibling_label) {
+ prev = offset ^ sibling_label;
+ GRN_DAT_DEBUG_THROW_IF(ith_node(prev).label() != sibling_label);
+ sibling_label = ith_node(prev).sibling();
+ }
+ GRN_DAT_DEBUG_THROW_IF(label == sibling_label);
+ ith_node(next).set_sibling(ith_node(prev).sibling());
+ ith_node(prev).set_sibling(label);
+ }
+ return next;
+}
+
+UInt32 Trie::append_key(const UInt8 *ptr, UInt32 length, UInt32 key_id) {
+ GRN_DAT_THROW_IF(SIZE_ERROR, key_id > max_num_keys());
+
+ const UInt32 key_pos = next_key_pos();
+ const UInt32 key_size = Key::estimate_size(length);
+
+ GRN_DAT_THROW_IF(SIZE_ERROR, key_size > (key_buf_size() - key_pos));
+ Key::create(key_buf_.ptr() + key_pos, key_id, ptr, length);
+
+ header_->set_next_key_pos(key_pos + key_size);
+ return key_pos;
+}
+
+UInt32 Trie::separate(const UInt8 *ptr, UInt32 length,
+ UInt32 node_id, UInt32 i) {
+ GRN_DAT_DEBUG_THROW_IF(node_id >= num_nodes());
+ GRN_DAT_DEBUG_THROW_IF(!ith_node(node_id).is_linker());
+ GRN_DAT_DEBUG_THROW_IF(i > length);
+
+ const UInt32 key_pos = ith_node(node_id).key_pos();
+ const Key &key = get_key(key_pos);
+
+ UInt16 labels[2];
+ labels[0] = (i < key.length()) ? (UInt16)key[i] : (UInt16)TERMINAL_LABEL;
+ labels[1] = (i < length) ? (UInt16)ptr[i] : (UInt16)TERMINAL_LABEL;
+ GRN_DAT_DEBUG_THROW_IF(labels[0] == labels[1]);
+
+ const UInt32 offset = find_offset(labels, 2);
+
+ UInt32 next = offset ^ labels[0];
+ reserve_node(next);
+ GRN_DAT_DEBUG_THROW_IF(ith_node(offset).is_offset());
+
+ ith_node(next).set_label(labels[0]);
+ ith_node(next).set_key_pos(key_pos);
+
+ next = offset ^ labels[1];
+ reserve_node(next);
+
+ ith_node(next).set_label(labels[1]);
+
+ ith_node(offset).set_is_offset(true);
+ ith_node(node_id).set_offset(offset);
+
+ if ((labels[0] == TERMINAL_LABEL) ||
+ ((labels[1] != TERMINAL_LABEL) && (labels[0] < labels[1]))) {
+ ith_node(node_id).set_child(labels[0]);
+ ith_node(offset ^ labels[0]).set_sibling(labels[1]);
+ } else {
+ ith_node(node_id).set_child(labels[1]);
+ ith_node(offset ^ labels[1]).set_sibling(labels[0]);
+ }
+ return next;
+}
+
+void Trie::resolve(UInt32 node_id, UInt16 label) {
+ GRN_DAT_DEBUG_THROW_IF(node_id >= num_nodes());
+ GRN_DAT_DEBUG_THROW_IF(ith_node(node_id).is_linker());
+ GRN_DAT_DEBUG_THROW_IF(label > MAX_LABEL);
+
+ UInt32 offset = ith_node(node_id).offset();
+ if (offset != INVALID_OFFSET) {
+ UInt16 labels[MAX_LABEL + 1];
+ UInt32 num_labels = 0;
+
+ UInt32 next_label = ith_node(node_id).child();
+ GRN_DAT_DEBUG_THROW_IF(next_label == INVALID_LABEL);
+ while (next_label != INVALID_LABEL) {
+ GRN_DAT_DEBUG_THROW_IF(next_label > MAX_LABEL);
+ labels[num_labels++] = next_label;
+ next_label = ith_node(offset ^ next_label).sibling();
+ }
+ GRN_DAT_DEBUG_THROW_IF(num_labels == 0);
+
+ labels[num_labels] = label;
+ offset = find_offset(labels, num_labels + 1);
+ migrate_nodes(node_id, offset, labels, num_labels);
+ } else {
+ offset = find_offset(&label, 1);
+ if (offset >= num_nodes()) {
+ GRN_DAT_DEBUG_THROW_IF((offset / BLOCK_SIZE) != num_blocks());
+ reserve_block(num_blocks());
+ }
+ ith_node(offset).set_is_offset(true);
+ ith_node(node_id).set_offset(offset);
+ }
+}
+
+void Trie::migrate_nodes(UInt32 node_id, UInt32 dest_offset,
+ const UInt16 *labels, UInt32 num_labels) {
+ GRN_DAT_DEBUG_THROW_IF(node_id >= num_nodes());
+ GRN_DAT_DEBUG_THROW_IF(ith_node(node_id).is_linker());
+ GRN_DAT_DEBUG_THROW_IF(labels == NULL);
+ GRN_DAT_DEBUG_THROW_IF(num_labels == 0);
+ GRN_DAT_DEBUG_THROW_IF(num_labels > (MAX_LABEL + 1));
+
+ const UInt32 src_offset = ith_node(node_id).offset();
+ GRN_DAT_DEBUG_THROW_IF(src_offset == INVALID_OFFSET);
+ GRN_DAT_DEBUG_THROW_IF(!ith_node(src_offset).is_offset());
+
+ for (UInt32 i = 0; i < num_labels; ++i) {
+ const UInt32 src_node_id = src_offset ^ labels[i];
+ const UInt32 dest_node_id = dest_offset ^ labels[i];
+ GRN_DAT_DEBUG_THROW_IF(ith_node(src_node_id).is_phantom());
+ GRN_DAT_DEBUG_THROW_IF(ith_node(src_node_id).label() != labels[i]);
+
+ reserve_node(dest_node_id);
+ ith_node(dest_node_id).set_except_is_offset(
+ ith_node(src_node_id).except_is_offset());
+ ith_node(dest_node_id).set_base(ith_node(src_node_id).base());
+ }
+ header_->set_num_zombies(num_zombies() + num_labels);
+
+ GRN_DAT_DEBUG_THROW_IF(ith_node(dest_offset).is_offset());
+ ith_node(dest_offset).set_is_offset(true);
+ ith_node(node_id).set_offset(dest_offset);
+}
+
+UInt32 Trie::find_offset(const UInt16 *labels, UInt32 num_labels) {
+ GRN_DAT_DEBUG_THROW_IF(labels == NULL);
+ GRN_DAT_DEBUG_THROW_IF(num_labels == 0);
+ GRN_DAT_DEBUG_THROW_IF(num_labels > (MAX_LABEL + 1));
+
+ // Blocks are tested in descending order of level. Basically, a lower level
+ // block contains more phantom nodes.
+ UInt32 level = 1;
+ while (num_labels >= (1U << level)) {
+ ++level;
+ }
+ level = (level < MAX_BLOCK_LEVEL) ? (MAX_BLOCK_LEVEL - level) : 0;
+
+ UInt32 block_count = 0;
+ do {
+ UInt32 leader = header_->ith_leader(level);
+ if (leader == INVALID_LEADER) {
+ // This level has no blocks and it is thus skipped.
+ continue;
+ }
+
+ UInt32 block_id = leader;
+ do {
+ const Block &block = ith_block(block_id);
+ GRN_DAT_DEBUG_THROW_IF(block.level() != level);
+
+ const UInt32 first = (block_id * BLOCK_SIZE) | block.first_phantom();
+ UInt32 node_id = first;
+ do {
+ GRN_DAT_DEBUG_THROW_IF(!ith_node(node_id).is_phantom());
+ const UInt32 offset = node_id ^ labels[0];
+ if (!ith_node(offset).is_offset()) {
+ UInt32 i = 1;
+ for ( ; i < num_labels; ++i) {
+ if (!ith_node(offset ^ labels[i]).is_phantom()) {
+ break;
+ }
+ }
+ if (i >= num_labels) {
+ return offset;
+ }
+ }
+ node_id = (block_id * BLOCK_SIZE) | ith_node(node_id).next();
+ } while (node_id != first);
+
+ const UInt32 prev = block_id;
+ const UInt32 next = block.next();
+ block_id = next;
+ ith_block(prev).set_failure_count(ith_block(prev).failure_count() + 1);
+
+ // The level of a block is updated when this function fails many times,
+ // actually MAX_FAILURE_COUNT times, in that block.
+ if (ith_block(prev).failure_count() == MAX_FAILURE_COUNT) {
+ update_block_level(prev, level + 1);
+ if (next == leader) {
+ break;
+ } else {
+ // Note that the leader might be updated in the level update.
+ leader = header_->ith_leader(level);
+ continue;
+ }
+ }
+ } while ((++block_count < MAX_BLOCK_COUNT) && (block_id != leader));
+ } while ((block_count < MAX_BLOCK_COUNT) && (level-- != 0));
+
+ return num_nodes() ^ labels[0];
+}
+
+void Trie::reserve_node(UInt32 node_id) {
+ GRN_DAT_DEBUG_THROW_IF(node_id > num_nodes());
+ if (node_id >= num_nodes()) {
+ reserve_block(node_id / BLOCK_SIZE);
+ }
+
+ Node &node = ith_node(node_id);
+ GRN_DAT_DEBUG_THROW_IF(!node.is_phantom());
+
+ const UInt32 block_id = node_id / BLOCK_SIZE;
+ Block &block = ith_block(block_id);
+ GRN_DAT_DEBUG_THROW_IF(block.num_phantoms() == 0);
+
+ const UInt32 next = (block_id * BLOCK_SIZE) | node.next();
+ const UInt32 prev = (block_id * BLOCK_SIZE) | node.prev();
+ GRN_DAT_DEBUG_THROW_IF(next >= num_nodes());
+ GRN_DAT_DEBUG_THROW_IF(prev >= num_nodes());
+
+ if ((node_id & BLOCK_MASK) == block.first_phantom()) {
+ // The first phantom node is removed from the block and the second phantom
+ // node comes first.
+ block.set_first_phantom(next & BLOCK_MASK);
+ }
+
+ ith_node(next).set_prev(prev & BLOCK_MASK);
+ ith_node(prev).set_next(next & BLOCK_MASK);
+
+ if (block.level() != MAX_BLOCK_LEVEL) {
+ const UInt32 threshold = 1U << ((MAX_BLOCK_LEVEL - block.level() - 1) * 2);
+ if (block.num_phantoms() == threshold) {
+ update_block_level(block_id, block.level() + 1);
+ }
+ }
+ block.set_num_phantoms(block.num_phantoms() - 1);
+
+ node.set_is_phantom(false);
+
+ GRN_DAT_DEBUG_THROW_IF(node.offset() != INVALID_OFFSET);
+ GRN_DAT_DEBUG_THROW_IF(node.label() != INVALID_LABEL);
+
+ header_->set_num_phantoms(num_phantoms() - 1);
+}
+
+void Trie::reserve_block(UInt32 block_id) {
+ GRN_DAT_DEBUG_THROW_IF(block_id != num_blocks());
+ GRN_DAT_THROW_IF(SIZE_ERROR, block_id >= max_num_blocks());
+
+ header_->set_num_blocks(block_id + 1);
+ ith_block(block_id).set_failure_count(0);
+ ith_block(block_id).set_first_phantom(0);
+ ith_block(block_id).set_num_phantoms(BLOCK_SIZE);
+
+ const UInt32 begin = block_id * BLOCK_SIZE;
+ const UInt32 end = begin + BLOCK_SIZE;
+ GRN_DAT_DEBUG_THROW_IF(end != num_nodes());
+
+ Base base;
+ base.set_offset(INVALID_OFFSET);
+
+ Check check;
+ check.set_is_phantom(true);
+
+ for (UInt32 i = begin; i < end; ++i) {
+ check.set_prev((i - 1) & BLOCK_MASK);
+ check.set_next((i + 1) & BLOCK_MASK);
+ ith_node(i).set_base(base);
+ ith_node(i).set_check(check);
+ }
+
+ // The level of the new block is 0.
+ set_block_level(block_id, 0);
+ header_->set_num_phantoms(num_phantoms() + BLOCK_SIZE);
+}
+
+void Trie::update_block_level(UInt32 block_id, UInt32 level) {
+ GRN_DAT_DEBUG_THROW_IF(block_id >= num_blocks());
+ GRN_DAT_DEBUG_THROW_IF(level > MAX_BLOCK_LEVEL);
+
+ unset_block_level(block_id);
+ set_block_level(block_id, level);
+}
+
+void Trie::set_block_level(UInt32 block_id, UInt32 level) {
+ GRN_DAT_DEBUG_THROW_IF(block_id >= num_blocks());
+ GRN_DAT_DEBUG_THROW_IF(level > MAX_BLOCK_LEVEL);
+
+ const UInt32 leader = header_->ith_leader(level);
+ if (leader == INVALID_LEADER) {
+ // The new block becomes the only one block of the linked list.
+ ith_block(block_id).set_next(block_id);
+ ith_block(block_id).set_prev(block_id);
+ header_->set_ith_leader(level, block_id);
+ } else {
+ // The new block is added to the end of the list.
+ const UInt32 next = leader;
+ const UInt32 prev = ith_block(leader).prev();
+ GRN_DAT_DEBUG_THROW_IF(next >= num_blocks());
+ GRN_DAT_DEBUG_THROW_IF(prev >= num_blocks());
+ ith_block(block_id).set_next(next);
+ ith_block(block_id).set_prev(prev);
+ ith_block(next).set_prev(block_id);
+ ith_block(prev).set_next(block_id);
+ }
+ ith_block(block_id).set_level(level);
+ ith_block(block_id).set_failure_count(0);
+}
+
+void Trie::unset_block_level(UInt32 block_id) {
+ GRN_DAT_DEBUG_THROW_IF(block_id >= num_blocks());
+
+ const UInt32 level = ith_block(block_id).level();
+ GRN_DAT_DEBUG_THROW_IF(level > MAX_BLOCK_LEVEL);
+
+ const UInt32 leader = header_->ith_leader(level);
+ GRN_DAT_DEBUG_THROW_IF(leader == INVALID_LEADER);
+
+ const UInt32 next = ith_block(block_id).next();
+ const UInt32 prev = ith_block(block_id).prev();
+ GRN_DAT_DEBUG_THROW_IF(next >= num_blocks());
+ GRN_DAT_DEBUG_THROW_IF(prev >= num_blocks());
+
+ if (next == block_id) {
+ // The linked list becomes empty.
+ header_->set_ith_leader(level, INVALID_LEADER);
+ } else {
+ ith_block(next).set_prev(prev);
+ ith_block(prev).set_next(next);
+ if (block_id == leader) {
+ // The second block becomes the leader of the linked list.
+ header_->set_ith_leader(level, next);
+ }
+ }
+}
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/trie.hpp b/storage/mroonga/vendor/groonga/lib/dat/trie.hpp
new file mode 100644
index 00000000..bf7d0b98
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/trie.hpp
@@ -0,0 +1,285 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "array.hpp"
+#include "header.hpp"
+#include "node.hpp"
+#include "block.hpp"
+#include "entry.hpp"
+#include "key.hpp"
+#include "file.hpp"
+
+namespace grn {
+namespace dat {
+
+class GRN_DAT_API Trie {
+ public:
+ Trie();
+ ~Trie();
+
+ void create(const char *file_name = NULL,
+ UInt64 file_size = 0,
+ UInt32 max_num_keys = 0,
+ double num_nodes_per_key = 0.0,
+ double average_key_length = 0.0);
+
+ void create(const Trie &trie,
+ const char *file_name = NULL,
+ UInt64 file_size = 0,
+ UInt32 max_num_keys = 0,
+ double num_nodes_per_key = 0.0,
+ double average_key_length = 0.0);
+
+ void repair(const Trie &trie, const char *file_name = NULL);
+
+ void open(const char *file_name);
+ void close();
+
+ void swap(Trie *trie);
+
+ // Users can access a key by its position or ID.
+ const Key &get_key(UInt32 key_pos) const {
+ GRN_DAT_DEBUG_THROW_IF(key_pos >= next_key_pos());
+ return *reinterpret_cast<const Key *>(key_buf_.ptr() + key_pos);
+ }
+ // If a specified ID is invalid, e.g. the key is already deleted, this
+ // function returns a reference to an invalid key object whose id() returns
+ // INVALID_KEY_ID.
+ const Key &ith_key(UInt32 key_id) const {
+ if ((key_id >= min_key_id()) && (key_id <= max_key_id()) &&
+ ith_entry(key_id).is_valid()) {
+ return get_key(ith_entry(key_id).key_pos());
+ }
+ return Key::invalid_key();
+ }
+
+ bool search(const void *ptr, UInt32 length, UInt32 *key_pos = NULL) const {
+ return search_key(static_cast<const UInt8 *>(ptr), length, key_pos);
+ }
+ // Longest prefix match search.
+ bool lcp_search(const void *ptr, UInt32 length,
+ UInt32 *key_pos = NULL) const {
+ return lcp_search_key(static_cast<const UInt8 *>(ptr), length, key_pos);
+ }
+
+ bool remove(UInt32 key_id) {
+ const Key &key = ith_key(key_id);
+ if (key.is_valid()) {
+ return remove(key.ptr(), key.length());
+ }
+ return false;
+ }
+ bool remove(const void *ptr, UInt32 length) {
+ return remove_key(static_cast<const UInt8 *>(ptr), length);
+ }
+
+ bool insert(const void *ptr, UInt32 length, UInt32 *key_pos = NULL) {
+ return insert_key(static_cast<const UInt8 *>(ptr), length, key_pos);
+ }
+
+ bool update(UInt32 key_id, const void *ptr, UInt32 length,
+ UInt32 *key_pos = NULL) {
+ return update_key(ith_key(key_id), static_cast<const UInt8 *>(ptr),
+ length, key_pos);
+ }
+ bool update(const void *src_ptr, UInt32 src_length,
+ const void *dest_ptr, UInt32 dest_length,
+ UInt32 *key_pos = NULL) {
+ UInt32 src_key_pos;
+ if (!search(src_ptr, src_length, &src_key_pos)) {
+ return false;
+ }
+ const Key &src_key = get_key(src_key_pos);
+ return update_key(src_key, static_cast<const UInt8 *>(dest_ptr),
+ dest_length, key_pos);
+ }
+
+ const Node &ith_node(UInt32 i) const {
+ GRN_DAT_DEBUG_THROW_IF(i >= num_nodes());
+ return nodes_[i];
+ }
+ const Block &ith_block(UInt32 i) const {
+ GRN_DAT_DEBUG_THROW_IF(i >= num_blocks());
+ return blocks_[i];
+ }
+ const Entry &ith_entry(UInt32 i) const {
+ GRN_DAT_DEBUG_THROW_IF(i < min_key_id());
+ GRN_DAT_DEBUG_THROW_IF(i > max_key_id());
+ return entries_[i];
+ }
+
+ const Header &header() const {
+ return *header_;
+ }
+
+ UInt64 file_size() const {
+ return header_->file_size();
+ }
+ UInt64 virtual_size() const {
+ return sizeof(Header)
+ + (sizeof(Entry) * num_keys())
+ + (sizeof(Block) * num_blocks())
+ + (sizeof(Node) * num_nodes())
+ + total_key_length();
+ }
+ UInt32 total_key_length() const {
+ return header_->total_key_length();
+ }
+ UInt32 num_keys() const {
+ return header_->num_keys();
+ }
+ UInt32 min_key_id() const {
+ return header_->min_key_id();
+ }
+ UInt32 next_key_id() const {
+ return header_->next_key_id();
+ }
+ UInt32 max_key_id() const {
+ return header_->max_key_id();
+ }
+ UInt32 max_num_keys() const {
+ return header_->max_num_keys();
+ }
+ UInt32 num_nodes() const {
+ return header_->num_nodes();
+ }
+ UInt32 num_phantoms() const {
+ return header_->num_phantoms();
+ }
+ UInt32 num_zombies() const {
+ return header_->num_zombies();
+ }
+ UInt32 max_num_nodes() const {
+ return header_->max_num_nodes();
+ }
+ UInt32 num_blocks() const {
+ return header_->num_blocks();
+ }
+ UInt32 max_num_blocks() const {
+ return header_->max_num_blocks();
+ }
+ UInt32 next_key_pos() const {
+ return header_->next_key_pos();
+ }
+ UInt32 key_buf_size() const {
+ return header_->key_buf_size();
+ }
+ UInt32 status_flags() const {
+ return header_->status_flags();
+ }
+
+ void clear_status_flags() {
+ header_->set_status_flags(status_flags() & ~CHANGING_MASK);
+ }
+
+ void flush();
+
+ private:
+ File file_;
+ Header *header_;
+ Array<Node> nodes_;
+ Array<Block> blocks_;
+ Array<Entry> entries_;
+ Array<UInt32> key_buf_;
+
+ void create_file(const char *file_name,
+ UInt64 file_size,
+ UInt32 max_num_keys,
+ double num_nodes_per_key,
+ double average_key_length);
+ void create_file(const char *file_name,
+ UInt64 file_size,
+ UInt32 max_num_keys,
+ UInt32 max_num_blocks,
+ UInt32 key_buf_size);
+
+ void open_file(const char *file_name);
+
+ void map_address(void *address);
+
+ void build_from_trie(const Trie &trie);
+ void build_from_trie(const Trie &trie, UInt32 src, UInt32 dest);
+
+ void repair_trie(const Trie &trie);
+ void build_from_keys(const UInt32 *begin, const UInt32 *end,
+ UInt32 depth, UInt32 node_id);
+
+ void mkq_sort(UInt32 *l, UInt32 *r, UInt32 depth);
+ void insertion_sort(UInt32 *l, UInt32 *r, UInt32 depth);
+
+ inline int get_label(UInt32 key_id, UInt32 depth) const;
+ inline int get_median(UInt32 a, UInt32 b, UInt32 c, UInt32 depth) const;
+ inline bool less_than(UInt32 lhs, UInt32 rhs, UInt32 depth) const;
+ inline static void swap_ids(UInt32 *lhs, UInt32 *rhs);
+
+ bool search_key(const UInt8 *ptr, UInt32 length, UInt32 *key_pos) const;
+ bool search_linker(const UInt8 *ptr, UInt32 length,
+ UInt32 &node_id, UInt32 &query_pos) const;
+
+ bool lcp_search_key(const UInt8 *ptr, UInt32 length, UInt32 *key_pos) const;
+
+ bool remove_key(const UInt8 *ptr, UInt32 length);
+
+ bool insert_key(const UInt8 *ptr, UInt32 length, UInt32 *key_pos);
+ bool insert_linker(const UInt8 *ptr, UInt32 length,
+ UInt32 &node_id, UInt32 query_pos);
+
+ bool update_key(const Key &key, const UInt8 *ptr, UInt32 length,
+ UInt32 *key_pos);
+
+ UInt32 insert_node(UInt32 node_id, UInt16 label);
+ UInt32 append_key(const UInt8 *ptr, UInt32 length, UInt32 key_id);
+
+ UInt32 separate(const UInt8 *ptr, UInt32 length,
+ UInt32 node_id, UInt32 i);
+ void resolve(UInt32 node_id, UInt16 label);
+ void migrate_nodes(UInt32 node_id, UInt32 dest_offset,
+ const UInt16 *labels, UInt32 num_labels);
+
+ UInt32 find_offset(const UInt16 *labels, UInt32 num_labels);
+
+ void reserve_node(UInt32 node_id);
+ void reserve_block(UInt32 block_id);
+
+ void update_block_level(UInt32 block_id, UInt32 level);
+ void set_block_level(UInt32 block_id, UInt32 level);
+ void unset_block_level(UInt32 block_id);
+
+ Node &ith_node(UInt32 i) {
+ GRN_DAT_DEBUG_THROW_IF(i >= num_nodes());
+ return nodes_[i];
+ }
+ Block &ith_block(UInt32 i) {
+ GRN_DAT_DEBUG_THROW_IF(i >= num_blocks());
+ return blocks_[i];
+ }
+ Entry &ith_entry(UInt32 i) {
+ GRN_DAT_DEBUG_THROW_IF(i < min_key_id());
+ GRN_DAT_DEBUG_THROW_IF(i > (max_key_id() + 1));
+ return entries_[i];
+ }
+
+ // Disallows copy and assignment.
+ Trie(const Trie &);
+ Trie &operator=(const Trie &);
+};
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/dat/vector.hpp b/storage/mroonga/vendor/groonga/lib/dat/vector.hpp
new file mode 100644
index 00000000..8a67b27b
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/dat/vector.hpp
@@ -0,0 +1,191 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "dat.hpp"
+
+#include <new>
+
+namespace grn {
+namespace dat {
+
+template <typename T>
+class GRN_DAT_API Vector {
+ public:
+ Vector() : buf_(NULL), size_(0), capacity_(0) {}
+ ~Vector() {
+ for (UInt32 i = 0; i < size(); ++i) {
+ buf_[i].~T();
+ }
+ delete [] reinterpret_cast<char *>(buf_);
+ }
+
+ const T &operator[](UInt32 i) const {
+ GRN_DAT_DEBUG_THROW_IF(i >= size());
+ return buf_[i];
+ }
+ T &operator[](UInt32 i) {
+ GRN_DAT_DEBUG_THROW_IF(i >= size());
+ return buf_[i];
+ }
+
+ const T &front() const {
+ GRN_DAT_DEBUG_THROW_IF(empty());
+ return buf_[0];
+ }
+ T &front() {
+ GRN_DAT_DEBUG_THROW_IF(empty());
+ return buf_[0];
+ }
+
+ const T &back() const {
+ GRN_DAT_DEBUG_THROW_IF(empty());
+ return buf_[size() - 1];
+ }
+ T &back() {
+ GRN_DAT_DEBUG_THROW_IF(empty());
+ return buf_[size() - 1];
+ }
+
+ const T *begin() const {
+ return buf_;
+ }
+ T *begin() {
+ return buf_;
+ }
+
+ const T *end() const {
+ return buf_ + size_;
+ }
+ T *end() {
+ return buf_ + size_;
+ }
+
+ void push_back() {
+ reserve(size() + 1);
+ new (&buf_[size()]) T;
+ ++size_;
+ }
+ void push_back(const T &x) {
+ reserve(size() + 1);
+ new (&buf_[size()]) T(x);
+ ++size_;
+ }
+
+ void pop_back() {
+ GRN_DAT_DEBUG_THROW_IF(empty());
+ back().~T();
+ --size_;
+ }
+
+ void clear() {
+ resize(0);
+ }
+
+ void resize(UInt32 new_size) {
+ if (new_size > capacity()) {
+ reserve(new_size);
+ }
+ for (UInt32 i = size(); i < new_size; ++i) {
+ new (&buf_[i]) T;
+ }
+ for (UInt32 i = new_size; i < size(); ++i) {
+ buf_[i].~T();
+ }
+ size_ = new_size;
+ }
+ template <typename U>
+ void resize(UInt32 new_size, const U &value) {
+ if (new_size > capacity()) {
+ reserve(new_size);
+ }
+ for (UInt32 i = size(); i < new_size; ++i) {
+ new (&buf_[i]) T(value);
+ }
+ for (UInt32 i = new_size; i < size(); ++i) {
+ buf_[i].~T();
+ }
+ size_ = new_size;
+ }
+
+ void reserve(UInt32 new_capacity) {
+ if (new_capacity <= capacity()) {
+ return;
+ } else if ((new_capacity / 2) < capacity()) {
+ if (capacity() < (MAX_UINT32 / 2)) {
+ new_capacity = capacity() * 2;
+ } else {
+ new_capacity = MAX_UINT32;
+ }
+ }
+
+ T *new_buf = reinterpret_cast<T *>(
+ new (std::nothrow) char[sizeof(new_capacity) * new_capacity]);
+ GRN_DAT_THROW_IF(MEMORY_ERROR, new_buf == NULL);
+
+ for (UInt32 i = 0; i < size(); ++i) {
+ new (&new_buf[i]) T(buf_[i]);
+ }
+ for (UInt32 i = 0; i < size(); ++i) {
+ buf_[i].~T();
+ }
+
+ T *old_buf = buf_;
+ buf_ = new_buf;
+ delete [] reinterpret_cast<char *>(old_buf);
+
+ capacity_ = new_capacity;
+ }
+
+ void swap(Vector *rhs) {
+ T * const temp_buf = buf_;
+ buf_ = rhs->buf_;
+ rhs->buf_ = temp_buf;
+
+ const UInt32 temp_size = size_;
+ size_ = rhs->size_;
+ rhs->size_ = temp_size;
+
+ const UInt32 temp_capacity = capacity_;
+ capacity_ = rhs->capacity_;
+ rhs->capacity_ = temp_capacity;
+ }
+
+ bool empty() const {
+ return size_ == 0;
+ }
+ UInt32 size() const {
+ return size_;
+ }
+ UInt32 capacity() const {
+ return capacity_;
+ }
+
+ private:
+ T *buf_;
+ UInt32 size_;
+ UInt32 capacity_;
+
+ // Disallows copy and assignment.
+ Vector(const Vector &);
+ Vector &operator=(const Vector &);
+};
+
+} // namespace dat
+} // namespace grn
diff --git a/storage/mroonga/vendor/groonga/lib/db.c b/storage/mroonga/vendor/groonga/lib/db.c
new file mode 100644
index 00000000..7749d4c0
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/db.c
@@ -0,0 +1,14054 @@
+/* -*- 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-1335 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"
+#include "grn_proc.h"
+#include "grn_plugin.h"
+#include "grn_geo.h"
+#include "grn_scorers.h"
+#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;
+ unsigned int weight;
+} weight_uvector_entry;
+
+#define IS_WEIGHT_UVECTOR(obj) ((obj)->header.flags & GRN_OBJ_WITH_WEIGHT)
+
+#define GRN_TABLE_GROUPED (0x01<<0)
+#define GRN_TABLE_IS_GROUPED(table)\
+ ((table)->header.impl_flags & GRN_TABLE_GROUPED)
+#define GRN_TABLE_GROUPED_ON(table)\
+ ((table)->header.impl_flags |= GRN_TABLE_GROUPED)
+#define GRN_TABLE_IS_MULTI_KEYS_GROUPED(table)\
+ (GRN_TABLE_IS_GROUPED(table) &&\
+ table->header.domain == GRN_ID_NIL)
+
+#define WITH_NORMALIZE(table,key,key_size,block) do {\
+ if ((table)->normalizer && key && key_size > 0) {\
+ grn_obj *nstr;\
+ if ((nstr = grn_string_open(ctx, key, key_size,\
+ (table)->normalizer, 0))) {\
+ const char *key;\
+ unsigned int key_size;\
+ grn_string_get_normalized(ctx, nstr, &key, &key_size, NULL);\
+ block\
+ grn_obj_close(ctx, nstr);\
+ }\
+ } else {\
+ block\
+ }\
+} while (0)
+
+inline static grn_id
+grn_table_add_v_inline(grn_ctx *ctx, grn_obj *table, const void *key, int key_size,
+ void **value, int *added);
+inline static void
+grn_table_add_subrec_inline(grn_obj *table, grn_rset_recinfo *ri, double score,
+ grn_rset_posinfo *pi, int dir);
+inline static grn_id
+grn_table_cursor_next_inline(grn_ctx *ctx, grn_table_cursor *tc);
+inline static int
+grn_table_cursor_get_value_inline(grn_ctx *ctx, grn_table_cursor *tc, void **value);
+
+static void grn_obj_ensure_bulk(grn_ctx *ctx, grn_obj *obj);
+static void grn_obj_ensure_vector(grn_ctx *ctx, grn_obj *obj);
+
+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];
+
+void
+grn_db_init_from_env(void)
+{
+ grn_getenv("GRN_DB_KEY",
+ grn_db_key,
+ GRN_ENV_BUFFER_SIZE);
+}
+
+inline static void
+gen_pathname(const char *path, char *buffer, int fno)
+{
+ size_t len = strlen(path);
+ grn_memcpy(buffer, path, len);
+ if (fno >= 0) {
+ buffer[len] = '.';
+ grn_itoh(fno, buffer + len + 1, 7);
+ buffer[len + 8] = '\0';
+ } else {
+ buffer[len] = '\0';
+ }
+}
+
+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
+grn_db_config_create(grn_ctx *ctx, grn_db *s, const char *path,
+ const char *context_tag)
+{
+ char *config_path;
+ char config_path_buffer[PATH_MAX];
+ uint32_t flags = GRN_OBJ_KEY_VAR_SIZE;
+
+ 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;
+ }
+
+ return GRN_TRUE;
+}
+
+static grn_bool
+grn_db_config_open(grn_ctx *ctx, grn_db *s, const char *path)
+{
+ char config_path[PATH_MAX];
+
+ 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 {
+ return grn_db_config_create(ctx, s, path, "[db][open]");
+ }
+}
+
+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 = NULL;
+
+ GRN_API_ENTER;
+
+ 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;
+ }
+ }
+
+ 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 {
+ 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 {
+ 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 = NULL;
+
+ GRN_API_ENTER;
+
+ 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;
+ }
+ 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);
+ }
+#endif
+ 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);
+ CRITICAL_SECTION_FIN(s->lock);
+ GRN_FREE(s);
+ }
+
+ GRN_API_RETURN(NULL);
+}
+
+static grn_id
+grn_db_curr_id(grn_ctx *ctx, grn_obj *db)
+{
+ grn_id curr_id = GRN_ID_NIL;
+ grn_db *s = (grn_db *)db;
+ switch (s->keys->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ curr_id = grn_pat_curr_id(ctx, (grn_pat *)s->keys);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ curr_id = grn_dat_curr_id(ctx, (grn_dat *)s->keys);
+ break;
+ }
+ return curr_id;
+}
+
+/* s must be validated by caller */
+grn_rc
+grn_db_close(grn_ctx *ctx, grn_obj *db)
+{
+ grn_id id;
+ db_value *vp;
+ grn_db *s = (grn_db *)db;
+ grn_bool ctx_used_db;
+ if (!s) { return GRN_INVALID_ARGUMENT; }
+ GRN_API_ENTER;
+
+ ctx_used_db = ctx->impl && ctx->impl->db == db;
+ if (ctx_used_db) {
+#ifdef GRN_WITH_MECAB
+ grn_db_fin_mecab_tokenizer(ctx);
+#endif
+ grn_ctx_loader_clear(ctx);
+ if (ctx->impl->parser) {
+ grn_expr_parser_close(ctx);
+ }
+ }
+
+ GRN_TINY_ARRAY_EACH(&s->values, 1, grn_db_curr_id(ctx, db), id, vp, {
+ if (vp->ptr) { grn_obj_close(ctx, vp->ptr); }
+ });
+
+ if (ctx_used_db) {
+ if (ctx->impl->values) {
+ grn_db_obj *o;
+ GRN_ARRAY_EACH(ctx, ctx->impl->values, 0, 0, id, &o, {
+ grn_obj_close(ctx, *((grn_obj **)o));
+ });
+ grn_array_truncate(ctx, ctx->impl->values);
+ }
+ }
+
+/* grn_tiny_array_fin should be refined.. */
+#ifdef WIN32
+ {
+ grn_tiny_array *a = &s->values;
+ CRITICAL_SECTION_FIN(a->lock);
+ }
+#endif
+ grn_tiny_array_fin(&s->values);
+
+ switch (s->keys->header.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;
+ }
+ 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) {
+ grn_cache *cache;
+ cache = grn_cache_current_get(ctx);
+ if (cache) {
+ grn_cache_expire(cache, -1);
+ }
+ ctx->impl->db = NULL;
+ }
+
+ GRN_API_RETURN(GRN_SUCCESS);
+}
+
+grn_obj *
+grn_ctx_get(grn_ctx *ctx, const char *name, int name_size)
+{
+ grn_obj *obj = NULL;
+ grn_obj *db;
+ if (!ctx || !ctx->impl || !(db = ctx->impl->db)) {
+ return NULL;
+ }
+ 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);
+ }
+ 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);
+}
+
+grn_obj *
+grn_ctx_db(grn_ctx *ctx)
+{
+ return (ctx && ctx->impl) ? ctx->impl->db : NULL;
+}
+
+grn_obj *
+grn_db_keys(grn_obj *s)
+{
+ return (grn_obj *)(((grn_db *)s)->keys);
+}
+
+uint32_t
+grn_obj_get_last_modified(grn_ctx *ctx, grn_obj *obj)
+{
+ 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;
+ }
+}
+
+uint32_t
+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)
+{
+ 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_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)
+{
+ grn_timeval tv_;
+ if (!tv) {
+ grn_timeval_now(ctx, &tv_);
+ tv = &tv_;
+ }
+ if (obj) {
+ switch (obj->header.type) {
+ case GRN_DB :
+ grn_obj_touch_db(ctx, obj, tv);
+ break;
+ 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 :
+ if (!IS_TEMP(obj)) {
+ grn_obj_get_io(ctx, obj)->header->last_modified = tv->tv_sec;
+ grn_obj_touch(ctx, DB_OBJ(obj)->db, tv);
+ }
+ break;
+ }
+ }
+}
+
+grn_rc
+grn_db_check_name(grn_ctx *ctx, const char *name, unsigned int name_size)
+{
+ int len;
+ const char *name_end = name + name_size;
+ if (name_size > 0 &&
+ *name == GRN_DB_PSEUDO_COLUMN_PREFIX) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ while (name < name_end) {
+ char c = *name;
+ if ((unsigned int)((c | 0x20) - 'a') >= 26u &&
+ (unsigned int)(c - '0') >= 10u &&
+ c != '_' &&
+ c != '-' &&
+ c != '#' &&
+ c != '@') {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!(len = grn_charlen(ctx, name, name_end))) { break; }
+ name += len;
+ }
+ return GRN_SUCCESS;
+}
+
+static grn_obj *
+grn_type_open(grn_ctx *ctx, grn_obj_spec *spec)
+{
+ struct _grn_type *res;
+ res = GRN_MALLOC(sizeof(struct _grn_type));
+ if (res) {
+ GRN_DB_OBJ_SET_TYPE(res, GRN_TYPE);
+ res->obj.header = spec->header;
+ GRN_TYPE_SIZE(&res->obj) = GRN_TYPE_SIZE(spec);
+ }
+ return (grn_obj *)res;
+}
+
+grn_obj *
+grn_proc_create(grn_ctx *ctx, const char *name, int name_size, grn_proc_type type,
+ grn_proc_func *init, grn_proc_func *next, grn_proc_func *fin,
+ unsigned int nvars, grn_expr_var *vars)
+{
+ grn_proc *res = NULL;
+ grn_id id = GRN_ID_NIL;
+ grn_id range = GRN_ID_NIL;
+ int added = 0;
+ grn_obj *db;
+ 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);
+ }
+ if (name_size < 0) {
+ name_size = strlen(name);
+ }
+ if (grn_db_check_name(ctx, name, name_size)) {
+ GRN_DB_CHECK_NAME_ERR("[proc][create]", name, name_size);
+ GRN_API_RETURN(NULL);
+ }
+ if (!GRN_DB_P(db)) {
+ ERR(GRN_INVALID_ARGUMENT, "invalid db assigned");
+ GRN_API_RETURN(NULL);
+ }
+ if (name && name_size) {
+ grn_db *s = (grn_db *)db;
+ if (!(id = grn_table_get(ctx, s->keys, name, name_size))) {
+ if (!(id = grn_table_add(ctx, s->keys, name, name_size, &added))) {
+ ERR(GRN_NO_MEMORY_AVAILABLE, "grn_table_add failed");
+ GRN_API_RETURN(NULL);
+ }
+ }
+ if (!added) {
+ db_value *vp;
+ if ((vp = grn_tiny_array_at(&s->values, id)) && (res = (grn_proc *)vp->ptr)) {
+ /* TODO: Do more robust check. */
+ if (res->funcs[PROC_INIT] ||
+ res->funcs[PROC_NEXT] ||
+ res->funcs[PROC_FIN]) {
+ ERR(GRN_INVALID_ARGUMENT, "already used name");
+ GRN_API_RETURN(NULL);
+ }
+ if (range != GRN_ID_NIL) {
+ grn_plugin_close(ctx, range);
+ }
+ GRN_API_RETURN((grn_obj *)res);
+ } else {
+ added = 1;
+ }
+ }
+ } else if (ctx->impl && ctx->impl->values) {
+ id = grn_array_add(ctx, ctx->impl->values, NULL) | GRN_OBJ_TMP_OBJECT;
+ added = 1;
+ }
+ if (!res) { res = GRN_MALLOCN(grn_proc, 1); }
+ if (res) {
+ GRN_DB_OBJ_SET_TYPE(res, GRN_PROC);
+ res->obj.db = db;
+ res->obj.id = id;
+ res->obj.header.domain = GRN_ID_NIL;
+ res->obj.header.flags = path ? GRN_OBJ_CUSTOM_NAME : 0;
+ res->obj.range = range;
+ res->type = type;
+ res->funcs[PROC_INIT] = init;
+ res->funcs[PROC_NEXT] = next;
+ res->funcs[PROC_FIN] = fin;
+ 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;
+ if (added) {
+ if (grn_db_obj_init(ctx, db, id, DB_OBJ(res))) {
+ // grn_obj_delete(ctx, db, id);
+ GRN_FREE(res);
+ GRN_API_RETURN(NULL);
+ }
+ }
+ while (nvars--) {
+ grn_obj *v = grn_expr_add_var(ctx, (grn_obj *)res, vars->name, vars->name_size);
+ GRN_OBJ_INIT(v, vars->value.header.type, 0, vars->value.header.domain);
+ GRN_TEXT_PUT(ctx, v, GRN_TEXT_VALUE(&vars->value), GRN_TEXT_LEN(&vars->value));
+ vars++;
+ }
+ }
+ GRN_API_RETURN((grn_obj *)res);
+}
+
+/* grn_table */
+
+static void
+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)
+{
+ *subrec_size = 0;
+ *subrec_offset = 0;
+ if (flags & GRN_OBJ_WITH_SUBREC) {
+ switch (flags & GRN_OBJ_UNIT_MASK) {
+ case GRN_OBJ_UNIT_DOCUMENT_NONE :
+ break;
+ case GRN_OBJ_UNIT_DOCUMENT_SECTION :
+ *subrec_offset = sizeof(grn_id);
+ *subrec_size = sizeof(uint32_t);
+ break;
+ case GRN_OBJ_UNIT_DOCUMENT_POSITION :
+ *subrec_offset = sizeof(grn_id);
+ *subrec_size = sizeof(uint32_t) + sizeof(uint32_t);
+ break;
+ case GRN_OBJ_UNIT_SECTION_NONE :
+ *key_size += sizeof(uint32_t);
+ break;
+ case GRN_OBJ_UNIT_SECTION_POSITION :
+ *key_size += sizeof(uint32_t);
+ *subrec_offset = sizeof(grn_id) + sizeof(uint32_t);
+ *subrec_size = sizeof(uint32_t);
+ break;
+ case GRN_OBJ_UNIT_POSITION_NONE :
+ *key_size += sizeof(uint32_t) + sizeof(uint32_t);
+ break;
+ case GRN_OBJ_UNIT_USERDEF_DOCUMENT :
+ *subrec_size = range_size;
+ break;
+ case GRN_OBJ_UNIT_USERDEF_SECTION :
+ *subrec_size = range_size + sizeof(uint32_t);
+ break;
+ case GRN_OBJ_UNIT_USERDEF_POSITION :
+ *subrec_size = range_size + sizeof(uint32_t) + sizeof(uint32_t);
+ break;
+ }
+ *value_size = (uintptr_t)GRN_RSET_SUBRECS_NTH((((grn_rset_recinfo *)0)->subrecs),
+ *subrec_size, max_n_subrecs);
+ } else {
+ *value_size = range_size;
+ }
+ *value_size += additional_value_size;
+}
+
+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_table_flags flags,
+ grn_obj *key_type, grn_obj *value_type)
+{
+ 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 :
+ 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 :
+ 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_table_flags flags, grn_obj *key_type,
+ grn_obj *value_type,
+ uint32_t max_n_subrecs,
+ uint32_t additional_value_size)
+{
+ grn_id id;
+ grn_id domain = GRN_ID_NIL, range = GRN_ID_NIL;
+ uint32_t key_size, value_size = 0, range_size = 0;
+ uint8_t subrec_size, subrec_offset;
+ grn_obj *res = NULL;
+ grn_obj *db;
+ char buffer[PATH_MAX];
+ if (!ctx->impl || !(db = ctx->impl->db)) {
+ ERR(GRN_INVALID_ARGUMENT, "[table][create] db not initialized");
+ return NULL;
+ }
+ if (grn_db_check_name(ctx, name, name_size)) {
+ GRN_DB_CHECK_NAME_ERR("[table][create]", name, name_size);
+ return NULL;
+ }
+ if (!GRN_DB_P(db)) {
+ ERR(GRN_INVALID_ARGUMENT, "[table][create] invalid db assigned");
+ return NULL;
+ }
+ if (grn_table_create_validate(ctx, name, name_size, path, flags,
+ key_type, value_type)) {
+ return NULL;
+ }
+ if (key_type) {
+ domain = DB_OBJ(key_type)->id;
+ switch (key_type->header.type) {
+ case GRN_TYPE :
+ {
+ grn_db_obj *t = (grn_db_obj *)key_type;
+ flags |= t->header.flags;
+ key_size = GRN_TYPE_SIZE(t);
+ if (key_size > GRN_TABLE_MAX_KEY_SIZE) {
+ int type_name_size;
+ char type_name[GRN_TABLE_MAX_KEY_SIZE];
+ type_name_size = grn_obj_name(ctx, key_type, type_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[table][create] key size too big: <%.*s> <%.*s>(%u) (max:%u)",
+ name_size, name,
+ type_name_size, type_name,
+ key_size, GRN_TABLE_MAX_KEY_SIZE);
+ return NULL;
+ }
+ }
+ break;
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ key_size = sizeof(grn_id);
+ break;
+ default :
+ {
+ 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 type must be type or table: <%.*s> (%.*s)",
+ name_size, name, key_name_size, key_name);
+ return NULL;
+ }
+ break;
+ }
+ } else {
+ key_size = (flags & GRN_OBJ_KEY_VAR_SIZE) ? GRN_TABLE_MAX_KEY_SIZE : sizeof(grn_id);
+ }
+ if (value_type) {
+ range = DB_OBJ(value_type)->id;
+ switch (value_type->header.type) {
+ case GRN_TYPE :
+ {
+ grn_db_obj *t = (grn_db_obj *)value_type;
+ if (t->header.flags & GRN_OBJ_KEY_VAR_SIZE) {
+ int type_name_size;
+ char type_name[GRN_TABLE_MAX_KEY_SIZE];
+ type_name_size = grn_obj_name(ctx, value_type, type_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[table][create] value type must be fixed size: <%.*s> (%.*s)",
+ name_size, name, type_name_size, type_name);
+ return NULL;
+ }
+ range_size = GRN_TYPE_SIZE(t);
+ }
+ break;
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ range_size = sizeof(grn_id);
+ break;
+ default :
+ {
+ int value_name_size;
+ char value_name[GRN_TABLE_MAX_KEY_SIZE];
+ value_name_size = grn_obj_name(ctx, value_type, value_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[table][create] value type must be type or table: <%.*s> (%.*s)",
+ name_size, name, value_name_size, value_name);
+ return NULL;
+ }
+ break;
+ }
+ }
+
+ 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:%u:table_create %.*s", id, name_size, name);
+ if (!path) {
+ if (GRN_DB_PERSISTENT_P(db)) {
+ grn_db_generate_pathname(ctx, db, id, buffer);
+ path = buffer;
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "path not assigned for persistent table");
+ grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
+ return NULL;
+ }
+ } else {
+ flags |= GRN_OBJ_CUSTOM_NAME;
+ }
+ } else {
+ if (path) {
+ ERR(GRN_INVALID_ARGUMENT, "path assigned for temporary table");
+ grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
+ return NULL;
+ }
+ if (GRN_DB_PERSISTENT_P(db) && name && name_size) {
+ ERR(GRN_INVALID_ARGUMENT, "name assigned for temporary table");
+ grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
+ return NULL;
+ }
+ }
+ calc_rec_size(flags, max_n_subrecs, range_size, additional_value_size,
+ &subrec_size, &subrec_offset, &key_size, &value_size);
+ switch (flags & GRN_OBJ_TABLE_TYPE_MASK) {
+ case GRN_OBJ_TABLE_HASH_KEY :
+ res = (grn_obj *)grn_hash_create(ctx, path, key_size, value_size, flags);
+ break;
+ case GRN_OBJ_TABLE_PAT_KEY :
+ res = (grn_obj *)grn_pat_create(ctx, path, key_size, value_size, flags);
+ break;
+ case GRN_OBJ_TABLE_DAT_KEY :
+ res = (grn_obj *)grn_dat_create(ctx, path, key_size, value_size, flags);
+ break;
+ case GRN_OBJ_TABLE_NO_KEY :
+ domain = range;
+ res = (grn_obj *)grn_array_create(ctx, path, value_size, flags);
+ break;
+ }
+ if (res) {
+ DB_OBJ(res)->header.impl_flags = 0;
+ DB_OBJ(res)->header.domain = domain;
+ DB_OBJ(res)->range = range;
+ DB_OBJ(res)->max_n_subrecs = max_n_subrecs;
+ DB_OBJ(res)->subrec_size = subrec_size;
+ 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_FALSE);
+ res = NULL;
+ }
+ } else {
+ grn_obj_delete_by_id(ctx, db, id, GRN_TRUE);
+ }
+ return res;
+}
+
+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)
+{
+ grn_obj *res;
+ GRN_API_ENTER;
+ res = grn_table_create_with_max_n_subrecs(ctx, name, name_size, path,
+ flags, key_type, value_type,
+ 0, 0);
+ GRN_API_RETURN(res);
+}
+
+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_obj *res = NULL;
+ GRN_API_ENTER;
+ if (group_key) {
+ grn_obj *key_type;
+ key_type = grn_ctx_at(ctx, grn_obj_get_range(ctx, group_key));
+ if (key_type) {
+ res = grn_table_create_with_max_n_subrecs(ctx, name, name_size, path,
+ GRN_TABLE_HASH_KEY|
+ GRN_OBJ_WITH_SUBREC|
+ GRN_OBJ_UNIT_USERDEF_DOCUMENT,
+ key_type, value_type,
+ max_n_subrecs, 0);
+ grn_obj_unlink(ctx, key_type);
+ }
+ } else {
+ res = grn_table_create_with_max_n_subrecs(ctx, name, name_size, path,
+ GRN_TABLE_HASH_KEY|
+ GRN_OBJ_KEY_VAR_SIZE|
+ GRN_OBJ_WITH_SUBREC|
+ GRN_OBJ_UNIT_USERDEF_DOCUMENT,
+ NULL, value_type,
+ max_n_subrecs, 0);
+ }
+ GRN_API_RETURN(res);
+}
+
+unsigned int
+grn_table_get_subrecs(grn_ctx *ctx, grn_obj *table, grn_id id,
+ grn_id *subrecbuf, int *scorebuf, int buf_size)
+{
+ unsigned int count = 0;
+ GRN_API_ENTER;
+ if (GRN_OBJ_TABLEP(table)) {
+ uint32_t value_size;
+ grn_rset_recinfo *ri;
+ uint32_t subrec_size = DB_OBJ(table)->subrec_size;
+ uint32_t max_n_subrecs = DB_OBJ(table)->max_n_subrecs;
+ if (subrec_size < sizeof(grn_id)) { goto exit; }
+ if (!max_n_subrecs) { goto exit; }
+ ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, table, id, &value_size);
+ if (ri) {
+ byte *psubrec = (byte *)ri->subrecs;
+ uint32_t n_subrecs = (uint32_t)GRN_RSET_N_SUBRECS(ri);
+ uint32_t limit = value_size / (GRN_RSET_SCORE_SIZE + subrec_size);
+ if ((int) limit > buf_size) {
+ limit = buf_size;
+ }
+ if (limit > n_subrecs) {
+ limit = n_subrecs;
+ }
+ if (limit > max_n_subrecs) {
+ limit = max_n_subrecs;
+ }
+ for (; count < limit; count++) {
+ if (scorebuf) {
+ scorebuf[count] = *((double *)psubrec);
+ }
+ psubrec += GRN_RSET_SCORE_SIZE;
+ if (subrecbuf) {
+ subrecbuf[count] = *((grn_id *)psubrec);
+ }
+ psubrec += subrec_size;
+ }
+ }
+ }
+exit :
+ GRN_API_RETURN(count);
+}
+
+grn_obj *
+grn_table_open(grn_ctx *ctx, const char *name, unsigned int name_size, const char *path)
+{
+ grn_obj *db;
+ if (!ctx->impl || !(db = ctx->impl->db)) {
+ ERR(GRN_INVALID_ARGUMENT, "db not initialized");
+ return NULL;
+ }
+ GRN_API_ENTER;
+ if (!GRN_DB_P(db)) {
+ ERR(GRN_INVALID_ARGUMENT, "invalid db assigned");
+ GRN_API_RETURN(NULL);
+ } else {
+ grn_obj *res = grn_ctx_get(ctx, name, name_size);
+ if (res) {
+ const char *path2 = grn_obj_path(ctx, res);
+ if (path && (!path2 || strcmp(path, path2))) {
+ ERR(GRN_INVALID_ARGUMENT, "path unmatch");
+ GRN_API_RETURN(NULL);
+ }
+ } else if (path) {
+ uint32_t type = grn_io_detect_type(ctx, path);
+ if (!type) { GRN_API_RETURN(NULL); }
+ switch (type) {
+ case GRN_TABLE_HASH_KEY :
+ res = (grn_obj *)grn_hash_open(ctx, path);
+ break;
+ case GRN_TABLE_PAT_KEY :
+ res = (grn_obj *)grn_pat_open(ctx, path);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ res = (grn_obj *)grn_dat_open(ctx, path);
+ break;
+ case GRN_TABLE_NO_KEY :
+ res = (grn_obj *)grn_array_open(ctx, path);
+ break;
+ }
+ if (res) {
+ grn_id id = grn_obj_register(ctx, db, name, name_size);
+ res->header.flags |= GRN_OBJ_CUSTOM_NAME;
+ res->header.domain = GRN_ID_NIL; /* unknown */
+ DB_OBJ(res)->range = GRN_ID_NIL; /* unknown */
+ grn_db_obj_init(ctx, db, id, DB_OBJ(res));
+ }
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "path is missing");
+ }
+ GRN_API_RETURN(res);
+ }
+}
+
+grn_id
+grn_table_lcp_search(grn_ctx *ctx, grn_obj *table, const void *key, unsigned int key_size)
+{
+ grn_id id = GRN_ID_NIL;
+ GRN_API_ENTER;
+ switch (table->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ {
+ grn_pat *pat = (grn_pat *)table;
+ WITH_NORMALIZE(pat, key, key_size, {
+ id = grn_pat_lcp_search(ctx, pat, key, key_size);
+ });
+ }
+ break;
+ case GRN_TABLE_DAT_KEY :
+ {
+ grn_dat *dat = (grn_dat *)table;
+ WITH_NORMALIZE(dat, key, key_size, {
+ id = grn_dat_lcp_search(ctx, dat, key, key_size);
+ });
+ }
+ break;
+ case GRN_TABLE_HASH_KEY :
+ {
+ grn_hash *hash = (grn_hash *)table;
+ WITH_NORMALIZE(hash, key, key_size, {
+ id = grn_hash_get(ctx, hash, key, key_size, NULL);
+ });
+ }
+ break;
+ }
+ GRN_API_RETURN(id);
+}
+
+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) {
+ ERR(GRN_INVALID_ARGUMENT, "default_set_value_hook failed");
+ } else {
+ grn_obj *flags = grn_ctx_pop(ctx);
+ grn_obj *newvalue = grn_ctx_pop(ctx);
+ grn_obj *oldvalue = grn_ctx_pop(ctx);
+ grn_obj *id = grn_ctx_pop(ctx);
+ grn_hook *h = pctx->currh;
+ 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 */ }
+ if (target) {
+ switch (target->header.type) {
+ case GRN_COLUMN_INDEX :
+ grn_ii_column_update(ctx, (grn_ii *)target,
+ GRN_UINT32_VALUE(id),
+ section, oldvalue, newvalue, NULL);
+ }
+ }
+ }
+ return NULL;
+}
+
+grn_id
+grn_table_add(grn_ctx *ctx, grn_obj *table, const void *key, unsigned int key_size, int *added)
+{
+ grn_id id = GRN_ID_NIL;
+ GRN_API_ENTER;
+ if (table) {
+ int added_ = 0;
+ switch (table->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ {
+ grn_pat *pat = (grn_pat *)table;
+ WITH_NORMALIZE(pat, key, key_size, {
+ if (pat->io && !(pat->io->flags & GRN_IO_TEMPORARY)) {
+ if (grn_io_lock(ctx, pat->io, grn_lock_timeout)) {
+ id = GRN_ID_NIL;
+ } else {
+ id = grn_pat_add(ctx, pat, key, key_size, NULL, &added_);
+ grn_io_unlock(pat->io);
+ }
+ } else {
+ id = grn_pat_add(ctx, pat, key, key_size, NULL, &added_);
+ }
+ });
+ if (added) { *added = added_; }
+ }
+ break;
+ case GRN_TABLE_DAT_KEY :
+ {
+ grn_dat *dat = (grn_dat *)table;
+ WITH_NORMALIZE(dat, key, key_size, {
+ if (dat->io && !(dat->io->flags & GRN_IO_TEMPORARY)) {
+ if (grn_io_lock(ctx, dat->io, grn_lock_timeout)) {
+ id = GRN_ID_NIL;
+ } else {
+ id = grn_dat_add(ctx, dat, key, key_size, NULL, &added_);
+ grn_io_unlock(dat->io);
+ }
+ } else {
+ id = grn_dat_add(ctx, dat, key, key_size, NULL, &added_);
+ }
+ });
+ if (added) { *added = added_; }
+ }
+ break;
+ case GRN_TABLE_HASH_KEY :
+ {
+ grn_hash *hash = (grn_hash *)table;
+ WITH_NORMALIZE(hash, key, key_size, {
+ if (hash->io && !(hash->io->flags & GRN_IO_TEMPORARY)) {
+ if (grn_io_lock(ctx, hash->io, grn_lock_timeout)) {
+ id = GRN_ID_NIL;
+ } else {
+ id = grn_hash_add(ctx, hash, key, key_size, NULL, &added_);
+ grn_io_unlock(hash->io);
+ }
+ } else {
+ id = grn_hash_add(ctx, hash, key, key_size, NULL, &added_);
+ }
+ });
+ if (added) { *added = added_; }
+ }
+ break;
+ case GRN_TABLE_NO_KEY :
+ {
+ grn_array *array = (grn_array *)table;
+ if (array->io && !(array->io->flags & GRN_IO_TEMPORARY)) {
+ if (grn_io_lock(ctx, array->io, grn_lock_timeout)) {
+ id = GRN_ID_NIL;
+ } else {
+ id = grn_array_add(ctx, array, NULL);
+ grn_io_unlock(array->io);
+ }
+ } else {
+ id = grn_array_add(ctx, array, NULL);
+ }
+ added_ = id ? 1 : 0;
+ if (added) { *added = added_; }
+ }
+ break;
+ }
+ if (added_) {
+ grn_hook *hooks = DB_OBJ(table)->hooks[GRN_HOOK_INSERT];
+ if (hooks) {
+ // todo : grn_proc_ctx_open()
+ grn_obj id_, flags_, oldvalue_, value_;
+ grn_proc_ctx pctx = {{0}, hooks->proc, NULL, hooks, hooks, PROC_INIT, 4, 4, {{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}}};
+ GRN_UINT32_INIT(&id_, 0);
+ GRN_UINT32_INIT(&flags_, 0);
+ GRN_TEXT_INIT(&oldvalue_, 0);
+ GRN_TEXT_INIT(&value_, GRN_OBJ_DO_SHALLOW_COPY);
+ GRN_TEXT_SET_REF(&value_, key, key_size);
+ GRN_UINT32_SET(ctx, &id_, id);
+ GRN_UINT32_SET(ctx, &flags_, GRN_OBJ_SET);
+ 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, &table, &pctx.user_data);
+ } else {
+ grn_obj_default_set_value_hook(ctx, 1, &table, &pctx.user_data);
+ }
+ if (ctx->rc) { break; }
+ hooks = hooks->next;
+ pctx.offset++;
+ }
+ }
+ }
+ }
+ GRN_API_RETURN(id);
+}
+
+grn_id
+grn_table_get_by_key(grn_ctx *ctx, grn_obj *table, grn_obj *key)
+{
+ grn_id id = GRN_ID_NIL;
+ if (table->header.domain == key->header.domain) {
+ id = grn_table_get(ctx, table, GRN_TEXT_VALUE(key), GRN_TEXT_LEN(key));
+ } else {
+ grn_rc rc;
+ grn_obj buf;
+ GRN_OBJ_INIT(&buf, GRN_BULK, 0, table->header.domain);
+ if ((rc = grn_obj_cast(ctx, key, &buf, GRN_TRUE))) {
+ 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));
+ }
+ GRN_OBJ_FIN(ctx, &buf);
+ }
+ return id;
+}
+
+grn_id
+grn_table_add_by_key(grn_ctx *ctx, grn_obj *table, grn_obj *key, int *added)
+{
+ grn_id id = GRN_ID_NIL;
+ if (table->header.domain == key->header.domain) {
+ id = grn_table_add(ctx, table, GRN_TEXT_VALUE(key), GRN_TEXT_LEN(key), added);
+ } else {
+ grn_rc rc;
+ grn_obj buf;
+ GRN_OBJ_INIT(&buf, GRN_BULK, 0, table->header.domain);
+ if ((rc = grn_obj_cast(ctx, key, &buf, GRN_TRUE))) {
+ 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);
+ }
+ GRN_OBJ_FIN(ctx, &buf);
+ }
+ return id;
+}
+
+grn_id
+grn_table_get(grn_ctx *ctx, grn_obj *table, const void *key, unsigned int key_size)
+{
+ grn_id id = GRN_ID_NIL;
+ GRN_API_ENTER;
+ if (table) {
+ if (table->header.type == GRN_DB) {
+ grn_db *db = (grn_db *)table;
+ table = db->keys;
+ }
+ switch (table->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ WITH_NORMALIZE((grn_pat *)table, key, key_size, {
+ id = grn_pat_get(ctx, (grn_pat *)table, key, key_size, NULL);
+ });
+ break;
+ case GRN_TABLE_DAT_KEY :
+ WITH_NORMALIZE((grn_dat *)table, key, key_size, {
+ id = grn_dat_get(ctx, (grn_dat *)table, key, key_size, NULL);
+ });
+ break;
+ case GRN_TABLE_HASH_KEY :
+ WITH_NORMALIZE((grn_hash *)table, key, key_size, {
+ id = grn_hash_get(ctx, (grn_hash *)table, key, key_size, NULL);
+ });
+ break;
+ }
+ }
+ GRN_API_RETURN(id);
+}
+
+grn_id
+grn_table_at(grn_ctx *ctx, grn_obj *table, grn_id id)
+{
+ GRN_API_ENTER;
+ if (table) {
+ switch (table->header.type) {
+ case GRN_DB :
+ {
+ grn_db *db = (grn_db *)table;
+ id = grn_table_at(ctx, db->keys, id);
+ }
+ break;
+ case GRN_TABLE_PAT_KEY :
+ id = grn_pat_at(ctx, (grn_pat *)table, id);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ id = grn_dat_at(ctx, (grn_dat *)table, id);
+ break;
+ case GRN_TABLE_HASH_KEY :
+ id = grn_hash_at(ctx, (grn_hash *)table, id);
+ break;
+ case GRN_TABLE_NO_KEY :
+ id = grn_array_at(ctx, (grn_array *)table, id);
+ break;
+ default :
+ id = GRN_ID_NIL;
+ }
+ }
+ GRN_API_RETURN(id);
+}
+
+inline static grn_id
+grn_table_add_v_inline(grn_ctx *ctx, grn_obj *table, const void *key, int key_size,
+ void **value, int *added)
+{
+ grn_id id = GRN_ID_NIL;
+ if (!key || !key_size) { return GRN_ID_NIL; }
+ if (table) {
+ switch (table->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ WITH_NORMALIZE((grn_pat *)table, key, key_size, {
+ id = grn_pat_add(ctx, (grn_pat *)table, key, key_size, value, added);
+ });
+ break;
+ case GRN_TABLE_DAT_KEY :
+ WITH_NORMALIZE((grn_dat *)table, key, key_size, {
+ id = grn_dat_add(ctx, (grn_dat *)table, key, key_size, value, added);
+ });
+ break;
+ case GRN_TABLE_HASH_KEY :
+ WITH_NORMALIZE((grn_hash *)table, key, key_size, {
+ id = grn_hash_add(ctx, (grn_hash *)table, key, key_size, value, added);
+ });
+ break;
+ case GRN_TABLE_NO_KEY :
+ id = grn_array_add(ctx, (grn_array *)table, value);
+ if (added) { *added = id ? 1 : 0; }
+ break;
+ }
+ }
+ return id;
+}
+
+grn_id
+grn_table_add_v(grn_ctx *ctx, grn_obj *table, const void *key, int key_size,
+ void **value, int *added) {
+ grn_id id;
+ GRN_API_ENTER;
+ id = grn_table_add_v_inline(ctx, table, key, key_size, value, added);
+ GRN_API_RETURN(id);
+}
+
+grn_id
+grn_table_get_v(grn_ctx *ctx, grn_obj *table, const void *key, int key_size,
+ void **value)
+{
+ grn_id id = GRN_ID_NIL;
+ GRN_API_ENTER;
+ if (table) {
+ switch (table->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ WITH_NORMALIZE((grn_pat *)table, key, key_size, {
+ id = grn_pat_get(ctx, (grn_pat *)table, key, key_size, value);
+ });
+ break;
+ case GRN_TABLE_DAT_KEY :
+ WITH_NORMALIZE((grn_dat *)table, key, key_size, {
+ id = grn_dat_get(ctx, (grn_dat *)table, key, key_size, value);
+ });
+ break;
+ case GRN_TABLE_HASH_KEY :
+ WITH_NORMALIZE((grn_hash *)table, key, key_size, {
+ id = grn_hash_get(ctx, (grn_hash *)table, key, key_size, value);
+ });
+ break;
+ }
+ }
+ GRN_API_RETURN(id);
+}
+
+int
+grn_table_get_key(grn_ctx *ctx, grn_obj *table, grn_id id, void *keybuf, int buf_size)
+{
+ 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);
+ break;
+ case GRN_TABLE_PAT_KEY :
+ r = grn_pat_get_key(ctx, (grn_pat *)table, id, keybuf, buf_size);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ r = grn_dat_get_key(ctx, (grn_dat *)table, id, keybuf, buf_size);
+ break;
+ case GRN_TABLE_NO_KEY :
+ {
+ grn_array *a = (grn_array *)table;
+ if (a->obj.header.domain) {
+ if ((unsigned int) buf_size >= a->value_size) {
+ r = grn_array_get_value(ctx, a, id, keybuf);
+ } else {
+ r = a->value_size;
+ }
+ }
+ }
+ break;
+ }
+ }
+ GRN_API_RETURN(r);
+}
+
+int
+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);
+ break;
+ case GRN_TABLE_PAT_KEY :
+ r = grn_pat_get_key2(ctx, (grn_pat *)table, id, bulk);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ r = grn_dat_get_key2(ctx, (grn_dat *)table, id, bulk);
+ break;
+ case GRN_TABLE_NO_KEY :
+ {
+ grn_array *a = (grn_array *)table;
+ if (a->obj.header.domain) {
+ if (!grn_bulk_space(ctx, bulk, a->value_size)) {
+ char *curr = GRN_BULK_CURR(bulk);
+ r = grn_array_get_value(ctx, a, id, curr - a->value_size);
+ }
+ }
+ }
+ break;
+ }
+ }
+ GRN_API_RETURN(r);
+}
+
+static grn_rc
+grn_obj_clear_value(grn_ctx *ctx, grn_obj *obj, grn_id id)
+{
+ grn_rc rc = GRN_SUCCESS;
+ if (GRN_DB_OBJP(obj)) {
+ grn_obj buf;
+ grn_id range = DB_OBJ(obj)->range;
+ GRN_OBJ_INIT(&buf, GRN_BULK, 0, range);
+ switch (obj->header.type) {
+ case GRN_COLUMN_VAR_SIZE :
+ case GRN_COLUMN_FIX_SIZE :
+ rc = grn_obj_set_value(ctx, obj, id, &buf, GRN_OBJ_SET);
+ break;
+ }
+ GRN_OBJ_FIN(ctx, &buf);
+ }
+ return rc;
+}
+
+static void
+call_delete_hook(grn_ctx *ctx, grn_obj *table, grn_id rid, const void *key, unsigned int key_size)
+{
+ if (rid) {
+ grn_hook *hooks = DB_OBJ(table)->hooks[GRN_HOOK_DELETE];
+ if (hooks) {
+ // todo : grn_proc_ctx_open()
+ grn_obj id_, flags_, oldvalue_, value_;
+ grn_proc_ctx pctx = {{0}, hooks->proc, NULL, hooks, hooks, PROC_INIT, 4, 4, {{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}}};
+ GRN_UINT32_INIT(&id_, 0);
+ GRN_UINT32_INIT(&flags_, 0);
+ GRN_TEXT_INIT(&oldvalue_, GRN_OBJ_DO_SHALLOW_COPY);
+ GRN_TEXT_INIT(&value_, 0);
+ GRN_TEXT_SET_REF(&oldvalue_, key, key_size);
+ GRN_UINT32_SET(ctx, &id_, rid);
+ GRN_UINT32_SET(ctx, &flags_, GRN_OBJ_SET);
+ 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, &table, &pctx.user_data);
+ } else {
+ grn_obj_default_set_value_hook(ctx, 1, &table, &pctx.user_data);
+ }
+ if (ctx->rc) { break; }
+ hooks = hooks->next;
+ pctx.offset++;
+ }
+ }
+ }
+}
+
+static void
+clear_column_values(grn_ctx *ctx, grn_obj *table, grn_id rid)
+{
+ if (rid) {
+ 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, table, "", 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_clear_value(ctx, col, rid); }
+ });
+ }
+ grn_hash_close(ctx, cols);
+ }
+ }
+}
+
+static void
+delete_reference_records_in_index(grn_ctx *ctx, grn_obj *table, grn_id id,
+ grn_obj *index)
+{
+ grn_ii *ii = (grn_ii *)index;
+ grn_ii_cursor *ii_cursor = NULL;
+ grn_posting *posting;
+ grn_obj source_ids;
+ unsigned int i, n_ids;
+ grn_obj sources;
+ grn_bool have_reference_source = GRN_FALSE;
+
+ GRN_UINT32_INIT(&source_ids, GRN_OBJ_VECTOR);
+ GRN_PTR_INIT(&sources, GRN_OBJ_VECTOR, 0);
+
+ grn_obj_get_info(ctx, index, GRN_INFO_SOURCE, &source_ids);
+ n_ids = GRN_BULK_VSIZE(&source_ids) / sizeof(grn_id);
+ if (n_ids == 0) {
+ goto exit;
+ }
+
+ for (i = 0; i < n_ids; i++) {
+ grn_id source_id;
+ grn_obj *source;
+
+ source_id = GRN_UINT32_VALUE_AT(&source_ids, i);
+ source = grn_ctx_at(ctx, source_id);
+ if (grn_obj_get_range(ctx, source) == index->header.domain) {
+ GRN_PTR_PUT(ctx, &sources, source);
+ have_reference_source = GRN_TRUE;
+ } else {
+ grn_obj_unlink(ctx, source);
+ GRN_PTR_PUT(ctx, &sources, NULL);
+ }
+ }
+
+ if (!have_reference_source) {
+ goto exit;
+ }
+
+ ii_cursor = grn_ii_cursor_open(ctx, ii, id, GRN_ID_NIL, GRN_ID_MAX,
+ ii->n_elements, 0);
+ if (!ii_cursor) {
+ goto exit;
+ }
+
+ while ((posting = grn_ii_cursor_next(ctx, ii_cursor))) {
+ grn_obj *source = GRN_PTR_VALUE_AT(&sources, posting->sid - 1);
+ if (!source) {
+ continue;
+ }
+ switch (source->header.type) {
+ case GRN_COLUMN_VAR_SIZE :
+ switch (source->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) {
+ case GRN_OBJ_COLUMN_SCALAR :
+ grn_obj_clear_value(ctx, source, posting->rid);
+ break;
+ case GRN_OBJ_COLUMN_VECTOR :
+ {
+ grn_obj value;
+ grn_obj new_value;
+ GRN_TEXT_INIT(&value, 0);
+ grn_obj_get_value(ctx, source, posting->rid, &value);
+ if (value.header.type == GRN_UVECTOR) {
+ int i, n_ids;
+ GRN_RECORD_INIT(&new_value, GRN_OBJ_VECTOR, value.header.domain);
+ n_ids = GRN_BULK_VSIZE(&value) / sizeof(grn_id);
+ for (i = 0; i < n_ids; i++) {
+ grn_id reference_id = GRN_RECORD_VALUE_AT(&value, i);
+ if (reference_id == id) {
+ continue;
+ }
+ GRN_RECORD_PUT(ctx, &new_value, reference_id);
+ }
+ } else {
+ unsigned int i, n_elements;
+ GRN_TEXT_INIT(&new_value, GRN_OBJ_VECTOR);
+ n_elements = grn_vector_size(ctx, &value);
+ for (i = 0; i < n_elements; i++) {
+ const char *content;
+ unsigned int content_length;
+ unsigned int weight;
+ grn_id domain;
+ content_length =
+ grn_vector_get_element(ctx, &value, i,
+ &content, &weight, &domain);
+ if (grn_table_get(ctx, table, content, content_length) == id) {
+ continue;
+ }
+ grn_vector_add_element(ctx, &new_value, content, content_length,
+ weight, domain);
+ }
+ }
+ grn_obj_set_value(ctx, source, posting->rid, &new_value,
+ GRN_OBJ_SET);
+ GRN_OBJ_FIN(ctx, &new_value);
+ GRN_OBJ_FIN(ctx, &value);
+ }
+ break;
+ }
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ grn_obj_clear_value(ctx, source, posting->rid);
+ break;
+ }
+ }
+
+exit:
+ if (ii_cursor) {
+ grn_ii_cursor_close(ctx, ii_cursor);
+ }
+ grn_obj_unlink(ctx, &source_ids);
+ {
+ int i, n_sources;
+ n_sources = GRN_BULK_VSIZE(&sources) / sizeof(grn_obj *);
+ for (i = 0; i < n_sources; i++) {
+ grn_obj *source = GRN_PTR_VALUE_AT(&sources, i);
+ grn_obj_unlink(ctx, source);
+ }
+ grn_obj_unlink(ctx, &sources);
+ }
+}
+
+static grn_rc
+delete_reference_records(grn_ctx *ctx, grn_obj *table, grn_id id)
+{
+ grn_hash *cols;
+ grn_id *key;
+
+ cols = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY);
+ if (!cols) {
+ return ctx->rc;
+ }
+
+ if (!grn_table_columns(ctx, table, "", 0, (grn_obj *)cols)) {
+ grn_hash_close(ctx, cols);
+ return ctx->rc;
+ }
+
+ GRN_HASH_EACH(ctx, cols, tid, &key, NULL, NULL, {
+ grn_obj *col = grn_ctx_at(ctx, *key);
+ if (!col) {
+ continue;
+ }
+ if (col->header.type != GRN_COLUMN_INDEX) {
+ continue;
+ }
+ delete_reference_records_in_index(ctx, table, id, col);
+ if (ctx->rc != GRN_SUCCESS) {
+ break;
+ }
+ });
+
+ grn_hash_close(ctx, cols);
+
+ return ctx->rc;
+}
+
+static grn_rc
+grn_table_delete_prepare(grn_ctx *ctx, grn_obj *table,
+ grn_id id, const void *key, unsigned int key_size)
+{
+ grn_rc rc;
+
+ rc = delete_reference_records(ctx, table, id);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ call_delete_hook(ctx, table, id, key, key_size);
+ clear_column_values(ctx, table, id);
+
+ return rc;
+}
+
+grn_rc
+grn_table_delete(grn_ctx *ctx, grn_obj *table, const void *key, unsigned int key_size)
+{
+ grn_id rid = GRN_ID_NIL;
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ GRN_API_ENTER;
+ if (table) {
+ if (key && key_size) { rid = grn_table_get(ctx, table, key, key_size); }
+ if (rid) {
+ rc = grn_table_delete_prepare(ctx, table, rid, key, key_size);
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+ switch (table->header.type) {
+ case GRN_DB :
+ /* todo : delete tables and columns from db */
+ break;
+ case GRN_TABLE_PAT_KEY :
+ WITH_NORMALIZE((grn_pat *)table, key, key_size, {
+ grn_pat *pat = (grn_pat *)table;
+ if (pat->io && !(pat->io->flags & GRN_IO_TEMPORARY)) {
+ if (!(rc = grn_io_lock(ctx, pat->io, grn_lock_timeout))) {
+ rc = grn_pat_delete(ctx, pat, key, key_size, NULL);
+ grn_io_unlock(pat->io);
+ }
+ } else {
+ rc = grn_pat_delete(ctx, pat, key, key_size, NULL);
+ }
+ });
+ break;
+ case GRN_TABLE_DAT_KEY :
+ WITH_NORMALIZE((grn_dat *)table, key, key_size, {
+ grn_dat *dat = (grn_dat *)table;
+ if (dat->io && !(dat->io->flags & GRN_IO_TEMPORARY)) {
+ if (!(rc = grn_io_lock(ctx, dat->io, grn_lock_timeout))) {
+ rc = grn_dat_delete(ctx, dat, key, key_size, NULL);
+ grn_io_unlock(dat->io);
+ }
+ } else {
+ rc = grn_dat_delete(ctx, dat, key, key_size, NULL);
+ }
+ });
+ break;
+ case GRN_TABLE_HASH_KEY :
+ WITH_NORMALIZE((grn_hash *)table, key, key_size, {
+ grn_hash *hash = (grn_hash *)table;
+ if (hash->io && !(hash->io->flags & GRN_IO_TEMPORARY)) {
+ if (!(rc = grn_io_lock(ctx, hash->io, grn_lock_timeout))) {
+ rc = grn_hash_delete(ctx, hash, key, key_size, NULL);
+ grn_io_unlock(hash->io);
+ }
+ } else {
+ rc = grn_hash_delete(ctx, hash, key, key_size, NULL);
+ }
+ });
+ break;
+ }
+ if (rc == GRN_SUCCESS) {
+ grn_obj_touch(ctx, table, NULL);
+ }
+ }
+ }
+exit :
+ GRN_API_RETURN(rc);
+}
+
+grn_rc
+_grn_table_delete_by_id(grn_ctx *ctx, grn_obj *table, grn_id id,
+ grn_table_delete_optarg *optarg)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ if (table) {
+ if (id) {
+ const void *key = NULL;
+ unsigned int key_size = 0;
+
+ if (table->header.type != GRN_TABLE_NO_KEY) {
+ key = _grn_table_key(ctx, table, id, &key_size);
+ }
+ rc = grn_table_delete_prepare(ctx, table, id, key, key_size);
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+ // todo : support optarg
+ switch (table->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ rc = grn_pat_delete_by_id(ctx, (grn_pat *)table, id, optarg);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ rc = grn_dat_delete_by_id(ctx, (grn_dat *)table, id, optarg);
+ break;
+ case GRN_TABLE_HASH_KEY :
+ rc = grn_hash_delete_by_id(ctx, (grn_hash *)table, id, optarg);
+ break;
+ case GRN_TABLE_NO_KEY :
+ rc = grn_array_delete_by_id(ctx, (grn_array *)table, id, optarg);
+ break;
+ }
+ }
+ }
+exit :
+ return rc;
+}
+
+grn_rc
+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_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);
+ }
+ } else {
+ rc = _grn_table_delete_by_id(ctx, table, id, NULL);
+ }
+ if (rc == GRN_SUCCESS) {
+ grn_obj_touch(ctx, table, NULL);
+ }
+ GRN_API_RETURN(rc);
+}
+
+grn_rc grn_ja_truncate(grn_ctx *ctx, grn_ja *ja);
+grn_rc grn_ra_truncate(grn_ctx *ctx, grn_ra *ra);
+
+grn_rc
+grn_column_truncate(grn_ctx *ctx, grn_obj *column)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ GRN_API_ENTER;
+ if (column) {
+ grn_hook *hooks;
+ switch (column->header.type) {
+ case GRN_COLUMN_INDEX :
+ rc = grn_ii_truncate(ctx, (grn_ii *)column);
+ break;
+ case GRN_COLUMN_VAR_SIZE :
+ for (hooks = DB_OBJ(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; }
+ if ((rc = grn_ii_truncate(ctx, (grn_ii *)target))) { goto exit; }
+ }
+ rc = grn_ja_truncate(ctx, (grn_ja *)column);
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ for (hooks = DB_OBJ(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; }
+ if ((rc = grn_ii_truncate(ctx, (grn_ii *)target))) { goto exit; }
+ }
+ rc = grn_ra_truncate(ctx, (grn_ra *)column);
+ break;
+ }
+ if (rc == GRN_SUCCESS) {
+ grn_obj_touch(ctx, column, NULL);
+ }
+ }
+exit :
+ GRN_API_RETURN(rc);
+}
+
+grn_rc
+grn_table_truncate(grn_ctx *ctx, grn_obj *table)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ GRN_API_ENTER;
+ if (table) {
+ grn_hook *hooks;
+ grn_hash *cols;
+ grn_obj *tokenizer;
+ grn_obj *normalizer;
+ grn_obj token_filters;
+ if ((cols = 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 *)cols)) {
+ grn_id *key;
+ GRN_HASH_EACH(ctx, cols, id, &key, NULL, NULL, {
+ grn_obj *col = grn_ctx_at(ctx, *key);
+ if (col) { grn_column_truncate(ctx, col); }
+ });
+ }
+ grn_hash_close(ctx, cols);
+ }
+ if (table->header.type != GRN_TABLE_NO_KEY) {
+ grn_table_get_info(ctx, table, NULL, NULL, &tokenizer, &normalizer, NULL);
+ GRN_PTR_INIT(&token_filters, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ grn_obj_get_info(ctx, table, GRN_INFO_TOKEN_FILTERS, &token_filters);
+ }
+ switch (table->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ for (hooks = DB_OBJ(table)->hooks[GRN_HOOK_INSERT]; 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 ((rc = grn_ii_truncate(ctx, (grn_ii *)target))) { goto exit; }
+ }
+ rc = grn_pat_truncate(ctx, (grn_pat *)table);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ for (hooks = DB_OBJ(table)->hooks[GRN_HOOK_INSERT]; 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 ((rc = grn_ii_truncate(ctx, (grn_ii *)target))) { goto exit; }
+ }
+ rc = grn_dat_truncate(ctx, (grn_dat *)table);
+ break;
+ case GRN_TABLE_HASH_KEY :
+ for (hooks = DB_OBJ(table)->hooks[GRN_HOOK_INSERT]; 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 ((rc = grn_ii_truncate(ctx, (grn_ii *)target))) { goto exit; }
+ }
+ rc = grn_hash_truncate(ctx, (grn_hash *)table);
+ break;
+ case GRN_TABLE_NO_KEY :
+ rc = grn_array_truncate(ctx, (grn_array *)table);
+ break;
+ }
+ if (table->header.type != GRN_TABLE_NO_KEY) {
+ grn_obj_set_info(ctx, table, GRN_INFO_DEFAULT_TOKENIZER, tokenizer);
+ grn_obj_set_info(ctx, table, GRN_INFO_NORMALIZER, normalizer);
+ grn_obj_set_info(ctx, table, GRN_INFO_TOKEN_FILTERS, &token_filters);
+ GRN_OBJ_FIN(ctx, &token_filters);
+ }
+ if (rc == GRN_SUCCESS) {
+ grn_obj_touch(ctx, table, NULL);
+ }
+ }
+exit :
+ GRN_API_RETURN(rc);
+}
+
+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)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ GRN_API_ENTER;
+ if (table) {
+ switch (table->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ 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; }
+ if (token_filters) { *token_filters = &(((grn_pat *)table)->token_filters); }
+ rc = GRN_SUCCESS;
+ break;
+ case GRN_TABLE_DAT_KEY :
+ 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; }
+ if (token_filters) { *token_filters = &(((grn_dat *)table)->token_filters); }
+ rc = GRN_SUCCESS;
+ break;
+ case GRN_TABLE_HASH_KEY :
+ 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; }
+ if (token_filters) { *token_filters = &(((grn_hash *)table)->token_filters); }
+ rc = GRN_SUCCESS;
+ break;
+ case GRN_TABLE_NO_KEY :
+ if (flags) { *flags = grn_array_get_flags(ctx, ((grn_array *)table)); }
+ if (encoding) { *encoding = GRN_ENC_NONE; }
+ if (tokenizer) { *tokenizer = NULL; }
+ if (normalizer) { *normalizer = NULL; }
+ if (token_filters) { *token_filters = NULL; }
+ rc = GRN_SUCCESS;
+ break;
+ }
+ }
+ GRN_API_RETURN(rc);
+}
+
+unsigned int
+grn_table_size(grn_ctx *ctx, grn_obj *table)
+{
+ unsigned int n = 0;
+ GRN_API_ENTER;
+ if (table) {
+ switch (table->header.type) {
+ case GRN_DB :
+ n = grn_table_size(ctx, ((grn_db *)table)->keys);
+ break;
+ case GRN_TABLE_PAT_KEY :
+ n = grn_pat_size(ctx, (grn_pat *)table);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ n = grn_dat_size(ctx, (grn_dat *)table);
+ break;
+ case GRN_TABLE_HASH_KEY :
+ n = grn_hash_size(ctx, (grn_hash *)table);
+ break;
+ case GRN_TABLE_NO_KEY :
+ n = grn_array_size(ctx, (grn_array *)table);
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "not supported");
+ break;
+ }
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "invalid table assigned");
+ }
+ GRN_API_RETURN(n);
+}
+
+inline static void
+subrecs_push(byte *subrecs, int size, int n_subrecs, double score, void *body, int dir)
+{
+ byte *v;
+ double *c2;
+ int n = n_subrecs - 1, n2;
+ while (n) {
+ n2 = (n - 1) >> 1;
+ c2 = GRN_RSET_SUBRECS_NTH(subrecs,size,n2);
+ if (GRN_RSET_SUBRECS_CMP(score, *c2, dir) >= 0) { break; }
+ GRN_RSET_SUBRECS_COPY(subrecs,size,n,c2);
+ n = n2;
+ }
+ v = subrecs + n * (GRN_RSET_SCORE_SIZE + size);
+ *((double *)v) = score;
+ grn_memcpy(v + GRN_RSET_SCORE_SIZE, body, size);
+}
+
+inline static void
+subrecs_replace_min(byte *subrecs, int size, int n_subrecs, double score, void *body, int dir)
+{
+ byte *v;
+ int n = 0, n1, n2;
+ double *c1, *c2;
+ for (;;) {
+ n1 = n * 2 + 1;
+ n2 = n1 + 1;
+ c1 = n1 < n_subrecs ? GRN_RSET_SUBRECS_NTH(subrecs,size,n1) : NULL;
+ c2 = n2 < n_subrecs ? GRN_RSET_SUBRECS_NTH(subrecs,size,n2) : NULL;
+ if (c1 && GRN_RSET_SUBRECS_CMP(score, *c1, dir) > 0) {
+ if (c2 &&
+ GRN_RSET_SUBRECS_CMP(score, *c2, dir) > 0 &&
+ GRN_RSET_SUBRECS_CMP(*c1, *c2, dir) > 0) {
+ GRN_RSET_SUBRECS_COPY(subrecs,size,n,c2);
+ n = n2;
+ } else {
+ GRN_RSET_SUBRECS_COPY(subrecs,size,n,c1);
+ n = n1;
+ }
+ } else {
+ if (c2 && GRN_RSET_SUBRECS_CMP(score, *c2, dir) > 0) {
+ GRN_RSET_SUBRECS_COPY(subrecs,size,n,c2);
+ n = n2;
+ } else {
+ break;
+ }
+ }
+ }
+ v = subrecs + n * (GRN_RSET_SCORE_SIZE + size);
+ grn_memcpy(v, &score, GRN_RSET_SCORE_SIZE);
+ grn_memcpy(v + GRN_RSET_SCORE_SIZE, body, size);
+}
+
+inline static void
+grn_table_add_subrec_inline(grn_obj *table, grn_rset_recinfo *ri, double score,
+ grn_rset_posinfo *pi, int dir)
+{
+ if (DB_OBJ(table)->header.flags & GRN_OBJ_WITH_SUBREC) {
+ int limit = DB_OBJ(table)->max_n_subrecs;
+ ri->score += score;
+ ri->n_subrecs += 1;
+ if (limit) {
+ int subrec_size = DB_OBJ(table)->subrec_size;
+ int n_subrecs = GRN_RSET_N_SUBRECS(ri);
+ if (pi) {
+ byte *body = (byte *)pi + DB_OBJ(table)->subrec_offset;
+ if (limit < n_subrecs) {
+ if (GRN_RSET_SUBRECS_CMP(score, *((double *)(ri->subrecs)), dir) > 0) {
+ subrecs_replace_min((byte *)ri->subrecs, subrec_size, limit, score, body, dir);
+ }
+ } else {
+ subrecs_push((byte *)ri->subrecs, subrec_size, n_subrecs, score, body, dir);
+ }
+ }
+ }
+ }
+}
+
+void
+grn_table_add_subrec(grn_obj *table, grn_rset_recinfo *ri, double score,
+ grn_rset_posinfo *pi, int dir)
+{
+ grn_table_add_subrec_inline(table, ri, score, pi, dir);
+}
+
+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_rc rc;
+ grn_table_cursor *tc = NULL;
+ unsigned int table_size;
+ if (!table) { return tc; }
+ GRN_API_ENTER;
+ table_size = grn_table_size(ctx, table);
+ if (flags & GRN_CURSOR_PREFIX) {
+ if (offset < 0) {
+ ERR(GRN_TOO_SMALL_OFFSET,
+ "can't use negative offset with GRN_CURSOR_PREFIX: %d", offset);
+ } else if (offset != 0 && offset >= (int) table_size) {
+ ERR(GRN_TOO_LARGE_OFFSET,
+ "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 smaller limit than -1 with GRN_CURSOR_PREFIX: %d",
+ limit);
+ } else if (limit == -1) {
+ limit = table_size;
+ }
+ }
+ } else {
+ rc = grn_normalize_offset_and_limit(ctx, table_size, &offset, &limit);
+ if (rc) {
+ ERR(rc, "grn_normalize_offset_and_limit failed");
+ }
+ }
+ if (!ctx->rc) {
+ if (table->header.type == GRN_DB) { table = ((grn_db *)table)->keys; }
+ switch (table->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ {
+ grn_pat *pat = (grn_pat *)table;
+ WITH_NORMALIZE(pat, min, min_size, {
+ WITH_NORMALIZE(pat, max, max_size, {
+ grn_pat_cursor *pat_cursor;
+ pat_cursor = grn_pat_cursor_open(ctx, pat,
+ min, min_size,
+ max, max_size,
+ offset, limit, flags);
+ tc = (grn_table_cursor *)pat_cursor;
+ });
+ });
+ }
+ break;
+ case GRN_TABLE_DAT_KEY :
+ {
+ grn_dat *dat = (grn_dat *)table;
+ WITH_NORMALIZE(dat, min, min_size, {
+ WITH_NORMALIZE(dat, max, max_size, {
+ grn_dat_cursor *dat_cursor;
+ dat_cursor = grn_dat_cursor_open(ctx, dat,
+ min, min_size,
+ max, max_size,
+ offset, limit, flags);
+ tc = (grn_table_cursor *)dat_cursor;
+ });
+ });
+ }
+ break;
+ case GRN_TABLE_HASH_KEY :
+ {
+ grn_hash *hash = (grn_hash *)table;
+ WITH_NORMALIZE(hash, min, min_size, {
+ WITH_NORMALIZE(hash, max, max_size, {
+ grn_hash_cursor *hash_cursor;
+ hash_cursor = grn_hash_cursor_open(ctx, hash,
+ min, min_size,
+ max, max_size,
+ offset, limit, flags);
+ tc = (grn_table_cursor *)hash_cursor;
+ });
+ });
+ }
+ break;
+ case GRN_TABLE_NO_KEY :
+ tc = (grn_table_cursor *)grn_array_cursor_open(ctx, (grn_array *)table,
+ GRN_ID_NIL, GRN_ID_NIL,
+ offset, limit, flags);
+ break;
+ }
+ }
+ if (tc) {
+ grn_id id = grn_obj_register(ctx, ctx->impl->db, NULL, 0);
+ DB_OBJ(tc)->header.domain = GRN_ID_NIL;
+ DB_OBJ(tc)->range = GRN_ID_NIL;
+ grn_db_obj_init(ctx, ctx->impl->db, id, DB_OBJ(tc));
+ }
+ GRN_API_RETURN(tc);
+}
+
+grn_table_cursor *
+grn_table_cursor_open_by_id(grn_ctx *ctx, grn_obj *table,
+ grn_id min, grn_id max, int flags)
+{
+ grn_table_cursor *tc = NULL;
+ GRN_API_ENTER;
+ if (table) {
+ switch (table->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ tc = (grn_table_cursor *)grn_pat_cursor_open(ctx, (grn_pat *)table,
+ NULL, 0, NULL, 0, 0, -1, flags);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ tc = (grn_table_cursor *)grn_dat_cursor_open(ctx, (grn_dat *)table,
+ NULL, 0, NULL, 0, 0, -1, flags);
+ break;
+ case GRN_TABLE_HASH_KEY :
+ tc = (grn_table_cursor *)grn_hash_cursor_open(ctx, (grn_hash *)table,
+ NULL, 0, NULL, 0, 0, -1, flags);
+ break;
+ case GRN_TABLE_NO_KEY :
+ tc = (grn_table_cursor *)grn_array_cursor_open(ctx, (grn_array *)table,
+ min, max, 0, -1, flags);
+ break;
+ }
+ }
+ GRN_API_RETURN(tc);
+}
+
+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) {
+ rc = GRN_INVALID_ARGUMENT;
+ ERR(rc, "%s invalid cursor", tag);
+ } else {
+ {
+ if (DB_OBJ(tc)->finalizer) {
+ DB_OBJ(tc)->finalizer(ctx, 1, (grn_obj **)&tc, &DB_OBJ(tc)->user_data);
+ }
+ if (DB_OBJ(tc)->source) {
+ GRN_FREE(DB_OBJ(tc)->source);
+ }
+ /*
+ grn_hook_entry entry;
+ for (entry = 0; entry < N_HOOK_ENTRIES; entry++) {
+ grn_hook_free(ctx, DB_OBJ(tc)->hooks[entry]);
+ }
+ */
+ grn_obj_delete_by_id(ctx, DB_OBJ(tc)->db, DB_OBJ(tc)->id, GRN_FALSE);
+ }
+ switch (tc->header.type) {
+ case GRN_CURSOR_TABLE_PAT_KEY :
+ grn_pat_cursor_close(ctx, (grn_pat_cursor *)tc);
+ break;
+ case GRN_CURSOR_TABLE_DAT_KEY :
+ grn_dat_cursor_close(ctx, (grn_dat_cursor *)tc);
+ break;
+ case GRN_CURSOR_TABLE_HASH_KEY :
+ grn_hash_cursor_close(ctx, (grn_hash_cursor *)tc);
+ break;
+ case GRN_CURSOR_TABLE_NO_KEY :
+ grn_array_cursor_close(ctx, (grn_array_cursor *)tc);
+ break;
+ default :
+ rc = GRN_INVALID_ARGUMENT;
+ ERR(rc, "%s invalid type %d", tag, tc->header.type);
+ break;
+ }
+ }
+ GRN_API_RETURN(rc);
+}
+
+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, "%s invalid cursor", tag);
+ } else {
+ switch (tc->header.type) {
+ case GRN_CURSOR_TABLE_PAT_KEY :
+ id = grn_pat_cursor_next(ctx, (grn_pat_cursor *)tc);
+ break;
+ case GRN_CURSOR_TABLE_DAT_KEY :
+ id = grn_dat_cursor_next(ctx, (grn_dat_cursor *)tc);
+ break;
+ case GRN_CURSOR_TABLE_HASH_KEY :
+ id = grn_hash_cursor_next(ctx, (grn_hash_cursor *)tc);
+ break;
+ case GRN_CURSOR_TABLE_NO_KEY :
+ id = grn_array_cursor_next(ctx, (grn_array_cursor *)tc);
+ break;
+ case GRN_CURSOR_COLUMN_INDEX :
+ {
+ grn_posting *ip = grn_index_cursor_next(ctx, (grn_obj *)tc, NULL);
+ if (ip) { id = ip->rid; }
+ }
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "%s invalid type %d", tag, tc->header.type);
+ break;
+ }
+ }
+ return id;
+}
+
+grn_id
+grn_table_cursor_next(grn_ctx *ctx, grn_table_cursor *tc)
+{
+ grn_id id;
+ GRN_API_ENTER;
+ id = grn_table_cursor_next_inline(ctx, tc);
+ GRN_API_RETURN(id);
+}
+
+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, "%s invalid cursor", tag);
+ } else {
+ switch (tc->header.type) {
+ case GRN_CURSOR_TABLE_PAT_KEY :
+ len = grn_pat_cursor_get_key(ctx, (grn_pat_cursor *)tc, key);
+ break;
+ case GRN_CURSOR_TABLE_DAT_KEY :
+ len = grn_dat_cursor_get_key(ctx, (grn_dat_cursor *)tc, (const void **)key);
+ break;
+ case GRN_CURSOR_TABLE_HASH_KEY :
+ len = grn_hash_cursor_get_key(ctx, (grn_hash_cursor *)tc, key);
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "%s invalid type %d", tag, tc->header.type);
+ break;
+ }
+ }
+ GRN_API_RETURN(len);
+}
+
+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, "%s invalid cursor", tag);
+ } else {
+ switch (tc->header.type) {
+ case GRN_CURSOR_TABLE_PAT_KEY :
+ len = grn_pat_cursor_get_value(ctx, (grn_pat_cursor *)tc, value);
+ break;
+ case GRN_CURSOR_TABLE_DAT_KEY :
+ *value = NULL;
+ len = 0;
+ break;
+ case GRN_CURSOR_TABLE_HASH_KEY :
+ len = grn_hash_cursor_get_value(ctx, (grn_hash_cursor *)tc, value);
+ break;
+ case GRN_CURSOR_TABLE_NO_KEY :
+ len = grn_array_cursor_get_value(ctx, (grn_array_cursor *)tc, value);
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "%s invalid type %d", tag, tc->header.type);
+ break;
+ }
+ }
+ return len;
+}
+
+int
+grn_table_cursor_get_value(grn_ctx *ctx, grn_table_cursor *tc, void **value)
+{
+ int len;
+ GRN_API_ENTER;
+ len = grn_table_cursor_get_value_inline(ctx, tc, value);
+ GRN_API_RETURN(len);
+}
+
+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, "%s invalid cursor", tag);
+ } else {
+ switch (tc->header.type) {
+ case GRN_CURSOR_TABLE_PAT_KEY :
+ rc = grn_pat_cursor_set_value(ctx, (grn_pat_cursor *)tc, value, flags);
+ break;
+ case GRN_CURSOR_TABLE_DAT_KEY :
+ rc = GRN_OPERATION_NOT_SUPPORTED;
+ break;
+ case GRN_CURSOR_TABLE_HASH_KEY :
+ rc = grn_hash_cursor_set_value(ctx, (grn_hash_cursor *)tc, value, flags);
+ break;
+ case GRN_CURSOR_TABLE_NO_KEY :
+ rc = grn_array_cursor_set_value(ctx, (grn_array_cursor *)tc, value, flags);
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "%s invalid type %d", tag, tc->header.type);
+ break;
+ }
+ }
+ GRN_API_RETURN(rc);
+}
+
+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, "%s invalid cursor", tag);
+ } else {
+ grn_id id;
+ grn_obj *table;
+ const void *key = NULL;
+ unsigned int key_size = 0;
+ switch (tc->header.type) {
+ case GRN_CURSOR_TABLE_PAT_KEY :
+ {
+ grn_pat_cursor *pc = (grn_pat_cursor *)tc;
+ id = pc->curr_rec;
+ table = (grn_obj *)(pc->pat);
+ key = _grn_pat_key(ctx, pc->pat, id, &key_size);
+ rc = grn_table_delete_prepare(ctx, table, id, key, key_size);
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+ rc = grn_pat_cursor_delete(ctx, pc, NULL);
+ }
+ break;
+ case GRN_CURSOR_TABLE_DAT_KEY :
+ rc = GRN_OPERATION_NOT_SUPPORTED;
+ break;
+ case GRN_CURSOR_TABLE_HASH_KEY :
+ {
+ grn_hash_cursor *hc = (grn_hash_cursor *)tc;
+ id = hc->curr_rec;
+ table = (grn_obj *)(hc->hash);
+ key = _grn_hash_key(ctx, hc->hash, id, &key_size);
+ rc = grn_table_delete_prepare(ctx, table, id, key, key_size);
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+ rc = grn_hash_cursor_delete(ctx, hc, NULL);
+ }
+ break;
+ case GRN_CURSOR_TABLE_NO_KEY :
+ {
+ grn_array_cursor *ac = (grn_array_cursor *)tc;
+ id = ac->curr_rec;
+ table = (grn_obj *)(ac->array);
+ rc = grn_table_delete_prepare(ctx, table, id, key, key_size);
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+ rc = grn_array_cursor_delete(ctx, ac, NULL);
+ }
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "%s invalid type %d", tag, tc->header.type);
+ break;
+ }
+ }
+exit :
+ GRN_API_RETURN(rc);
+}
+
+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, "%s invalid cursor", tag);
+ } else {
+ switch (tc->header.type) {
+ case GRN_CURSOR_TABLE_PAT_KEY :
+ obj = (grn_obj *)(((grn_pat_cursor *)tc)->pat);
+ break;
+ case GRN_CURSOR_TABLE_DAT_KEY :
+ obj = (grn_obj *)(((grn_dat_cursor *)tc)->dat);
+ break;
+ case GRN_CURSOR_TABLE_HASH_KEY :
+ obj = (grn_obj *)(((grn_hash_cursor *)tc)->hash);
+ break;
+ case GRN_CURSOR_TABLE_NO_KEY :
+ obj = (grn_obj *)(((grn_array_cursor *)tc)->array);
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "%s invalid type %d", tag, tc->header.type);
+ break;
+ }
+ }
+ GRN_API_RETURN(obj);
+}
+
+typedef struct {
+ grn_db_obj obj;
+ grn_obj *index;
+ grn_table_cursor *tc;
+ grn_ii_cursor *iic;
+ grn_id tid;
+ grn_id rid_min;
+ grn_id rid_max;
+ int flags;
+} grn_index_cursor;
+
+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_index_cursor *ic = NULL;
+ GRN_API_ENTER;
+ if (tc && (ic = GRN_MALLOCN(grn_index_cursor, 1))) {
+ ic->tc = tc;
+ ic->index = index;
+ ic->iic = NULL;
+ ic->tid = GRN_ID_NIL;
+ ic->rid_min = rid_min;
+ ic->rid_max = rid_max;
+ ic->flags = flags;
+ GRN_DB_OBJ_SET_TYPE(ic, GRN_CURSOR_COLUMN_INDEX);
+ {
+ grn_id id = grn_obj_register(ctx, ctx->impl->db, NULL, 0);
+ DB_OBJ(ic)->header.domain = GRN_ID_NIL;
+ DB_OBJ(ic)->range = GRN_ID_NIL;
+ grn_db_obj_init(ctx, ctx->impl->db, id, DB_OBJ(ic));
+ }
+ }
+ GRN_API_RETURN((grn_obj *)ic);
+}
+
+grn_posting *
+grn_index_cursor_next(grn_ctx *ctx, grn_obj *c, grn_id *tid)
+{
+ grn_posting *ip = NULL;
+ grn_index_cursor *ic = (grn_index_cursor *)c;
+ GRN_API_ENTER;
+ if (ic->iic) {
+ if (ic->flags & GRN_OBJ_WITH_POSITION) {
+ ip = grn_ii_cursor_next_pos(ctx, ic->iic);
+ while (!ip && grn_ii_cursor_next(ctx, ic->iic)) {
+ ip = grn_ii_cursor_next_pos(ctx, ic->iic);
+ break;
+ }
+ } else {
+ ip = grn_ii_cursor_next(ctx, ic->iic);
+ }
+ }
+ if (!ip) {
+ while ((ic->tid = grn_table_cursor_next_inline(ctx, ic->tc))) {
+ grn_ii *ii = (grn_ii *)ic->index;
+ if (ic->iic) { grn_ii_cursor_close(ctx, ic->iic); }
+ if ((ic->iic = grn_ii_cursor_open(ctx, ii, ic->tid,
+ ic->rid_min, ic->rid_max,
+ ii->n_elements, ic->flags))) {
+ ip = grn_ii_cursor_next(ctx, ic->iic);
+ if (ip && ic->flags & GRN_OBJ_WITH_POSITION) {
+ ip = grn_ii_cursor_next_pos(ctx, ic->iic);
+ }
+ if (ip) {
+ break;
+ }
+ }
+ }
+ }
+ if (tid) { *tid = ic->tid; }
+ GRN_API_RETURN((grn_posting *)ip);
+}
+
+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 rc = GRN_SUCCESS;
+ GRN_API_ENTER;
+ switch (table->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ {
+ grn_pat *pat = (grn_pat *)table;
+ WITH_NORMALIZE(pat, key, key_size, {
+ switch (mode) {
+ case GRN_OP_EXACT :
+ {
+ grn_id id = grn_pat_get(ctx, pat, key, key_size, NULL);
+ if (id) { grn_table_add(ctx, res, &id, sizeof(grn_id), NULL); }
+ }
+ // todo : support op;
+ break;
+ case GRN_OP_LCP :
+ {
+ grn_id id = grn_pat_lcp_search(ctx, pat, key, key_size);
+ if (id) { grn_table_add(ctx, res, &id, sizeof(grn_id), NULL); }
+ }
+ // todo : support op;
+ break;
+ case GRN_OP_SUFFIX :
+ rc = grn_pat_suffix_search(ctx, pat, key, key_size, (grn_hash *)res);
+ // todo : support op;
+ break;
+ case GRN_OP_PREFIX :
+ rc = grn_pat_prefix_search(ctx, pat, key, key_size, (grn_hash *)res);
+ // todo : support op;
+ break;
+ case GRN_OP_TERM_EXTRACT :
+ {
+ int len;
+ grn_id tid;
+ const char *sp = key;
+ const char *se = sp + key_size;
+ for (; sp < se; sp += len) {
+ if ((tid = grn_pat_lcp_search(ctx, pat, sp, se - sp))) {
+ grn_table_add(ctx, res, &tid, sizeof(grn_id), NULL);
+ /* todo : nsubrec++ if GRN_OBJ_TABLE_SUBSET assigned */
+ }
+ if (!(len = grn_charlen(ctx, sp, se))) { break; }
+ }
+ }
+ // todo : support op;
+ break;
+ default :
+ rc = GRN_INVALID_ARGUMENT;
+ ERR(rc, "invalid mode %d", mode);
+ }
+ });
+ }
+ break;
+ case GRN_TABLE_DAT_KEY :
+ {
+ grn_dat *dat = (grn_dat *)table;
+ WITH_NORMALIZE(dat, key, key_size, {
+ switch (mode) {
+ case GRN_OP_EXACT :
+ {
+ grn_id id = grn_dat_get(ctx, dat, key, key_size, NULL);
+ if (id) { grn_table_add(ctx, res, &id, sizeof(grn_id), NULL); }
+ }
+ break;
+ case GRN_OP_PREFIX :
+ {
+ grn_dat_cursor *dc = grn_dat_cursor_open(ctx, dat, key, key_size, NULL, 0,
+ 0, -1, GRN_CURSOR_PREFIX);
+ if (dc) {
+ grn_id id;
+ while ((id = grn_dat_cursor_next(ctx, dc))) {
+ grn_table_add(ctx, res, &id, sizeof(grn_id), NULL);
+ }
+ grn_dat_cursor_close(ctx, dc);
+ }
+ }
+ break;
+ case GRN_OP_LCP :
+ {
+ grn_id id = grn_dat_lcp_search(ctx, dat, key, key_size);
+ if (id) { grn_table_add(ctx, res, &id, sizeof(grn_id), NULL); }
+ }
+ break;
+ case GRN_OP_TERM_EXTRACT :
+ {
+ int len;
+ grn_id tid;
+ const char *sp = key;
+ const char *se = sp + key_size;
+ for (; sp < se; sp += len) {
+ if ((tid = grn_dat_lcp_search(ctx, dat, sp, se - sp))) {
+ grn_table_add(ctx, res, &tid, sizeof(grn_id), NULL);
+ /* todo : nsubrec++ if GRN_OBJ_TABLE_SUBSET assigned */
+ }
+ if (!(len = grn_charlen(ctx, sp, se))) { break; }
+ }
+ }
+ // todo : support op;
+ break;
+ default :
+ rc = GRN_INVALID_ARGUMENT;
+ ERR(rc, "invalid mode %d", mode);
+ }
+ });
+ }
+ break;
+ case GRN_TABLE_HASH_KEY :
+ {
+ grn_hash *hash = (grn_hash *)table;
+ grn_id id = GRN_ID_NIL;
+ WITH_NORMALIZE(hash, key, key_size, {
+ id = grn_hash_get(ctx, hash, key, key_size, NULL);
+ });
+ if (id) { grn_table_add(ctx, res, &id, sizeof(grn_id), NULL); }
+ }
+ break;
+ }
+ 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)
+{
+ grn_id r = GRN_ID_NIL;
+ GRN_API_ENTER;
+ if (table) {
+ switch (table->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ r = grn_pat_next(ctx, (grn_pat *)table, id);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ r = grn_dat_next(ctx, (grn_dat *)table, id);
+ break;
+ case GRN_TABLE_HASH_KEY :
+ r = grn_hash_next(ctx, (grn_hash *)table, id);
+ break;
+ case GRN_TABLE_NO_KEY :
+ r = grn_array_next(ctx, (grn_array *)table, id);
+ break;
+ }
+ }
+ GRN_API_RETURN(r);
+}
+
+static grn_rc
+grn_accessor_resolve_one_index_column(grn_ctx *ctx, grn_accessor *accessor,
+ grn_obj *current_res, grn_obj **next_res)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *column = NULL;
+ grn_id next_res_domain_id = GRN_ID_NIL;
+
+ {
+ grn_obj *index;
+ grn_obj source_ids;
+ unsigned int i, n_ids;
+
+ index = accessor->obj;
+ next_res_domain_id = index->header.domain;
+
+ GRN_UINT32_INIT(&source_ids, GRN_OBJ_VECTOR);
+ grn_obj_get_info(ctx, index, GRN_INFO_SOURCE, &source_ids);
+ n_ids = GRN_BULK_VSIZE(&source_ids) / sizeof(grn_id);
+ for (i = 0; i < n_ids; i++) {
+ grn_id source_id;
+ grn_obj *source;
+
+ source_id = GRN_UINT32_VALUE_AT(&source_ids, i);
+ source = grn_ctx_at(ctx, source_id);
+ if (DB_OBJ(source)->range == next_res_domain_id) {
+ column = source;
+ break;
+ }
+ grn_obj_unlink(ctx, source);
+ }
+
+ if (!column) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+
+ {
+ 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,
+ GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
+ next_res_domain, NULL);
+ rc = ctx->rc;
+ grn_obj_unlink(ctx, next_res_domain);
+ if (!*next_res) {
+ return rc;
+ }
+ }
+
+ {
+ grn_obj_flags column_value_flags = 0;
+ grn_obj column_value;
+ grn_posting add_posting;
+ grn_id *tid;
+ grn_rset_recinfo *recinfo;
+
+ if (column->header.type == GRN_COLUMN_VAR_SIZE) {
+ column_value_flags |= GRN_OBJ_VECTOR;
+ }
+ GRN_VALUE_FIX_SIZE_INIT(&column_value,
+ column_value_flags,
+ next_res_domain_id);
+
+ add_posting.sid = 0;
+ add_posting.pos = 0;
+ add_posting.weight = 0;
+
+ GRN_HASH_EACH(ctx, (grn_hash *)current_res, id, &tid, NULL, &recinfo, {
+ int i;
+ int n_elements;
+
+ add_posting.weight = recinfo->score - 1;
+
+ GRN_BULK_REWIND(&column_value);
+ grn_obj_get_value(ctx, column, *tid, &column_value);
+
+ n_elements = GRN_BULK_VSIZE(&column_value) / sizeof(grn_id);
+ for (i = 0; i < n_elements; i++) {
+ add_posting.rid = GRN_RECORD_VALUE_AT(&column_value, i);
+ rc = grn_ii_posting_add(ctx,
+ &add_posting,
+ (grn_hash *)*next_res,
+ GRN_OP_OR);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ });
+
+ GRN_OBJ_FIN(ctx, &column_value);
+ }
+
+ if (rc != GRN_SUCCESS) {
+ grn_obj_unlink(ctx, *next_res);
+ }
+
+ return rc;
+}
+
+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_rc rc = GRN_SUCCESS;
+ grn_index_datum index_datum;
+ unsigned int n_index_data;
+ grn_id next_res_domain_id = GRN_ID_NIL;
+
+ n_index_data = grn_column_get_all_index_data(ctx,
+ accessor->obj,
+ &index_datum,
+ 1);
+ if (n_index_data == 0) {
+ return GRN_INVALID_ARGUMENT;
+ }
+
+ {
+ 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,
+ GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
+ next_res_domain, NULL);
+ rc = ctx->rc;
+ grn_obj_unlink(ctx, next_res_domain);
+ if (!*next_res) {
+ return rc;
+ }
+ }
+
+ {
+ grn_id *tid;
+ grn_rset_recinfo *recinfo;
+
+ GRN_HASH_EACH(ctx, (grn_hash *)current_res, id, &tid, NULL, &recinfo, {
+ grn_ii *ii = (grn_ii *)(index_datum.index);
+ grn_ii_cursor *ii_cursor;
+ grn_posting *posting;
+
+ ii_cursor = grn_ii_cursor_open(ctx, ii, *tid,
+ GRN_ID_NIL, GRN_ID_MAX,
+ ii->n_elements,
+ 0);
+ if (!ii_cursor) {
+ continue;
+ }
+
+ while ((posting = grn_ii_cursor_next(ctx, ii_cursor))) {
+ 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,
+ (grn_hash *)*next_res,
+ GRN_OP_OR);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ grn_ii_cursor_close(ctx, ii_cursor);
+
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ });
+ }
+
+ if (rc != GRN_SUCCESS) {
+ grn_obj_unlink(ctx, *next_res);
+ }
+
+ return rc;
+}
+
+grn_rc
+grn_accessor_resolve(grn_ctx *ctx, grn_obj *accessor, int deep,
+ grn_obj *base_res, grn_obj *res,
+ grn_operator op)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_accessor *a;
+ grn_obj accessor_stack;
+ int i, n_accessors;
+ grn_obj *current_res = base_res;
+
+ GRN_PTR_INIT(&accessor_stack, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ n_accessors = 0;
+ for (a = (grn_accessor *)accessor; a; a = a->next) {
+ if (deep == n_accessors) {
+ break;
+ }
+ GRN_PTR_PUT(ctx, &accessor_stack, a);
+ n_accessors++;
+ }
+
+ for (i = n_accessors; i > 0; i--) {
+ grn_obj *next_res = NULL;
+
+ 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);
+ } 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);
+ }
+
+ if (current_res != base_res) {
+ grn_obj_unlink(ctx, current_res);
+ }
+
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+
+ current_res = next_res;
+ }
+
+ if (rc == GRN_SUCCESS && current_res != base_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 {
+ if (rc == GRN_SUCCESS) {
+ rc = GRN_INVALID_ARGUMENT;
+ }
+ }
+
+ GRN_OBJ_FIN(ctx, &accessor_stack);
+ 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)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_accessor *a;
+ grn_obj *last_obj = NULL;
+ int n_accessors;
+
+ for (a = (grn_accessor *)obj; a; a = a->next) {
+ if (!a->next) {
+ last_obj = a->obj;
+ }
+ }
+ n_accessors = 0;
+ for (a = (grn_accessor *)obj; a; a = a->next) {
+ n_accessors++;
+ if (GRN_OBJ_INDEX_COLUMNP(a->obj)) {
+ break;
+ }
+ }
+
+ {
+ grn_obj *index;
+ grn_operator index_op = GRN_OP_MATCH;
+ if (optarg && optarg->mode != GRN_OP_EXACT) {
+ index_op = optarg->mode;
+ }
+ if (grn_column_index(ctx, last_obj, index_op, &index, 1, NULL) == 0) {
+ rc = GRN_INVALID_ARGUMENT;
+ goto exit;
+ }
+
+ if (n_accessors == 1) {
+ rc = grn_obj_search(ctx, index, query, res, op, optarg);
+ } else {
+ grn_obj *base_res;
+ 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,
+ range,
+ NULL);
+ rc = ctx->rc;
+ grn_obj_unlink(ctx, range);
+ 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, res, op);
+ grn_obj_unlink(ctx, base_res);
+ }
+ }
+
+exit :
+ return rc;
+}
+
+static grn_rc
+grn_obj_search_column_index_by_id(grn_ctx *ctx, grn_obj *obj,
+ grn_id tid,
+ grn_obj *res, grn_operator op,
+ grn_search_optarg *optarg)
+{
+ 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_posting *pos;
+ grn_hash *s = (grn_hash *)res;
+ while ((pos = grn_ii_cursor_next(ctx, c))) {
+ /* todo: support orgarg(op)
+ res_add(ctx, s, (grn_rset_posinfo *) pos,
+ get_weight(ctx, s, pos->rid, pos->sid, wvm, optarg), op);
+ */
+ grn_hash_add(ctx, s, pos, s->key_size, NULL, NULL);
+ }
+ grn_ii_cursor_close(ctx, c);
+ }
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_obj_search_column_index_by_key(grn_ctx *ctx, grn_obj *obj,
+ grn_obj *query,
+ grn_obj *res, grn_operator op,
+ grn_search_optarg *optarg)
+{
+ grn_rc rc;
+ unsigned int key_type = GRN_ID_NIL;
+ const char *key;
+ unsigned int key_len;
+ grn_obj *table;
+ grn_obj casted_query;
+ grn_bool need_cast = GRN_FALSE;
+
+ table = grn_ctx_at(ctx, obj->header.domain);
+ if (table) {
+ key_type = table->header.domain;
+ need_cast = (query->header.domain != key_type);
+ grn_obj_unlink(ctx, table);
+ }
+ if (need_cast) {
+ GRN_OBJ_INIT(&casted_query, GRN_BULK, 0, key_type);
+ rc = grn_obj_cast(ctx, query, &casted_query, GRN_FALSE);
+ if (rc == GRN_SUCCESS) {
+ key = GRN_BULK_HEAD(&casted_query);
+ key_len = GRN_BULK_VSIZE(&casted_query);
+ }
+ } else {
+ rc = GRN_SUCCESS;
+ key = GRN_BULK_HEAD(query);
+ 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);
+ }
+ if (need_cast) {
+ GRN_OBJ_FIN(ctx, &casted_query);
+ }
+
+ return rc;
+}
+
+static grn_rc
+grn_obj_search_column_index(grn_ctx *ctx, grn_obj *obj, grn_obj *query,
+ grn_obj *res, grn_operator op,
+ grn_search_optarg *optarg)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+
+ if (DB_OBJ(obj)->range == res->header.domain) {
+ switch (query->header.type) {
+ case GRN_BULK :
+ if (query->header.domain == obj->header.domain &&
+ GRN_BULK_VSIZE(query) == sizeof(grn_id)) {
+ grn_id tid = GRN_RECORD_VALUE(query);
+ rc = grn_obj_search_column_index_by_id(ctx, obj, tid, res, op, optarg);
+ } else {
+ rc = grn_obj_search_column_index_by_key(ctx, obj, query,
+ res, op, optarg);
+ }
+ break;
+ case GRN_QUERY :
+ rc = GRN_FUNCTION_NOT_IMPLEMENTED;
+ break;
+ }
+ }
+
+ return rc;
+}
+
+grn_rc
+grn_obj_search(grn_ctx *ctx, grn_obj *obj, grn_obj *query,
+ grn_obj *res, grn_operator op, grn_search_optarg *optarg)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ GRN_API_ENTER;
+ if (GRN_ACCESSORP(obj)) {
+ rc = grn_obj_search_accessor(ctx, obj, query, res, op, optarg);
+ } else if (GRN_DB_OBJP(obj)) {
+ switch (obj->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_HASH_KEY :
+ {
+ const void *key = GRN_BULK_HEAD(query);
+ uint32_t key_size = GRN_BULK_VSIZE(query);
+ grn_operator mode = optarg ? optarg->mode : GRN_OP_EXACT;
+ if (key && key_size) {
+ 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;
+ case GRN_COLUMN_INDEX :
+ rc = grn_obj_search_column_index(ctx, obj, query, res, op, optarg);
+ break;
+ }
+ }
+ GRN_API_RETURN(rc);
+}
+
+#define GRN_TABLE_GROUP_BY_KEY 0
+#define GRN_TABLE_GROUP_BY_VALUE 1
+#define GRN_TABLE_GROUP_BY_COLUMN_VALUE 2
+
+#define GRN_TABLE_GROUP_FILTER_PREFIX 0
+#define GRN_TABLE_GROUP_FILTER_SUFFIX (1L<<2)
+
+inline static void
+grn_table_group_add_subrec(grn_ctx *ctx,
+ grn_obj *table,
+ grn_rset_recinfo *ri, double score,
+ grn_rset_posinfo *pi, int dir,
+ grn_obj *calc_target,
+ grn_obj *value_buffer)
+{
+ grn_table_group_flags flags;
+
+ if (!(DB_OBJ(table)->header.flags & GRN_OBJ_WITH_SUBREC)) {
+ return;
+ }
+
+ grn_table_add_subrec_inline(table, ri, score, pi, dir);
+
+ flags = DB_OBJ(table)->flags.group;
+
+ if (!(flags & (GRN_TABLE_GROUP_CALC_MAX |
+ GRN_TABLE_GROUP_CALC_MIN |
+ GRN_TABLE_GROUP_CALC_SUM |
+ GRN_TABLE_GROUP_CALC_AVG))) {
+ return;
+ }
+
+ GRN_BULK_REWIND(value_buffer);
+ grn_obj_get_value(ctx, calc_target, pi->rid, value_buffer);
+ grn_rset_recinfo_update_calc_values(ctx, ri, table, value_buffer);
+}
+
+static grn_bool
+accelerated_table_group(grn_ctx *ctx, grn_obj *table, grn_obj *key,
+ grn_table_group_result *result)
+{
+ grn_obj *res = result->table;
+ grn_obj *calc_target = result->calc_target;
+ if (key->header.type == GRN_ACCESSOR) {
+ grn_accessor *a = (grn_accessor *)key;
+ if (a->action == GRN_ACCESSOR_GET_KEY &&
+ a->next && a->next->action == GRN_ACCESSOR_GET_COLUMN_VALUE &&
+ a->next->obj && !a->next->next) {
+ grn_obj *range = grn_ctx_at(ctx, grn_obj_get_range(ctx, key));
+ int idp = GRN_OBJ_TABLEP(range);
+ grn_table_cursor *tc;
+ if ((tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1, 0))) {
+ grn_bool processed = GRN_TRUE;
+ grn_obj value_buffer;
+ GRN_VOID_INIT(&value_buffer);
+ switch (a->next->obj->header.type) {
+ case GRN_COLUMN_FIX_SIZE :
+ {
+ grn_id id;
+ grn_ra *ra = (grn_ra *)a->next->obj;
+ unsigned int element_size = (ra)->header->element_size;
+ grn_ra_cache cache;
+ GRN_RA_CACHE_INIT(ra, &cache);
+ while ((id = grn_table_cursor_next_inline(ctx, tc))) {
+ void *v, *value;
+ grn_id *id_;
+ uint32_t key_size;
+ 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);
+ }
+ id_ = (grn_id *)_grn_table_key(ctx, table, id, &key_size);
+ v = grn_ra_ref_cache(ctx, ra, *id_, &cache);
+ if (idp && *((grn_id *)v) &&
+ grn_table_at(ctx, range, *((grn_id *)v)) == GRN_ID_NIL) {
+ continue;
+ }
+ if ((!idp || *((grn_id *)v)) &&
+ grn_table_add_v_inline(ctx, res, v, element_size, &value, NULL)) {
+ grn_table_group_add_subrec(ctx, res, value,
+ ri ? ri->score : 0,
+ (grn_rset_posinfo *)&id, 0,
+ calc_target,
+ &value_buffer);
+ }
+ }
+ GRN_RA_CACHE_FIN(ra, &cache);
+ }
+ break;
+ case GRN_COLUMN_VAR_SIZE :
+ if (idp) { /* todo : support other type */
+ grn_id id;
+ grn_ja *ja = (grn_ja *)a->next->obj;
+ while ((id = grn_table_cursor_next_inline(ctx, tc))) {
+ grn_io_win jw;
+ unsigned int len = 0;
+ void *value;
+ grn_id *v, *id_;
+ uint32_t key_size;
+ 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);
+ }
+ id_ = (grn_id *)_grn_table_key(ctx, table, id, &key_size);
+ if ((v = grn_ja_ref(ctx, ja, *id_, &jw, &len))) {
+ while (len) {
+ 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);
+ }
+ v++;
+ len -= sizeof(grn_id);
+ }
+ grn_ja_unref(ctx, &jw);
+ }
+ }
+ } else {
+ processed = GRN_FALSE;
+ }
+ break;
+ default :
+ processed = GRN_FALSE;
+ break;
+ }
+ GRN_OBJ_FIN(ctx, &value_buffer);
+ grn_table_cursor_close(ctx, tc);
+ return processed;
+ }
+ }
+ }
+ return GRN_FALSE;
+}
+
+static void
+grn_table_group_single_key_records(grn_ctx *ctx, grn_obj *table,
+ grn_obj *key, grn_table_group_result *result)
+{
+ grn_obj bulk;
+ grn_obj value_buffer;
+ grn_table_cursor *tc;
+ grn_obj *res = result->table;
+ grn_obj *calc_target = result->calc_target;
+
+ GRN_TEXT_INIT(&bulk, 0);
+ GRN_VOID_INIT(&value_buffer);
+ if ((tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1, 0))) {
+ grn_id id;
+ grn_obj *range = grn_ctx_at(ctx, grn_obj_get_range(ctx, key));
+ int idp = GRN_OBJ_TABLEP(range);
+ while ((id = grn_table_cursor_next_inline(ctx, tc))) {
+ void *value;
+ grn_rset_recinfo *ri = NULL;
+ GRN_BULK_REWIND(&bulk);
+ if (DB_OBJ(table)->header.flags & GRN_OBJ_WITH_SUBREC) {
+ grn_table_cursor_get_value_inline(ctx, tc, (void **)&ri);
+ }
+ grn_obj_get_value(ctx, key, id, &bulk);
+ switch (bulk.header.type) {
+ case GRN_UVECTOR :
+ {
+ 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;
+ }
+ }
+
+ 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;
+ case GRN_VECTOR :
+ {
+ unsigned int i, n_elements;
+ n_elements = grn_vector_size(ctx, &bulk);
+ for (i = 0; i < n_elements; i++) {
+ const char *content;
+ unsigned int content_length;
+ content_length = grn_vector_get_element(ctx, &bulk, i,
+ &content, NULL, NULL);
+ if (grn_table_add_v_inline(ctx, res,
+ content, content_length,
+ &value, NULL)) {
+ grn_table_group_add_subrec(ctx, res, value,
+ ri ? ri->score : 0,
+ (grn_rset_posinfo *)&id, 0,
+ calc_target,
+ &value_buffer);
+ }
+ }
+ }
+ break;
+ case GRN_BULK :
+ {
+ if ((!idp || *((grn_id *)GRN_BULK_HEAD(&bulk))) &&
+ grn_table_add_v_inline(ctx, res,
+ GRN_BULK_HEAD(&bulk), GRN_BULK_VSIZE(&bulk),
+ &value, NULL)) {
+ grn_table_group_add_subrec(ctx, res, value,
+ ri ? ri->score : 0,
+ (grn_rset_posinfo *)&id, 0,
+ calc_target,
+ &value_buffer);
+ }
+ }
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "invalid column");
+ break;
+ }
+ }
+ grn_table_cursor_close(ctx, tc);
+ }
+ 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
+grn_table_group_with_range_gap(grn_ctx *ctx, grn_obj *table,
+ grn_table_sort_key *group_key,
+ grn_obj *res, uint32_t range_gap)
+{
+ grn_obj *key = group_key->key;
+ if (key->header.type == GRN_ACCESSOR) {
+ grn_accessor *a = (grn_accessor *)key;
+ if (a->action == GRN_ACCESSOR_GET_KEY &&
+ a->next && a->next->action == GRN_ACCESSOR_GET_COLUMN_VALUE &&
+ a->next->obj && !a->next->next) {
+ grn_obj *range = grn_ctx_at(ctx, grn_obj_get_range(ctx, key));
+ int idp = GRN_OBJ_TABLEP(range);
+ grn_table_cursor *tc;
+ if ((tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL,
+ 0, 0, -1, 0))) {
+ switch (a->next->obj->header.type) {
+ case GRN_COLUMN_FIX_SIZE :
+ {
+ grn_id id;
+ grn_ra *ra = (grn_ra *)a->next->obj;
+ unsigned int element_size = (ra)->header->element_size;
+ grn_ra_cache cache;
+ GRN_RA_CACHE_INIT(ra, &cache);
+ while ((id = grn_table_cursor_next_inline(ctx, tc))) {
+ void *v, *value;
+ grn_id *id_;
+ uint32_t key_size;
+ 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);
+ }
+ id_ = (grn_id *)_grn_table_key(ctx, table, id, &key_size);
+ v = grn_ra_ref_cache(ctx, ra, *id_, &cache);
+ if (idp && *((grn_id *)v) &&
+ grn_table_at(ctx, range, *((grn_id *)v)) == GRN_ID_NIL) {
+ continue;
+ }
+ if ((!idp || *((grn_id *)v))) {
+ grn_id id;
+ if (element_size == sizeof(uint32_t)) {
+ uint32_t quantized = (*(uint32_t *)v);
+ quantized -= quantized % range_gap;
+ id = grn_table_add_v_inline(ctx, res, &quantized,
+ element_size, &value, NULL);
+ } else {
+ id = grn_table_add_v_inline(ctx, res, v,
+ element_size, &value, NULL);
+ }
+ if (id) {
+ grn_table_add_subrec_inline(res, value,
+ ri ? ri->score : 0,
+ (grn_rset_posinfo *)&id, 0);
+ }
+ }
+ }
+ GRN_RA_CACHE_FIN(ra, &cache);
+ }
+ break;
+ case GRN_COLUMN_VAR_SIZE :
+ if (idp) { /* todo : support other type */
+ grn_id id;
+ grn_ja *ja = (grn_ja *)a->next->obj;
+ while ((id = grn_table_cursor_next_inline(ctx, tc))) {
+ grn_io_win jw;
+ unsigned int len = 0;
+ void *value;
+ grn_id *v, *id_;
+ uint32_t key_size;
+ 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);
+ }
+ id_ = (grn_id *)_grn_table_key(ctx, table, id, &key_size);
+ if ((v = grn_ja_ref(ctx, ja, *id_, &jw, &len))) {
+ while (len) {
+ if ((*v != GRN_ID_NIL) &&
+ grn_table_add_v_inline(ctx, res, v, sizeof(grn_id), &value, NULL)) {
+ grn_table_add_subrec_inline(res, value, ri ? ri->score : 0,
+ (grn_rset_posinfo *)&id, 0);
+ }
+ v++;
+ len -= sizeof(grn_id);
+ }
+ grn_ja_unref(ctx, &jw);
+ }
+ }
+ } else {
+ return 0;
+ }
+ break;
+ default :
+ return 0;
+ }
+ grn_table_cursor_close(ctx, tc);
+ GRN_TABLE_GROUPED_ON(res);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+static inline void
+grn_table_group_multi_keys_add_record(grn_ctx *ctx,
+ grn_table_sort_key *keys,
+ int n_keys,
+ grn_table_group_result *results,
+ int n_results,
+ grn_id id,
+ grn_rset_recinfo *ri,
+ grn_obj *vector,
+ grn_obj *bulk)
+{
+ int r;
+ grn_table_group_result *rp;
+
+ for (r = 0, rp = results; r < n_results; r++, rp++) {
+ void *value;
+ int i;
+ int end;
+
+ if (rp->key_end > n_keys) {
+ end = n_keys;
+ } else {
+ end = rp->key_end + 1;
+ }
+ GRN_BULK_REWIND(bulk);
+ grn_text_benc(ctx, bulk, end - rp->key_begin);
+ for (i = rp->key_begin; i < end; i++) {
+ grn_section section = vector->u.v.sections[i];
+ grn_text_benc(ctx, bulk, section.length);
+ }
+ {
+ grn_obj *body = vector->u.v.body;
+ if (body) {
+ GRN_TEXT_PUT(ctx, bulk, GRN_BULK_HEAD(body), GRN_BULK_VSIZE(body));
+ }
+ }
+ for (i = rp->key_begin; i < end; i++) {
+ grn_section section = vector->u.v.sections[i];
+ grn_text_benc(ctx, bulk, section.weight);
+ grn_text_benc(ctx, bulk, section.domain);
+ }
+
+ // todo : cut off GRN_ID_NIL
+ if (grn_table_add_v_inline(ctx, rp->table,
+ GRN_BULK_HEAD(bulk), GRN_BULK_VSIZE(bulk),
+ &value, NULL)) {
+ grn_table_group_add_subrec(ctx, rp->table, value,
+ ri ? ri->score : 0,
+ (grn_rset_posinfo *)&id, 0,
+ rp->calc_target,
+ bulk);
+ }
+ }
+}
+
+static void
+grn_table_group_multi_keys_scalar_records(grn_ctx *ctx,
+ grn_obj *table,
+ grn_table_sort_key *keys,
+ int n_keys,
+ grn_table_group_result *results,
+ int n_results)
+{
+ grn_id id;
+ grn_table_cursor *tc;
+ grn_obj bulk;
+ grn_obj vector;
+
+ tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1, 0);
+ if (!tc) {
+ return;
+ }
+
+ GRN_TEXT_INIT(&bulk, 0);
+ GRN_OBJ_INIT(&vector, GRN_VECTOR, 0, GRN_DB_VOID);
+ while ((id = grn_table_cursor_next_inline(ctx, tc))) {
+ int k;
+ grn_table_sort_key *kp;
+ 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_BULK_REWIND(&vector);
+ for (k = 0, kp = keys; k < n_keys; k++, kp++) {
+ GRN_BULK_REWIND(&bulk);
+ grn_obj_get_value(ctx, kp->key, id, &bulk);
+ grn_vector_add_element(ctx, &vector,
+ GRN_BULK_HEAD(&bulk), GRN_BULK_VSIZE(&bulk),
+ 0,
+ bulk.header.domain);
+ }
+
+ grn_table_group_multi_keys_add_record(ctx, keys, n_keys, results, n_results,
+ id, ri, &vector, &bulk);
+ }
+ GRN_OBJ_FIN(ctx, &vector);
+ GRN_OBJ_FIN(ctx, &bulk);
+ grn_table_cursor_close(ctx, tc);
+}
+
+static inline void
+grn_table_group_multi_keys_vector_record(grn_ctx *ctx,
+ grn_table_sort_key *keys,
+ grn_obj *key_buffers,
+ int nth_key,
+ int n_keys,
+ grn_table_group_result *results,
+ int n_results,
+ grn_id id,
+ grn_rset_recinfo *ri,
+ grn_obj *vector,
+ grn_obj *bulk)
+{
+ int k;
+ grn_table_sort_key *kp;
+
+ for (k = nth_key, kp = &(keys[nth_key]); k < n_keys; k++, kp++) {
+ grn_obj *key_buffer = &(key_buffers[k]);
+ switch (key_buffer->header.type) {
+ case GRN_UVECTOR :
+ {
+ unsigned int n_vector_elements;
+ grn_id domain;
+ grn_id *ids;
+ unsigned int i, n_ids;
+
+ n_vector_elements = grn_vector_size(ctx, vector);
+ domain = key_buffer->header.domain;
+ ids = (grn_id *)GRN_BULK_HEAD(key_buffer);
+ n_ids = GRN_BULK_VSIZE(key_buffer) / sizeof(grn_id);
+ for (i = 0; i < n_ids; i++) {
+ grn_id element_id = ids[i];
+ grn_vector_add_element(ctx, vector,
+ (const char *)(&element_id), sizeof(grn_id),
+ 0,
+ domain);
+ grn_table_group_multi_keys_vector_record(ctx,
+ keys, key_buffers,
+ k + 1, n_keys,
+ results, n_results,
+ id, ri, vector, bulk);
+ while (grn_vector_size(ctx, vector) != n_vector_elements) {
+ const char *content;
+ grn_vector_pop_element(ctx, vector, &content, NULL, NULL);
+ }
+ }
+ return;
+ }
+ break;
+ case GRN_VECTOR :
+ {
+ unsigned int n_vector_elements;
+ unsigned int i, n_key_elements;
+
+ n_vector_elements = grn_vector_size(ctx, vector);
+ n_key_elements = grn_vector_size(ctx, key_buffer);
+ for (i = 0; i < n_key_elements; i++) {
+ const char *content;
+ unsigned int content_length;
+ grn_id domain;
+ content_length = grn_vector_get_element(ctx, key_buffer, i,
+ &content, NULL, &domain);
+ grn_vector_add_element(ctx, vector,
+ content, content_length,
+ 0,
+ domain);
+ grn_table_group_multi_keys_vector_record(ctx,
+ keys, key_buffers,
+ k + 1, n_keys,
+ results, n_results,
+ id, ri, vector, bulk);
+ while (grn_vector_size(ctx, vector) != n_vector_elements) {
+ grn_vector_pop_element(ctx, vector, &content, NULL, NULL);
+ }
+ }
+ return;
+ }
+ break;
+ default :
+ grn_vector_add_element(ctx, vector,
+ GRN_BULK_HEAD(key_buffer),
+ GRN_BULK_VSIZE(key_buffer),
+ 0,
+ key_buffer->header.domain);
+ }
+ }
+
+ if (k == n_keys) {
+ grn_table_group_multi_keys_add_record(ctx,
+ keys, n_keys,
+ results, n_results,
+ id, ri, vector, bulk);
+ }
+}
+
+static void
+grn_table_group_multi_keys_vector_records(grn_ctx *ctx,
+ grn_obj *table,
+ grn_table_sort_key *keys,
+ int n_keys,
+ grn_table_group_result *results,
+ int n_results)
+{
+ grn_id id;
+ grn_table_cursor *tc;
+ grn_obj bulk;
+ grn_obj vector;
+ grn_obj *key_buffers;
+ int k;
+
+ tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1, 0);
+ if (!tc) {
+ return;
+ }
+
+ key_buffers = GRN_MALLOCN(grn_obj, n_keys);
+ if (!key_buffers) {
+ grn_table_cursor_close(ctx, tc);
+ return;
+ }
+
+ GRN_TEXT_INIT(&bulk, 0);
+ GRN_OBJ_INIT(&vector, GRN_VECTOR, 0, GRN_DB_VOID);
+ for (k = 0; k < n_keys; k++) {
+ GRN_VOID_INIT(&(key_buffers[k]));
+ }
+ while ((id = grn_table_cursor_next_inline(ctx, tc))) {
+ grn_table_sort_key *kp;
+ 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);
+ }
+
+ for (k = 0, kp = keys; k < n_keys; k++, kp++) {
+ grn_obj *key_buffer = &(key_buffers[k]);
+ GRN_BULK_REWIND(key_buffer);
+ grn_obj_get_value(ctx, kp->key, id, key_buffer);
+ }
+
+ GRN_BULK_REWIND(&vector);
+ grn_table_group_multi_keys_vector_record(ctx,
+ keys, key_buffers, 0, n_keys,
+ results, n_results,
+ id, ri, &vector, &bulk);
+ }
+ for (k = 0; k < n_keys; k++) {
+ GRN_OBJ_FIN(ctx, &(key_buffers[k]));
+ }
+ GRN_FREE(key_buffers);
+ GRN_OBJ_FIN(ctx, &vector);
+ GRN_OBJ_FIN(ctx, &bulk);
+ grn_table_cursor_close(ctx, tc);
+}
+
+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_rc rc = GRN_SUCCESS;
+ 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;
+ }
+ GRN_API_ENTER;
+ {
+ int k, r;
+ grn_table_sort_key *kp;
+ grn_table_group_result *rp;
+ for (k = 0, kp = keys; k < n_keys; k++, kp++) {
+ if ((kp->flags & GRN_TABLE_GROUP_BY_COLUMN_VALUE) && !kp->key) {
+ ERR(GRN_INVALID_ARGUMENT, "column missing in (%d)", k);
+ goto exit;
+ }
+ }
+ for (r = 0, rp = results; r < n_results; r++, rp++) {
+ if (!rp->table) {
+ 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 (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;
+ }
+ additional_value_size = grn_rset_recinfo_calc_values_size(ctx,
+ rp->flags);
+ rp->table = grn_table_create_with_max_n_subrecs(ctx, NULL, 0, NULL,
+ flags,
+ key_type, table,
+ rp->max_n_subrecs,
+ additional_value_size);
+ if (key_type) {
+ grn_obj_unlink(ctx, key_type);
+ }
+ if (!rp->table) {
+ goto exit;
+ }
+ DB_OBJ(rp->table)->flags.group = rp->flags;
+ }
+ }
+ 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);
+ }
+ } else {
+ grn_bool have_vector = GRN_FALSE;
+ for (k = 0, kp = keys; k < n_keys; k++, kp++) {
+ grn_id range_id;
+ grn_obj_flags range_flags = 0;
+ grn_obj_get_range_info(ctx, kp->key, &range_id, &range_flags);
+ if (range_flags == GRN_OBJ_VECTOR) {
+ have_vector = GRN_TRUE;
+ break;
+ }
+ }
+ if (have_vector) {
+ grn_table_group_multi_keys_vector_records(ctx, table,
+ keys, n_keys,
+ results, n_results);
+ } else {
+ grn_table_group_multi_keys_scalar_records(ctx, table,
+ keys, n_keys,
+ results, n_results);
+ }
+ }
+ for (r = 0, rp = results; r < n_results; r++, rp++) {
+ GRN_TABLE_GROUPED_ON(rp->table);
+ }
+ }
+exit :
+ GRN_API_RETURN(rc);
+}
+
+grn_rc
+grn_table_setoperation(grn_ctx *ctx, grn_obj *table1, grn_obj *table2, grn_obj *res,
+ grn_operator op)
+{
+ 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 {
+ 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) &&
+ (DB_OBJ(table2)->header.flags & GRN_OBJ_WITH_SUBREC));
+ switch (table1->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ value_size = ((grn_hash *)table1)->value_size;
+ break;
+ case GRN_TABLE_PAT_KEY :
+ value_size = ((grn_pat *)table1)->value_size;
+ break;
+ case GRN_TABLE_DAT_KEY :
+ value_size = 0;
+ break;
+ case GRN_TABLE_NO_KEY :
+ value_size = ((grn_array *)table1)->value_size;
+ break;
+ }
+ switch (table2->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ if (value_size < ((grn_hash *)table2)->value_size) {
+ value_size = ((grn_hash *)table2)->value_size;
+ }
+ break;
+ case GRN_TABLE_PAT_KEY :
+ if (value_size < ((grn_pat *)table2)->value_size) {
+ value_size = ((grn_pat *)table2)->value_size;
+ }
+ break;
+ case GRN_TABLE_DAT_KEY :
+ value_size = 0;
+ break;
+ case GRN_TABLE_NO_KEY :
+ if (value_size < ((grn_array *)table2)->value_size) {
+ value_size = ((grn_array *)table2)->value_size;
+ }
+ break;
+ }
+ switch (op) {
+ case GRN_OP_OR :
+ if (have_subrec) {
+ int added;
+ GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, {
+ if (grn_table_add_v_inline(ctx, table1, key, key_size, &value1, &added)) {
+ if (added) {
+ grn_memcpy(value1, value2, value_size);
+ } else {
+ grn_rset_recinfo *ri1 = value1;
+ grn_rset_recinfo *ri2 = value2;
+ grn_table_add_subrec_inline(table1, ri1, ri2->score, NULL, 0);
+ }
+ }
+ });
+ } else {
+ GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, {
+ if (grn_table_add_v_inline(ctx, table1, key, key_size, &value1, NULL)) {
+ grn_memcpy(value1, value2, value_size);
+ }
+ });
+ }
+ break;
+ case GRN_OP_AND :
+ if (have_subrec) {
+ GRN_TABLE_EACH(ctx, table1, 0, 0, id, &key, &key_size, &value1, {
+ if (grn_table_get_v(ctx, table2, key, key_size, &value2)) {
+ grn_rset_recinfo *ri1 = value1;
+ grn_rset_recinfo *ri2 = value2;
+ ri1->score += ri2->score;
+ } else {
+ _grn_table_delete_by_id(ctx, table1, id, NULL);
+ }
+ });
+ } else {
+ GRN_TABLE_EACH(ctx, table1, 0, 0, id, &key, &key_size, &value1, {
+ if (!grn_table_get_v(ctx, table2, key, key_size, &value2)) {
+ _grn_table_delete_by_id(ctx, table1, id, NULL);
+ }
+ });
+ }
+ break;
+ case GRN_OP_AND_NOT :
+ GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, {
+ grn_table_delete(ctx, table1, key, key_size);
+ });
+ break;
+ case GRN_OP_ADJUST :
+ 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;
+ }
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_rc
+grn_table_difference(grn_ctx *ctx, grn_obj *table1, grn_obj *table2,
+ grn_obj *res1, grn_obj *res2)
+{
+ void *key = NULL;
+ uint32_t key_size = 0;
+ if (table1 != res1 || table2 != res2) { return GRN_INVALID_ARGUMENT; }
+ if (grn_table_size(ctx, table1) > grn_table_size(ctx, table2)) {
+ GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, NULL, {
+ grn_id id1;
+ if ((id1 = grn_table_get(ctx, table1, key, key_size))) {
+ _grn_table_delete_by_id(ctx, table1, id1, NULL);
+ _grn_table_delete_by_id(ctx, table2, id, NULL);
+ }
+ });
+ } else {
+ GRN_TABLE_EACH(ctx, table1, 0, 0, id, &key, &key_size, NULL, {
+ grn_id id2;
+ if ((id2 = grn_table_get(ctx, table2, key, key_size))) {
+ _grn_table_delete_by_id(ctx, table1, id, NULL);
+ _grn_table_delete_by_id(ctx, table2, id2, NULL);
+ }
+ });
+ }
+ return GRN_SUCCESS;
+}
+
+static grn_obj *grn_obj_get_accessor(grn_ctx *ctx, grn_obj *obj,
+ const char *name, unsigned int name_size);
+
+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;
+
+ 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 {
+ 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;
+}
+
+grn_obj *
+grn_obj_column(grn_ctx *ctx, grn_obj *table, const char *name, unsigned int name_size)
+{
+ grn_obj *column = NULL;
+ GRN_API_ENTER;
+ if (GRN_OBJ_TABLEP(table)) {
+ if (grn_db_check_name(ctx, name, name_size) ||
+ !(column = grn_obj_column_(ctx, table, name, name_size))) {
+ column = grn_obj_get_accessor(ctx, table, name, name_size);
+ }
+ } else if (GRN_ACCESSORP(table)) {
+ column = grn_obj_get_accessor(ctx, table, name, name_size);
+ }
+ GRN_API_RETURN(column);
+}
+
+int
+grn_table_columns(grn_ctx *ctx, grn_obj *table, const char *name, unsigned int name_size,
+ grn_obj *res)
+{
+ int n = 0;
+ grn_id id;
+
+ GRN_API_ENTER;
+
+ 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, 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),
+ GRN_OP_PREFIX, res, GRN_OP_OR);
+ grn_obj_close(ctx, &bulk);
+ n = grn_table_size(ctx, res);
+ }
+ }
+
+ GRN_API_RETURN(n);
+}
+
+const char *
+_grn_table_key(grn_ctx *ctx, grn_obj *table, grn_id id, uint32_t *key_size)
+{
+ GRN_ASSERT(table);
+ if (table->header.type == GRN_DB) { table = ((grn_db *)table)->keys; }
+ switch (table->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ return _grn_hash_key(ctx, (grn_hash *)table, id, key_size);
+ case GRN_TABLE_PAT_KEY :
+ return _grn_pat_key(ctx, (grn_pat *)table, id, key_size);
+ case GRN_TABLE_DAT_KEY :
+ return _grn_dat_key(ctx, (grn_dat *)table, id, key_size);
+ case GRN_TABLE_NO_KEY :
+ {
+ grn_array *a = (grn_array *)table;
+ const char *v;
+ if (a->obj.header.domain && a->value_size &&
+ (v = _grn_array_get_value(ctx, a, id))) {
+ *key_size = a->value_size;
+ return v;
+ } else {
+ *key_size = 0;
+ }
+ }
+ break;
+ }
+ return NULL;
+}
+
+/* column */
+
+grn_obj *
+grn_column_create(grn_ctx *ctx, grn_obj *table,
+ const char *name, unsigned int name_size,
+ const char *path, grn_column_flags flags, grn_obj *type)
+{
+ grn_db *s;
+ uint32_t value_size;
+ grn_obj *db= NULL, *res = NULL;
+ 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");
+ goto exit;
+ }
+ if (!type) {
+ ERR(GRN_INVALID_ARGUMENT, "[column][create] type is missing");
+ goto exit;
+ }
+ if (!name || !name_size) {
+ ERR(GRN_INVALID_ARGUMENT, "[column][create] name is missing");
+ goto exit;
+ }
+ db = DB_OBJ(table)->db;
+ s = (grn_db *)db;
+ if (!GRN_DB_P(s)) {
+ int table_name_len;
+ char table_name[GRN_TABLE_MAX_KEY_SIZE];
+ table_name_len = grn_obj_name(ctx, table, table_name, GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[column][create] invalid db assigned: <%.*s>.<%.*s>",
+ table_name_len, table_name, name_size, name);
+ goto exit;
+ }
+
+ if (grn_db_check_name(ctx, name, name_size)) {
+ GRN_DB_CHECK_NAME_ERR("[column][create]", name, name_size);
+ goto exit;
+ }
+
+ 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 - table_name_len,
+ table_name_len, fullname, name_size, name);
+ 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 & ~GRN_OBJ_KEY_MASK;
+ value_size = GRN_TYPE_SIZE(t);
+ }
+ break;
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ value_size = sizeof(grn_id);
+ break;
+ default :
+ /*
+ if (type == grn_type_any) {
+ value_size = sizeof(grn_id) + sizeof(grn_id);
+ }
+ */
+ value_size = sizeof(grn_id);
+ }
+
+ 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)) {
+ grn_db_generate_pathname(ctx, db, id, buffer);
+ path = buffer;
+ } else {
+ int table_name_len;
+ char table_name[GRN_TABLE_MAX_KEY_SIZE];
+ table_name_len = grn_obj_name(ctx, table, table_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[column][create] path not assigned for persistent column"
+ ": <%.*s>.<%.*s>",
+ table_name_len, table_name, name_size, name);
+ goto exit;
+ }
+ } else {
+ flags |= GRN_OBJ_CUSTOM_NAME;
+ }
+ } else {
+ if (path) {
+ int table_name_len;
+ char table_name[GRN_TABLE_MAX_KEY_SIZE];
+ table_name_len = grn_obj_name(ctx, table, table_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[column][create] path assigned for temporary column"
+ ": <%.*s>.<%.*s>",
+ table_name_len, table_name, name_size, name);
+ goto exit;
+ }
+ }
+ switch (flags & GRN_OBJ_COLUMN_TYPE_MASK) {
+ case GRN_OBJ_COLUMN_SCALAR :
+ if ((flags & GRN_OBJ_KEY_VAR_SIZE) || value_size > sizeof(int64_t)) {
+ res = (grn_obj *)grn_ja_create(ctx, path, value_size, flags);
+ } else {
+ res = (grn_obj *)grn_ra_create(ctx, path, value_size);
+ }
+ break;
+ case GRN_OBJ_COLUMN_VECTOR :
+ res = (grn_obj *)grn_ja_create(ctx, path, value_size * 30/*todo*/, flags);
+ //todo : zlib support
+ break;
+ case GRN_OBJ_COLUMN_INDEX :
+ res = (grn_obj *)grn_ii_create(ctx, path, table, flags); //todo : ii layout support
+ break;
+ }
+ if (res) {
+ DB_OBJ(res)->header.domain = domain;
+ DB_OBJ(res)->header.impl_flags = 0;
+ DB_OBJ(res)->range = range;
+ 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_FALSE);
+ res = NULL;
+ } else {
+ grn_obj_touch(ctx, res, NULL);
+ }
+ }
+exit :
+ if (!res && id) { grn_obj_delete_by_id(ctx, db, id, GRN_TRUE); }
+ GRN_API_RETURN(res);
+}
+
+grn_obj *
+grn_column_open(grn_ctx *ctx, grn_obj *table,
+ const char *name, unsigned int name_size,
+ const char *path, grn_obj *type)
+{
+ grn_id domain;
+ grn_obj *res = NULL;
+ grn_db *s;
+ char fullname[GRN_TABLE_MAX_KEY_SIZE];
+ GRN_API_ENTER;
+ if (!table || !type || !name || !name_size) {
+ ERR(GRN_INVALID_ARGUMENT, "missing type or name");
+ goto exit;
+ }
+ s = (grn_db *)DB_OBJ(table)->db;
+ if (!GRN_DB_P(s)) {
+ ERR(GRN_INVALID_ARGUMENT, "invalid db assigned");
+ goto exit;
+ }
+ if (grn_db_check_name(ctx, name, name_size)) {
+ GRN_DB_CHECK_NAME_ERR("[column][open]", 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) {
+ ERR(GRN_INVALID_ARGUMENT, "too long column name");
+ goto exit;
+ }
+ fullname[len] = GRN_DB_DELIMITER;
+ grn_memcpy(fullname + len + 1, name, name_size);
+ name_size += len + 1;
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "todo : not supported yet");
+ goto exit;
+ }
+ res = grn_ctx_get(ctx, fullname, name_size);
+ if (res) {
+ const char *path2 = grn_obj_path(ctx, res);
+ if (path && (!path2 || strcmp(path, path2))) { goto exit; }
+ } else if (path) {
+ uint32_t dbtype = grn_io_detect_type(ctx, path);
+ if (!dbtype) { goto exit; }
+ switch (dbtype) {
+ case GRN_COLUMN_VAR_SIZE :
+ res = (grn_obj *)grn_ja_open(ctx, path);
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ res = (grn_obj *)grn_ra_open(ctx, path);
+ break;
+ case GRN_COLUMN_INDEX :
+ res = (grn_obj *)grn_ii_open(ctx, path, table);
+ break;
+ }
+ if (res) {
+ grn_id id = grn_obj_register(ctx, (grn_obj *)s, fullname, name_size);
+ DB_OBJ(res)->header.domain = domain;
+ DB_OBJ(res)->range = DB_OBJ(type)->id;
+ res->header.flags |= GRN_OBJ_CUSTOM_NAME;
+ grn_db_obj_init(ctx, (grn_obj *)s, id, DB_OBJ(res));
+ }
+ }
+exit :
+ GRN_API_RETURN(res);
+}
+
+/*
+typedef struct {
+ grn_id id;
+ int flags;
+} grn_column_set_value_arg;
+
+static grn_rc
+default_column_set_value(grn_ctx *ctx, grn_proc_ctx *pctx, grn_obj *in, grn_obj *out)
+{
+ grn_user_data *data = grn_proc_ctx_get_local_data(pctx);
+ if (data) {
+ grn_column_set_value_arg *arg = data->ptr;
+ unsigned int value_size = in->u.p.size; //todo
+ if (!pctx->obj) { return GRN_ID_NIL; }
+ switch (pctx->obj->header.type) {
+ case GRN_COLUMN_VAR_SIZE :
+ return grn_ja_put(ctx, (grn_ja *)pctx->obj, arg->id,
+ in->u.p.ptr, value_size, 0, NULL); // todo type->flag
+ case GRN_COLUMN_FIX_SIZE :
+ if (((grn_ra *)pctx->obj)->header->element_size < value_size) {
+ ERR(GRN_INVALID_ARGUMENT, "too long value (%d)", value_size);
+ return GRN_INVALID_ARGUMENT;
+ } else {
+ void *v = grn_ra_ref(ctx, (grn_ra *)pctx->obj, arg->id);
+ if (!v) {
+ ERR(GRN_NO_MEMORY_AVAILABLE, "ra get failed");
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ grn_memcpy(v, in->u.p.ptr, value_size);
+ grn_ra_unref(ctx, (grn_ra *)pctx->obj, arg->id);
+ }
+ break;
+ case GRN_COLUMN_INDEX :
+ // todo : how??
+ break;
+ }
+ return GRN_SUCCESS;
+ } else {
+ ERR(GRN_OBJECT_CORRUPT, "grn_proc_ctx_get_local_data failed");
+ return ctx->rc;
+ }
+}
+*/
+
+/**** grn_vector ****/
+
+//#define VECTOR(obj) ((grn_vector *)obj)
+
+/*
+#define INITIAL_VECTOR_SIZE 256
+
+int
+grn_vector_delimit(grn_ctx *ctx, grn_obj *vector)
+{
+ grn_vector *v = VECTOR(vector);
+ uint32_t *offsets;
+ if (!(v->n_entries & (INITIAL_VECTOR_SIZE - 1))) {
+ offsets = GRN_REALLOC(v->offsets, sizeof(uint32_t) *
+ (v->n_entries + INITIAL_VECTOR_SIZE));
+ if (!offsets) { return -1; }
+ v->offsets = offsets;
+ }
+ v->offsets[v->n_entries] = GRN_BULK_VSIZE(vector);
+ return ++(v->n_entries);
+}
+*/
+
+static unsigned int
+grn_uvector_element_size_internal(grn_ctx *ctx, grn_obj *uvector)
+{
+ unsigned int element_size;
+
+ if (IS_WEIGHT_UVECTOR(uvector)) {
+ element_size = sizeof(weight_uvector_entry);
+ } else {
+ switch (uvector->header.domain) {
+ case GRN_DB_BOOL :
+ element_size = sizeof(grn_bool);
+ break;
+ case GRN_DB_INT8 :
+ element_size = sizeof(int8_t);
+ break;
+ case GRN_DB_UINT8 :
+ element_size = sizeof(uint8_t);
+ break;
+ case GRN_DB_INT16 :
+ element_size = sizeof(int16_t);
+ break;
+ case GRN_DB_UINT16 :
+ element_size = sizeof(uint16_t);
+ break;
+ case GRN_DB_INT32 :
+ element_size = sizeof(int32_t);
+ break;
+ case GRN_DB_UINT32 :
+ element_size = sizeof(uint32_t);
+ break;
+ case GRN_DB_INT64 :
+ element_size = sizeof(int64_t);
+ break;
+ case GRN_DB_UINT64 :
+ element_size = sizeof(uint64_t);
+ break;
+ case GRN_DB_FLOAT :
+ element_size = sizeof(double);
+ break;
+ case GRN_DB_TIME :
+ element_size = sizeof(int64_t);
+ break;
+ case GRN_DB_TOKYO_GEO_POINT :
+ case GRN_DB_WGS84_GEO_POINT :
+ element_size = sizeof(grn_geo_point);
+ break;
+ default :
+ element_size = sizeof(grn_id);
+ break;
+ }
+ }
+
+ return element_size;
+}
+
+static unsigned int
+grn_uvector_size_internal(grn_ctx *ctx, grn_obj *uvector)
+{
+ unsigned int element_size;
+
+ element_size = grn_uvector_element_size_internal(ctx, uvector);
+ return GRN_BULK_VSIZE(uvector) / element_size;
+}
+
+unsigned int
+grn_vector_size(grn_ctx *ctx, grn_obj *vector)
+{
+ unsigned int size;
+ if (!vector) {
+ ERR(GRN_INVALID_ARGUMENT, "vector is null");
+ return 0;
+ }
+ GRN_API_ENTER;
+ switch (vector->header.type) {
+ case GRN_BULK :
+ size = GRN_BULK_VSIZE(vector);
+ break;
+ case GRN_UVECTOR :
+ size = grn_uvector_size_internal(ctx, vector);
+ break;
+ case GRN_VECTOR :
+ size = vector->u.v.n_sections;
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "not vector");
+ size = 0;
+ break;
+ }
+ GRN_API_RETURN(size);
+}
+
+static grn_obj *
+grn_vector_body(grn_ctx *ctx, grn_obj *v)
+{
+ if (!v) {
+ ERR(GRN_INVALID_ARGUMENT, "invalid argument");
+ return NULL;
+ }
+ switch (v->header.type) {
+ case GRN_VECTOR :
+ if (!v->u.v.body) {
+ v->u.v.body = grn_obj_open(ctx, GRN_BULK, 0, v->header.domain);
+ }
+ return v->u.v.body;
+ case GRN_BULK :
+ case GRN_UVECTOR :
+ return v;
+ default :
+ return NULL;
+ }
+}
+
+unsigned int
+grn_vector_get_element(grn_ctx *ctx, grn_obj *vector,
+ unsigned int offset, const char **str,
+ unsigned int *weight, grn_id *domain)
+{
+ unsigned int length = 0;
+ GRN_API_ENTER;
+ if (!vector || vector->header.type != GRN_VECTOR) {
+ ERR(GRN_INVALID_ARGUMENT, "invalid vector");
+ goto exit;
+ }
+ if ((unsigned int) vector->u.v.n_sections <= offset) {
+ ERR(GRN_RANGE_ERROR, "offset out of range");
+ goto exit;
+ }
+ {
+ grn_section *vp = &vector->u.v.sections[offset];
+ grn_obj *body = grn_vector_body(ctx, vector);
+ *str = GRN_BULK_HEAD(body) + vp->offset;
+ if (weight) { *weight = vp->weight; }
+ if (domain) { *domain = vp->domain; }
+ length = vp->length;
+ }
+exit :
+ GRN_API_RETURN(length);
+}
+
+unsigned int
+grn_vector_pop_element(grn_ctx *ctx, grn_obj *vector,
+ const char **str, unsigned int *weight, grn_id *domain)
+{
+ unsigned int offset, length = 0;
+ GRN_API_ENTER;
+ if (!vector || vector->header.type != GRN_VECTOR) {
+ ERR(GRN_INVALID_ARGUMENT, "invalid vector");
+ goto exit;
+ }
+ if (!vector->u.v.n_sections) {
+ ERR(GRN_RANGE_ERROR, "offset out of range");
+ goto exit;
+ }
+ offset = --vector->u.v.n_sections;
+ {
+ grn_section *vp = &vector->u.v.sections[offset];
+ grn_obj *body = grn_vector_body(ctx, vector);
+ *str = GRN_BULK_HEAD(body) + vp->offset;
+ if (weight) { *weight = vp->weight; }
+ if (domain) { *domain = vp->domain; }
+ length = vp->length;
+ grn_bulk_truncate(ctx, body, vp->offset);
+ }
+exit :
+ GRN_API_RETURN(length);
+}
+
+#define W_SECTIONS_UNIT 8
+#define S_SECTIONS_UNIT (1 << W_SECTIONS_UNIT)
+#define M_SECTIONS_UNIT (S_SECTIONS_UNIT - 1)
+
+grn_rc
+grn_vector_delimit(grn_ctx *ctx, grn_obj *v, unsigned int weight, grn_id domain)
+{
+ if (v->header.type != GRN_VECTOR) { return GRN_INVALID_ARGUMENT; }
+ if (!(v->u.v.n_sections & M_SECTIONS_UNIT)) {
+ grn_section *vp = GRN_REALLOC(v->u.v.sections, sizeof(grn_section) *
+ (v->u.v.n_sections + S_SECTIONS_UNIT));
+ if (!vp) { return GRN_NO_MEMORY_AVAILABLE; }
+ v->u.v.sections = vp;
+ }
+ {
+ grn_obj *body = grn_vector_body(ctx, v);
+ grn_section *vp = &v->u.v.sections[v->u.v.n_sections];
+ vp->offset = v->u.v.n_sections ? vp[-1].offset + vp[-1].length : 0;
+ vp->length = GRN_BULK_VSIZE(body) - vp->offset;
+ vp->weight = weight;
+ vp->domain = domain;
+ }
+ v->u.v.n_sections++;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_vector_decode(grn_ctx *ctx, grn_obj *v, const char *data, uint32_t data_size)
+{
+ uint8_t *p = (uint8_t *)data;
+ uint8_t *pe = p + data_size;
+ uint32_t n, n0 = v->u.v.n_sections;
+ GRN_B_DEC(n, p);
+ if (((n0 + M_SECTIONS_UNIT) >> W_SECTIONS_UNIT) !=
+ ((n0 + n + M_SECTIONS_UNIT) >> W_SECTIONS_UNIT)) {
+ grn_section *vp = GRN_REALLOC(v->u.v.sections, sizeof(grn_section) *
+ ((n0 + n + M_SECTIONS_UNIT) & ~M_SECTIONS_UNIT));
+ if (!vp) { return GRN_NO_MEMORY_AVAILABLE; }
+ v->u.v.sections = vp;
+ }
+ {
+ 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 = offset + o;
+ vp->weight = 0;
+ vp->domain = 0;
+ o += l;
+ }
+ if (pe < p + o) { return GRN_INVALID_ARGUMENT; }
+ 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++) {
+ if (pe <= p) { return GRN_INVALID_ARGUMENT; }
+ GRN_B_DEC(vp->weight, p);
+ GRN_B_DEC(vp->domain, p);
+ }
+ }
+ }
+ v->u.v.n_sections += n;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_vector_add_element(grn_ctx *ctx, grn_obj *vector,
+ const char *str, unsigned int str_len,
+ unsigned int weight, grn_id domain)
+{
+ grn_obj *body;
+ GRN_API_ENTER;
+ if (!vector) {
+ ERR(GRN_INVALID_ARGUMENT, "vector is null");
+ goto exit;
+ }
+ if ((body = grn_vector_body(ctx, vector))) {
+ grn_bulk_write(ctx, body, str, str_len);
+ grn_vector_delimit(ctx, vector, weight, domain);
+ }
+exit :
+ GRN_API_RETURN(ctx->rc);
+}
+
+/*
+grn_obj *
+grn_sections_to_vector(grn_ctx *ctx, grn_obj *sections)
+{
+ grn_obj *vector = grn_vector_open(ctx, 0);
+ if (vector) {
+ grn_section *vp;
+ int i;
+ for (i = sections->u.v.n_sections, vp = sections->u.v.sections; i; i--, vp++) {
+ grn_text_benc(ctx, vector, vp->weight);
+ grn_text_benc(ctx, vector, vp->domain);
+ grn_bulk_write(ctx, vector, vp->str, vp->str_len);
+ grn_vector_delimit(ctx, vector);
+ }
+ }
+ return vector;
+}
+
+grn_obj *
+grn_vector_to_sections(grn_ctx *ctx, grn_obj *vector, grn_obj *sections)
+{
+ if (!sections) {
+ sections = grn_obj_open(ctx, GRN_VECTOR, GRN_OBJ_DO_SHALLOW_COPY, 0);
+ }
+ if (sections) {
+ int i, n = grn_vector_size(ctx, vector);
+ sections->u.v.src = vector;
+ for (i = 0; i < n; i++) {
+ unsigned int size;
+ const uint8_t *pe, *p = (uint8_t *)grn_vector_fetch(ctx, vector, i, &size);
+ if (p) {
+ grn_id domain;
+ unsigned int weight;
+ pe = p + size;
+ if (p < pe) {
+ GRN_B_DEC(weight, p);
+ if (p < pe) {
+ GRN_B_DEC(domain, p);
+ if (p <= pe) {
+ grn_vector_add(ctx, sections, (char *)p, pe - p, weight, domain);
+ }
+ }
+ }
+ }
+ }
+ }
+ return sections;
+}
+*/
+
+/**** uvector ****/
+
+unsigned int
+grn_uvector_size(grn_ctx *ctx, grn_obj *uvector)
+{
+ unsigned int size;
+
+ if (!uvector) {
+ ERR(GRN_INVALID_ARGUMENT, "uvector must not be NULL");
+ return 0;
+ }
+
+ if (uvector->header.type != GRN_UVECTOR) {
+ grn_obj type_name;
+ GRN_TEXT_INIT(&type_name, 0);
+ grn_inspect_type(ctx, &type_name, uvector->header.type);
+ ERR(GRN_INVALID_ARGUMENT, "must be GRN_UVECTOR: %.*s",
+ (int)GRN_TEXT_LEN(&type_name), GRN_TEXT_VALUE(&type_name));
+ GRN_OBJ_FIN(ctx, &type_name);
+ return 0;
+ }
+
+ GRN_API_ENTER;
+ size = grn_uvector_size_internal(ctx, uvector);
+ GRN_API_RETURN(size);
+}
+
+unsigned int
+grn_uvector_element_size(grn_ctx *ctx, grn_obj *uvector)
+{
+ unsigned int element_size;
+
+ if (!uvector) {
+ ERR(GRN_INVALID_ARGUMENT, "uvector must not be NULL");
+ return 0;
+ }
+
+ if (uvector->header.type != GRN_UVECTOR) {
+ grn_obj type_name;
+ GRN_TEXT_INIT(&type_name, 0);
+ grn_inspect_type(ctx, &type_name, uvector->header.type);
+ ERR(GRN_INVALID_ARGUMENT, "must be GRN_UVECTOR: %.*s",
+ (int)GRN_TEXT_LEN(&type_name), GRN_TEXT_VALUE(&type_name));
+ GRN_OBJ_FIN(ctx, &type_name);
+ return 0;
+ }
+
+ GRN_API_ENTER;
+ element_size = grn_uvector_element_size_internal(ctx, uvector);
+ GRN_API_RETURN(element_size);
+}
+
+grn_rc
+grn_uvector_add_element(grn_ctx *ctx, grn_obj *uvector,
+ grn_id id, unsigned int weight)
+{
+ GRN_API_ENTER;
+ if (!uvector) {
+ ERR(GRN_INVALID_ARGUMENT, "uvector is null");
+ goto exit;
+ }
+ if (IS_WEIGHT_UVECTOR(uvector)) {
+ weight_uvector_entry entry;
+ entry.id = id;
+ entry.weight = weight;
+ grn_bulk_write(ctx, uvector,
+ (const char *)&entry, sizeof(weight_uvector_entry));
+ } else {
+ grn_bulk_write(ctx, uvector,
+ (const char *)&id, sizeof(grn_id));
+ }
+exit :
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_id
+grn_uvector_get_element(grn_ctx *ctx, grn_obj *uvector,
+ unsigned int offset, unsigned int *weight)
+{
+ grn_id id = GRN_ID_NIL;
+
+ GRN_API_ENTER;
+ if (!uvector || uvector->header.type != GRN_UVECTOR) {
+ ERR(GRN_INVALID_ARGUMENT, "invalid uvector");
+ goto exit;
+ }
+
+ if (IS_WEIGHT_UVECTOR(uvector)) {
+ const weight_uvector_entry *entry;
+ const weight_uvector_entry *entries_start;
+ const weight_uvector_entry *entries_end;
+
+ entries_start = (const weight_uvector_entry *)GRN_BULK_HEAD(uvector);
+ entries_end = (const weight_uvector_entry *)GRN_BULK_CURR(uvector);
+ if (offset > entries_end - entries_start) {
+ ERR(GRN_RANGE_ERROR, "offset out of range");
+ goto exit;
+ }
+
+ entry = entries_start + offset;
+ id = entry->id;
+ if (weight) { *weight = entry->weight; }
+ } else {
+ const grn_id *ids_start;
+ const grn_id *ids_end;
+
+ ids_start = (const grn_id *)GRN_BULK_HEAD(uvector);
+ ids_end = (const grn_id *)GRN_BULK_CURR(uvector);
+ if (offset > ids_end - ids_start) {
+ ERR(GRN_RANGE_ERROR, "offset out of range");
+ goto exit;
+ }
+ id = ids_start[offset];
+ if (weight) { *weight = 0; }
+ }
+exit :
+ GRN_API_RETURN(id);
+}
+
+/**** accessor ****/
+
+static grn_accessor *
+accessor_new(grn_ctx *ctx)
+{
+ grn_accessor *res = GRN_MALLOCN(grn_accessor, 1);
+ if (res) {
+ res->header.type = GRN_ACCESSOR;
+ 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;
+}
+
+inline static grn_bool
+grn_obj_get_accessor_rset_value(grn_ctx *ctx, grn_obj *obj,
+ grn_accessor **res, uint8_t action)
+{
+ grn_bool succeeded = GRN_FALSE;
+ grn_accessor **rp;
+
+ for (rp = res; GRN_TRUE; rp = &(*rp)->next) {
+ *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) {
+ (*rp)->action = action;
+ succeeded = GRN_TRUE;
+ goto exit;
+ }
+ 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;
+ succeeded = GRN_TRUE;
+ goto exit;
+ }
+ break;
+ }
+#undef CHECK_GROUP_CALC_FLAG
+
+ switch (obj->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_HASH_KEY :
+ (*rp)->action = GRN_ACCESSOR_GET_KEY;
+ break;
+ case GRN_TABLE_NO_KEY :
+ if (!obj->header.domain) {
+ goto exit;
+ }
+ (*rp)->action = GRN_ACCESSOR_GET_VALUE;
+ break;
+ default :
+ /* lookup failed */
+ goto exit;
+ }
+ if (!(obj = grn_ctx_at(ctx, obj->header.domain))) {
+ goto exit;
+ }
+ }
+
+exit :
+ if (!succeeded) {
+ grn_obj_close(ctx, (grn_obj *)*res);
+ *res = NULL;
+ }
+
+ return succeeded;
+}
+
+static grn_obj *
+grn_obj_get_accessor(grn_ctx *ctx, grn_obj *obj, const char *name, unsigned int name_size)
+{
+ grn_accessor *res = NULL, **rp = NULL, **rp0 = NULL;
+ grn_bool is_chained = GRN_FALSE;
+ if (!obj) { return NULL; }
+ GRN_API_ENTER;
+ if (obj->header.type == GRN_ACCESSOR) {
+ is_chained = GRN_TRUE;
+ for (rp0 = (grn_accessor **)&obj; *rp0; rp0 = &(*rp0)->next) {
+ res = *rp0;
+ }
+ switch (res->action) {
+ case GRN_ACCESSOR_GET_KEY :
+ obj = grn_ctx_at(ctx, res->obj->header.domain);
+ break;
+ case GRN_ACCESSOR_GET_VALUE :
+ case GRN_ACCESSOR_GET_SCORE :
+ case GRN_ACCESSOR_GET_NSUBRECS :
+ case GRN_ACCESSOR_GET_MAX :
+ case GRN_ACCESSOR_GET_MIN :
+ case GRN_ACCESSOR_GET_SUM :
+ case GRN_ACCESSOR_GET_AVG :
+ obj = grn_ctx_at(ctx, DB_OBJ(res->obj)->range);
+ break;
+ case GRN_ACCESSOR_GET_COLUMN_VALUE :
+ obj = grn_ctx_at(ctx, DB_OBJ(res->obj)->range);
+ break;
+ case GRN_ACCESSOR_LOOKUP :
+ /* todo */
+ break;
+ case GRN_ACCESSOR_FUNCALL :
+ /* todo */
+ break;
+ }
+ }
+ if (!obj) {
+ res = NULL;
+ goto exit;
+ }
+ {
+ size_t len;
+ const char *sp, *se = name + name_size;
+ if (*name == GRN_DB_DELIMITER) { name++; }
+ for (sp = name; (len = grn_charlen(ctx, sp, se)); sp += len) {
+ if (*sp == GRN_DB_DELIMITER) { break; }
+ }
+ if (!(len = sp - name)) { goto exit; }
+ if (*name == GRN_DB_PSEUDO_COLUMN_PREFIX) { /* pseudo column */
+ int done = 0;
+ if (len < 2) { goto exit; }
+ switch (name[1]) {
+ case 'k' : /* key */
+ if (len != GRN_COLUMN_NAME_KEY_LEN ||
+ memcmp(name, GRN_COLUMN_NAME_KEY, GRN_COLUMN_NAME_KEY_LEN)) {
+ goto exit;
+ }
+ for (rp = &res; !done; rp = &(*rp)->next) {
+ *rp = accessor_new(ctx);
+ (*rp)->obj = obj;
+ if (GRN_TABLE_IS_MULTI_KEYS_GROUPED(obj)) {
+ (*rp)->action = GRN_ACCESSOR_GET_KEY;
+ done++;
+ break;
+ }
+ if (!(obj = grn_ctx_at(ctx, obj->header.domain))) {
+ grn_obj_close(ctx, (grn_obj *)res);
+ res = NULL;
+ goto exit;
+ }
+ switch (obj->header.type) {
+ case GRN_DB :
+ (*rp)->action = GRN_ACCESSOR_GET_KEY;
+ rp = &(*rp)->next;
+ *rp = accessor_new(ctx);
+ (*rp)->obj = obj;
+ (*rp)->action = GRN_ACCESSOR_GET_DB_OBJ;
+ done++;
+ break;
+ case GRN_TYPE :
+ (*rp)->action = GRN_ACCESSOR_GET_KEY;
+ done++;
+ break;
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_HASH_KEY :
+ (*rp)->action = GRN_ACCESSOR_GET_KEY;
+ break;
+ case GRN_TABLE_NO_KEY :
+ if (obj->header.domain) {
+ (*rp)->action = GRN_ACCESSOR_GET_VALUE;
+ break;
+ }
+ /* fallthru */
+ default :
+ /* lookup failed */
+ grn_obj_close(ctx, (grn_obj *)res);
+ res = NULL;
+ goto exit;
+ }
+ }
+ break;
+ case 'i' : /* id */
+ if (len != GRN_COLUMN_NAME_ID_LEN ||
+ memcmp(name, GRN_COLUMN_NAME_ID, GRN_COLUMN_NAME_ID_LEN)) {
+ goto exit;
+ }
+ for (rp = &res; !done; rp = &(*rp)->next) {
+ *rp = accessor_new(ctx);
+ (*rp)->obj = obj;
+ if (!obj->header.domain) {
+ (*rp)->action = GRN_ACCESSOR_GET_ID;
+ done++;
+ } else {
+ if (!(obj = grn_ctx_at(ctx, obj->header.domain))) {
+ grn_obj_close(ctx, (grn_obj *)res);
+ res = NULL;
+ goto exit;
+ }
+ switch (obj->header.type) {
+ case GRN_DB :
+ case GRN_TYPE :
+ (*rp)->action = GRN_ACCESSOR_GET_ID;
+ done++;
+ break;
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_NO_KEY :
+ (*rp)->action = GRN_ACCESSOR_GET_KEY;
+ break;
+ default :
+ /* lookup failed */
+ grn_obj_close(ctx, (grn_obj *)res);
+ res = NULL;
+ goto exit;
+ }
+ }
+ }
+ break;
+ case 'v' : /* value */
+ if (len != GRN_COLUMN_NAME_VALUE_LEN ||
+ memcmp(name, GRN_COLUMN_NAME_VALUE, GRN_COLUMN_NAME_VALUE_LEN)) {
+ goto exit;
+ }
+ for (rp = &res; !done; rp = &(*rp)->next) {
+ *rp = accessor_new(ctx);
+ (*rp)->obj = obj;
+ if (!obj->header.domain) {
+ if (DB_OBJ((*rp)->obj)->range) {
+ (*rp)->action = GRN_ACCESSOR_GET_VALUE;
+ done++;
+ } else {
+ grn_obj_close(ctx, (grn_obj *)res);
+ res = NULL;
+ goto exit;
+ }
+ done++;
+ } else {
+ if (!(obj = grn_ctx_at(ctx, obj->header.domain))) {
+ grn_obj_close(ctx, (grn_obj *)res);
+ res = NULL;
+ goto exit;
+ }
+ switch (obj->header.type) {
+ case GRN_DB :
+ case GRN_TYPE :
+ if (DB_OBJ((*rp)->obj)->range) {
+ (*rp)->action = GRN_ACCESSOR_GET_VALUE;
+ done++;
+ } else {
+ grn_obj_close(ctx, (grn_obj *)res);
+ res = NULL;
+ goto exit;
+ }
+ break;
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_NO_KEY :
+ (*rp)->action = GRN_ACCESSOR_GET_KEY;
+ break;
+ default :
+ /* lookup failed */
+ grn_obj_close(ctx, (grn_obj *)res);
+ res = NULL;
+ goto exit;
+ }
+ }
+ }
+ break;
+ case 's' : /* score, sum */
+ if (len == GRN_COLUMN_NAME_SCORE_LEN &&
+ memcmp(name, GRN_COLUMN_NAME_SCORE, GRN_COLUMN_NAME_SCORE_LEN) == 0) {
+ if (!grn_obj_get_accessor_rset_value(ctx, obj, &res,
+ GRN_ACCESSOR_GET_SCORE)) {
+ goto exit;
+ }
+ } else if (len == GRN_COLUMN_NAME_SUM_LEN &&
+ memcmp(name,
+ GRN_COLUMN_NAME_SUM,
+ GRN_COLUMN_NAME_SUM_LEN) == 0) {
+ if (!grn_obj_get_accessor_rset_value(ctx, obj, &res,
+ GRN_ACCESSOR_GET_SUM)) {
+ goto exit;
+ }
+ } else {
+ goto exit;
+ }
+ break;
+ case 'n' : /* nsubrecs */
+ if (len != GRN_COLUMN_NAME_NSUBRECS_LEN ||
+ memcmp(name,
+ GRN_COLUMN_NAME_NSUBRECS,
+ GRN_COLUMN_NAME_NSUBRECS_LEN)) {
+ goto exit;
+ }
+ if (!grn_obj_get_accessor_rset_value(ctx, obj, &res,
+ GRN_ACCESSOR_GET_NSUBRECS)) {
+ goto exit;
+ }
+ break;
+ case 'm' : /* max, min */
+ if (len == GRN_COLUMN_NAME_MAX_LEN &&
+ memcmp(name,
+ GRN_COLUMN_NAME_MAX,
+ GRN_COLUMN_NAME_MAX_LEN) == 0) {
+ if (!grn_obj_get_accessor_rset_value(ctx, obj, &res,
+ GRN_ACCESSOR_GET_MAX)) {
+ goto exit;
+ }
+ } else if (len == GRN_COLUMN_NAME_MIN_LEN &&
+ memcmp(name,
+ GRN_COLUMN_NAME_MIN,
+ GRN_COLUMN_NAME_MIN_LEN) == 0) {
+ if (!grn_obj_get_accessor_rset_value(ctx, obj, &res,
+ GRN_ACCESSOR_GET_MIN)) {
+ goto exit;
+ }
+ } else {
+ goto exit;
+ }
+ break;
+ case 'a' : /* avg */
+ if (len == GRN_COLUMN_NAME_AVG_LEN &&
+ memcmp(name,
+ GRN_COLUMN_NAME_AVG,
+ GRN_COLUMN_NAME_AVG_LEN) == 0) {
+ if (!grn_obj_get_accessor_rset_value(ctx, obj, &res,
+ GRN_ACCESSOR_GET_AVG)) {
+ goto exit;
+ }
+ } else {
+ goto exit;
+ }
+ break;
+ default :
+ res = NULL;
+ goto exit;
+ }
+ } else {
+ /* if obj->header.type == GRN_TYPE ... lookup table */
+ for (rp = &res; ; rp = &(*rp)->next) {
+ grn_obj *column = grn_obj_column_(ctx, obj, name, len);
+ if (column) {
+ *rp = accessor_new(ctx);
+ (*rp)->obj = column;
+ /*
+ switch (column->header.type) {
+ case GRN_COLUMN_VAR_SIZE :
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ break;
+ case GRN_COLUMN_INDEX :
+ break;
+ }
+ */
+ (*rp)->action = GRN_ACCESSOR_GET_COLUMN_VALUE;
+ break;
+ } else {
+ grn_id next_obj_id;
+ next_obj_id = obj->header.domain;
+ if (!next_obj_id) {
+ // ERR(GRN_INVALID_ARGUMENT, "no such column: <%s>", name);
+ if (!is_chained) {
+ grn_obj_close(ctx, (grn_obj *)res);
+ }
+ res = NULL;
+ goto exit;
+ }
+ *rp = accessor_new(ctx);
+ (*rp)->obj = obj;
+ obj = grn_ctx_at(ctx, next_obj_id);
+ if (!obj) {
+ grn_obj_close(ctx, (grn_obj *)res);
+ res = NULL;
+ goto exit;
+ }
+ switch (obj->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_NO_KEY :
+ (*rp)->action = GRN_ACCESSOR_GET_KEY;
+ break;
+ default :
+ /* lookup failed */
+ grn_obj_close(ctx, (grn_obj *)res);
+ res = NULL;
+ goto exit;
+ }
+ }
+ }
+ }
+ if (sp != se) {
+ if (!grn_obj_get_accessor(ctx, (grn_obj *)res, sp, se - sp)) {
+ if (!is_chained) {
+ grn_obj_close(ctx, (grn_obj *)res);
+ res = NULL;
+ goto exit;
+ }
+ }
+ }
+ }
+ if (rp0) { *rp0 = res; }
+ exit :
+ GRN_API_RETURN((grn_obj *)res);
+}
+
+inline static grn_bool
+grn_column_is_vector(grn_ctx *ctx, grn_obj *column)
+{
+ grn_obj_flags type;
+
+ if (column->header.type != GRN_COLUMN_VAR_SIZE) {
+ return GRN_FALSE;
+ }
+
+ type = column->header.flags & GRN_OBJ_COLUMN_TYPE_MASK;
+ return type == GRN_OBJ_COLUMN_VECTOR;
+}
+
+inline static grn_bool
+grn_column_is_index(grn_ctx *ctx, grn_obj *column)
+{
+ grn_obj_flags type;
+
+ if (column->header.type == GRN_ACCESSOR) {
+ grn_accessor *a;
+ for (a = (grn_accessor *)column; a; a = a->next) {
+ if (a->next) {
+ continue;
+ }
+ if (a->action != GRN_ACCESSOR_GET_COLUMN_VALUE) {
+ return GRN_FALSE;
+ }
+
+ column = a->obj;
+ }
+ }
+
+ if (column->header.type != GRN_COLUMN_INDEX) {
+ return GRN_FALSE;
+ }
+
+ type = column->header.flags & GRN_OBJ_COLUMN_TYPE_MASK;
+ return type == GRN_OBJ_COLUMN_INDEX;
+}
+
+inline static void
+grn_obj_get_range_info(grn_ctx *ctx, grn_obj *obj,
+ grn_id *range_id, grn_obj_flags *range_flags)
+{
+ 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;
+ }
+ } else if (obj->header.type == GRN_ACCESSOR) {
+ grn_accessor *a;
+ for (a = (grn_accessor *)obj; a; a = a->next) {
+ switch (a->action) {
+ case GRN_ACCESSOR_GET_ID :
+ *range_id = GRN_DB_UINT32;
+ break;
+ case GRN_ACCESSOR_GET_VALUE :
+ if (GRN_DB_OBJP(a->obj)) {
+ *range_id = DB_OBJ(a->obj)->range;
+ }
+ break;
+ case GRN_ACCESSOR_GET_SCORE :
+ *range_id = GRN_DB_FLOAT;
+ break;
+ case GRN_ACCESSOR_GET_NSUBRECS :
+ *range_id = GRN_DB_INT32;
+ break;
+ case GRN_ACCESSOR_GET_MAX :
+ case GRN_ACCESSOR_GET_MIN :
+ case GRN_ACCESSOR_GET_SUM :
+ *range_id = GRN_DB_INT64;
+ break;
+ case GRN_ACCESSOR_GET_AVG :
+ *range_id = GRN_DB_FLOAT;
+ break;
+ case GRN_ACCESSOR_GET_COLUMN_VALUE :
+ grn_obj_get_range_info(ctx, a->obj, range_id, range_flags);
+ break;
+ case GRN_ACCESSOR_GET_KEY :
+ if (GRN_DB_OBJP(a->obj)) { *range_id = DB_OBJ(a->obj)->header.domain; }
+ break;
+ default :
+ if (GRN_DB_OBJP(a->obj)) { *range_id = DB_OBJ(a->obj)->range; }
+ break;
+ }
+ }
+ }
+}
+
+grn_id
+grn_obj_get_range(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_id range_id = GRN_ID_NIL;
+ grn_obj_flags range_flags = 0;
+
+ grn_obj_get_range_info(ctx, obj, &range_id, &range_flags);
+
+ return range_id;
+}
+
+int
+grn_obj_is_persistent(grn_ctx *ctx, grn_obj *obj)
+{
+ int res = 0;
+ if (GRN_DB_OBJP(obj)) {
+ res = IS_TEMP(obj) ? 0 : 1;
+ } else if (obj->header.type == GRN_ACCESSOR) {
+ grn_accessor *a;
+ for (a = (grn_accessor *)obj; a; a = a->next) {
+ switch (a->action) {
+ case GRN_ACCESSOR_GET_SCORE :
+ case GRN_ACCESSOR_GET_NSUBRECS :
+ case GRN_ACCESSOR_GET_MAX :
+ case GRN_ACCESSOR_GET_MIN :
+ case GRN_ACCESSOR_GET_SUM :
+ case GRN_ACCESSOR_GET_AVG :
+ res = 0;
+ break;
+ case GRN_ACCESSOR_GET_ID :
+ case GRN_ACCESSOR_GET_VALUE :
+ case GRN_ACCESSOR_GET_COLUMN_VALUE :
+ case GRN_ACCESSOR_GET_KEY :
+ if (GRN_DB_OBJP(a->obj)) { res = IS_TEMP(obj) ? 0 : 1; }
+ break;
+ default :
+ if (GRN_DB_OBJP(a->obj)) { res = IS_TEMP(obj) ? 0 : 1; }
+ break;
+ }
+ }
+ }
+ return res;
+}
+
+#define SRC2RECORD() do {\
+ grn_obj *table = grn_ctx_at(ctx, dest->header.domain);\
+ if (GRN_OBJ_TABLEP(table)) {\
+ grn_obj *p_key = src;\
+ grn_id id;\
+ if (table->header.type != GRN_TABLE_NO_KEY) {\
+ grn_obj key;\
+ GRN_OBJ_INIT(&key, GRN_BULK, 0, table->header.domain);\
+ if (src->header.domain != table->header.domain) {\
+ rc = grn_obj_cast(ctx, src, &key, GRN_TRUE);\
+ p_key = &key;\
+ }\
+ 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 {\
+ GRN_RECORD_SET(ctx, dest, GRN_ID_NIL);\
+ }\
+ }\
+ GRN_OBJ_FIN(ctx, &key);\
+ } else {\
+ grn_obj record_id;\
+ GRN_UINT32_INIT(&record_id, 0);\
+ 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 {\
+ rc = GRN_FUNCTION_NOT_IMPLEMENTED;\
+ }\
+} while (0)
+
+inline static grn_rc
+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;
+
+ switch (dest->header.domain) {
+ case GRN_DB_BOOL :
+ GRN_BOOL_SET(ctx, dest, GRN_BOOL_VALUE(src));
+ break;
+ case GRN_DB_INT8 :
+ GRN_INT8_SET(ctx, dest, GRN_BOOL_VALUE(src));
+ break;
+ case GRN_DB_UINT8 :
+ GRN_UINT8_SET(ctx, dest, GRN_BOOL_VALUE(src));
+ break;
+ case GRN_DB_INT16 :
+ GRN_INT16_SET(ctx, dest, GRN_BOOL_VALUE(src));
+ break;
+ case GRN_DB_UINT16 :
+ GRN_UINT16_SET(ctx, dest, GRN_BOOL_VALUE(src));
+ break;
+ case GRN_DB_INT32 :
+ GRN_INT32_SET(ctx, dest, GRN_BOOL_VALUE(src));
+ break;
+ case GRN_DB_UINT32 :
+ GRN_UINT32_SET(ctx, dest, GRN_BOOL_VALUE(src));
+ break;
+ case GRN_DB_INT64 :
+ GRN_INT64_SET(ctx, dest, GRN_BOOL_VALUE(src));
+ break;
+ case GRN_DB_UINT64 :
+ GRN_UINT64_SET(ctx, dest, GRN_BOOL_VALUE(src));
+ break;
+ case GRN_DB_FLOAT :
+ GRN_FLOAT_SET(ctx, dest, GRN_BOOL_VALUE(src));
+ break;
+ case GRN_DB_TIME :
+ GRN_TIME_SET(ctx, dest, GRN_BOOL_VALUE(src));
+ break;
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ {
+ const char *bool_text;
+ bool_text = GRN_BOOL_VALUE(src) ? "true" : "false";
+ GRN_TEXT_PUTS(ctx, dest, bool_text);
+ }
+ break;
+ case GRN_DB_TOKYO_GEO_POINT :
+ case GRN_DB_WGS84_GEO_POINT :
+ rc = GRN_INVALID_ARGUMENT;
+ break;
+ default :
+ SRC2RECORD();
+ break;
+ }
+ return rc;
+}
+
+#define NUM2DEST(getvalue,totext,tobool,totime,tofloat)\
+ switch (dest->header.domain) {\
+ case GRN_DB_BOOL :\
+ tobool(ctx, dest, getvalue(src));\
+ break;\
+ case GRN_DB_INT8 :\
+ GRN_INT8_SET(ctx, dest, getvalue(src));\
+ break;\
+ case GRN_DB_UINT8 :\
+ GRN_UINT8_SET(ctx, dest, getvalue(src));\
+ break;\
+ case GRN_DB_INT16 :\
+ GRN_INT16_SET(ctx, dest, getvalue(src));\
+ break;\
+ case GRN_DB_UINT16 :\
+ GRN_UINT16_SET(ctx, dest, getvalue(src));\
+ break;\
+ case GRN_DB_INT32 :\
+ GRN_INT32_SET(ctx, dest, getvalue(src));\
+ break;\
+ case GRN_DB_UINT32 :\
+ GRN_UINT32_SET(ctx, dest, getvalue(src));\
+ break;\
+ case GRN_DB_TIME :\
+ totime(ctx, dest, getvalue(src));\
+ break;\
+ case GRN_DB_INT64 :\
+ GRN_INT64_SET(ctx, dest, getvalue(src));\
+ break;\
+ case GRN_DB_UINT64 :\
+ GRN_UINT64_SET(ctx, dest, getvalue(src));\
+ break;\
+ case GRN_DB_FLOAT :\
+ tofloat(ctx, dest, getvalue(src));\
+ break;\
+ case GRN_DB_SHORT_TEXT :\
+ case GRN_DB_TEXT :\
+ case GRN_DB_LONG_TEXT :\
+ totext(ctx, dest, getvalue(src));\
+ break;\
+ case GRN_DB_TOKYO_GEO_POINT :\
+ case GRN_DB_WGS84_GEO_POINT :\
+ rc = GRN_INVALID_ARGUMENT;\
+ break;\
+ default :\
+ SRC2RECORD();\
+ break;\
+ }
+
+#define TEXT2DEST(type,tonum,setvalue) do {\
+ const char *cur, *str = GRN_TEXT_VALUE(src);\
+ const char *str_end = GRN_BULK_CURR(src);\
+ type i = tonum(str, str_end, &cur);\
+ if (cur == str_end) {\
+ setvalue(ctx, dest, i);\
+ } else if (cur != str) {\
+ const char *rest;\
+ grn_obj buf;\
+ GRN_VOID_INIT(&buf);\
+ rc = grn_aton(ctx, str, str_end, &rest, &buf);\
+ if (!rc) {\
+ rc = grn_obj_cast(ctx, &buf, dest, add_record_if_not_exist);\
+ }\
+ GRN_OBJ_FIN(ctx, &buf);\
+ } else {\
+ rc = GRN_INVALID_ARGUMENT;\
+ }\
+} while (0)
+
+#define NUM2BOOL(ctx, dest, value) GRN_BOOL_SET(ctx, dest, value != 0)
+#define FLOAT2BOOL(ctx, dest, value) do {\
+ double value_ = value;\
+ GRN_BOOL_SET(ctx, dest, value_ < -DBL_EPSILON || DBL_EPSILON < value_);\
+} while (0)
+
+#define NUM2TIME(ctx, dest, value)\
+ 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) 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);
+#define TIME2FLOAT(ctx, dest, value)\
+ GRN_FLOAT_SET(ctx, dest, (double)(value) / GRN_TIME_USEC_PER_SEC);
+#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 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, add_record_if_not_exist);
+ break;
+ case GRN_DB_INT8 :
+ NUM2DEST(GRN_INT8_VALUE, grn_text_itoa, NUM2BOOL, NUM2TIME, NUM2FLOAT);
+ break;
+ case GRN_DB_UINT8 :
+ NUM2DEST(GRN_UINT8_VALUE, grn_text_lltoa, NUM2BOOL, NUM2TIME, NUM2FLOAT);
+ break;
+ case GRN_DB_INT16 :
+ NUM2DEST(GRN_INT16_VALUE, grn_text_itoa, NUM2BOOL, NUM2TIME, NUM2FLOAT);
+ break;
+ case GRN_DB_UINT16 :
+ NUM2DEST(GRN_UINT16_VALUE, grn_text_lltoa, NUM2BOOL, NUM2TIME, NUM2FLOAT);
+ break;
+ case GRN_DB_INT32 :
+ NUM2DEST(GRN_INT32_VALUE, grn_text_itoa, NUM2BOOL, NUM2TIME, NUM2FLOAT);
+ break;
+ case GRN_DB_UINT32 :
+ NUM2DEST(GRN_UINT32_VALUE, grn_text_lltoa, NUM2BOOL, NUM2TIME, NUM2FLOAT);
+ break;
+ case GRN_DB_INT64 :
+ NUM2DEST(GRN_INT64_VALUE, grn_text_lltoa, NUM2BOOL, NUM2TIME, NUM2FLOAT);
+ break;
+ case GRN_DB_TIME :
+ NUM2DEST(GRN_TIME_VALUE, grn_text_lltoa, NUM2BOOL, TIME2TIME, TIME2FLOAT);
+ break;
+ case GRN_DB_UINT64 :
+ NUM2DEST(GRN_UINT64_VALUE, grn_text_lltoa, NUM2BOOL, NUM2TIME, NUM2FLOAT);
+ break;
+ case GRN_DB_FLOAT :
+ NUM2DEST(GRN_FLOAT_VALUE, grn_text_ftoa, FLOAT2BOOL, FLOAT2TIME,
+ FLOAT2FLOAT);
+ break;
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ switch (dest->header.domain) {
+ case GRN_DB_BOOL :
+ GRN_BOOL_SET(ctx, dest, GRN_TEXT_LEN(src) > 0);
+ break;
+ case GRN_DB_INT8 :
+ TEXT2DEST(int8_t, grn_atoi8, GRN_INT8_SET);
+ break;
+ case GRN_DB_UINT8 :
+ TEXT2DEST(uint8_t, grn_atoui8, GRN_UINT8_SET);
+ break;
+ case GRN_DB_INT16 :
+ TEXT2DEST(int16_t, grn_atoi16, GRN_INT16_SET);
+ break;
+ case GRN_DB_UINT16 :
+ TEXT2DEST(uint16_t, grn_atoui16, GRN_UINT16_SET);
+ break;
+ case GRN_DB_INT32 :
+ TEXT2DEST(int32_t, grn_atoi, GRN_INT32_SET);
+ break;
+ case GRN_DB_UINT32 :
+ TEXT2DEST(uint32_t, grn_atoui, GRN_UINT32_SET);
+ break;
+ case GRN_DB_TIME :
+ {
+ grn_timeval v;
+ int len = GRN_TEXT_LEN(src);
+ char *str = GRN_TEXT_VALUE(src);
+ if (grn_str2timeval(str, len, &v)) {
+ double d;
+ char *end;
+ grn_obj buf;
+ GRN_TEXT_INIT(&buf, 0);
+ GRN_TEXT_PUT(ctx, &buf, str, len);
+ GRN_TEXT_PUTC(ctx, &buf, '\0');
+ errno = 0;
+ d = strtod(GRN_TEXT_VALUE(&buf), &end);
+ if (!errno && end + 1 == GRN_BULK_CURR(&buf)) {
+ v.tv_sec = d;
+ v.tv_nsec = ((d - v.tv_sec) * GRN_TIME_NSEC_PER_SEC);
+ } else {
+ rc = GRN_INVALID_ARGUMENT;
+ }
+ GRN_OBJ_FIN(ctx, &buf);
+ }
+ GRN_TIME_SET(ctx, dest,
+ GRN_TIME_PACK((int64_t)v.tv_sec,
+ GRN_TIME_NSEC_TO_USEC(v.tv_nsec)));
+ }
+ break;
+ case GRN_DB_INT64 :
+ TEXT2DEST(int64_t, grn_atoll, GRN_INT64_SET);
+ break;
+ case GRN_DB_UINT64 :
+ TEXT2DEST(int64_t, grn_atoll, GRN_UINT64_SET);
+ break;
+ case GRN_DB_FLOAT :
+ {
+ double d;
+ char *end;
+ grn_obj buf;
+ GRN_TEXT_INIT(&buf, 0);
+ GRN_TEXT_PUT(ctx, &buf, GRN_TEXT_VALUE(src), GRN_TEXT_LEN(src));
+ GRN_TEXT_PUTC(ctx, &buf, '\0');
+ errno = 0;
+ d = strtod(GRN_TEXT_VALUE(&buf), &end);
+ if (!errno && end + 1 == GRN_BULK_CURR(&buf)) {
+ GRN_FLOAT_SET(ctx, dest, d);
+ } else {
+ rc = GRN_INVALID_ARGUMENT;
+ }
+ GRN_OBJ_FIN(ctx, &buf);
+ }
+ break;
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ GRN_TEXT_PUT(ctx, dest, GRN_TEXT_VALUE(src), GRN_TEXT_LEN(src));
+ break;
+ case GRN_DB_TOKYO_GEO_POINT :
+ case GRN_DB_WGS84_GEO_POINT :
+ {
+ int latitude, longitude;
+ double degree;
+ const char *cur, *str = GRN_TEXT_VALUE(src);
+ const char *str_end = GRN_BULK_CURR(src);
+ if (str == str_end) {
+ GRN_GEO_POINT_SET(ctx, dest, 0, 0);
+ } else {
+ char *end;
+ grn_obj buf, *buf_p = NULL;
+ latitude = grn_atoi(str, str_end, &cur);
+ if (cur < str_end && cur[0] == '.') {
+ GRN_TEXT_INIT(&buf, 0);
+ GRN_TEXT_PUT(ctx, &buf, str, GRN_TEXT_LEN(src));
+ GRN_TEXT_PUTC(ctx, &buf, '\0');
+ buf_p = &buf;
+ errno = 0;
+ degree = strtod(GRN_TEXT_VALUE(buf_p), &end);
+ if (errno) {
+ rc = GRN_INVALID_ARGUMENT;
+ } else {
+ latitude = GRN_GEO_DEGREE2MSEC(degree);
+ cur = str + (end - GRN_TEXT_VALUE(buf_p));
+ }
+ }
+ if (!rc && (cur[0] == 'x' || cur[0] == ',') && cur + 1 < str_end) {
+ const char *c = cur + 1;
+ longitude = grn_atoi(c, str_end, &cur);
+ if (cur < str_end && cur[0] == '.') {
+ if (!buf_p) {
+ GRN_TEXT_INIT(&buf, 0);
+ GRN_TEXT_PUT(ctx, &buf, str, GRN_TEXT_LEN(src));
+ GRN_TEXT_PUTC(ctx, &buf, '\0');
+ buf_p = &buf;
+ }
+ errno = 0;
+ degree = strtod(GRN_TEXT_VALUE(buf_p) + (c - str), &end);
+ if (errno) {
+ rc = GRN_INVALID_ARGUMENT;
+ } else {
+ longitude = GRN_GEO_DEGREE2MSEC(degree);
+ cur = str + (end - GRN_TEXT_VALUE(buf_p));
+ }
+ }
+ if (!rc && cur == str_end) {
+ if ((GRN_GEO_MIN_LATITUDE <= latitude &&
+ latitude <= GRN_GEO_MAX_LATITUDE) &&
+ (GRN_GEO_MIN_LONGITUDE <= longitude &&
+ longitude <= GRN_GEO_MAX_LONGITUDE)) {
+ GRN_GEO_POINT_SET(ctx, dest, latitude, longitude);
+ } else {
+ rc = GRN_INVALID_ARGUMENT;
+ }
+ } else {
+ rc = GRN_INVALID_ARGUMENT;
+ }
+ } else {
+ rc = GRN_INVALID_ARGUMENT;
+ }
+ if (buf_p) { GRN_OBJ_FIN(ctx, buf_p); }
+ }
+ }
+ break;
+ default :
+ SRC2RECORD();
+ break;
+ }
+ break;
+ case GRN_DB_TOKYO_GEO_POINT :
+ case GRN_DB_WGS84_GEO_POINT :
+ if (src->header.domain == dest->header.domain) {
+ GRN_TEXT_PUT(ctx, dest, GRN_TEXT_VALUE(src), GRN_TEXT_LEN(src));
+ } else {
+ int latitude, longitude;
+ double latitude_in_degree, longitude_in_degree;
+ GRN_GEO_POINT_VALUE(src, latitude, longitude);
+ latitude_in_degree = GRN_GEO_MSEC2DEGREE(latitude);
+ longitude_in_degree = GRN_GEO_MSEC2DEGREE(longitude);
+ /* TokyoGeoPoint <-> WGS84GeoPoint is based on
+ http://www.jalan.net/jw/jwp0200/jww0203.do
+
+ jx: longitude in degree in Tokyo Geodetic System.
+ jy: latitude in degree in Tokyo Geodetic System.
+ wx: longitude in degree in WGS 84.
+ wy: latitude in degree in WGS 84.
+
+ jy = wy * 1.000106961 - wx * 0.000017467 - 0.004602017
+ jx = wx * 1.000083049 + wy * 0.000046047 - 0.010041046
+
+ wy = jy - jy * 0.00010695 + jx * 0.000017464 + 0.0046017
+ wx = jx - jy * 0.000046038 - jx * 0.000083043 + 0.010040
+ */
+ if (dest->header.domain == GRN_DB_TOKYO_GEO_POINT) {
+ double wgs84_latitude_in_degree = latitude_in_degree;
+ double wgs84_longitude_in_degree = longitude_in_degree;
+ int tokyo_latitude, tokyo_longitude;
+ double tokyo_latitude_in_degree, tokyo_longitude_in_degree;
+ tokyo_latitude_in_degree =
+ wgs84_latitude_in_degree * 1.000106961 -
+ wgs84_longitude_in_degree * 0.000017467 -
+ 0.004602017;
+ tokyo_longitude_in_degree =
+ wgs84_longitude_in_degree * 1.000083049 +
+ wgs84_latitude_in_degree * 0.000046047 -
+ 0.010041046;
+ tokyo_latitude = GRN_GEO_DEGREE2MSEC(tokyo_latitude_in_degree);
+ tokyo_longitude = GRN_GEO_DEGREE2MSEC(tokyo_longitude_in_degree);
+ GRN_GEO_POINT_SET(ctx, dest, tokyo_latitude, tokyo_longitude);
+ } else {
+ double tokyo_latitude_in_degree = latitude_in_degree;
+ double tokyo_longitude_in_degree = longitude_in_degree;
+ int wgs84_latitude, wgs84_longitude;
+ double wgs84_latitude_in_degree, wgs84_longitude_in_degree;
+ wgs84_latitude_in_degree =
+ tokyo_latitude_in_degree -
+ tokyo_latitude_in_degree * 0.00010695 +
+ tokyo_longitude_in_degree * 0.000017464 +
+ 0.0046017;
+ wgs84_longitude_in_degree =
+ tokyo_longitude_in_degree -
+ tokyo_latitude_in_degree * 0.000046038 -
+ tokyo_longitude_in_degree * 0.000083043 +
+ 0.010040;
+ wgs84_latitude = GRN_GEO_DEGREE2MSEC(wgs84_latitude_in_degree);
+ wgs84_longitude = GRN_GEO_DEGREE2MSEC(wgs84_longitude_in_degree);
+ GRN_GEO_POINT_SET(ctx, dest, wgs84_latitude, wgs84_longitude);
+ }
+ }
+ break;
+ case GRN_VOID :
+ rc = grn_obj_reinit(ctx, dest, dest->header.domain, dest->header.flags);
+ break;
+ default :
+ 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;
+}
+
+const char *
+grn_accessor_get_value_(grn_ctx *ctx, grn_accessor *a, grn_id id, uint32_t *size)
+{
+ const char *value = NULL;
+ for (;;) {
+ switch (a->action) {
+ case GRN_ACCESSOR_GET_ID :
+ value = (const char *)(uintptr_t)id;
+ *size = GRN_OBJ_GET_VALUE_IMD;
+ break;
+ case GRN_ACCESSOR_GET_KEY :
+ value = _grn_table_key(ctx, a->obj, id, size);
+ break;
+ case GRN_ACCESSOR_GET_VALUE :
+ value = grn_obj_get_value_(ctx, a->obj, id, size);
+ break;
+ case GRN_ACCESSOR_GET_SCORE :
+ if ((value = grn_obj_get_value_(ctx, a->obj, id, size))) {
+ value = (const char *)&((grn_rset_recinfo *)value)->score;
+ *size = sizeof(double);
+ }
+ break;
+ case GRN_ACCESSOR_GET_NSUBRECS :
+ if ((value = grn_obj_get_value_(ctx, a->obj, id, size))) {
+ value = (const char *)&((grn_rset_recinfo *)value)->n_subrecs;
+ *size = sizeof(int);
+ }
+ break;
+ case GRN_ACCESSOR_GET_MAX :
+ if ((value = grn_obj_get_value_(ctx, a->obj, id, size))) {
+ value =
+ (const char *)grn_rset_recinfo_get_max_(ctx,
+ (grn_rset_recinfo *)value,
+ a->obj);
+ *size = GRN_RSET_MAX_SIZE;
+ }
+ break;
+ case GRN_ACCESSOR_GET_MIN :
+ if ((value = grn_obj_get_value_(ctx, a->obj, id, size))) {
+ value =
+ (const char *)grn_rset_recinfo_get_min_(ctx,
+ (grn_rset_recinfo *)value,
+ a->obj);
+ *size = GRN_RSET_MIN_SIZE;
+ }
+ break;
+ case GRN_ACCESSOR_GET_SUM :
+ if ((value = grn_obj_get_value_(ctx, a->obj, id, size))) {
+ value =
+ (const char *)grn_rset_recinfo_get_sum_(ctx,
+ (grn_rset_recinfo *)value,
+ a->obj);
+ *size = GRN_RSET_SUM_SIZE;
+ }
+ break;
+ case GRN_ACCESSOR_GET_AVG :
+ if ((value = grn_obj_get_value_(ctx, a->obj, id, size))) {
+ value =
+ (const char *)grn_rset_recinfo_get_avg_(ctx,
+ (grn_rset_recinfo *)value,
+ a->obj);
+ *size = GRN_RSET_AVG_SIZE;
+ }
+ break;
+ case GRN_ACCESSOR_GET_COLUMN_VALUE :
+ /* todo : support vector */
+ value = grn_obj_get_value_(ctx, a->obj, id, size);
+ break;
+ case GRN_ACCESSOR_GET_DB_OBJ :
+ value = _grn_table_key(ctx, ((grn_db *)ctx->impl->db)->keys, id, size);
+ break;
+ case GRN_ACCESSOR_LOOKUP :
+ /* todo */
+ break;
+ case GRN_ACCESSOR_FUNCALL :
+ /* todo */
+ break;
+ }
+ if (value && (a = a->next)) {
+ id = *((grn_id *)value);
+ } else {
+ break;
+ }
+ }
+ return value;
+}
+
+static grn_obj *
+grn_accessor_get_value(grn_ctx *ctx, grn_accessor *a, grn_id id, grn_obj *value)
+{
+ uint32_t vs = 0;
+ uint32_t size0;
+ void *vp = NULL;
+ if (!value) {
+ if (!(value = grn_obj_open(ctx, GRN_BULK, 0, 0))) { return NULL; }
+ } else {
+ value->header.type = GRN_BULK;
+ }
+ size0 = GRN_BULK_VSIZE(value);
+ for (;;) {
+ grn_bulk_truncate(ctx, value, size0);
+ switch (a->action) {
+ case GRN_ACCESSOR_GET_ID :
+ GRN_UINT32_PUT(ctx, value, id);
+ value->header.domain = GRN_DB_UINT32;
+ vp = GRN_BULK_HEAD(value) + size0;
+ vs = GRN_BULK_VSIZE(value) - size0;
+ break;
+ case GRN_ACCESSOR_GET_KEY :
+ if (!a->next && GRN_TABLE_IS_MULTI_KEYS_GROUPED(a->obj)) {
+ grn_obj_ensure_vector(ctx, value);
+ if (id) {
+ grn_obj raw_vector;
+ GRN_TEXT_INIT(&raw_vector, 0);
+ grn_table_get_key2(ctx, a->obj, id, &raw_vector);
+ grn_vector_decode(ctx, value,
+ GRN_BULK_HEAD(&raw_vector),
+ GRN_BULK_VSIZE(&raw_vector));
+ GRN_OBJ_FIN(ctx, &raw_vector);
+ }
+ vp = NULL;
+ vs = 0;
+ } else {
+ if (id) {
+ grn_table_get_key2(ctx, a->obj, id, value);
+ vp = GRN_BULK_HEAD(value) + size0;
+ vs = GRN_BULK_VSIZE(value) - size0;
+ } else {
+ vp = NULL;
+ vs = 0;
+ }
+ value->header.domain = a->obj->header.domain;
+ }
+ break;
+ case GRN_ACCESSOR_GET_VALUE :
+ grn_obj_get_value(ctx, a->obj, id, value);
+ vp = GRN_BULK_HEAD(value) + size0;
+ vs = GRN_BULK_VSIZE(value) - size0;
+ break;
+ case GRN_ACCESSOR_GET_SCORE :
+ if (id) {
+ grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs);
+ GRN_FLOAT_PUT(ctx, value, ri->score);
+ } else {
+ GRN_FLOAT_PUT(ctx, value, 0.0);
+ }
+ value->header.domain = GRN_DB_FLOAT;
+ break;
+ case GRN_ACCESSOR_GET_NSUBRECS :
+ if (id) {
+ grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs);
+ GRN_INT32_PUT(ctx, value, ri->n_subrecs);
+ } else {
+ GRN_INT32_PUT(ctx, value, 0);
+ }
+ value->header.domain = GRN_DB_INT32;
+ break;
+ case GRN_ACCESSOR_GET_MAX :
+ if (id) {
+ grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs);
+ int64_t max;
+ max = grn_rset_recinfo_get_max(ctx, ri, a->obj);
+ GRN_INT64_PUT(ctx, value, max);
+ } else {
+ GRN_INT64_PUT(ctx, value, 0);
+ }
+ value->header.domain = GRN_DB_INT64;
+ break;
+ case GRN_ACCESSOR_GET_MIN :
+ if (id) {
+ grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs);
+ int64_t min;
+ min = grn_rset_recinfo_get_min(ctx, ri, a->obj);
+ GRN_INT64_PUT(ctx, value, min);
+ } else {
+ GRN_INT64_PUT(ctx, value, 0);
+ }
+ value->header.domain = GRN_DB_INT64;
+ break;
+ case GRN_ACCESSOR_GET_SUM :
+ if (id) {
+ grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs);
+ int64_t sum;
+ sum = grn_rset_recinfo_get_sum(ctx, ri, a->obj);
+ GRN_INT64_PUT(ctx, value, sum);
+ } else {
+ GRN_INT64_PUT(ctx, value, 0);
+ }
+ value->header.domain = GRN_DB_INT64;
+ break;
+ case GRN_ACCESSOR_GET_AVG :
+ if (id) {
+ grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs);
+ double avg;
+ avg = grn_rset_recinfo_get_avg(ctx, ri, a->obj);
+ GRN_FLOAT_PUT(ctx, value, avg);
+ } else {
+ GRN_FLOAT_PUT(ctx, value, 0.0);
+ }
+ value->header.domain = GRN_DB_FLOAT;
+ break;
+ case GRN_ACCESSOR_GET_COLUMN_VALUE :
+ /* todo : support vector */
+ grn_obj_get_value(ctx, a->obj, id, value);
+ vp = GRN_BULK_HEAD(value) + size0;
+ vs = GRN_BULK_VSIZE(value) - size0;
+ break;
+ case GRN_ACCESSOR_GET_DB_OBJ :
+ value = grn_ctx_at(ctx, id);
+ grn_obj_close(ctx, value);
+ return value;
+ break;
+ case GRN_ACCESSOR_LOOKUP :
+ /* todo */
+ break;
+ case GRN_ACCESSOR_FUNCALL :
+ /* todo */
+ break;
+ }
+ if ((a = a->next)) {
+ if (vs > 0) {
+ id = *((grn_id *)vp);
+ } else {
+ id = GRN_ID_NIL;
+ }
+ } else {
+ break;
+ }
+ }
+ return value;
+}
+
+static grn_rc
+grn_accessor_set_value(grn_ctx *ctx, grn_accessor *a, grn_id id,
+ grn_obj *value, int flags)
+{
+ grn_rc rc = GRN_SUCCESS;
+ if (!value) { value = grn_obj_open(ctx, GRN_BULK, 0, 0); }
+ if (value) {
+ grn_obj buf;
+ void *vp = NULL;
+ GRN_TEXT_INIT(&buf, 0);
+ for (;;) {
+ GRN_BULK_REWIND(&buf);
+ switch (a->action) {
+ case GRN_ACCESSOR_GET_KEY :
+ grn_table_get_key2(ctx, a->obj, id, &buf);
+ vp = GRN_BULK_HEAD(&buf);
+ break;
+ case GRN_ACCESSOR_GET_VALUE :
+ if (a->next) {
+ grn_obj_get_value(ctx, a->obj, id, &buf);
+ vp = GRN_BULK_HEAD(&buf);
+ } else {
+ rc = grn_obj_set_value(ctx, a->obj, id, value, flags);
+ }
+ break;
+ case GRN_ACCESSOR_GET_SCORE :
+ {
+ grn_rset_recinfo *ri;
+ if (a->next) {
+ grn_obj_get_value(ctx, a->obj, id, &buf);
+ ri = (grn_rset_recinfo *)GRN_BULK_HEAD(&buf);
+ vp = &ri->score;
+ } else {
+ uint32_t size;
+ if ((ri = (grn_rset_recinfo *) grn_obj_get_value_(ctx, a->obj, id, &size))) {
+ // todo : flags support
+ if (value->header.domain == GRN_DB_FLOAT) {
+ ri->score = GRN_FLOAT_VALUE(value);
+ } else {
+ grn_obj buf;
+ GRN_FLOAT_INIT(&buf, 0);
+ grn_obj_cast(ctx, value, &buf, GRN_FALSE);
+ ri->score = GRN_FLOAT_VALUE(&buf);
+ GRN_OBJ_FIN(ctx, &buf);
+ }
+ }
+ }
+ }
+ break;
+ case GRN_ACCESSOR_GET_NSUBRECS :
+ grn_obj_get_value(ctx, a->obj, id, &buf);
+ {
+ grn_rset_recinfo *ri = (grn_rset_recinfo *)GRN_BULK_HEAD(&buf);
+ vp = &ri->n_subrecs;
+ }
+ break;
+ case GRN_ACCESSOR_GET_MAX :
+ grn_obj_get_value(ctx, a->obj, id, &buf);
+ {
+ grn_rset_recinfo *ri = (grn_rset_recinfo *)GRN_BULK_HEAD(&buf);
+ if (value->header.type == GRN_DB_INT64) {
+ grn_rset_recinfo_set_max(ctx, ri, a->obj, GRN_INT64_VALUE(value));
+ } else {
+ grn_obj value_int64;
+ GRN_INT64_INIT(&value_int64, 0);
+ if (!grn_obj_cast(ctx, value, &value_int64, GRN_FALSE)) {
+ grn_rset_recinfo_set_max(ctx, ri, a->obj,
+ GRN_INT64_VALUE(&value_int64));
+ }
+ GRN_OBJ_FIN(ctx, &value_int64);
+ }
+ }
+ break;
+ case GRN_ACCESSOR_GET_MIN :
+ grn_obj_get_value(ctx, a->obj, id, &buf);
+ {
+ grn_rset_recinfo *ri = (grn_rset_recinfo *)GRN_BULK_HEAD(&buf);
+ if (value->header.type == GRN_DB_INT64) {
+ grn_rset_recinfo_set_min(ctx, ri, a->obj, GRN_INT64_VALUE(value));
+ } else {
+ grn_obj value_int64;
+ GRN_INT64_INIT(&value_int64, 0);
+ if (!grn_obj_cast(ctx, value, &value_int64, GRN_FALSE)) {
+ grn_rset_recinfo_set_min(ctx, ri, a->obj,
+ GRN_INT64_VALUE(&value_int64));
+ }
+ GRN_OBJ_FIN(ctx, &value_int64);
+ }
+ }
+ break;
+ case GRN_ACCESSOR_GET_SUM :
+ grn_obj_get_value(ctx, a->obj, id, &buf);
+ {
+ grn_rset_recinfo *ri = (grn_rset_recinfo *)GRN_BULK_HEAD(&buf);
+ if (value->header.type == GRN_DB_INT64) {
+ grn_rset_recinfo_set_sum(ctx, ri, a->obj, GRN_INT64_VALUE(value));
+ } else {
+ grn_obj value_int64;
+ GRN_INT64_INIT(&value_int64, 0);
+ if (!grn_obj_cast(ctx, value, &value_int64, GRN_FALSE)) {
+ grn_rset_recinfo_set_sum(ctx, ri, a->obj,
+ GRN_INT64_VALUE(&value_int64));
+ }
+ GRN_OBJ_FIN(ctx, &value_int64);
+ }
+ }
+ break;
+ case GRN_ACCESSOR_GET_AVG :
+ grn_obj_get_value(ctx, a->obj, id, &buf);
+ {
+ grn_rset_recinfo *ri = (grn_rset_recinfo *)GRN_BULK_HEAD(&buf);
+ if (value->header.type == GRN_DB_FLOAT) {
+ grn_rset_recinfo_set_avg(ctx, ri, a->obj, GRN_FLOAT_VALUE(value));
+ } else {
+ grn_obj value_float;
+ GRN_FLOAT_INIT(&value_float, 0);
+ if (!grn_obj_cast(ctx, value, &value_float, GRN_FALSE)) {
+ grn_rset_recinfo_set_avg(ctx, ri, a->obj,
+ GRN_FLOAT_VALUE(&value_float));
+ }
+ GRN_OBJ_FIN(ctx, &value_float);
+ }
+ }
+ break;
+ case GRN_ACCESSOR_GET_COLUMN_VALUE :
+ /* todo : support vector */
+ if (a->next) {
+ grn_obj_get_value(ctx, a->obj, id, &buf);
+ vp = GRN_BULK_HEAD(&buf);
+ } else {
+ rc = grn_obj_set_value(ctx, a->obj, id, value, flags);
+ }
+ break;
+ case GRN_ACCESSOR_LOOKUP :
+ /* todo */
+ break;
+ case GRN_ACCESSOR_FUNCALL :
+ /* todo */
+ break;
+ }
+ if ((a = a->next)) {
+ id = *((grn_id *)vp);
+ } else {
+ break;
+ }
+ }
+ grn_obj_close(ctx, &buf);
+ }
+ return rc;
+}
+
+#define INCRDECR(op) \
+ switch (DB_OBJ(obj)->range) {\
+ case GRN_DB_INT8 :\
+ if (s == sizeof(int8_t)) {\
+ int8_t *vp = (int8_t *)p;\
+ *vp op *(int8_t *)v;\
+ rc = GRN_SUCCESS;\
+ } else {\
+ rc = GRN_INVALID_ARGUMENT;\
+ }\
+ break;\
+ case GRN_DB_UINT8 :\
+ if (s == sizeof(uint8_t)) {\
+ uint8_t *vp = (uint8_t *)p;\
+ *vp op *(int8_t *)v;\
+ rc = GRN_SUCCESS;\
+ } else {\
+ rc = GRN_INVALID_ARGUMENT;\
+ }\
+ break;\
+ case GRN_DB_INT16 :\
+ if (s == sizeof(int16_t)) {\
+ int16_t *vp = (int16_t *)p;\
+ *vp op *(int16_t *)v;\
+ rc = GRN_SUCCESS;\
+ } else {\
+ rc = GRN_INVALID_ARGUMENT;\
+ }\
+ break;\
+ case GRN_DB_UINT16 :\
+ if (s == sizeof(uint16_t)) {\
+ uint16_t *vp = (uint16_t *)p;\
+ *vp op *(int16_t *)v;\
+ rc = GRN_SUCCESS;\
+ } else {\
+ rc = GRN_INVALID_ARGUMENT;\
+ }\
+ break;\
+ case GRN_DB_INT32 :\
+ if (s == sizeof(int32_t)) {\
+ int32_t *vp = (int32_t *)p;\
+ *vp op *(int32_t *)v;\
+ rc = GRN_SUCCESS;\
+ } else {\
+ rc = GRN_INVALID_ARGUMENT;\
+ }\
+ break;\
+ case GRN_DB_UINT32 :\
+ if (s == sizeof(uint32_t)) {\
+ uint32_t *vp = (uint32_t *)p;\
+ *vp op *(int32_t *)v;\
+ rc = GRN_SUCCESS;\
+ } else {\
+ rc = GRN_INVALID_ARGUMENT;\
+ }\
+ break;\
+ case GRN_DB_INT64 :\
+ case GRN_DB_TIME :\
+ if (s == sizeof(int64_t)) {\
+ int64_t *vp = (int64_t *)p;\
+ *vp op *(int64_t *)v;\
+ rc = GRN_SUCCESS;\
+ } else {\
+ rc = GRN_INVALID_ARGUMENT;\
+ }\
+ break;\
+ case GRN_DB_FLOAT :\
+ if (s == sizeof(double)) {\
+ double *vp = (double *)p;\
+ *vp op *(double *)v;\
+ rc = GRN_SUCCESS;\
+ } else {\
+ rc = GRN_INVALID_ARGUMENT;\
+ }\
+ break;\
+ default :\
+ rc = GRN_OPERATION_NOT_SUPPORTED;\
+ break;\
+ }
+
+uint32_t
+grn_obj_size(grn_ctx *ctx, grn_obj *obj)
+{
+ if (!obj) { return 0; }
+ switch (obj->header.type) {
+ case GRN_VOID :
+ case GRN_BULK :
+ case GRN_PTR :
+ case GRN_UVECTOR :
+ case GRN_PVECTOR :
+ case GRN_MSG :
+ return GRN_BULK_VSIZE(obj);
+ case GRN_VECTOR :
+ return obj->u.v.body ? GRN_BULK_VSIZE(obj->u.v.body) : 0;
+ default :
+ return 0;
+ }
+}
+
+inline static int
+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];
+ void *v = GRN_BULK_HEAD(value);
+ unsigned int s = grn_obj_size(ctx, value);
+ if (hooks || obj->header.type == GRN_COLUMN_VAR_SIZE) {
+ grn_obj oldbuf, *oldvalue;
+ GRN_TEXT_INIT(&oldbuf, 0);
+ oldvalue = grn_obj_get_value(ctx, obj, id, &oldbuf);
+ if (flags & GRN_OBJ_SET) {
+ void *ov;
+ unsigned int os;
+ ov = GRN_BULK_HEAD(oldvalue);
+ os = grn_obj_size(ctx, oldvalue);
+ if ((ov && v && os == s && !memcmp(ov, v, s)) &&
+ !(obj->header.type == GRN_COLUMN_FIX_SIZE &&
+ grn_bulk_is_zero(ctx, value))) {
+ grn_obj_close(ctx, oldvalue);
+ return 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, {{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{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 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)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ grn_id range = DB_OBJ(obj)->range;
+ void *v = GRN_BULK_HEAD(value);
+ grn_obj buf;
+
+ if (call_hook(ctx, obj, id, value, flags)) {
+ if (ctx->rc) {
+ rc = ctx->rc;
+ }
+ return rc;
+ }
+
+ if (range != value->header.domain) {
+ GRN_OBJ_INIT(&buf, GRN_BULK, 0, range);
+ if (grn_obj_cast(ctx, value, &buf, GRN_TRUE) == GRN_SUCCESS) {
+ v = GRN_BULK_HEAD(&buf);
+ }
+ }
+ rc = grn_pat_set_value(ctx, (grn_pat *)obj, id, v, flags);
+ if (range != value->header.domain) {
+ grn_obj_close(ctx, &buf);
+ }
+
+ return rc;
+}
+
+static grn_rc
+grn_obj_set_value_table_hash_key(grn_ctx *ctx, grn_obj *obj, grn_id id,
+ grn_obj *value, int flags)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ grn_id range = DB_OBJ(obj)->range;
+ void *v = GRN_BULK_HEAD(value);
+ grn_obj buf;
+
+ if (call_hook(ctx, obj, id, value, flags)) {
+ if (ctx->rc) {
+ rc = ctx->rc;
+ }
+ return rc;
+ }
+
+ if (range != value->header.domain) {
+ GRN_OBJ_INIT(&buf, GRN_BULK, 0, range);
+ if (grn_obj_cast(ctx, value, &buf, GRN_TRUE) == GRN_SUCCESS) {
+ v = GRN_BULK_HEAD(&buf);
+ }
+ }
+ rc = grn_hash_set_value(ctx, (grn_hash *)obj, id, v, flags);
+ if (range != value->header.domain) {
+ grn_obj_close(ctx, &buf);
+ }
+
+ return rc;
+}
+
+static grn_rc
+grn_obj_set_value_table_no_key(grn_ctx *ctx, grn_obj *obj, grn_id id,
+ grn_obj *value, int flags)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ grn_id range = DB_OBJ(obj)->range;
+ void *v = GRN_BULK_HEAD(value);
+ grn_obj buf;
+
+ if (call_hook(ctx, obj, id, value, flags)) {
+ if (ctx->rc) {
+ rc = ctx->rc;
+ }
+ return rc;
+ }
+
+ if (range != value->header.domain) {
+ GRN_OBJ_INIT(&buf, GRN_BULK, 0, range);
+ if (grn_obj_cast(ctx, value, &buf, GRN_TRUE) == GRN_SUCCESS) {
+ v = GRN_BULK_HEAD(&buf);
+ }
+ }
+ rc = grn_array_set_value(ctx, (grn_array *)obj, id, v, flags);
+ if (range != value->header.domain) {
+ grn_obj_close(ctx, &buf);
+ }
+
+ return rc;
+}
+
+static grn_rc
+grn_obj_set_value_column_var_size_scalar(grn_ctx *ctx, grn_obj *obj, grn_id id,
+ grn_obj *value, int flags)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ grn_id range = DB_OBJ(obj)->range;
+ void *v = GRN_BULK_HEAD(value);
+ unsigned int s = grn_obj_size(ctx, value);
+ grn_obj buf;
+ grn_id buf_domain = GRN_DB_VOID;
+
+ if (call_hook(ctx, obj, id, value, flags)) {
+ if (ctx->rc) {
+ rc = ctx->rc;
+ }
+ return rc;
+ }
+
+ switch (flags & GRN_OBJ_SET_MASK) {
+ case GRN_OBJ_INCR :
+ case GRN_OBJ_DECR :
+ if (value->header.domain == GRN_DB_INT32 ||
+ value->header.domain == GRN_DB_INT64) {
+ /* do nothing */
+ } else if (GRN_DB_INT8 <= value->header.domain &&
+ value->header.domain < GRN_DB_INT32) {
+ buf_domain = GRN_DB_INT32;
+ } else {
+ buf_domain = GRN_DB_INT64;
+ }
+ break;
+ default :
+ if (range != value->header.domain) {
+ buf_domain = range;
+ }
+ break;
+ }
+
+ if (buf_domain != GRN_DB_VOID) {
+ GRN_OBJ_INIT(&buf, GRN_BULK, 0, buf_domain);
+ if (grn_obj_cast(ctx, value, &buf, GRN_TRUE) == GRN_SUCCESS) {
+ v = GRN_BULK_HEAD(&buf);
+ s = GRN_BULK_VSIZE(&buf);
+ }
+ }
+
+ rc = grn_ja_put(ctx, (grn_ja *)obj, id, v, s, flags, NULL);
+
+ if (buf_domain != GRN_DB_VOID) {
+ grn_obj_close(ctx, &buf);
+ }
+
+ return rc;
+}
+
+static grn_rc
+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_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;
+
+ if (column->header.flags & GRN_OBJ_WITH_WEIGHT) {
+ if (!IS_WEIGHT_UVECTOR(value)) {
+ need_convert = GRN_TRUE;
+ }
+ } else {
+ if (IS_WEIGHT_UVECTOR(value)) {
+ need_convert = GRN_TRUE;
+ 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, column_range_id);
+ uvector.header.flags |= uvector_flags;
+ n = grn_uvector_size(ctx, value);
+ 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);
+ } else {
+ raw_value = GRN_BULK_HEAD(value);
+ size = GRN_BULK_VSIZE(value);
+ }
+
+ 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);
+ }
+
+ return rc;
+}
+
+static grn_rc
+grn_obj_set_value_column_var_size_vector(grn_ctx *ctx, grn_obj *obj, grn_id id,
+ grn_obj *value, int flags)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ grn_id range = DB_OBJ(obj)->range;
+ void *v = GRN_BULK_HEAD(value);
+ unsigned int s = grn_obj_size(ctx, value);
+ grn_obj *lexicon = grn_ctx_at(ctx, range);
+
+ if (call_hook(ctx, obj, id, value, flags)) {
+ if (ctx->rc) {
+ rc = ctx->rc;
+ }
+ return rc;
+ }
+
+ if (value->header.type == GRN_UVECTOR) {
+ rc = grn_obj_set_value_column_var_size_vector_uvector(ctx, obj,
+ id, value,
+ flags);
+ return rc;
+ }
+
+ if (GRN_OBJ_TABLEP(lexicon)) {
+ grn_obj uvector;
+ GRN_RECORD_INIT(&uvector, GRN_OBJ_VECTOR, range);
+ if (obj->header.flags & GRN_OBJ_WITH_WEIGHT) {
+ uvector.header.flags |= GRN_OBJ_WITH_WEIGHT;
+ }
+ switch (value->header.type) {
+ case GRN_BULK :
+ {
+ unsigned int token_flags = 0;
+ grn_token_cursor *token_cursor;
+ if (v && s &&
+ (token_cursor = grn_token_cursor_open(ctx, lexicon, v, s,
+ GRN_TOKEN_ADD, token_flags))) {
+ while (token_cursor->status == GRN_TOKEN_CURSOR_DOING) {
+ grn_id tid = grn_token_cursor_next(ctx, token_cursor);
+ grn_uvector_add_element(ctx, &uvector, tid, 0);
+ }
+ grn_token_cursor_close(ctx, token_cursor);
+ }
+ rc = grn_ja_put(ctx, (grn_ja *)obj, id,
+ GRN_BULK_HEAD(&uvector), GRN_BULK_VSIZE(&uvector),
+ flags, NULL);
+ }
+ break;
+ case GRN_VECTOR :
+ {
+ unsigned int n;
+ n = grn_vector_size(ctx, value);
+ if (n > 0) {
+ unsigned int i;
+ grn_obj value_buf, cast_buf;
+ GRN_OBJ_INIT(&value_buf, GRN_BULK, 0, GRN_DB_VOID);
+ GRN_OBJ_INIT(&cast_buf, GRN_BULK, 0, lexicon->header.domain);
+ for (i = 0; i < n; i++) {
+ grn_id tid;
+ const char *element;
+ unsigned int element_length;
+ unsigned int weight;
+ grn_id element_domain;
+
+ element_length = grn_vector_get_element(ctx, value, i,
+ &element, &weight,
+ &element_domain);
+ if (element_domain != lexicon->header.domain) {
+ GRN_BULK_REWIND(&cast_buf);
+ GRN_BULK_REWIND(&value_buf);
+ grn_bulk_write(ctx, &value_buf, element, element_length);
+ value_buf.header.domain = element_domain;
+ rc = grn_obj_cast(ctx, &value_buf, &cast_buf, GRN_TRUE);
+ if (rc) {
+ grn_obj *range_obj;
+ range_obj = grn_ctx_at(ctx, range);
+ ERR_CAST(obj, range_obj, &value_buf);
+ grn_obj_unlink(ctx, range_obj);
+ } else {
+ element = GRN_BULK_HEAD(&cast_buf);
+ element_length = GRN_BULK_VSIZE(&cast_buf);
+ }
+ } else {
+ rc = GRN_SUCCESS;
+ }
+ if (rc) {
+ continue;
+ }
+ tid = grn_table_add(ctx, lexicon, element, element_length, NULL);
+ grn_uvector_add_element(ctx, &uvector, tid, weight);
+ }
+ GRN_OBJ_FIN(ctx, &value_buf);
+ GRN_OBJ_FIN(ctx, &cast_buf);
+ }
+ }
+ rc = grn_ja_put(ctx, (grn_ja *)obj, id,
+ GRN_BULK_HEAD(&uvector), GRN_BULK_VSIZE(&uvector),
+ flags, NULL);
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "vector, uvector or bulk required");
+ break;
+ }
+ grn_obj_close(ctx, &uvector);
+ } else {
+ switch (value->header.type) {
+ case GRN_BULK :
+ if (!GRN_BULK_VSIZE(value)) {
+ rc = grn_ja_put(ctx, (grn_ja *)obj, id, NULL, 0, flags, NULL);
+ } else {
+ grn_obj v;
+ GRN_OBJ_INIT(&v, GRN_VECTOR, GRN_OBJ_DO_SHALLOW_COPY, GRN_DB_TEXT);
+ v.u.v.body = value;
+ grn_vector_delimit(ctx, &v, 0, GRN_ID_NIL);
+ rc = grn_ja_putv(ctx, (grn_ja *)obj, id, &v, 0);
+ grn_obj_close(ctx, &v);
+ }
+ break;
+ case GRN_VECTOR :
+ rc = grn_ja_putv(ctx, (grn_ja *)obj, id, value, 0);
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "vector or bulk required");
+ break;
+ }
+ }
+ return rc;
+}
+
+static grn_rc
+grn_obj_set_value_column_fix_size(grn_ctx *ctx, grn_obj *obj, grn_id id,
+ grn_obj *value, int flags)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ grn_id range = DB_OBJ(obj)->range;
+ void *v = GRN_BULK_HEAD(value);
+ unsigned int s = grn_obj_size(ctx, value);
+ grn_obj buf, *value_ = value;
+ uint32_t element_size = ((grn_ra *)obj)->header->element_size;
+ GRN_OBJ_INIT(&buf, GRN_BULK, 0, range);
+ if (range != value->header.domain) {
+ rc = grn_obj_cast(ctx, value, &buf, GRN_TRUE);
+ if (rc) {
+ grn_obj *range_obj;
+ range_obj = grn_ctx_at(ctx, range);
+ ERR_CAST(obj, range_obj, value);
+ grn_obj_unlink(ctx, range_obj);
+ } else {
+ value_ = &buf;
+ v = GRN_BULK_HEAD(&buf);
+ s = GRN_BULK_VSIZE(&buf);
+ }
+ } else {
+ rc = GRN_SUCCESS;
+ }
+ if (rc) {
+ /* do nothing because it already has error. */
+ } else if (element_size < s) {
+ ERR(GRN_INVALID_ARGUMENT, "too long value (%d)", s);
+ } else {
+ void *p = grn_ra_ref(ctx, (grn_ra *)obj, id);
+ if (!p) {
+ ERR(GRN_NO_MEMORY_AVAILABLE, "ra get failed");
+ rc = GRN_NO_MEMORY_AVAILABLE;
+ return rc;
+ }
+ 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;
+ }
+ if (element_size != s) {
+ if (!s) {
+ memset(p, 0, element_size);
+ } else {
+ void *b;
+ if ((b = GRN_CALLOC(element_size))) {
+ grn_memcpy(b, v, s);
+ grn_memcpy(p, b, element_size);
+ GRN_FREE(b);
+ }
+ }
+ } else {
+ grn_memcpy(p, v, s);
+ }
+ rc = GRN_SUCCESS;
+ break;
+ case GRN_OBJ_INCR :
+ /* todo : support hook */
+ INCRDECR(+=);
+ break;
+ case GRN_OBJ_DECR :
+ /* todo : support hook */
+ INCRDECR(-=);
+ break;
+ default :
+ rc = GRN_OPERATION_NOT_SUPPORTED;
+ break;
+ }
+ grn_ra_unref(ctx, (grn_ra *)obj, id);
+ }
+ GRN_OBJ_FIN(ctx, &buf);
+ return rc;
+}
+
+static grn_rc
+grn_obj_set_value_column_index(grn_ctx *ctx, grn_obj *obj, grn_id id,
+ grn_obj *value, int flags)
+{
+ char column_name[GRN_TABLE_MAX_KEY_SIZE];
+ int column_name_size;
+ column_name_size = grn_obj_name(ctx, obj, column_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_INVALID_ARGUMENT,
+ "can't set value to index column directly: <%.*s>",
+ column_name_size, column_name);
+ return ctx->rc;
+}
+
+grn_rc
+grn_obj_set_value(grn_ctx *ctx, grn_obj *obj, grn_id id,
+ grn_obj *value, int flags)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ GRN_API_ENTER;
+ if (!GRN_DB_OBJP(obj)) {
+ if (obj->header.type == GRN_ACCESSOR) {
+ rc = grn_accessor_set_value(ctx, (grn_accessor *)obj, id, value, flags);
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "not db_obj");
+ }
+ } else {
+ switch (obj->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ rc = grn_obj_set_value_table_pat_key(ctx, obj, id, value, flags);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ rc = GRN_OPERATION_NOT_SUPPORTED;
+ break;
+ case GRN_TABLE_HASH_KEY :
+ rc = grn_obj_set_value_table_hash_key(ctx, obj, id, value, flags);
+ break;
+ case GRN_TABLE_NO_KEY :
+ rc = grn_obj_set_value_table_no_key(ctx, obj, id, value, flags);
+ break;
+ case GRN_COLUMN_VAR_SIZE :
+ switch (obj->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) {
+ case GRN_OBJ_COLUMN_SCALAR :
+ rc = grn_obj_set_value_column_var_size_scalar(ctx, obj, id, value,
+ flags);
+ break;
+ case GRN_OBJ_COLUMN_VECTOR :
+ rc = grn_obj_set_value_column_var_size_vector(ctx, obj, id, value,
+ flags);
+ break;
+ default :
+ ERR(GRN_FILE_CORRUPT, "invalid GRN_OBJ_COLUMN_TYPE");
+ break;
+ }
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ rc = grn_obj_set_value_column_fix_size(ctx, obj, id, value, flags);
+ break;
+ case GRN_COLUMN_INDEX :
+ rc = grn_obj_set_value_column_index(ctx, obj, id, value, flags);
+ break;
+ }
+ }
+ GRN_API_RETURN(rc);
+}
+
+const char *
+grn_obj_get_value_(grn_ctx *ctx, grn_obj *obj, grn_id id, uint32_t *size)
+{
+ const char *value = NULL;
+ *size = 0;
+ switch (obj->header.type) {
+ case GRN_ACCESSOR :
+ value = grn_accessor_get_value_(ctx, (grn_accessor *)obj, id, size);
+ break;
+ case GRN_TABLE_PAT_KEY :
+ value = grn_pat_get_value_(ctx, (grn_pat *)obj, id, size);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ ERR(GRN_FUNCTION_NOT_IMPLEMENTED, "GRN_TABLE_DAT_KEY not supported");
+ break;
+ case GRN_TABLE_HASH_KEY :
+ value = grn_hash_get_value_(ctx, (grn_hash *)obj, id, size);
+ break;
+ case GRN_TABLE_NO_KEY :
+ if ((value = _grn_array_get_value(ctx, (grn_array *)obj, id))) {
+ *size = ((grn_array *)obj)->value_size;
+ }
+ break;
+ case GRN_COLUMN_VAR_SIZE :
+ {
+ grn_io_win jw;
+ if ((value = grn_ja_ref(ctx, (grn_ja *)obj, id, &jw, size))) {
+ grn_ja_unref(ctx, &jw);
+ }
+ }
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ if ((value = grn_ra_ref(ctx, (grn_ra *)obj, id))) {
+ grn_ra_unref(ctx, (grn_ra *)obj, id);
+ *size = ((grn_ra *)obj)->header->element_size;
+ }
+ break;
+ case GRN_COLUMN_INDEX :
+ ERR(GRN_FUNCTION_NOT_IMPLEMENTED, "todo: GRN_COLUMN_INDEX");
+ break;
+ }
+ return value;
+}
+
+static void
+grn_obj_get_value_expr(grn_ctx *ctx, grn_obj *expr, grn_id id, grn_obj *value)
+{
+ grn_expr *e = (grn_expr *)expr;
+ grn_expr_code *code;
+
+ if (e->codes_curr != 1) {
+ return;
+ }
+
+ code = e->codes;
+ if (code->op != GRN_OP_GET_VALUE) {
+ return;
+ }
+
+ if (!code->value) {
+ return;
+ }
+
+ switch (code->value->header.type) {
+ case GRN_COLUMN_VAR_SIZE :
+ case GRN_COLUMN_FIX_SIZE :
+ grn_obj_get_value(ctx, code->value, id, value);
+ break;
+ default :
+ break;
+ }
+}
+
+static void
+grn_obj_get_value_column_index(grn_ctx *ctx, grn_obj *index_column,
+ grn_id id, grn_obj *value)
+{
+ grn_ii *ii = (grn_ii *)index_column;
+ grn_obj_ensure_bulk(ctx, value);
+ if (id) {
+ GRN_UINT32_SET(ctx, value, grn_ii_estimate_size(ctx, ii, id));
+ } else {
+ GRN_UINT32_SET(ctx, value, 0);
+ }
+ value->header.domain = GRN_DB_UINT32;
+}
+
+static grn_obj *
+grn_obj_get_value_column_vector(grn_ctx *ctx, grn_obj *obj,
+ grn_id id, grn_obj *value)
+{
+ grn_obj *lexicon;
+
+ lexicon = grn_ctx_at(ctx, DB_OBJ(obj)->range);
+ if (lexicon && !GRN_OBJ_TABLEP(lexicon) &&
+ (lexicon->header.flags & GRN_OBJ_KEY_VAR_SIZE)) {
+ grn_obj_ensure_vector(ctx, value);
+ if (id) {
+ grn_obj v_;
+ GRN_TEXT_INIT(&v_, 0);
+ grn_ja_get_value(ctx, (grn_ja *)obj, id, &v_);
+ grn_vector_decode(ctx, value, GRN_TEXT_VALUE(&v_), GRN_TEXT_LEN(&v_));
+ GRN_OBJ_FIN(ctx, &v_);
+ }
+ } else {
+ grn_obj_ensure_bulk(ctx, value);
+ if (id) {
+ grn_ja_get_value(ctx, (grn_ja *)obj, id, value);
+ }
+ value->header.type = GRN_UVECTOR;
+ if (obj->header.flags & GRN_OBJ_WITH_WEIGHT) {
+ value->header.flags |= GRN_OBJ_WITH_WEIGHT;
+ } else {
+ value->header.flags &= ~GRN_OBJ_WITH_WEIGHT;
+ }
+ }
+
+ return value;
+}
+
+grn_obj *
+grn_obj_get_value(grn_ctx *ctx, grn_obj *obj, grn_id id, grn_obj *value)
+{
+ GRN_API_ENTER;
+ if (!obj) {
+ ERR(GRN_INVALID_ARGUMENT, "grn_obj_get_value failed");
+ goto exit;
+ }
+ if (!value) {
+ if (!(value = grn_obj_open(ctx, GRN_BULK, 0, 0))) {
+ ERR(GRN_INVALID_ARGUMENT, "grn_obj_get_value failed");
+ goto exit;
+ }
+ }
+ switch (value->header.type) {
+ case GRN_VOID :
+ grn_obj_reinit(ctx, value, GRN_DB_TEXT, 0);
+ break;
+ case GRN_BULK :
+ case GRN_VECTOR :
+ case GRN_UVECTOR :
+ case GRN_MSG :
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "grn_obj_get_value failed");
+ goto exit;
+ }
+ switch (obj->header.type) {
+ case GRN_ACCESSOR :
+ grn_obj_ensure_bulk(ctx, value);
+ value = grn_accessor_get_value(ctx, (grn_accessor *)obj, id, value);
+ break;
+ case GRN_EXPR :
+ grn_obj_get_value_expr(ctx, obj, id, value);
+ break;
+ case GRN_TABLE_PAT_KEY :
+ {
+ grn_pat *pat = (grn_pat *)obj;
+ uint32_t size = pat->value_size;
+ grn_obj_ensure_bulk(ctx, value);
+ if (id) {
+ if (grn_bulk_space(ctx, value, size)) {
+ MERR("grn_bulk_space failed");
+ goto exit;
+ }
+ {
+ char *curr = GRN_BULK_CURR(value);
+ grn_pat_get_value(ctx, pat, id, curr - size);
+ }
+ }
+ value->header.type = GRN_BULK;
+ value->header.domain = grn_obj_get_range(ctx, obj);
+ }
+ break;
+ case GRN_TABLE_DAT_KEY :
+ ERR(GRN_FUNCTION_NOT_IMPLEMENTED, "GRN_TABLE_DAT_KEY not supported");
+ break;
+ case GRN_TABLE_HASH_KEY :
+ {
+ grn_bool processed = GRN_FALSE;
+ grn_obj_ensure_bulk(ctx, value);
+ value->header.domain = grn_obj_get_range(ctx, obj);
+ if (id) {
+ if (GRN_TABLE_IS_MULTI_KEYS_GROUPED(obj)) {
+ grn_obj *domain;
+ domain = grn_ctx_at(ctx, value->header.domain);
+ if (GRN_OBJ_TABLEP(domain)) {
+ grn_id subrec_id;
+ if (grn_table_get_subrecs(ctx, obj, id, &subrec_id, NULL, 1) == 1) {
+ GRN_RECORD_SET(ctx, value, subrec_id);
+ processed = GRN_TRUE;
+ }
+ }
+ }
+ if (!processed) {
+ grn_hash *hash = (grn_hash *)obj;
+ uint32_t size = hash->value_size;
+ if (grn_bulk_space(ctx, value, size)) {
+ MERR("grn_bulk_space failed");
+ goto exit;
+ }
+ {
+ char *curr = GRN_BULK_CURR(value);
+ grn_hash_get_value(ctx, hash, id, curr - size);
+ }
+ }
+ }
+ }
+ break;
+ case GRN_TABLE_NO_KEY :
+ {
+ grn_array *array = (grn_array *)obj;
+ uint32_t size = array->value_size;
+ grn_obj_ensure_bulk(ctx, value);
+ if (id) {
+ if (grn_bulk_space(ctx, value, size)) {
+ MERR("grn_bulk_space failed");
+ goto exit;
+ }
+ {
+ char *curr = GRN_BULK_CURR(value);
+ grn_array_get_value(ctx, array, id, curr - size);
+ }
+ }
+ value->header.type = GRN_BULK;
+ value->header.domain = grn_obj_get_range(ctx, obj);
+ }
+ break;
+ case GRN_COLUMN_VAR_SIZE :
+ switch (obj->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) {
+ case GRN_OBJ_COLUMN_VECTOR :
+ grn_obj_get_value_column_vector(ctx, obj, id, value);
+ break;
+ case GRN_OBJ_COLUMN_SCALAR :
+ grn_obj_ensure_bulk(ctx, value);
+ if (id) {
+ grn_ja_get_value(ctx, (grn_ja *)obj, id, value);
+ }
+ value->header.type = GRN_BULK;
+ break;
+ default :
+ ERR(GRN_FILE_CORRUPT, "invalid GRN_OBJ_COLUMN_TYPE");
+ break;
+ }
+ value->header.domain = grn_obj_get_range(ctx, obj);
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ grn_obj_ensure_bulk(ctx, value);
+ value->header.type = GRN_BULK;
+ value->header.domain = grn_obj_get_range(ctx, obj);
+ if (id) {
+ unsigned int element_size;
+ void *v = grn_ra_ref(ctx, (grn_ra *)obj, id);
+ if (v) {
+ element_size = ((grn_ra *)obj)->header->element_size;
+ grn_bulk_write(ctx, value, v, element_size);
+ grn_ra_unref(ctx, (grn_ra *)obj, id);
+ }
+ }
+ break;
+ case GRN_COLUMN_INDEX :
+ grn_obj_get_value_column_index(ctx, obj, id, value);
+ break;
+ }
+exit :
+ GRN_API_RETURN(value);
+}
+
+int
+grn_obj_get_values(grn_ctx *ctx, grn_obj *obj, grn_id offset, void **values)
+{
+ int nrecords = -1;
+ GRN_API_ENTER;
+ if (obj->header.type == GRN_COLUMN_FIX_SIZE) {
+ grn_obj *domain = grn_column_table(ctx, obj);
+ if (domain) {
+ int table_size = (int)grn_table_size(ctx, domain);
+ if (0 < offset && offset <= (grn_id) table_size) {
+ grn_ra *ra = (grn_ra *)obj;
+ void *p = grn_ra_ref(ctx, ra, offset);
+ if (p) {
+ if ((offset >> ra->element_width) == ((unsigned int) table_size >> ra->element_width)) {
+ nrecords = (table_size & ra->element_mask) + 1 - (offset & ra->element_mask);
+ } else {
+ nrecords = ra->element_mask + 1 - (offset & ra->element_mask);
+ }
+ if (values) { *values = p; }
+ grn_ra_unref(ctx, ra, offset);
+ } else {
+ ERR(GRN_NO_MEMORY_AVAILABLE, "ra get failed");
+ }
+ } else {
+ nrecords = 0;
+ }
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "no domain found");
+ }
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "obj is not a fix sized column");
+ }
+ GRN_API_RETURN(nrecords);
+}
+
+grn_rc
+grn_column_index_update(grn_ctx *ctx, grn_obj *column,
+ grn_id id, unsigned int section,
+ grn_obj *oldvalue, grn_obj *newvalue)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ GRN_API_ENTER;
+ if (column->header.type != GRN_COLUMN_INDEX) {
+ ERR(GRN_INVALID_ARGUMENT, "invalid column assigned");
+ } else {
+ rc = grn_ii_column_update(ctx, (grn_ii *)column, id, section, oldvalue, newvalue, NULL);
+ }
+ GRN_API_RETURN(rc);
+}
+
+grn_obj *
+grn_column_table(grn_ctx *ctx, grn_obj *column)
+{
+ grn_obj *obj = NULL;
+ grn_db_obj *col = DB_OBJ(column);
+ GRN_API_ENTER;
+ if (col) {
+ obj = grn_ctx_at(ctx, col->header.domain);
+ }
+ GRN_API_RETURN(obj);
+}
+
+grn_obj *
+grn_obj_get_info(grn_ctx *ctx, grn_obj *obj, grn_info_type type, grn_obj *valuebuf)
+{
+ GRN_API_ENTER;
+ switch (type) {
+ case GRN_INFO_SUPPORT_ZLIB :
+ 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_ZLIB_SUPPORT");
+ goto exit;
+ }
+#ifdef GRN_WITH_ZLIB
+ GRN_BOOL_PUT(ctx, valuebuf, GRN_TRUE);
+#else
+ GRN_BOOL_PUT(ctx, valuebuf, GRN_FALSE);
+#endif
+ break;
+ case GRN_INFO_SUPPORT_LZ4 :
+ 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_LZ4_SUPPORT");
+ goto exit;
+ }
+#ifdef GRN_WITH_LZ4
+ GRN_BOOL_PUT(ctx, valuebuf, GRN_TRUE);
+#else /* GRN_WITH_LZ4 */
+ 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");
+ goto exit;
+ }
+ switch (type) {
+ case GRN_INFO_ENCODING :
+ if (!valuebuf) {
+ if (!(valuebuf = grn_obj_open(ctx, GRN_BULK, 0, 0))) {
+ ERR(GRN_INVALID_ARGUMENT, "grn_obj_get_info failed");
+ goto exit;
+ }
+ }
+ {
+ grn_encoding enc;
+ if (obj->header.type == GRN_DB) { obj = ((grn_db *)obj)->keys; }
+ switch (obj->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ enc = ((grn_pat *)obj)->encoding;
+ grn_bulk_write(ctx, valuebuf, (const char *)&enc, sizeof(grn_encoding));
+ break;
+ case GRN_TABLE_DAT_KEY :
+ enc = ((grn_dat *)obj)->encoding;
+ grn_bulk_write(ctx, valuebuf, (const char *)&enc, sizeof(grn_encoding));
+ break;
+ case GRN_TABLE_HASH_KEY :
+ enc = ((grn_hash *)obj)->encoding;
+ grn_bulk_write(ctx, valuebuf, (const char *)&enc, sizeof(grn_encoding));
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "grn_obj_get_info failed");
+ }
+ }
+ break;
+ case GRN_INFO_SOURCE :
+ if (!valuebuf) {
+ if (!(valuebuf = grn_obj_open(ctx, GRN_BULK, 0, 0))) {
+ ERR(GRN_INVALID_ARGUMENT, "grn_obj_get_info failed");
+ goto exit;
+ }
+ }
+ if (!GRN_DB_OBJP(obj)) {
+ ERR(GRN_INVALID_ARGUMENT, "only db_obj can accept GRN_INFO_SOURCE");
+ goto exit;
+ }
+ grn_bulk_write(ctx, valuebuf, DB_OBJ(obj)->source, DB_OBJ(obj)->source_size);
+ break;
+ case GRN_INFO_DEFAULT_TOKENIZER :
+ switch (DB_OBJ(obj)->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ valuebuf = ((grn_hash *)obj)->tokenizer;
+ break;
+ case GRN_TABLE_PAT_KEY :
+ valuebuf = ((grn_pat *)obj)->tokenizer;
+ break;
+ case GRN_TABLE_DAT_KEY :
+ valuebuf = ((grn_dat *)obj)->tokenizer;
+ break;
+ }
+ break;
+ case GRN_INFO_NORMALIZER :
+ switch (DB_OBJ(obj)->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ valuebuf = ((grn_hash *)obj)->normalizer;
+ break;
+ case GRN_TABLE_PAT_KEY :
+ valuebuf = ((grn_pat *)obj)->normalizer;
+ break;
+ case GRN_TABLE_DAT_KEY :
+ valuebuf = ((grn_dat *)obj)->normalizer;
+ break;
+ }
+ break;
+ case GRN_INFO_TOKEN_FILTERS :
+ if (!valuebuf) {
+ if (!(valuebuf = grn_obj_open(ctx, GRN_PVECTOR, 0, 0))) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "grn_obj_get_info: failed to allocate value buffer");
+ goto exit;
+ }
+ }
+ {
+ grn_obj *token_filters = NULL;
+ switch (obj->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ token_filters = &(((grn_hash *)obj)->token_filters);
+ break;
+ case GRN_TABLE_PAT_KEY :
+ token_filters = &(((grn_pat *)obj)->token_filters);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ token_filters = &(((grn_dat *)obj)->token_filters);
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT,
+ /* TODO: Show type name instead of type ID */
+ "[info][get][token-filters] target object must be one of "
+ "GRN_TABLE_HASH_KEY, GRN_TABLE_PAT_KEY and GRN_TABLE_DAT_KEY: %d",
+ obj->header.type);
+ break;
+ }
+ if (token_filters) {
+ grn_bulk_write(ctx,
+ valuebuf,
+ GRN_BULK_HEAD(token_filters),
+ GRN_BULK_VSIZE(token_filters));
+ }
+ }
+ break;
+ default :
+ /* todo */
+ break;
+ }
+ }
+exit :
+ GRN_API_RETURN(valuebuf);
+}
+
+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);
+ 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 :
+ grn_obj_add_hook(ctx, source, GRN_HOOK_INSERT, 0, NULL, &data);
+ grn_obj_add_hook(ctx, source, GRN_HOOK_DELETE, 0, NULL, &data);
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ case GRN_COLUMN_INDEX :
+ grn_obj_add_hook(ctx, source, GRN_HOOK_SET, 0, NULL, &data);
+ break;
+ default :
+ /* invalid target */
+ break;
+ }
+ }
+ }
+ grn_obj_close(ctx, &data);
+}
+
+static void
+del_hook(grn_ctx *ctx, grn_obj *obj, grn_hook_entry entry, grn_obj *hld)
+{
+ int i;
+ void *hld_value = NULL;
+ uint32_t hld_size = 0;
+ grn_hook **last;
+ hld_value = GRN_BULK_HEAD(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(GRN_NEXT_ADDR(*last), hld_value, hld_size)) {
+ grn_obj_delete_hook(ctx, obj, entry, i);
+ return;
+ }
+ }
+}
+
+static void
+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);
+ 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;
+
+ 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);
+}
+
+#define N_HOOK_ENTRIES 5
+
+grn_rc
+grn_hook_pack(grn_ctx *ctx, grn_db_obj *obj, grn_obj *buf)
+{
+ grn_rc rc;
+ grn_hook_entry e;
+ for (e = 0; e < N_HOOK_ENTRIES; e++) {
+ grn_hook *hooks;
+ for (hooks = obj->hooks[e]; hooks; hooks = hooks->next) {
+ 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 *)GRN_NEXT_ADDR(hooks), hooks->hld_size))) { goto exit; }
+ }
+ if ((rc = grn_text_benc(ctx, buf, 0))) { goto exit; }
+ }
+exit :
+ return rc;
+}
+
+static grn_rc
+grn_hook_unpack(grn_ctx *ctx, grn_db_obj *obj, const char *buf, uint32_t buf_size)
+{
+ grn_hook_entry e;
+ const uint8_t *p = (uint8_t *)buf, *pe = p + buf_size;
+ for (e = 0; e < N_HOOK_ENTRIES; e++) {
+ grn_hook *new, **last = &obj->hooks[e];
+ for (;;) {
+ grn_id id;
+ uint32_t hld_size;
+ GRN_B_DEC(id, p);
+ if (!id--) { break; }
+ if (p >= pe) { return GRN_FILE_CORRUPT; }
+ GRN_B_DEC(hld_size, p);
+ if (p >= pe) { return GRN_FILE_CORRUPT; }
+ if (!(new = GRN_MALLOC(sizeof(grn_hook) + hld_size))) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ if (id) {
+ new->proc = (grn_proc *)grn_ctx_at(ctx, id);
+ if (!new->proc) {
+ GRN_FREE(new);
+ return ctx->rc;
+ }
+ } else {
+ new->proc = NULL;
+ }
+ if ((new->hld_size = hld_size)) {
+ grn_memcpy(GRN_NEXT_ADDR(new), p, hld_size);
+ p += hld_size;
+ }
+ *last = new;
+ last = &new->next;
+ if (p >= pe) { return GRN_FILE_CORRUPT; }
+ }
+ *last = NULL;
+ }
+ return GRN_SUCCESS;
+}
+
+static void
+grn_token_filters_pack(grn_ctx *ctx,
+ grn_obj *token_filters,
+ grn_obj *buffer)
+{
+ unsigned int i, n_token_filters;
+
+ n_token_filters = GRN_BULK_VSIZE(token_filters) / sizeof(grn_obj *);
+ for (i = 0; i < n_token_filters; i++) {
+ grn_obj *token_filter = GRN_PTR_VALUE_AT(token_filters, i);
+ grn_id token_filter_id;
+
+ token_filter_id = grn_obj_id(ctx, token_filter);
+ GRN_RECORD_PUT(ctx, buffer, token_filter_id);
+ }
+}
+
+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;
+ spec.range = obj->range;
+ grn_bulk_write(ctx, b, (void *)&spec, sizeof(grn_obj_spec));
+ grn_vector_delimit(ctx, &v, 0, 0);
+ if (obj->header.flags & GRN_OBJ_CUSTOM_NAME) {
+ GRN_TEXT_PUTS(ctx, b, grn_obj_path(ctx, (grn_obj *)obj));
+ }
+ grn_vector_delimit(ctx, &v, 0, 0);
+ grn_bulk_write(ctx, b, obj->source, obj->source_size);
+ grn_vector_delimit(ctx, &v, 0, 0);
+ grn_hook_pack(ctx, obj, b);
+ grn_vector_delimit(ctx, &v, 0, 0);
+ switch (obj->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ grn_token_filters_pack(ctx, &(((grn_hash *)obj)->token_filters), b);
+ grn_vector_delimit(ctx, &v, 0, 0);
+ break;
+ case GRN_TABLE_PAT_KEY :
+ grn_token_filters_pack(ctx, &(((grn_pat *)obj)->token_filters), b);
+ grn_vector_delimit(ctx, &v, 0, 0);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ grn_token_filters_pack(ctx, &(((grn_dat *)obj)->token_filters), b);
+ grn_vector_delimit(ctx, &v, 0, 0);
+ break;
+ case GRN_EXPR :
+ grn_expr_pack(ctx, b, (grn_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 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];
+ int source_name_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_is_table(ctx, source)) {
+ source_name[source_name_size] = '\0';
+ grn_strncat(source_name,
+ GRN_TABLE_MAX_KEY_SIZE,
+ "._key",
+ GRN_TABLE_MAX_KEY_SIZE - source_name_size - 1);
+ source_name_size = strlen(source_name);
+ }
+
+ ERR(GRN_INVALID_ARGUMENT,
+ "[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_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;
+
+ lexicon_id = obj->header.domain;
+ lexicon = grn_ctx_at(ctx, lexicon_id);
+ if (!lexicon) {
+ goto exit;
+ }
+
+ lexicon_domain_id = lexicon->header.domain;
+ lexicon_domain = grn_ctx_at(ctx, lexicon_domain_id);
+ if (!lexicon_domain) {
+ goto exit;
+ }
+
+ source_ids = (grn_id *)GRN_BULK_HEAD(value);
+ n_source_ids = GRN_BULK_VSIZE(value) / sizeof(grn_id);
+ if (n_source_ids > 1 && !(obj->header.flags & GRN_OBJ_WITH_SECTION)) {
+ char index_name[GRN_TABLE_MAX_KEY_SIZE];
+ int index_name_size;
+ index_name_size = grn_obj_name(ctx, obj,
+ index_name, GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_INVALID_ARGUMENT,
+ "grn_obj_set_info(): GRN_INFO_SOURCE: "
+ "multi column index must be created with WITH_SECTION flag: <%.*s>",
+ index_name_size, index_name);
+ 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_is_table(ctx, source)) {
+ source_type_id = source->header.domain;
+ } else {
+ source_type_id = DB_OBJ(source)->range;
+ }
+ 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 (ctx->rc != GRN_SUCCESS) {
+ goto exit;
+ }
+ }
+
+exit:
+ if (lexicon) {
+ grn_obj_unlink(ctx, lexicon);
+ }
+ if (lexicon_domain) {
+ grn_obj_unlink(ctx, lexicon_domain);
+ }
+ return ctx->rc;
+}
+
+inline static void
+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;
+ 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, ' ');
+ while (vs) {
+ n = _grn_table_key(ctx, ctx->impl->db, *vp++, &s);
+ GRN_TEXT_PUT(ctx, &buf, n, s);
+ vs -= sizeof(grn_id);
+ if (vs) { GRN_TEXT_PUTC(ctx, &buf, ','); }
+ }
+ 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);
+}
+
+inline static grn_rc
+grn_obj_set_info_source_update(grn_ctx *ctx, grn_obj *obj, grn_obj *value)
+{
+ void *v = GRN_BULK_HEAD(value);
+ uint32_t s = GRN_BULK_VSIZE(value);
+ if (s) {
+ void *v2 = GRN_MALLOC(s);
+ if (!v2) {
+ return ctx->rc;
+ }
+ grn_memcpy(v2, v, s);
+ if (DB_OBJ(obj)->source) { GRN_FREE(DB_OBJ(obj)->source); }
+ DB_OBJ(obj)->source = v2;
+ DB_OBJ(obj)->source_size = s;
+
+ if (obj->header.type == GRN_COLUMN_INDEX) {
+ update_source_hook(ctx, obj);
+ grn_index_column_build(ctx, obj);
+ }
+ } else {
+ DB_OBJ(obj)->source = NULL;
+ DB_OBJ(obj)->source_size = 0;
+ }
+
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+grn_obj_set_info_source(grn_ctx *ctx, grn_obj *obj, grn_obj *value)
+{
+ grn_rc rc;
+
+ rc = grn_obj_set_info_source_validate(ctx, obj, value);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ grn_obj_set_info_source_log(ctx, obj, value);
+ rc = grn_obj_set_info_source_update(ctx, obj, value);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ grn_obj_spec_save(ctx, DB_OBJ(obj));
+
+ return rc;
+}
+
+static grn_rc
+grn_obj_set_info_token_filters(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *token_filters)
+{
+ grn_obj *current_token_filters;
+ unsigned int i, n_current_token_filters, n_token_filters;
+ grn_obj token_filter_names;
+
+ switch (table->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ current_token_filters = &(((grn_hash *)table)->token_filters);
+ break;
+ case GRN_TABLE_PAT_KEY :
+ current_token_filters = &(((grn_pat *)table)->token_filters);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ current_token_filters = &(((grn_dat *)table)->token_filters);
+ break;
+ default :
+ /* TODO: Show type name instead of type ID */
+ ERR(GRN_INVALID_ARGUMENT,
+ "[info][set][token-filters] target object must be one of "
+ "GRN_TABLE_HASH_KEY, GRN_TABLE_PAT_KEY and GRN_TABLE_DAT_KEY: %d",
+ table->header.type);
+ return ctx->rc;
+ }
+
+ n_current_token_filters =
+ GRN_BULK_VSIZE(current_token_filters) / sizeof(grn_obj *);
+ n_token_filters = GRN_BULK_VSIZE(token_filters) / sizeof(grn_obj *);
+
+ GRN_TEXT_INIT(&token_filter_names, 0);
+ GRN_BULK_REWIND(current_token_filters);
+ for (i = 0; i < n_token_filters; i++) {
+ grn_obj *token_filter = GRN_PTR_VALUE_AT(token_filters, i);
+ char token_filter_name[GRN_TABLE_MAX_KEY_SIZE];
+ unsigned int token_filter_name_size;
+
+ GRN_PTR_PUT(ctx, current_token_filters, token_filter);
+
+ if (i > 0) {
+ GRN_TEXT_PUTC(ctx, &token_filter_names, ',');
+ }
+ token_filter_name_size = grn_obj_name(ctx,
+ token_filter,
+ token_filter_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ GRN_TEXT_PUT(ctx,
+ &token_filter_names,
+ token_filter_name,
+ token_filter_name_size);
+ }
+ if (n_token_filters > 0 || n_token_filters != n_current_token_filters) {
+ 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));
+ }
+ GRN_OBJ_FIN(ctx, &token_filter_names);
+ grn_obj_spec_save(ctx, DB_OBJ(table));
+
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_obj_set_info(grn_ctx *ctx, grn_obj *obj, grn_info_type type, grn_obj *value)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ GRN_API_ENTER;
+ if (!obj) {
+ ERR(GRN_INVALID_ARGUMENT, "grn_obj_set_info failed");
+ goto exit;
+ }
+ switch (type) {
+ case GRN_INFO_SOURCE :
+ if (!GRN_DB_OBJP(obj)) {
+ ERR(GRN_INVALID_ARGUMENT, "only db_obj can accept GRN_INFO_SOURCE");
+ goto exit;
+ }
+ rc = grn_obj_set_info_source(ctx, obj, value);
+ break;
+ case GRN_INFO_DEFAULT_TOKENIZER :
+ if (!value || DB_OBJ(value)->header.type == GRN_PROC) {
+ switch (DB_OBJ(obj)->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ ((grn_hash *)obj)->tokenizer = value;
+ ((grn_hash *)obj)->header.common->tokenizer = grn_obj_id(ctx, value);
+ rc = GRN_SUCCESS;
+ break;
+ case GRN_TABLE_PAT_KEY :
+ ((grn_pat *)obj)->tokenizer = value;
+ ((grn_pat *)obj)->header->tokenizer = grn_obj_id(ctx, value);
+ rc = GRN_SUCCESS;
+ break;
+ case GRN_TABLE_DAT_KEY :
+ ((grn_dat *)obj)->tokenizer = value;
+ ((grn_dat *)obj)->header->tokenizer = grn_obj_id(ctx, value);
+ rc = GRN_SUCCESS;
+ break;
+ }
+ }
+ break;
+ case GRN_INFO_NORMALIZER :
+ if (!value || DB_OBJ(value)->header.type == GRN_PROC) {
+ switch (DB_OBJ(obj)->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ ((grn_hash *)obj)->normalizer = value;
+ ((grn_hash *)obj)->header.common->normalizer = grn_obj_id(ctx, value);
+ rc = GRN_SUCCESS;
+ break;
+ case GRN_TABLE_PAT_KEY :
+ ((grn_pat *)obj)->normalizer = value;
+ ((grn_pat *)obj)->header->normalizer = grn_obj_id(ctx, value);
+ rc = GRN_SUCCESS;
+ break;
+ case GRN_TABLE_DAT_KEY :
+ ((grn_dat *)obj)->normalizer = value;
+ ((grn_dat *)obj)->header->normalizer = grn_obj_id(ctx, value);
+ rc = GRN_SUCCESS;
+ break;
+ }
+ }
+ break;
+ case GRN_INFO_TOKEN_FILTERS :
+ rc = grn_obj_set_info_token_filters(ctx, obj, value);
+ break;
+ default :
+ /* todo */
+ break;
+ }
+exit :
+ GRN_API_RETURN(rc);
+}
+
+grn_obj *
+grn_obj_get_element_info(grn_ctx *ctx, grn_obj *obj, grn_id id,
+ grn_info_type type, grn_obj *valuebuf)
+{
+ GRN_API_ENTER;
+ GRN_API_RETURN(valuebuf);
+}
+
+grn_rc
+grn_obj_set_element_info(grn_ctx *ctx, grn_obj *obj, grn_id id,
+ grn_info_type type, grn_obj *value)
+{
+ GRN_API_ENTER;
+ GRN_API_RETURN(GRN_SUCCESS);
+}
+
+static void
+grn_hook_free(grn_ctx *ctx, grn_hook *h)
+{
+ grn_hook *curr, *next;
+ for (curr = h; curr; curr = next) {
+ next = curr->next;
+ GRN_FREE(curr);
+ }
+}
+
+grn_rc
+grn_obj_add_hook(grn_ctx *ctx, grn_obj *obj, grn_hook_entry entry,
+ int offset, grn_obj *proc, grn_obj *hld)
+{
+ grn_rc rc = GRN_SUCCESS;
+ GRN_API_ENTER;
+ if (!GRN_DB_OBJP(obj)) {
+ rc = GRN_INVALID_ARGUMENT;
+ } else {
+ int i;
+ void *hld_value = NULL;
+ uint32_t hld_size = 0;
+ grn_hook *new, **last = &DB_OBJ(obj)->hooks[entry];
+ if (hld) {
+ hld_value = GRN_BULK_HEAD(hld);
+ hld_size = GRN_BULK_VSIZE(hld);
+ }
+ if (!(new = GRN_MALLOC(sizeof(grn_hook) + hld_size))) {
+ rc = GRN_NO_MEMORY_AVAILABLE;
+ goto exit;
+ }
+ new->proc = (grn_proc *)proc;
+ new->hld_size = hld_size;
+ if (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;
+ *last = new;
+ grn_obj_spec_save(ctx, DB_OBJ(obj));
+ }
+exit :
+ GRN_API_RETURN(rc);
+}
+
+int
+grn_obj_get_nhooks(grn_ctx *ctx, grn_obj *obj, grn_hook_entry entry)
+{
+ int res = 0;
+ GRN_API_ENTER;
+ {
+ grn_hook *hook = DB_OBJ(obj)->hooks[entry];
+ while (hook) {
+ res++;
+ hook = hook->next;
+ }
+ }
+ GRN_API_RETURN(res);
+}
+
+grn_obj *
+grn_obj_get_hook(grn_ctx *ctx, grn_obj *obj, grn_hook_entry entry,
+ int offset, grn_obj *hldbuf)
+{
+ grn_obj *res = NULL;
+ GRN_API_ENTER;
+ {
+ int i;
+ grn_hook *hook = DB_OBJ(obj)->hooks[entry];
+ for (i = 0; i < offset; i++) {
+ hook = hook->next;
+ if (!hook) { return NULL; }
+ }
+ res = (grn_obj *)hook->proc;
+ grn_bulk_write(ctx, hldbuf, (char *)GRN_NEXT_ADDR(hook), hook->hld_size);
+ }
+ GRN_API_RETURN(res);
+}
+
+grn_rc
+grn_obj_delete_hook(grn_ctx *ctx, grn_obj *obj, grn_hook_entry entry, int offset)
+{
+ GRN_API_ENTER;
+ {
+ int i = 0;
+ grn_hook *h, **last = &DB_OBJ(obj)->hooks[entry];
+ for (;;) {
+ if (!(h = *last)) { return GRN_INVALID_ARGUMENT; }
+ if (++i > offset) { break; }
+ last = &h->next;
+ }
+ *last = h->next;
+ GRN_FREE(h);
+ }
+ grn_obj_spec_save(ctx, DB_OBJ(obj));
+ GRN_API_RETURN(GRN_SUCCESS);
+}
+
+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) {
+ 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);
+ 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> -> <%.*s>",
+ length, name,
+ hook_name_length, hook_name);
+ rc = ctx->rc;
+ } else if (target->header.type == GRN_COLUMN_INDEX) {
+ //TODO: multicolumn MULTI_COLUMN_INDEXP
+ rc = _grn_obj_remove(ctx, target, GRN_FALSE);
+ } else {
+ //TODO: err
+ char fn[GRN_TABLE_MAX_KEY_SIZE];
+ int flen;
+ 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 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_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 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) {
+ 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 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;
+ while ((id = grn_table_cursor_next_inline(ctx, cur)) != GRN_ID_NIL) {
+ grn_obj *obj = grn_ctx_at(ctx, id);
+ grn_obj *range = NULL;
+
+ if (!obj) {
+ continue;
+ }
+
+ switch (obj->header.type) {
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ if (!DB_OBJ(obj)->range) {
+ break;
+ }
+
+ range = grn_ctx_at(ctx, DB_OBJ(obj)->range);
+ if (!range) {
+ break;
+ }
+
+ switch (range->header.type) {
+ 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 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;
+ while ((id = grn_table_cursor_next_inline(ctx, cur)) != GRN_ID_NIL) {
+ grn_obj *obj = grn_ctx_at(ctx, id);
+ grn_obj *domain = NULL;
+
+ if (!obj) {
+ continue;
+ }
+
+ switch (obj->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ if (!obj->header.domain) {
+ break;
+ }
+
+ domain = grn_ctx_at(ctx, obj->header.domain);
+ if (!domain) {
+ break;
+ }
+
+ switch (domain->header.type) {
+ 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 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;
+ while ((id = grn_table_cursor_next_inline(ctx, cur)) != GRN_ID_NIL) {
+ grn_obj *obj = grn_ctx_at(ctx, id);
+
+ if (!obj) {
+ continue;
+ }
+
+ switch (obj->header.type) {
+ 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;
+ }
+
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ grn_table_cursor_close(ctx, cur);
+ }
+ return rc;
+}
+
+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 ctx->rc;
+ }
+ } else {
+ spath = NULL;
+ }
+
+ key_type = s->keys->header.type;
+
+ rc = grn_obj_close(ctx, obj);
+ if (rc != GRN_SUCCESS) {
+ if (spath) {
+ GRN_FREE(spath);
+ }
+ return rc;
+ }
+
+ if (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 :
+ rc = grn_pat_remove(ctx, path);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ 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_rc
+remove_reference_tables(grn_ctx *ctx, grn_obj *table, grn_obj *db)
+{
+ 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,
+ GRN_CURSOR_BY_ID))) {
+ 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;
+ }
+
+ switch (object->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ if (DB_OBJ(object)->id == table_id) {
+ break;
+ }
+
+ if (object->header.domain == table_id) {
+ 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) {
+ 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;
+ }
+
+ 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 rc;
+}
+
+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, grn_bool dependent)
+{
+ 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;
+ }
+ }
+
+ 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) {
+ 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 grn_rc
+_grn_obj_remove_dat(grn_ctx *ctx, grn_obj *obj, grn_obj *db, grn_id id,
+ const char *path, grn_bool dependent)
+{
+ 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;
+ }
+ }
+
+ 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) {
+ 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 grn_rc
+_grn_obj_remove_hash(grn_ctx *ctx, grn_obj *obj, grn_obj *db, grn_id id,
+ const char *path, grn_bool dependent)
+{
+ 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;
+ }
+ }
+
+ 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) {
+ 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 grn_rc
+_grn_obj_remove_array(grn_ctx *ctx, grn_obj *obj, grn_obj *db, grn_id id,
+ const char *path, grn_bool dependent)
+{
+ 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;
+ }
+ }
+
+ 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) {
+ 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 grn_rc
+_grn_obj_remove_ja(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;
+
+ 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) {
+ 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 grn_rc
+_grn_obj_remove_ra(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;
+
+ 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) {
+ 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 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);
+ rc = grn_obj_close(ctx, obj);
+ if (rc != GRN_SUCCESS) { return rc; }
+
+ if (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 grn_rc
+_grn_obj_remove_db_obj(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;
+
+ rc = grn_obj_close(ctx, obj);
+ if (rc != GRN_SUCCESS) { return rc; }
+
+ if (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 grn_rc
+_grn_obj_remove_other(grn_ctx *ctx, grn_obj *obj, grn_obj *db, grn_id id,
+ const char *path)
+{
+ return grn_obj_close(ctx, 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;
+
+ 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 ctx->rc;
+ }
+ } else {
+ path = NULL;
+ }
+ if (GRN_DB_OBJP(obj)) {
+ id = DB_OBJ(obj)->id;
+ db = DB_OBJ(obj)->db;
+ }
+ switch (obj->header.type) {
+ case GRN_DB :
+ rc = _grn_obj_remove_db(ctx, obj, db, id, path);
+ break;
+ case GRN_TABLE_PAT_KEY :
+ rc = _grn_obj_remove_pat(ctx, obj, db, id, path, dependent);
+ is_temporary_open_target = GRN_TRUE;
+ break;
+ case GRN_TABLE_DAT_KEY :
+ rc = _grn_obj_remove_dat(ctx, obj, db, id, path, dependent);
+ is_temporary_open_target = GRN_TRUE;
+ break;
+ case GRN_TABLE_HASH_KEY :
+ rc = _grn_obj_remove_hash(ctx, obj, db, id, path, dependent);
+ is_temporary_open_target = GRN_TRUE;
+ break;
+ case GRN_TABLE_NO_KEY :
+ rc = _grn_obj_remove_array(ctx, obj, db, id, path, dependent);
+ is_temporary_open_target = GRN_TRUE;
+ break;
+ case GRN_COLUMN_VAR_SIZE :
+ rc = _grn_obj_remove_ja(ctx, obj, db, id, path);
+ is_temporary_open_target = GRN_TRUE;
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ rc = _grn_obj_remove_ra(ctx, obj, db, id, path);
+ is_temporary_open_target = GRN_TRUE;
+ break;
+ case GRN_COLUMN_INDEX :
+ rc = _grn_obj_remove_index(ctx, obj, db, id, path);
+ is_temporary_open_target = GRN_TRUE;
+ break;
+ default :
+ if (GRN_DB_OBJP(obj)) {
+ rc = _grn_obj_remove_db_obj(ctx, obj, db, id, path);
+ } else {
+ rc = _grn_obj_remove_other(ctx, obj, db, id, 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_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 {
+ rc = _grn_obj_remove(ctx, obj, GRN_FALSE);
+ }
+ 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
+grn_table_update_by_id(grn_ctx *ctx, grn_obj *table, grn_id id,
+ const void *dest_key, unsigned int dest_key_size)
+{
+ grn_rc rc = GRN_OPERATION_NOT_SUPPORTED;
+ GRN_API_ENTER;
+ if (table->header.type == GRN_TABLE_DAT_KEY) {
+ grn_dat *dat = (grn_dat *)table;
+ if (dat->io && !(dat->io->flags & GRN_IO_TEMPORARY)) {
+ if (grn_io_lock(ctx, dat->io, grn_lock_timeout)) {
+ rc = ctx->rc;
+ } else {
+ rc = grn_dat_update_by_id(ctx, dat, id, dest_key, dest_key_size);
+ grn_io_unlock(dat->io);
+ }
+ } else {
+ rc = grn_dat_update_by_id(ctx, dat, id, dest_key, dest_key_size);
+ }
+ }
+ GRN_API_RETURN(rc);
+}
+
+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_rc rc = GRN_OPERATION_NOT_SUPPORTED;
+ GRN_API_ENTER;
+ if (table->header.type == GRN_TABLE_DAT_KEY) {
+ rc = grn_dat_update(ctx, (grn_dat *)table,
+ src_key, src_key_size,
+ dest_key, dest_key_size);
+ }
+ GRN_API_RETURN(rc);
+}
+
+grn_rc
+grn_obj_rename(grn_ctx *ctx, grn_obj *obj, const char *name, unsigned int name_size)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ GRN_API_ENTER;
+ if (ctx && ctx->impl && GRN_DB_P(ctx->impl->db) && GRN_DB_OBJP(obj) && !IS_TEMP(obj)) {
+ grn_db *s = (grn_db *)ctx->impl->db;
+ grn_obj *keys = (grn_obj *)s->keys;
+ rc = grn_table_update_by_id(ctx, keys, DB_OBJ(obj)->id, name, name_size);
+ }
+ GRN_API_RETURN(rc);
+}
+
+grn_rc
+grn_table_rename(grn_ctx *ctx, grn_obj *table, const char *name, unsigned int name_size)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ grn_hash *cols;
+
+ GRN_API_ENTER;
+
+ if (!GRN_OBJ_TABLEP(table)) {
+ 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);
+ rc = GRN_INVALID_ARGUMENT;
+ ERR(rc,
+ "[table][rename] isn't table: <%.*s> -> <%.*s>",
+ table_name_size, table_name,
+ name_size, name);
+ goto exit;
+ }
+ if (IS_TEMP(table)) {
+ rc = GRN_INVALID_ARGUMENT;
+ ERR(rc,
+ "[table][rename] temporary table doesn't have name: "
+ "(anonymous) -> <%.*s>",
+ name_size, name);
+ goto exit;
+ }
+
+ if ((cols = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY))) {
+ grn_table_columns(ctx, table, "", 0, (grn_obj *)cols);
+ if (!(rc = grn_obj_rename(ctx, table, name, name_size))) {
+ grn_id *key;
+ char fullname[GRN_TABLE_MAX_KEY_SIZE];
+ grn_memcpy(fullname, name, name_size);
+ fullname[name_size] = GRN_DB_DELIMITER;
+ GRN_HASH_EACH(ctx, cols, id, &key, NULL, NULL, {
+ grn_obj *col = grn_ctx_at(ctx, *key);
+ if (col) {
+ int colname_len = grn_column_name(ctx, col, fullname + name_size + 1,
+ GRN_TABLE_MAX_KEY_SIZE - name_size - 1);
+ if (colname_len) {
+ if ((rc = grn_obj_rename(ctx, col, fullname,
+ name_size + 1 + colname_len))) {
+ break;
+ }
+ }
+ }
+ });
+ }
+ grn_hash_close(ctx, cols);
+ }
+exit:
+ GRN_API_RETURN(rc);
+}
+
+grn_rc
+grn_column_rename(grn_ctx *ctx, grn_obj *column, const char *name, unsigned int name_size)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ GRN_API_ENTER;
+ if (GRN_DB_OBJP(column)) {
+ char fullname[GRN_TABLE_MAX_KEY_SIZE];
+ grn_db *s = (grn_db *)DB_OBJ(column)->db;
+ int len = grn_table_get_key(ctx, s->keys, DB_OBJ(column)->header.domain,
+ fullname, GRN_TABLE_MAX_KEY_SIZE);
+ if (name_size + 1 + len > GRN_TABLE_MAX_KEY_SIZE) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[column][rename] 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);
+ goto exit;
+ }
+ fullname[len] = GRN_DB_DELIMITER;
+ 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);
+}
+
+grn_rc
+grn_obj_path_rename(grn_ctx *ctx, const char *old_path, const char *new_path)
+{
+ GRN_API_ENTER;
+ GRN_API_RETURN(GRN_SUCCESS);
+}
+
+/* db must be validated by caller */
+grn_id
+grn_obj_register(grn_ctx *ctx, grn_obj *db, const char *name, unsigned int name_size)
+{
+ grn_id id = GRN_ID_NIL;
+ if (name && name_size) {
+ grn_db *s = (grn_db *)db;
+ int added;
+ if (!(id = grn_table_add(ctx, s->keys, name, name_size, &added))) {
+ 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,
+ "[object][register] already used name was assigned: <%.*s>",
+ name_size, name);
+ id = GRN_ID_NIL;
+ }
+ } else if (ctx->impl && ctx->impl->values) {
+ id = grn_array_add(ctx, ctx->impl->values, NULL) | GRN_OBJ_TMP_OBJECT;
+ }
+ return id;
+}
+
+grn_rc
+grn_obj_delete_by_id(grn_ctx *ctx, grn_obj *db, grn_id id, grn_bool removep)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ GRN_API_ENTER;
+ if (id) {
+ if (id & GRN_OBJ_TMP_OBJECT) {
+ 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;
+ grn_db *s = (grn_db *)db;
+ if ((vp = grn_tiny_array_at(&s->values, id))) {
+ GRN_ASSERT(!vp->lock);
+ vp->lock = 0;
+ vp->ptr = NULL;
+ vp->done = 0;
+ }
+ if (removep) {
+ switch (s->keys->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ rc = grn_pat_delete_by_id(ctx, (grn_pat *)s->keys, id, NULL);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ rc = grn_dat_delete_by_id(ctx, (grn_dat *)s->keys, id, NULL);
+ break;
+ }
+ } else {
+ rc = GRN_SUCCESS;
+ }
+ }
+ }
+ GRN_API_RETURN(rc);
+}
+
+
+grn_rc
+grn_obj_path_by_id(grn_ctx *ctx, grn_obj *db, grn_id id, char *buffer)
+{
+ grn_rc rc = GRN_SUCCESS;
+ GRN_API_ENTER;
+ if (!GRN_DB_P(db) || !buffer) {
+ rc = GRN_INVALID_ARGUMENT;
+ } else {
+ grn_db_generate_pathname(ctx, db, id, buffer);
+ }
+ GRN_API_RETURN(rc);
+}
+
+/* db must be validated by caller */
+grn_rc
+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 (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;
+ vp = grn_tiny_array_at(&((grn_db *)db)->values, id);
+ if (!vp) {
+ rc = GRN_NO_MEMORY_AVAILABLE;
+ ERR(rc, "grn_tiny_array_at failed (%d)", id);
+ return rc;
+ }
+ vp->lock = 1;
+ vp->ptr = (grn_obj *)obj;
+ }
+ }
+ obj->id = id;
+ obj->db = db;
+ obj->source = NULL;
+ obj->source_size = 0;
+ {
+ grn_hook_entry entry;
+ for (entry = 0; entry < N_HOOK_ENTRIES; entry++) {
+ obj->hooks[entry] = NULL;
+ }
+ }
+ grn_obj_spec_save(ctx, obj);
+ return rc;
+}
+
+#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,\
+ decoded_spec,\
+ GRN_SERIALIZED_SPEC_INDEX_PATH,\
+ &path,\
+ NULL,\
+ NULL);\
+ if (size > PATH_MAX) { ERR(GRN_FILENAME_TOO_LONG, "too long path"); }\
+ grn_memcpy(buffer, path, size);\
+ buffer[size] = '\0';\
+ } else {\
+ grn_db_generate_pathname(ctx, (grn_obj *)s, id, buffer);\
+ }\
+} while (0)
+
+#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,\
+ decoded_spec,\
+ GRN_SERIALIZED_SPEC_INDEX_SOURCE,\
+ &p,\
+ NULL,\
+ NULL);\
+ if (size) {\
+ if ((r->source = GRN_MALLOC(size))) {\
+ grn_memcpy(r->source, p, size);\
+ r->source_size = size;\
+ }\
+ }\
+ size = grn_vector_get_element(ctx,\
+ decoded_spec,\
+ GRN_SERIALIZED_SPEC_INDEX_HOOK,\
+ &p,\
+ NULL,\
+ NULL);\
+ grn_hook_unpack(ctx, r, p, size);\
+ }\
+} while (0)
+
+static void
+grn_token_filters_unpack(grn_ctx *ctx,
+ grn_obj *token_filters,
+ grn_obj *spec_vector)
+{
+ grn_id *token_filter_ids;
+ unsigned int element_size;
+ unsigned int i, n_token_filter_ids;
+
+ if (grn_vector_size(ctx, spec_vector) <= GRN_SERIALIZED_SPEC_INDEX_TOKEN_FILTERS) {
+ return;
+ }
+
+ element_size = grn_vector_get_element(ctx,
+ spec_vector,
+ GRN_SERIALIZED_SPEC_INDEX_TOKEN_FILTERS,
+ (const char **)(&token_filter_ids),
+ NULL,
+ NULL);
+ n_token_filter_ids = element_size / sizeof(grn_id);
+ for (i = 0; i < n_token_filter_ids; i++) {
+ grn_id token_filter_id = token_filter_ids[i];
+ grn_obj *token_filter;
+
+ token_filter = grn_ctx_at(ctx, token_filter_id);
+ if (!token_filter) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "nonexistent token filter ID: %d", token_filter_id);
+ return;
+ }
+ GRN_PTR_PUT(ctx, token_filters, token_filter);
+ }
+}
+
+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)
+{
+ grn_obj *res = NULL;
+ if (!ctx || !ctx->impl || !id) { return res; }
+ GRN_API_ENTER;
+ if (id & GRN_OBJ_TMP_OBJECT) {
+ 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 {
+ grn_db *s = (grn_db *)ctx->impl->db;
+ if (s) {
+ db_value *vp;
+ uint32_t l, *pl, ntrial;
+ if (!(vp = grn_tiny_array_at(&s->values, id))) { goto exit; }
+#ifdef USE_NREF
+ pl = &vp->lock;
+ for (ntrial = 0;; ntrial++) {
+ GRN_ATOMIC_ADD_EX(pl, 1, l);
+ if (l < GRN_IO_MAX_REF) { break; }
+ if (ntrial >= 10) {
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "max trial in ctx_at(%p,%d)", vp->ptr, vp->lock);
+ break;
+ }
+ GRN_ATOMIC_ADD_EX(pl, -1, l);
+ GRN_FUTEX_WAIT(pl);
+ }
+#endif /* USE_NREF */
+ if (s->specs && !vp->ptr /* && !vp->done */) {
+#ifndef USE_NREF
+ pl = &vp->lock;
+ for (ntrial = 0;; ntrial++) {
+ GRN_ATOMIC_ADD_EX(pl, 1, l);
+ if (l < GRN_IO_MAX_REF) { break; }
+ if (ntrial >= 10) {
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "max trial in ctx_at(%p,%d)", vp->ptr, vp->lock);
+ break;
+ }
+ GRN_ATOMIC_ADD_EX(pl, -1, l);
+ GRN_FUTEX_WAIT(pl);
+ }
+#endif /* USE_NREF */
+ if (!l) {
+ 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];
+ 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_FIN(ctx, &decoded_spec);
+ grn_ja_unref(ctx, &iw);
+ }
+#ifndef USE_NREF
+ GRN_ATOMIC_ADD_EX(pl, -1, l);
+#endif /* USE_NREF */
+ vp->done = 1;
+ GRN_FUTEX_WAKE(&vp->ptr);
+ } else {
+ for (ntrial = 0; !vp->ptr; ntrial++) {
+ if (ntrial >= 1000) {
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "max trial in ctx_at(%d,%p,%d)!", id, vp->ptr, vp->lock);
+ break;
+ }
+ 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) {
+ grn_plugin_ensure_registered(ctx, res);
+ }
+ }
+ }
+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)
+{
+ grn_obj *obj = GRN_MALLOCN(grn_obj, 1);
+ if (obj) {
+ GRN_OBJ_INIT(obj, type, flags, domain);
+ obj->header.impl_flags |= GRN_OBJ_ALLOCATED;
+ }
+ return obj;
+}
+
+grn_obj *
+grn_obj_graft(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_obj *new = grn_obj_open(ctx, obj->header.type, obj->header.impl_flags, obj->header.domain);
+ if (new) {
+ /* todo : deep copy if (obj->header.impl_flags & GRN_OBJ_DO_SHALLOW_COPY) */
+ new->u.b.head = obj->u.b.head;
+ new->u.b.curr = obj->u.b.curr;
+ new->u.b.tail = obj->u.b.tail;
+ obj->u.b.head = NULL;
+ obj->u.b.curr = NULL;
+ obj->u.b.tail = NULL;
+ }
+ return new;
+}
+
+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) {
+ DB_OBJ(obj)->finalizer(ctx, 1, &obj, &DB_OBJ(obj)->user_data);
+ }
+ if (DB_OBJ(obj)->source) {
+ GRN_FREE(DB_OBJ(obj)->source);
+ }
+ for (entry = 0; entry < N_HOOK_ENTRIES; entry++) {
+ grn_hook_free(ctx, DB_OBJ(obj)->hooks[entry]);
+ }
+ grn_obj_delete_by_id(ctx, DB_OBJ(obj)->db, DB_OBJ(obj)->id, GRN_FALSE);
+ }
+ switch (obj->header.type) {
+ case GRN_VECTOR :
+ if (obj->u.v.body && !(obj->header.impl_flags & GRN_OBJ_REFER)) {
+ grn_obj_close(ctx, obj->u.v.body);
+ }
+ if (obj->u.v.sections) { GRN_FREE(obj->u.v.sections); }
+ if (obj->header.impl_flags & GRN_OBJ_ALLOCATED) { GRN_FREE(obj); }
+ rc = GRN_SUCCESS;
+ break;
+ case GRN_VOID :
+ case GRN_BULK :
+ case GRN_UVECTOR :
+ 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;
+ for (p = (grn_accessor *)obj; p; p = n) {
+ n = p->next;
+ GRN_FREE(p);
+ }
+ }
+ rc = GRN_SUCCESS;
+ break;
+ case GRN_SNIP :
+ rc = grn_snip_close(ctx, (grn_snip *)obj);
+ break;
+ case GRN_STRING :
+ rc = grn_string_close(ctx, obj);
+ break;
+ case GRN_CURSOR_TABLE_PAT_KEY :
+ grn_pat_cursor_close(ctx, (grn_pat_cursor *)obj);
+ break;
+ case GRN_CURSOR_TABLE_DAT_KEY :
+ grn_dat_cursor_close(ctx, (grn_dat_cursor *)obj);
+ break;
+ case GRN_CURSOR_TABLE_HASH_KEY :
+ grn_hash_cursor_close(ctx, (grn_hash_cursor *)obj);
+ break;
+ case GRN_CURSOR_TABLE_NO_KEY :
+ grn_array_cursor_close(ctx, (grn_array_cursor *)obj);
+ break;
+ case GRN_CURSOR_COLUMN_INDEX :
+ {
+ grn_index_cursor *ic = (grn_index_cursor *)obj;
+ if (ic->iic) { grn_ii_cursor_close(ctx, ic->iic); }
+ GRN_FREE(ic);
+ }
+ break;
+ 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;
+ break;
+ case GRN_DB :
+ rc = grn_db_close(ctx, obj);
+ break;
+ case GRN_TABLE_PAT_KEY :
+ rc = grn_pat_close(ctx, (grn_pat *)obj);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ rc = grn_dat_close(ctx, (grn_dat *)obj);
+ break;
+ case GRN_TABLE_HASH_KEY :
+ rc = grn_hash_close(ctx, (grn_hash *)obj);
+ break;
+ case GRN_TABLE_NO_KEY :
+ rc = grn_array_close(ctx, (grn_array *)obj);
+ break;
+ case GRN_COLUMN_VAR_SIZE :
+ rc = grn_ja_close(ctx, (grn_ja *)obj);
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ rc = grn_ra_close(ctx, (grn_ra *)obj);
+ break;
+ case GRN_COLUMN_INDEX :
+ rc = grn_ii_close(ctx, (grn_ii *)obj);
+ break;
+ case GRN_PROC :
+ {
+ uint32_t i;
+ grn_proc *p = (grn_proc *)obj;
+ /*
+ if (obj->header.domain) {
+ grn_hash_delete(ctx, ctx->impl->qe, &obj->header.domain, sizeof(grn_id), NULL);
+ }
+ */
+ for (i = 0; i < p->nvars; i++) {
+ grn_obj_close(ctx, &p->vars[i].value);
+ }
+ GRN_REALLOC(p->vars, 0);
+ grn_obj_close(ctx, &p->name_buf);
+ if (p->obj.range != GRN_ID_NIL) {
+ grn_plugin_close(ctx, p->obj.range);
+ }
+ GRN_FREE(obj);
+ rc = GRN_SUCCESS;
+ }
+ break;
+ case GRN_EXPR :
+ rc = grn_expr_close(ctx, obj);
+ break;
+ }
+ }
+ GRN_API_RETURN(rc);
+}
+
+void
+grn_obj_unlink(grn_ctx *ctx, grn_obj *obj)
+{
+ if (obj &&
+ (!GRN_DB_OBJP(obj) ||
+ (((grn_db_obj *)obj)->id & GRN_OBJ_TMP_OBJECT) ||
+ (((grn_db_obj *)obj)->id == GRN_ID_NIL) ||
+ obj->header.type == GRN_DB)) {
+ grn_obj_close(ctx, obj);
+ } else if (GRN_DB_OBJP(obj)) {
+#ifdef USE_NREF
+ grn_db_obj *dob = DB_OBJ(obj);
+ grn_db *s = (grn_db *)dob->db;
+ db_value *vp = grn_tiny_array_at(&s->values, dob->id);
+ if (vp) {
+ uint32_t l, *pl = &vp->lock;
+ if (!vp->lock) {
+ GRN_LOG(ctx, GRN_LOG_ERROR, "invalid unlink(%p,%d)", obj, vp->lock);
+ return;
+ }
+ GRN_ATOMIC_ADD_EX(pl, -1, l);
+ if (l == 1) {
+ GRN_ATOMIC_ADD_EX(pl, GRN_IO_MAX_REF, l);
+ if (l == GRN_IO_MAX_REF) {
+#ifdef CALL_FINALIZER
+ grn_obj_close(ctx, obj);
+ vp->done = 0;
+ if (dob->finalizer) {
+ dob->finalizer(ctx, 1, &obj, &dob->user_data);
+ dob->finalizer = NULL;
+ dob->user_data.ptr = NULL;
+ }
+#endif /* CALL_FINALIZER */
+ }
+ GRN_ATOMIC_ADD_EX(pl, -GRN_IO_MAX_REF, l);
+ GRN_FUTEX_WAKE(pl);
+ }
+ }
+#endif /* USE_NREF */
+ }
+}
+
+#define VECTOR_CLEAR(ctx,obj) do {\
+ if ((obj)->u.v.body && !((obj)->header.impl_flags & GRN_OBJ_REFER)) {\
+ grn_obj_close((ctx), (obj)->u.v.body);\
+ }\
+ if ((obj)->u.v.sections) { GRN_FREE((obj)->u.v.sections); }\
+ (obj)->header.impl_flags &= ~GRN_OBJ_DO_SHALLOW_COPY;\
+ (obj)->u.b.head = NULL;\
+ (obj)->u.b.curr = NULL;\
+ (obj)->u.b.tail = NULL;\
+} while (0)
+
+static void
+grn_obj_ensure_vector(grn_ctx *ctx, grn_obj *obj)
+{
+ if (obj->header.type != GRN_VECTOR) { grn_bulk_fin(ctx, obj); }
+ obj->header.type = GRN_VECTOR;
+ obj->header.flags &= ~GRN_OBJ_WITH_WEIGHT;
+}
+
+static void
+grn_obj_ensure_bulk(grn_ctx *ctx, grn_obj *obj)
+{
+ if (obj->header.type == GRN_VECTOR) { VECTOR_CLEAR(ctx, obj); }
+ obj->header.type = GRN_BULK;
+ obj->header.flags &= ~GRN_OBJ_WITH_WEIGHT;
+}
+
+grn_rc
+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); }
+ obj->header.type = GRN_VOID;
+ obj->header.domain = domain;
+ GRN_BULK_REWIND(obj);
+ break;
+ case GRN_DB_OBJECT :
+ case GRN_DB_BOOL :
+ case GRN_DB_INT8 :
+ case GRN_DB_UINT8 :
+ case GRN_DB_INT16 :
+ case GRN_DB_UINT16 :
+ case GRN_DB_INT32 :
+ case GRN_DB_UINT32 :
+ case GRN_DB_INT64 :
+ case GRN_DB_UINT64 :
+ case GRN_DB_FLOAT :
+ case GRN_DB_TIME :
+ case GRN_DB_TOKYO_GEO_POINT :
+ case GRN_DB_WGS84_GEO_POINT :
+ if (obj->header.type == GRN_VECTOR) { VECTOR_CLEAR(ctx, obj); }
+ obj->header.type = (flags & GRN_OBJ_VECTOR) ? GRN_UVECTOR : GRN_BULK;
+ obj->header.domain = domain;
+ GRN_BULK_REWIND(obj);
+ break;
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ if (flags & GRN_OBJ_VECTOR) {
+ if (obj->header.type != GRN_VECTOR) { grn_bulk_fin(ctx, obj); }
+ obj->header.type = GRN_VECTOR;
+ if (obj->u.v.body) {
+ grn_obj_reinit(ctx, obj->u.v.body, domain, 0);
+ }
+ obj->u.v.n_sections = 0;
+ } else {
+ if (obj->header.type == GRN_VECTOR) { VECTOR_CLEAR(ctx, obj); }
+ obj->header.type = GRN_BULK;
+ }
+ obj->header.domain = domain;
+ GRN_BULK_REWIND(obj);
+ break;
+ default :
+ {
+ grn_obj *d = grn_ctx_at(ctx, domain);
+ if (!d) {
+ ERR(GRN_INVALID_ARGUMENT, "invalid domain assigned");
+ } else {
+ if (d->header.type == GRN_TYPE && (d->header.flags & GRN_OBJ_KEY_VAR_SIZE)) {
+ if (flags & GRN_OBJ_VECTOR) {
+ if (obj->header.type != GRN_VECTOR) { grn_bulk_fin(ctx, obj); }
+ obj->header.type = GRN_VECTOR;
+ } else {
+ if (obj->header.type == GRN_VECTOR) { VECTOR_CLEAR(ctx, obj); }
+ obj->header.type = GRN_BULK;
+ }
+ } else {
+ if (obj->header.type == GRN_VECTOR) { VECTOR_CLEAR(ctx, obj); }
+ obj->header.type = (flags & GRN_OBJ_VECTOR) ? GRN_UVECTOR : GRN_BULK;
+ }
+ obj->header.domain = domain;
+ GRN_BULK_REWIND(obj);
+ }
+ }
+ break;
+ }
+ }
+ return ctx->rc;
+}
+
+grn_rc
+grn_obj_reinit_for(grn_ctx *ctx, grn_obj *obj, grn_obj *domain_obj)
+{
+ grn_id domain = GRN_ID_NIL;
+ grn_obj_flags flags = 0;
+
+ if (!GRN_DB_OBJP(domain_obj) && domain_obj->header.type != GRN_ACCESSOR) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ 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));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return ctx->rc;
+ }
+
+ if (grn_column_is_index(ctx, domain_obj)) {
+ domain = GRN_DB_UINT32;
+ } else {
+ grn_obj_get_range_info(ctx, domain_obj, &domain, &flags);
+ if (GRN_OBJ_TABLEP(domain_obj) &&
+ domain_obj->header.type != GRN_TABLE_NO_KEY) {
+ domain = domain_obj->header.domain;
+ }
+ }
+ return grn_obj_reinit(ctx, obj, domain, flags);
+}
+
+const char *
+grn_obj_path(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_io *io;
+ const char *path = NULL;
+ GRN_API_ENTER;
+ if (obj->header.type == GRN_PROC) {
+ path = grn_plugin_path(ctx, DB_OBJ(obj)->range);
+ GRN_API_RETURN(path);
+ }
+ io = grn_obj_get_io(ctx, obj);
+ if (io && !(io->flags & GRN_IO_TEMPORARY)) { path = io->path; }
+ GRN_API_RETURN(path);
+}
+
+int
+grn_obj_name(grn_ctx *ctx, grn_obj *obj, char *namebuf, int buf_size)
+{
+ int len = 0;
+ GRN_API_ENTER;
+ if (GRN_DB_OBJP(obj)) {
+ if (DB_OBJ(obj)->id) {
+ grn_db *s = (grn_db *)DB_OBJ(obj)->db;
+ 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);
+ }
+ }
+ }
+ GRN_API_RETURN(len);
+}
+
+int
+grn_column_name(grn_ctx *ctx, grn_obj *obj, char *namebuf, int buf_size)
+{
+ int len = 0;
+ char buf[GRN_TABLE_MAX_KEY_SIZE];
+ if (!obj) { return len; }
+ GRN_API_ENTER;
+ if (GRN_DB_OBJP(obj)) {
+ 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, 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) {
+ 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 :
+ ADD_DELMITER();
+ GRN_TEXT_PUTS(ctx, &name, GRN_COLUMN_NAME_ID);
+ break;
+ case GRN_ACCESSOR_GET_KEY :
+ if (!a->next) {
+ ADD_DELMITER();
+ GRN_TEXT_PUTS(ctx, &name, GRN_COLUMN_NAME_KEY);
+ }
+ break;
+ case GRN_ACCESSOR_GET_VALUE :
+ if (!a->next) {
+ ADD_DELMITER();
+ GRN_TEXT_PUTS(ctx, &name, GRN_COLUMN_NAME_VALUE);
+ }
+ break;
+ case GRN_ACCESSOR_GET_SCORE :
+ ADD_DELMITER();
+ GRN_TEXT_PUTS(ctx, &name, GRN_COLUMN_NAME_SCORE);
+ break;
+ case GRN_ACCESSOR_GET_NSUBRECS :
+ ADD_DELMITER();
+ GRN_TEXT_PUTS(ctx, &name, GRN_COLUMN_NAME_NSUBRECS);
+ break;
+ case GRN_ACCESSOR_GET_MAX :
+ ADD_DELMITER();
+ GRN_TEXT_PUTS(ctx, &name, GRN_COLUMN_NAME_MAX);
+ break;
+ case GRN_ACCESSOR_GET_MIN :
+ ADD_DELMITER();
+ GRN_TEXT_PUTS(ctx, &name, GRN_COLUMN_NAME_MIN);
+ break;
+ case GRN_ACCESSOR_GET_SUM :
+ ADD_DELMITER();
+ GRN_TEXT_PUTS(ctx, &name, GRN_COLUMN_NAME_SUM);
+ break;
+ case GRN_ACCESSOR_GET_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;
+ }
+ }
+#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);
+}
+
+grn_rc
+grn_column_name_(grn_ctx *ctx, grn_obj *obj, grn_obj *buf)
+{
+ if (GRN_DB_OBJP(obj)) {
+ 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;
+ 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;
+ for (a = (grn_accessor *)obj; a; a = a->next) {
+ switch (a->action) {
+ case GRN_ACCESSOR_GET_ID :
+ GRN_TEXT_PUT(ctx, buf, GRN_COLUMN_NAME_ID, GRN_COLUMN_NAME_ID_LEN);
+ break;
+ case GRN_ACCESSOR_GET_KEY :
+ if (!a->next) {
+ GRN_TEXT_PUT(ctx, buf, GRN_COLUMN_NAME_KEY, GRN_COLUMN_NAME_KEY_LEN);
+ }
+ break;
+ case GRN_ACCESSOR_GET_VALUE :
+ if (!a->next) {
+ GRN_TEXT_PUT(ctx, buf,
+ GRN_COLUMN_NAME_VALUE,
+ GRN_COLUMN_NAME_VALUE_LEN);
+ }
+ 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, a->obj, buf);
+ if (a->next) { GRN_TEXT_PUTC(ctx, buf, '.'); }
+ break;
+ case GRN_ACCESSOR_GET_DB_OBJ :
+ case GRN_ACCESSOR_LOOKUP :
+ case GRN_ACCESSOR_FUNCALL :
+ break;
+ }
+ }
+ }
+ return ctx->rc;
+}
+
+int
+grn_obj_expire(grn_ctx *ctx, grn_obj *obj, int threshold)
+{
+ GRN_API_ENTER;
+ GRN_API_RETURN(0);
+}
+
+int
+grn_obj_check(grn_ctx *ctx, grn_obj *obj)
+{
+ GRN_API_ENTER;
+ GRN_API_RETURN(0);
+}
+
+grn_rc
+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_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);
+}
+
+grn_rc
+grn_obj_unlock(grn_ctx *ctx, grn_obj *obj, grn_id id)
+{
+ GRN_API_ENTER;
+ 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);
+}
+
+grn_user_data *
+grn_obj_user_data(grn_ctx *ctx, grn_obj *obj)
+{
+ if (!GRN_DB_OBJP(obj)) { return NULL; }
+ return &DB_OBJ(obj)->user_data;
+}
+
+grn_rc
+grn_obj_set_finalizer(grn_ctx *ctx, grn_obj *obj, grn_proc_func *func)
+{
+ if (!GRN_DB_OBJP(obj)) { return GRN_INVALID_ARGUMENT; }
+ DB_OBJ(obj)->finalizer = func;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_obj_clear_lock(grn_ctx *ctx, grn_obj *obj)
+{
+ GRN_API_ENTER;
+ switch (obj->header.type) {
+ case GRN_DB:
+ {
+ grn_table_cursor *cur;
+ if ((cur = grn_table_cursor_open(ctx, obj, NULL, 0, NULL, 0, 0, -1, 0))) {
+ grn_id id;
+ while ((id = grn_table_cursor_next_inline(ctx, cur)) != GRN_ID_NIL) {
+ grn_obj *tbl = grn_ctx_at(ctx, id);
+ if (tbl) {
+ switch (tbl->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY:
+ case GRN_TABLE_DAT_KEY:
+ case GRN_TABLE_NO_KEY:
+ grn_obj_clear_lock(ctx, tbl);
+ break;
+ }
+ } else {
+ if (ctx->rc != GRN_SUCCESS) {
+ ERRCLR(ctx);
+ }
+ }
+ }
+ grn_table_cursor_close(ctx, cur);
+ }
+ }
+ 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);
+ /* fallthru */
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ {
+ 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_clear_lock(ctx, col); }
+ });
+ }
+ grn_hash_close(ctx, cols);
+ }
+ 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_get_io(ctx, obj));
+ if (obj) {
+ grn_io_clear_lock(((grn_ii *)obj)->chunk);
+ }
+ break;
+ }
+ GRN_API_RETURN(GRN_SUCCESS);
+}
+
+unsigned int
+grn_obj_is_locked(grn_ctx *ctx, grn_obj *obj)
+{
+ unsigned int res = 0;
+ GRN_API_ENTER;
+ 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);
+}
+
+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 && 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 :
+ rc = grn_dat_flush(ctx, (grn_dat *)obj);
+ break;
+ case GRN_COLUMN_INDEX :
+ rc = grn_ii_flush(ctx, (grn_ii *)obj);
+ break;
+ default :
+ {
+ 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);
+}
+
+grn_rc
+grn_obj_flush_recursive(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_rc rc = GRN_SUCCESS;
+
+ GRN_API_ENTER;
+ switch (obj->header.type) {
+ case GRN_DB :
+ {
+ grn_table_cursor *cursor;
+ grn_id id;
+
+ cursor = grn_table_cursor_open(ctx, obj, NULL, 0, NULL, 0, 0, -1, 0);
+ if (!cursor) {
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ while ((id = grn_table_cursor_next_inline(ctx, cursor)) != GRN_ID_NIL) {
+ grn_obj *table = grn_ctx_at(ctx, id);
+ rc = GRN_SUCCESS;
+ if (table) {
+ 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_flush_recursive(ctx, table);
+ break;
+ }
+ } else {
+ if (ctx->rc != GRN_SUCCESS) {
+ ERRCLR(ctx);
+ }
+ }
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ grn_table_cursor_close(ctx, cursor);
+ }
+ if (rc == GRN_SUCCESS) {
+ rc = grn_obj_flush(ctx, obj);
+ }
+ break;
+ case GRN_TABLE_NO_KEY :
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ {
+ grn_hash *columns;
+ columns = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY);
+ if (!columns) {
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ if (grn_table_columns(ctx, obj, "", 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) {
+ rc = grn_obj_flush(ctx, column);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ });
+ }
+ grn_hash_close(ctx, columns);
+ }
+
+ if (rc == GRN_SUCCESS) {
+ rc = grn_obj_flush(ctx, obj);
+ }
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ case GRN_COLUMN_INDEX :
+ rc = grn_obj_flush(ctx, obj);
+ break;
+ default :
+ {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, obj);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[flush] object must be DB, table or column: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ rc = ctx->rc;
+ GRN_OBJ_FIN(ctx, &inspected);
+ }
+ break;
+ }
+
+ GRN_API_RETURN(rc);
+}
+
+grn_obj *
+grn_obj_db(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_obj *db = NULL;
+ GRN_API_ENTER;
+ if (GRN_DB_OBJP(obj)) { db = DB_OBJ(obj)->db; }
+ GRN_API_RETURN(db);
+}
+
+grn_id
+grn_obj_id(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_id id = GRN_ID_NIL;
+ GRN_API_ENTER;
+ if (GRN_DB_OBJP(obj)) {
+ id = DB_OBJ(obj)->id;
+ }
+ GRN_API_RETURN(id);
+}
+
+int
+grn_obj_defrag(grn_ctx *ctx, grn_obj *obj, int threshold)
+{
+ int r = 0;
+ GRN_API_ENTER;
+ switch (obj->header.type) {
+ case GRN_DB:
+ {
+ grn_table_cursor *cur;
+ if ((cur = grn_table_cursor_open(ctx, obj, NULL, 0, NULL, 0, 0, -1, 0))) {
+ grn_id id;
+ while ((id = grn_table_cursor_next_inline(ctx, cur)) != GRN_ID_NIL) {
+ grn_obj *ja = grn_ctx_at(ctx, id);
+ if (ja && ja->header.type == GRN_COLUMN_VAR_SIZE) {
+ r += grn_ja_defrag(ctx, (grn_ja *)ja, threshold);
+ }
+ }
+ grn_table_cursor_close(ctx, cur);
+ }
+ }
+ break;
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ {
+ 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) {
+ r += grn_obj_defrag(ctx, col, threshold);
+ grn_obj_unlink(ctx, col);
+ }
+ });
+ }
+ grn_hash_close(ctx, cols);
+ }
+ }
+ break;
+ case GRN_COLUMN_VAR_SIZE:
+ r = grn_ja_defrag(ctx, (grn_ja *)obj, threshold);
+ break;
+ }
+ GRN_API_RETURN(r);
+}
+
+/**** sort ****/
+
+typedef struct {
+ grn_id id;
+ uint32_t size;
+ const void *value;
+} sort_reference_entry;
+
+enum {
+ KEY_ID = 0,
+ KEY_BULK,
+ KEY_INT8,
+ KEY_INT16,
+ KEY_INT32,
+ KEY_INT64,
+ KEY_UINT8,
+ KEY_UINT16,
+ KEY_UINT32,
+ KEY_UINT64,
+ KEY_FLOAT32,
+ KEY_FLOAT64,
+};
+
+#define CMPNUM(type) do {\
+ if (as) {\
+ if (bs) {\
+ type va = *((type *)(ap));\
+ type vb = *((type *)(bp));\
+ if (va != vb) { return va > vb; }\
+ } else {\
+ return 1;\
+ }\
+ } else {\
+ if (bs) { return 0; }\
+ }\
+} while (0)
+
+inline static int
+compare_reference(grn_ctx *ctx,
+ sort_reference_entry *a, sort_reference_entry *b,
+ grn_table_sort_key *keys, int n_keys)
+{
+ int i;
+ uint8_t type;
+ uint32_t as, bs;
+ const unsigned char *ap, *bp;
+ for (i = 0; i < n_keys; i++, keys++) {
+ if (i) {
+ const char *ap_raw, *bp_raw;
+ if (keys->flags & GRN_TABLE_SORT_DESC) {
+ ap_raw = grn_obj_get_value_(ctx, keys->key, b->id, &as);
+ bp_raw = grn_obj_get_value_(ctx, keys->key, a->id, &bs);
+ } else {
+ ap_raw = grn_obj_get_value_(ctx, keys->key, a->id, &as);
+ bp_raw = grn_obj_get_value_(ctx, keys->key, b->id, &bs);
+ }
+ ap = (const unsigned char *)ap_raw;
+ bp = (const unsigned char *)bp_raw;
+ } else {
+ if (keys->flags & GRN_TABLE_SORT_DESC) {
+ ap = b->value; as = b->size;
+ bp = a->value; bs = a->size;
+ } else {
+ ap = a->value; as = a->size;
+ bp = b->value; bs = b->size;
+ }
+ }
+ type = keys->offset;
+ switch (type) {
+ case KEY_ID :
+ if (ap != bp) { return ap > bp; }
+ break;
+ case KEY_BULK :
+ for (;; ap++, bp++, as--, bs--) {
+ if (!as) { if (bs) { return 0; } else { break; } }
+ if (!bs) { return 1; }
+ if (*ap < *bp) { return 0; }
+ if (*ap > *bp) { return 1; }
+ }
+ break;
+ case KEY_INT8 :
+ CMPNUM(int8_t);
+ break;
+ case KEY_INT16 :
+ CMPNUM(int16_t);
+ break;
+ case KEY_INT32 :
+ CMPNUM(int32_t);
+ break;
+ case KEY_INT64 :
+ CMPNUM(int64_t);
+ break;
+ case KEY_UINT8 :
+ CMPNUM(uint8_t);
+ break;
+ case KEY_UINT16 :
+ CMPNUM(uint16_t);
+ break;
+ case KEY_UINT32 :
+ CMPNUM(uint32_t);
+ break;
+ case KEY_UINT64 :
+ CMPNUM(uint64_t);
+ break;
+ case KEY_FLOAT32 :
+ if (as) {
+ if (bs) {
+ float va = *((float *)(ap));
+ float vb = *((float *)(bp));
+ if (va < vb || va > vb) { return va > vb; }
+ } else {
+ return 1;
+ }
+ } else {
+ if (bs) { return 0; }
+ }
+ break;
+ case KEY_FLOAT64 :
+ if (as) {
+ if (bs) {
+ double va = *((double *)(ap));
+ double vb = *((double *)(bp));
+ if (va < vb || va > vb) { return va > vb; }
+ } else {
+ return 1;
+ }
+ } else {
+ if (bs) { return 0; }
+ }
+ break;
+ }
+ }
+ return 0;
+}
+
+inline static void
+swap_reference(sort_reference_entry *a, sort_reference_entry *b)
+{
+ sort_reference_entry c_ = *a;
+ *a = *b;
+ *b = c_;
+}
+
+inline static sort_reference_entry *
+part_reference(grn_ctx *ctx,
+ sort_reference_entry *b, sort_reference_entry *e,
+ grn_table_sort_key *keys, int n_keys)
+{
+ sort_reference_entry *c;
+ intptr_t d = e - b;
+ if (compare_reference(ctx, b, e, keys, n_keys)) {
+ swap_reference(b, e);
+ }
+ if (d < 2) { return NULL; }
+ c = b + (d >> 1);
+ if (compare_reference(ctx, b, c, keys, n_keys)) {
+ swap_reference(b, c);
+ } else {
+ if (compare_reference(ctx, c, e, keys, n_keys)) {
+ swap_reference(c, e);
+ }
+ }
+ if (d < 3) { return NULL; }
+ b++;
+ swap_reference(b, c);
+ c = b;
+ for (;;) {
+ do {
+ b++;
+ } while (compare_reference(ctx, c, b, keys, n_keys));
+ do {
+ e--;
+ } while (compare_reference(ctx, e, c, keys, n_keys));
+ if (b >= e) { break; }
+ swap_reference(b, e);
+ }
+ swap_reference(c, e);
+ return e;
+}
+
+static void
+sort_reference(grn_ctx *ctx,
+ sort_reference_entry *head, sort_reference_entry *tail,
+ int from, int to,
+ grn_table_sort_key *keys, int n_keys)
+{
+ sort_reference_entry *c;
+ if (head < tail && (c = part_reference(ctx, head, tail, keys, n_keys))) {
+ intptr_t m = c - head + 1;
+ if (from < m - 1) {
+ sort_reference(ctx, head, c - 1, from, to, keys, n_keys);
+ }
+ if (m < to) {
+ sort_reference(ctx, c + 1, tail, from - m, to - m, keys, n_keys);
+ }
+ }
+}
+
+static sort_reference_entry *
+pack_reference(grn_ctx *ctx, grn_obj *table,
+ sort_reference_entry *head, sort_reference_entry *tail,
+ grn_table_sort_key *keys, int n_keys)
+{
+ int i = 0;
+ sort_reference_entry e, c;
+ grn_table_cursor *tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1, 0);
+ if (!tc) { return NULL; }
+ if ((c.id = grn_table_cursor_next_inline(ctx, tc))) {
+ c.value = grn_obj_get_value_(ctx, keys->key, c.id, &c.size);
+ while ((e.id = grn_table_cursor_next_inline(ctx, tc))) {
+ e.value = grn_obj_get_value_(ctx, keys->key, e.id, &e.size);
+ if (compare_reference(ctx, &c, &e, keys, n_keys)) {
+ *head++ = e;
+ } else {
+ *tail-- = e;
+ }
+ i++;
+ }
+ *head = c;
+ i++;
+ }
+ grn_table_cursor_close(ctx, tc);
+ return i > 2 ? head : NULL;
+}
+
+static int
+grn_table_sort_reference(grn_ctx *ctx, grn_obj *table,
+ int offset, int limit,
+ grn_obj *result,
+ grn_table_sort_key *keys, int n_keys)
+{
+ int e, n;
+ sort_reference_entry *array, *ep;
+ e = offset + limit;
+ n = grn_table_size(ctx, table);
+ if (!(array = GRN_MALLOC(sizeof(sort_reference_entry) * n))) {
+ return 0;
+ }
+ if ((ep = pack_reference(ctx, table, array, array + n - 1, keys, n_keys))) {
+ intptr_t m = ep - array + 1;
+ if (offset < m - 1) {
+ sort_reference(ctx, array, ep - 1, offset, e, keys, n_keys);
+ }
+ if (m < e) {
+ sort_reference(ctx, ep + 1, array + n - 1, offset - m, e - m, keys, n_keys);
+ }
+ }
+ {
+ int i;
+ grn_id *v;
+ for (i = 0, ep = array + offset; i < limit && ep < array + n; i++, ep++) {
+ if (!grn_array_add(ctx, (grn_array *)result, (void **)&v)) { break; }
+ *v = ep->id;
+ }
+ GRN_FREE(array);
+ return i;
+ }
+}
+
+
+typedef struct {
+ grn_id id;
+ grn_obj value;
+} sort_value_entry;
+
+inline static int
+compare_value(grn_ctx *ctx,
+ sort_value_entry *a, sort_value_entry *b,
+ grn_table_sort_key *keys, int n_keys,
+ grn_obj *a_buffer, grn_obj *b_buffer)
+{
+ int i;
+ uint8_t type;
+ uint32_t as, bs;
+ const unsigned char *ap, *bp;
+ for (i = 0; i < n_keys; i++, keys++) {
+ if (i) {
+ GRN_BULK_REWIND(a_buffer);
+ GRN_BULK_REWIND(b_buffer);
+ if (keys->flags & GRN_TABLE_SORT_DESC) {
+ grn_obj_get_value(ctx, keys->key, b->id, a_buffer);
+ grn_obj_get_value(ctx, keys->key, a->id, b_buffer);
+ } else {
+ grn_obj_get_value(ctx, keys->key, a->id, a_buffer);
+ grn_obj_get_value(ctx, keys->key, b->id, b_buffer);
+ }
+ ap = (const unsigned char *)GRN_BULK_HEAD(a_buffer);
+ as = GRN_BULK_VSIZE(a_buffer);
+ bp = (const unsigned char *)GRN_BULK_HEAD(b_buffer);
+ bs = GRN_BULK_VSIZE(b_buffer);
+ } else {
+ if (keys->flags & GRN_TABLE_SORT_DESC) {
+ ap = (const unsigned char *)GRN_BULK_HEAD(&b->value);
+ as = GRN_BULK_VSIZE(&b->value);
+ bp = (const unsigned char *)GRN_BULK_HEAD(&a->value);
+ bs = GRN_BULK_VSIZE(&a->value);
+ } else {
+ ap = (const unsigned char *)GRN_BULK_HEAD(&a->value);
+ as = GRN_BULK_VSIZE(&a->value);
+ bp = (const unsigned char *)GRN_BULK_HEAD(&b->value);
+ bs = GRN_BULK_VSIZE(&b->value);
+ }
+ }
+ type = keys->offset;
+ switch (type) {
+ case KEY_ID :
+ if (ap != bp) { return ap > bp; }
+ break;
+ case KEY_BULK :
+ for (;; ap++, bp++, as--, bs--) {
+ if (!as) { if (bs) { return 0; } else { break; } }
+ if (!bs) { return 1; }
+ if (*ap < *bp) { return 0; }
+ if (*ap > *bp) { return 1; }
+ }
+ break;
+ case KEY_INT8 :
+ CMPNUM(int8_t);
+ break;
+ case KEY_INT16 :
+ CMPNUM(int16_t);
+ break;
+ case KEY_INT32 :
+ CMPNUM(int32_t);
+ break;
+ case KEY_INT64 :
+ CMPNUM(int64_t);
+ break;
+ case KEY_UINT8 :
+ CMPNUM(uint8_t);
+ break;
+ case KEY_UINT16 :
+ CMPNUM(uint16_t);
+ break;
+ case KEY_UINT32 :
+ CMPNUM(uint32_t);
+ break;
+ case KEY_UINT64 :
+ CMPNUM(uint64_t);
+ break;
+ case KEY_FLOAT32 :
+ if (as) {
+ if (bs) {
+ float va = *((float *)(ap));
+ float vb = *((float *)(bp));
+ if (va < vb || va > vb) { return va > vb; }
+ } else {
+ return 1;
+ }
+ } else {
+ if (bs) { return 0; }
+ }
+ break;
+ case KEY_FLOAT64 :
+ if (as) {
+ if (bs) {
+ double va = *((double *)(ap));
+ double vb = *((double *)(bp));
+ if (va < vb || va > vb) { return va > vb; }
+ } else {
+ return 1;
+ }
+ } else {
+ if (bs) { return 0; }
+ }
+ break;
+ }
+ }
+ return 0;
+}
+
+inline static void
+swap_value(sort_value_entry *a, sort_value_entry *b)
+{
+ sort_value_entry c_ = *a;
+ *a = *b;
+ *b = c_;
+}
+
+inline static sort_value_entry *
+part_value(grn_ctx *ctx,
+ sort_value_entry *b, sort_value_entry *e,
+ grn_table_sort_key *keys, int n_keys,
+ grn_obj *a_buffer, grn_obj *b_buffer)
+{
+ sort_value_entry *c;
+ intptr_t d = e - b;
+ if (compare_value(ctx, b, e, keys, n_keys, a_buffer, b_buffer)) {
+ swap_value(b, e);
+ }
+ if (d < 2) { return NULL; }
+ c = b + (d >> 1);
+ if (compare_value(ctx, b, c, keys, n_keys, a_buffer, b_buffer)) {
+ swap_value(b, c);
+ } else {
+ if (compare_value(ctx, c, e, keys, n_keys, a_buffer, b_buffer)) {
+ swap_value(c, e);
+ }
+ }
+ if (d < 3) { return NULL; }
+ b++;
+ swap_value(b, c);
+ c = b;
+ for (;;) {
+ do {
+ b++;
+ } while (compare_value(ctx, c, b, keys, n_keys, a_buffer, b_buffer));
+ do {
+ e--;
+ } while (compare_value(ctx, e, c, keys, n_keys, a_buffer, b_buffer));
+ if (b >= e) { break; }
+ swap_value(b, e);
+ }
+ swap_value(c, e);
+ return e;
+}
+
+static void
+sort_value(grn_ctx *ctx,
+ sort_value_entry *head, sort_value_entry *tail,
+ int from, int to,
+ grn_table_sort_key *keys, int n_keys,
+ grn_obj *a_buffer, grn_obj *b_buffer)
+{
+ sort_value_entry *c;
+ if (head < tail && (c = part_value(ctx, head, tail, keys, n_keys,
+ a_buffer, b_buffer))) {
+ intptr_t m = c - head + 1;
+ if (from < m - 1) {
+ sort_value(ctx, head, c - 1, from, to, keys, n_keys, a_buffer, b_buffer);
+ }
+ if (m < to) {
+ sort_value(ctx, c + 1, tail, from - m, to - m, keys, n_keys,
+ a_buffer, b_buffer);
+ }
+ }
+}
+
+static sort_value_entry *
+pack_value(grn_ctx *ctx, grn_obj *table,
+ sort_value_entry *head, sort_value_entry *tail,
+ grn_table_sort_key *keys, int n_keys,
+ grn_obj *a_buffer, grn_obj *b_buffer)
+{
+ int i = 0;
+ sort_value_entry e, c;
+ grn_table_cursor *tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1, 0);
+ if (!tc) { return NULL; }
+ if ((c.id = grn_table_cursor_next_inline(ctx, tc))) {
+ GRN_TEXT_INIT(&c.value, 0);
+ grn_obj_get_value(ctx, keys->key, c.id, &c.value);
+ while ((e.id = grn_table_cursor_next_inline(ctx, tc))) {
+ GRN_TEXT_INIT(&e.value, 0);
+ grn_obj_get_value(ctx, keys->key, e.id, &e.value);
+ if (compare_value(ctx, &c, &e, keys, n_keys, a_buffer, b_buffer)) {
+ *head++ = e;
+ } else {
+ *tail-- = e;
+ }
+ i++;
+ }
+ *head = c;
+ i++;
+ }
+ grn_table_cursor_close(ctx, tc);
+ return i > 2 ? head : NULL;
+}
+
+static int
+grn_table_sort_value(grn_ctx *ctx, grn_obj *table,
+ int offset, int limit,
+ grn_obj *result,
+ grn_table_sort_key *keys, int n_keys)
+{
+ int e, n;
+ sort_value_entry *array, *ep;
+ e = offset + limit;
+ n = grn_table_size(ctx, table);
+ if (!(array = GRN_MALLOC(sizeof(sort_value_entry) * n))) {
+ return 0;
+ }
+ {
+ grn_obj a_buffer;
+ grn_obj b_buffer;
+ GRN_TEXT_INIT(&a_buffer, 0);
+ GRN_TEXT_INIT(&b_buffer, 0);
+ if ((ep = pack_value(ctx, table, array, array + n - 1, keys, n_keys,
+ &a_buffer, &b_buffer))) {
+ intptr_t m = ep - array + 1;
+ if (offset < m - 1) {
+ sort_value(ctx, array, ep - 1, offset, e, keys, n_keys,
+ &a_buffer, &b_buffer);
+ }
+ if (m < e) {
+ sort_value(ctx, ep + 1, array + n - 1, offset - m, e - m, keys, n_keys,
+ &a_buffer, &b_buffer);
+ }
+ }
+ GRN_OBJ_FIN(ctx, &a_buffer);
+ GRN_OBJ_FIN(ctx, &b_buffer);
+ }
+ {
+ int i;
+ grn_id *v;
+ for (i = 0, ep = array + offset; i < limit && ep < array + n; i++, ep++) {
+ if (!grn_array_add(ctx, (grn_array *)result, (void **)&v)) { break; }
+ *v = ep->id;
+ }
+ GRN_FREE(array);
+ return i;
+ }
+}
+
+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_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;
+ }
+
+ 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
+is_sub_record_accessor(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_accessor *accessor;
+
+ if (!obj) {
+ return GRN_FALSE;
+ }
+
+ if (obj->header.type != GRN_ACCESSOR) {
+ return GRN_FALSE;
+ }
+
+ for (accessor = (grn_accessor *)obj; accessor; accessor = accessor->next) {
+ switch (accessor->action) {
+ case GRN_ACCESSOR_GET_VALUE :
+ if (GRN_TABLE_IS_MULTI_KEYS_GROUPED(accessor->obj)) {
+ return GRN_TRUE;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ 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)
+{
+ if (obj && obj->header.type == GRN_ACCESSOR) {
+ grn_accessor *a;
+ for (a = (grn_accessor *)obj; a; a = a->next) {
+ if (a->action == GRN_ACCESSOR_GET_ID) { return 1; }
+ }
+ }
+ return 0;
+}
+
+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)
+{
+ grn_rc rc;
+ grn_obj *index;
+ int n, e, i = 0;
+ GRN_API_ENTER;
+ if (!n_keys || !keys) {
+ WARN(GRN_INVALID_ARGUMENT, "keys is null");
+ goto exit;
+ }
+ if (!table) {
+ WARN(GRN_INVALID_ARGUMENT, "table is null");
+ goto exit;
+ }
+ if (!(result && result->header.type == GRN_TABLE_NO_KEY)) {
+ WARN(GRN_INVALID_ARGUMENT, "result is not a array");
+ goto exit;
+ }
+ n = grn_table_size(ctx, table);
+ if ((rc = grn_normalize_offset_and_limit(ctx, n, &offset, &limit))) {
+ ERR(rc, "grn_normalize_offset_and_limit failed");
+ goto exit;
+ } else {
+ e = offset + limit;
+ }
+ if (keys->flags & GRN_TABLE_SORT_GEO) {
+ 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) &&
+ grn_column_index(ctx, keys->key, GRN_OP_LESS, &index, 1, NULL)) {
+ grn_id tid;
+ grn_pat *lexicon = (grn_pat *)grn_ctx_at(ctx, index->header.domain);
+ grn_pat_cursor *pc = grn_pat_cursor_open(ctx, lexicon, NULL, 0, NULL, 0,
+ 0 /* offset : can be used in unique index */,
+ -1 /* limit : can be used in unique index */,
+ (keys->flags & GRN_TABLE_SORT_DESC)
+ ? GRN_CURSOR_DESCENDING
+ : GRN_CURSOR_ASCENDING);
+ if (pc) {
+ 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_posting *posting;
+ while (i < e && (posting = grn_ii_cursor_next(ctx, ic))) {
+ if (offset <= i) {
+ grn_id *v;
+ if (!grn_array_add(ctx, (grn_array *)result, (void **)&v)) { break; }
+ *v = posting->rid;
+ }
+ i++;
+ }
+ grn_ii_cursor_close(ctx, ic);
+ }
+ }
+ grn_pat_cursor_close(ctx, pc);
+ }
+ } else {
+ 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--) {
+ if (is_compressed_column(ctx, kp->key)) {
+ have_compressed_column = GRN_TRUE;
+ }
+ 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 {
+ grn_obj *range = grn_ctx_at(ctx, grn_obj_get_range(ctx, kp->key));
+ if (range->header.type == GRN_TYPE) {
+ if (range->header.flags & GRN_OBJ_KEY_VAR_SIZE) {
+ kp->offset = KEY_BULK;
+ } else {
+ uint8_t key_type = range->header.flags & GRN_OBJ_KEY_MASK;
+ switch (key_type) {
+ case GRN_OBJ_KEY_UINT :
+ case GRN_OBJ_KEY_GEO_POINT :
+ switch (GRN_TYPE_SIZE(DB_OBJ(range))) {
+ case 1 :
+ kp->offset = KEY_UINT8;
+ break;
+ case 2 :
+ kp->offset = KEY_UINT16;
+ break;
+ case 4 :
+ kp->offset = KEY_UINT32;
+ break;
+ case 8 :
+ kp->offset = KEY_UINT64;
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "unsupported uint value");
+ goto exit;
+ }
+ break;
+ case GRN_OBJ_KEY_INT :
+ switch (GRN_TYPE_SIZE(DB_OBJ(range))) {
+ case 1 :
+ kp->offset = KEY_INT8;
+ break;
+ case 2 :
+ kp->offset = KEY_INT16;
+ break;
+ case 4 :
+ kp->offset = KEY_INT32;
+ break;
+ case 8 :
+ kp->offset = KEY_INT64;
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "unsupported int value");
+ goto exit;
+ }
+ break;
+ case GRN_OBJ_KEY_FLOAT :
+ switch (GRN_TYPE_SIZE(DB_OBJ(range))) {
+ case 4 :
+ kp->offset = KEY_FLOAT32;
+ break;
+ case 8 :
+ kp->offset = KEY_FLOAT64;
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "unsupported float value");
+ goto exit;
+ }
+ break;
+ }
+ }
+ } else {
+ if (kp->key->header.type == GRN_COLUMN_INDEX) {
+ have_index_value_get = GRN_TRUE;
+ }
+ kp->offset = KEY_UINT32;
+ }
+ }
+ }
+ 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);
+ } else {
+ i = grn_table_sort_reference(ctx, table, offset, limit, result,
+ keys, n_keys);
+ }
+ }
+exit :
+ GRN_API_RETURN(i);
+}
+
+static grn_obj *
+deftype(grn_ctx *ctx, const char *name,
+ grn_obj_flags flags, unsigned int size)
+{
+ grn_obj *o = grn_ctx_get(ctx, name, strlen(name));
+ if (!o) { o = grn_type_create(ctx, name, strlen(name), flags, size); }
+ return o;
+}
+
+grn_rc
+grn_db_init_builtin_types(grn_ctx *ctx)
+{
+ grn_id id;
+ grn_obj *obj, *db = ctx->impl->db;
+ char buf[] = "Sys00";
+ grn_obj_register(ctx, db, buf, 5);
+ obj = deftype(ctx, "Object",
+ GRN_OBJ_KEY_UINT, sizeof(uint64_t));
+ if (!obj || DB_OBJ(obj)->id != GRN_DB_OBJECT) { return GRN_FILE_CORRUPT; }
+ obj = deftype(ctx, "Bool",
+ GRN_OBJ_KEY_UINT, sizeof(uint8_t));
+ if (!obj || DB_OBJ(obj)->id != GRN_DB_BOOL) { return GRN_FILE_CORRUPT; }
+ obj = deftype(ctx, "Int8",
+ GRN_OBJ_KEY_INT, sizeof(int8_t));
+ if (!obj || DB_OBJ(obj)->id != GRN_DB_INT8) { return GRN_FILE_CORRUPT; }
+ obj = deftype(ctx, "UInt8",
+ GRN_OBJ_KEY_UINT, sizeof(uint8_t));
+ if (!obj || DB_OBJ(obj)->id != GRN_DB_UINT8) { return GRN_FILE_CORRUPT; }
+ obj = deftype(ctx, "Int16",
+ GRN_OBJ_KEY_INT, sizeof(int16_t));
+ if (!obj || DB_OBJ(obj)->id != GRN_DB_INT16) { return GRN_FILE_CORRUPT; }
+ obj = deftype(ctx, "UInt16",
+ GRN_OBJ_KEY_UINT, sizeof(uint16_t));
+ if (!obj || DB_OBJ(obj)->id != GRN_DB_UINT16) { return GRN_FILE_CORRUPT; }
+ obj = deftype(ctx, "Int32",
+ GRN_OBJ_KEY_INT, sizeof(int32_t));
+ if (!obj || DB_OBJ(obj)->id != GRN_DB_INT32) { return GRN_FILE_CORRUPT; }
+ obj = deftype(ctx, "UInt32",
+ GRN_OBJ_KEY_UINT, sizeof(uint32_t));
+ if (!obj || DB_OBJ(obj)->id != GRN_DB_UINT32) { return GRN_FILE_CORRUPT; }
+ obj = deftype(ctx, "Int64",
+ GRN_OBJ_KEY_INT, sizeof(int64_t));
+ if (!obj || DB_OBJ(obj)->id != GRN_DB_INT64) { return GRN_FILE_CORRUPT; }
+ obj = deftype(ctx, "UInt64",
+ GRN_OBJ_KEY_UINT, sizeof(uint64_t));
+ if (!obj || DB_OBJ(obj)->id != GRN_DB_UINT64) { return GRN_FILE_CORRUPT; }
+ obj = deftype(ctx, "Float",
+ GRN_OBJ_KEY_FLOAT, sizeof(double));
+ if (!obj || DB_OBJ(obj)->id != GRN_DB_FLOAT) { return GRN_FILE_CORRUPT; }
+ obj = deftype(ctx, "Time",
+ GRN_OBJ_KEY_INT, sizeof(int64_t));
+ if (!obj || DB_OBJ(obj)->id != GRN_DB_TIME) { return GRN_FILE_CORRUPT; }
+ obj = deftype(ctx, "ShortText",
+ GRN_OBJ_KEY_VAR_SIZE, GRN_TABLE_MAX_KEY_SIZE);
+ if (!obj || DB_OBJ(obj)->id != GRN_DB_SHORT_TEXT) { return GRN_FILE_CORRUPT; }
+ obj = deftype(ctx, "Text",
+ GRN_OBJ_KEY_VAR_SIZE, 1 << 16);
+ if (!obj || DB_OBJ(obj)->id != GRN_DB_TEXT) { return GRN_FILE_CORRUPT; }
+ obj = deftype(ctx, "LongText",
+ GRN_OBJ_KEY_VAR_SIZE, 1U << 31);
+ if (!obj || DB_OBJ(obj)->id != GRN_DB_LONG_TEXT) { return GRN_FILE_CORRUPT; }
+ obj = deftype(ctx, "TokyoGeoPoint",
+ GRN_OBJ_KEY_GEO_POINT, sizeof(grn_geo_point));
+ if (!obj || DB_OBJ(obj)->id != GRN_DB_TOKYO_GEO_POINT) { return GRN_FILE_CORRUPT; }
+ obj = deftype(ctx, "WGS84GeoPoint",
+ GRN_OBJ_KEY_GEO_POINT, sizeof(grn_geo_point));
+ if (!obj || DB_OBJ(obj)->id != GRN_DB_WGS84_GEO_POINT) { return GRN_FILE_CORRUPT; }
+ for (id = grn_db_curr_id(ctx, db) + 1; id < GRN_DB_MECAB; id++) {
+ grn_itoh(id, buf + 3, 2);
+ grn_obj_register(ctx, db, buf, 5);
+ }
+#ifdef GRN_WITH_MECAB
+ if (grn_db_init_mecab_tokenizer(ctx)) {
+ ERRCLR(ctx);
+#endif
+ grn_obj_register(ctx, db, "TokenMecab", 10);
+#ifdef GRN_WITH_MECAB
+ }
+#endif
+ grn_db_init_builtin_tokenizers(ctx);
+ grn_db_init_builtin_normalizers(ctx);
+ grn_db_init_builtin_scorers(ctx);
+ for (id = grn_db_curr_id(ctx, db) + 1; id < 128; id++) {
+ grn_itoh(id, buf + 3, 2);
+ grn_obj_register(ctx, db, buf, 5);
+ }
+ 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);
+ }
+ return ctx->rc;
+}
+
+#define MULTI_COLUMN_INDEXP(i) (DB_OBJ(i)->source_size > sizeof(grn_id))
+
+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,
+ unsigned int n_index_data,
+ grn_obj **index_buf, int buf_size,
+ int *section_buf)
+{
+ int n = 0;
+ grn_obj **ip = index_buf;
+ grn_hook *hooks;
+
+ for (hooks = DB_OBJ(obj)->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);
+ int section;
+ if (target->header.type != GRN_COLUMN_INDEX) { continue; }
+ if (obj->header.type != GRN_COLUMN_FIX_SIZE) {
+ 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 ((unsigned int) n < n_index_data) {
+ index_data[n].index = target;
+ index_data[n].section = section;
+ }
+ n++;
+ }
+
+ return n;
+}
+
+static grn_bool
+is_valid_regexp_index(grn_ctx *ctx, grn_obj *index_column)
+{
+ grn_obj *tokenizer;
+
+ tokenizer = grn_index_column_get_tokenizer(ctx, index_column);
+ /* TODO: Restrict to TokenRegexp? */
+ return tokenizer != NULL;
+}
+
+static int
+grn_column_find_index_data_column_match(grn_ctx *ctx, grn_obj *obj,
+ grn_operator op,
+ grn_index_datum *index_data,
+ unsigned int n_index_data,
+ grn_obj **index_buf, int buf_size,
+ int *section_buf)
+{
+ int n = 0;
+ 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 :
+ 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;
+ }
+
+ 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 ((unsigned int) 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) {
+ 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) {
+ *ip++ = target;
+ }
+ if ((unsigned int) n < n_index_data) {
+ index_data[n].index = target;
+ index_data[n].section = section;
+ }
+ n++;
+ }
+
+ return n;
+}
+
+static int
+grn_column_find_index_data_column_range(grn_ctx *ctx, grn_obj *obj,
+ grn_operator op,
+ grn_index_datum *index_data,
+ unsigned int n_index_data,
+ grn_obj **index_buf, int buf_size,
+ int *section_buf)
+{
+ int n = 0;
+ grn_obj **ip = index_buf;
+ 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;
+ 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; }
+ {
+ grn_obj *tokenizer, *lexicon = grn_ctx_at(ctx, target->header.domain);
+ if (!lexicon) { continue; }
+ if (lexicon->header.type != GRN_TABLE_PAT_KEY) { continue; }
+ /* FIXME: GRN_TABLE_DAT_KEY should be supported */
+ grn_table_get_info(ctx, lexicon, NULL, NULL, &tokenizer, NULL, NULL);
+ if (tokenizer) { continue; }
+ }
+ if (n < buf_size) {
+ *ip++ = target;
+ }
+ if ((unsigned int) n < n_index_data) {
+ index_data[n].index = target;
+ index_data[n].section = section;
+ }
+ n++;
+ }
+
+ return n;
+}
+
+static grn_bool
+is_valid_match_index(grn_ctx *ctx, grn_obj *index_column)
+{
+ return GRN_TRUE;
+}
+
+static grn_bool
+is_valid_range_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; }
+ /* FIXME: GRN_TABLE_DAT_KEY should be supported */
+ if (lexicon->header.type != GRN_TABLE_PAT_KEY) {
+ grn_obj_unlink(ctx, 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; }
+
+ return GRN_TRUE;
+}
+
+static grn_bool
+is_valid_index(grn_ctx *ctx, grn_obj *index_column, grn_operator op)
+{
+ switch (op) {
+ case GRN_OP_MATCH :
+ case GRN_OP_NEAR :
+ case GRN_OP_NEAR2 :
+ case GRN_OP_SIMILAR :
+ return is_valid_match_index(ctx, index_column);
+ break;
+ case GRN_OP_LESS :
+ case GRN_OP_GREATER :
+ case GRN_OP_LESS_EQUAL :
+ case GRN_OP_GREATER_EQUAL :
+ case GRN_OP_CALL :
+ return is_valid_range_index(ctx, index_column);
+ break;
+ case GRN_OP_REGEXP :
+ return is_valid_regexp_index(ctx, index_column);
+ break;
+ default :
+ return GRN_FALSE;
+ break;
+ }
+}
+
+static int
+find_section(grn_ctx *ctx, grn_obj *index_column, grn_obj *indexed_column)
+{
+ int section = 0;
+ grn_id indexed_column_id;
+ grn_id *source_ids;
+ int i, n_source_ids;
+
+ indexed_column_id = DB_OBJ(indexed_column)->id;
+
+ source_ids = DB_OBJ(index_column)->source;
+ n_source_ids = DB_OBJ(index_column)->source_size / sizeof(grn_id);
+ for (i = 0; i < n_source_ids; i++) {
+ grn_id source_id = source_ids[i];
+ if (source_id == indexed_column_id) {
+ section = i + 1;
+ break;
+ }
+ }
+
+ return section;
+}
+
+static int
+grn_column_find_index_data_accessor_index_column(grn_ctx *ctx, grn_accessor *a,
+ grn_operator op,
+ grn_index_datum *index_data,
+ unsigned int n_index_data,
+ grn_obj **index_buf,
+ int buf_size,
+ int *section_buf)
+{
+ grn_obj *index_column = a->obj;
+ int section = 0;
+
+ if (!is_valid_index(ctx, index_column, op)) {
+ return 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 (section_buf) {
+ *section_buf = section;
+ }
+ }
+ if (buf_size > 0) {
+ *index_buf = index_column;
+ }
+ if (n_index_data > 0) {
+ index_data[0].index = index_column;
+ index_data[0].section = section;
+ }
+
+ return 1;
+}
+
+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,
+ unsigned n_index_data,
+ grn_obj **index_buf, int buf_size,
+ int *section_buf)
+{
+ int n = 0;
+ grn_obj **ip = index_buf;
+ 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_find_index_data_accessor_index_column(ctx, a, op,
+ index_data,
+ n_index_data,
+ index_buf,
+ buf_size,
+ section_buf);
+ }
+
+ 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; }
+
+ found = GRN_TRUE;
+ if (!a->next) {
+ int section;
+
+ if (!is_valid_index(ctx, target, op)) {
+ continue;
+ }
+
+ section = (MULTI_COLUMN_INDEXP(target)) ? data->section : 0;
+ if (section_buf) {
+ *section_buf = section;
+ }
+ if (n < buf_size) {
+ *ip++ = target;
+ }
+ if ((unsigned int) n < n_index_data) {
+ index_data[n].index = target;
+ index_data[n].section = section;
+ }
+ n++;
+ }
+ }
+
+ 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 ((unsigned int) 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 ((unsigned int) n < n_index_data) {
+ index_data[n].index = index;
+ index_data[n].section = section;
+ }
+ n++;
+ }
+
+ if (!found) {
+ break;
+ }
+ a = a->next;
+ }
+
+ return n;
+}
+
+static int
+grn_column_find_index_data_accessor(grn_ctx *ctx, grn_obj *obj,
+ grn_operator op,
+ grn_index_datum *index_data,
+ unsigned n_index_data,
+ grn_obj **index_buf, int buf_size,
+ int *section_buf)
+{
+ int n = 0;
+
+ if (section_buf) {
+ *section_buf = 0;
+ }
+ 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].section = 0;
+ }
+ n++;
+ break;
+ case GRN_OP_PREFIX :
+ {
+ grn_accessor *a = (grn_accessor *)obj;
+ if (a->action == GRN_ACCESSOR_GET_KEY) {
+ if (a->obj->header.type == GRN_TABLE_PAT_KEY) {
+ if (buf_size > 0) {
+ index_buf[n] = obj;
+ }
+ if (n_index_data > 0) {
+ index_data[n].index = obj;
+ index_data[n].section = 0;
+ }
+ n++;
+ }
+ /* FIXME: GRN_TABLE_DAT_KEY should be supported */
+ }
+ }
+ break;
+ case GRN_OP_SUFFIX :
+ {
+ grn_accessor *a = (grn_accessor *)obj;
+ if (a->action == GRN_ACCESSOR_GET_KEY) {
+ 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;
+ }
+ if (n_index_data > 0) {
+ index_data[n].index = obj;
+ index_data[n].section = 0;
+ }
+ n++;
+ }
+ }
+ }
+ break;
+ case GRN_OP_MATCH :
+ case GRN_OP_NEAR :
+ case GRN_OP_NEAR2 :
+ case GRN_OP_SIMILAR :
+ case GRN_OP_LESS :
+ case GRN_OP_GREATER :
+ case GRN_OP_LESS_EQUAL :
+ 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,
+ section_buf);
+ break;
+ default :
+ break;
+ }
+
+ return n;
+}
+
+int
+grn_column_index(grn_ctx *ctx, grn_obj *obj, grn_operator op,
+ grn_obj **index_buf, int buf_size, int *section_buf)
+{
+ int n = 0;
+ GRN_API_ENTER;
+ 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,
+ section_buf);
+ break;
+ case GRN_OP_PREFIX :
+ case GRN_OP_SUFFIX :
+ case GRN_OP_MATCH :
+ case GRN_OP_NEAR :
+ 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,
+ section_buf);
+ break;
+ case GRN_OP_LESS :
+ case GRN_OP_GREATER :
+ case GRN_OP_LESS_EQUAL :
+ case GRN_OP_GREATER_EQUAL :
+ case GRN_OP_CALL :
+ n = grn_column_find_index_data_column_range(ctx, obj, op,
+ NULL, 0,
+ index_buf, buf_size,
+ section_buf);
+ break;
+ default :
+ break;
+ }
+ } else if (GRN_ACCESSORP(obj)) {
+ n = grn_column_find_index_data_accessor(ctx, obj, op,
+ NULL, 0,
+ index_buf, buf_size,
+ section_buf);
+ }
+ GRN_API_RETURN(n);
+}
+
+unsigned int
+grn_column_find_index_data(grn_ctx *ctx, grn_obj *obj, grn_operator op,
+ grn_index_datum *index_data,
+ unsigned int n_index_data)
+{
+ unsigned int n = 0;
+ GRN_API_ENTER;
+ 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);
+ break;
+ case GRN_OP_PREFIX :
+ case GRN_OP_SUFFIX :
+ case GRN_OP_MATCH :
+ case GRN_OP_NEAR :
+ 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);
+ break;
+ case GRN_OP_LESS :
+ case GRN_OP_GREATER :
+ case GRN_OP_LESS_EQUAL :
+ case GRN_OP_GREATER_EQUAL :
+ case GRN_OP_CALL :
+ n = grn_column_find_index_data_column_range(ctx, obj, op,
+ index_data, n_index_data,
+ NULL, 0, NULL);
+ break;
+ default :
+ break;
+ }
+ } else if (GRN_ACCESSORP(obj)) {
+ n = grn_column_find_index_data_accessor(ctx, obj, op,
+ index_data, n_index_data,
+ NULL, 0, NULL);
+ }
+ GRN_API_RETURN(n);
+}
+
+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)
+{
+ 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;
+ }
+
+ 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);
+ }
+ GRN_API_RETURN(n);
+}
+
+grn_rc
+grn_obj_columns(grn_ctx *ctx, grn_obj *table,
+ const char *str, unsigned int str_size, grn_obj *res)
+{
+ grn_obj *col;
+ const char *p = (char *)str, *q, *r, *pe = p + str_size, *tokbuf[256];
+ while (p < pe) {
+ 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++; }
+ if (p < r) {
+ if (r[-1] == '*') {
+ grn_hash *cols = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY);
+ if (cols) {
+ grn_id *key;
+ grn_table_columns(ctx, 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_PTR_PUT(ctx, res, col); }
+ });
+ grn_hash_close(ctx, cols);
+ }
+ {
+ grn_obj *type = grn_ctx_at(ctx, table->header.domain);
+ if (GRN_OBJ_TABLEP(type)) {
+ grn_obj *ai = grn_obj_column(ctx, table,
+ GRN_COLUMN_NAME_ID,
+ GRN_COLUMN_NAME_ID_LEN);
+ if (ai) {
+ if (ai->header.type == GRN_ACCESSOR) {
+ 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) {
+ if (a->action != GRN_ACCESSOR_GET_ID) {
+ ac->action = a->action;
+ ac->obj = a->obj;
+ ac->next = accessor_new(ctx);
+ if (!(ac = ac->next)) { break; }
+ } else {
+ ac->action = GRN_ACCESSOR_GET_COLUMN_VALUE;
+ ac->obj = col;
+ ac->next = NULL;
+ break;
+ }
+ }
+ }
+ });
+ grn_hash_close(ctx, cols);
+ }
+ }
+ grn_obj_unlink(ctx, ai);
+ }
+ }
+ }
+ } else if ((col = grn_obj_column(ctx, table, p, r - p))) {
+ GRN_PTR_PUT(ctx, res, col);
+ }
+ }
+ p = r;
+ }
+ p = q;
+ }
+ return ctx->rc;
+}
+
+static grn_table_sort_key *
+grn_table_sort_key_from_str_geo(grn_ctx *ctx, const char *str, unsigned int str_size,
+ grn_obj *table, unsigned int *nkeys)
+{
+ const char **tokbuf;
+ const char *p = str, *pe = str + str_size;
+ grn_table_sort_key *keys = NULL, *k = NULL;
+ while ((*p++ != '(')) { if (p == pe) { return NULL; } }
+ str = p;
+ while ((*p != ')')) { if (++p == pe) { return NULL; } }
+ str_size = p - str;
+ p = str;
+ if ((tokbuf = GRN_MALLOCN(const char *, str_size))) {
+ grn_id domain = GRN_ID_NIL;
+ 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++) {
+ const char *r = tokbuf[i];
+ while (p < r && (' ' == *p || ',' == *p)) { p++; }
+ if (p < r) {
+ k->flags = GRN_TABLE_SORT_ASC;
+ k->offset = 0;
+ if (*p == '+') {
+ p++;
+ } else if (*p == '-') {
+ k->flags = GRN_TABLE_SORT_DESC;
+ p++;
+ }
+ if (k == keys) {
+ if (!(k->key = grn_obj_column(ctx, table, p, r - p))) {
+ WARN(GRN_INVALID_ARGUMENT, "invalid sort key: <%.*s>(<%.*s>)",
+ (int)(tokbuf[i] - p), p, str_size, str);
+ break;
+ }
+ domain = grn_obj_get_range(ctx, k->key);
+ } else {
+ grn_obj buf;
+ GRN_TEXT_INIT(&buf, GRN_OBJ_DO_SHALLOW_COPY);
+ GRN_TEXT_SET(ctx, &buf, p + 1, r - p - 2); /* should be quoted */
+ k->key = grn_obj_open(ctx, GRN_BULK, 0, domain);
+ grn_obj_cast(ctx, &buf, k->key, GRN_FALSE);
+ GRN_OBJ_FIN(ctx, &buf);
+ }
+ k->flags |= GRN_TABLE_SORT_GEO;
+ k++;
+ }
+ p = r;
+ }
+ }
+ GRN_FREE(tokbuf);
+ }
+ if (!ctx->rc && k - keys > 0) {
+ *nkeys = k - keys;
+ } else {
+ grn_table_sort_key_close(ctx, keys, k - keys);
+ *nkeys = 0;
+ keys = NULL;
+ }
+ return keys;
+}
+
+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)
+{
+ const char *p = str;
+ const char **tokbuf;
+ grn_table_sort_key *keys = NULL, *k = NULL;
+
+ if (str_size == 0) {
+ return NULL;
+ }
+
+ if ((keys = grn_table_sort_key_from_str_geo(ctx, str, str_size, table, nkeys))) {
+ return keys;
+ }
+ if ((tokbuf = GRN_MALLOCN(const char *, str_size))) {
+ 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++) {
+ const char *r = tokbuf[i];
+ while (p < r && (' ' == *p || ',' == *p)) { p++; }
+ if (p < r) {
+ k->flags = GRN_TABLE_SORT_ASC;
+ k->offset = 0;
+ if (*p == '+') {
+ p++;
+ } else if (*p == '-') {
+ k->flags = GRN_TABLE_SORT_DESC;
+ p++;
+ }
+ if ((k->key = grn_obj_column(ctx, table, p, r - p))) {
+ k++;
+ } 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>: "
+ "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>: "
+ "table:<%.*s> keys:<%.*s>",
+ (int)(r - p), p,
+ table_name_size, table_name,
+ str_size, str);
+ break;
+ }
+ }
+ }
+ p = r;
+ }
+ }
+ GRN_FREE(tokbuf);
+ }
+ if (!ctx->rc && k - keys > 0) {
+ *nkeys = k - keys;
+ } else {
+ grn_table_sort_key_close(ctx, keys, k - keys);
+ *nkeys = 0;
+ keys = NULL;
+ }
+ return keys;
+}
+
+grn_rc
+grn_table_sort_key_close(grn_ctx *ctx, grn_table_sort_key *keys, unsigned int nkeys)
+{
+ unsigned int i;
+ if (keys) {
+ for (i = 0; i < nkeys; i++) {
+ grn_obj *key = keys[i].key;
+ if (!grn_obj_is_column(ctx, key)) {
+ grn_obj_unlink(ctx, key);
+ }
+ }
+ GRN_FREE(keys);
+ }
+ return ctx->rc;
+}
+
+grn_bool
+grn_table_is_grouped(grn_ctx *ctx, grn_obj *table)
+{
+ if (GRN_OBJ_TABLEP(table) && GRN_TABLE_IS_GROUPED(table)) {
+ return GRN_TRUE;
+ }
+ return GRN_FALSE;
+}
+
+unsigned int
+grn_table_max_n_subrecs(grn_ctx *ctx, grn_obj *table)
+{
+ if (GRN_OBJ_TABLEP(table)) {
+ return DB_OBJ(table)->max_n_subrecs;
+ }
+ return 0;
+}
+
+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_token_cursor *token_cursor = NULL;
+ grn_tokenize_mode mode = addp ? GRN_TOKENIZE_ADD : GRN_TOKENIZE_GET;
+ GRN_API_ENTER;
+ if (!(token_cursor = grn_token_cursor_open(ctx, table, str, str_len, mode, 0))) {
+ goto exit;
+ }
+ if (buf) {
+ GRN_BULK_REWIND(buf);
+ } else {
+ if (!(buf = grn_obj_open(ctx, GRN_UVECTOR, 0, DB_OBJ(table)->id))) {
+ goto exit;
+ }
+ }
+ while (token_cursor->status != GRN_TOKEN_CURSOR_DONE && token_cursor->status != GRN_TOKEN_CURSOR_DONE_SKIP) {
+ grn_id tid;
+ if ((tid = grn_token_cursor_next(ctx, token_cursor))) {
+ GRN_RECORD_PUT(ctx, buf, tid);
+ }
+ }
+exit :
+ if (token_cursor) {
+ grn_token_cursor_close(ctx, token_cursor);
+ }
+ GRN_API_RETURN(buf);
+}
+
+static void
+grn_db_recover_database_remove_orphan_inspect(grn_ctx *ctx, grn_obj *db)
+{
+ GRN_TABLE_EACH_BEGIN_FLAGS(ctx, db, cursor, id, GRN_CURSOR_BY_ID) {
+ void *key;
+ int key_size;
+
+ 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);
+ }
+ break;
+ }
+#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)) {
+ ERR(GRN_OBJECT_CORRUPT,
+ "[db][recover] database may be broken. Please re-create the database");
+ return;
+ }
+
+ grn_db_clear_dirty(ctx, db);
+ grn_db_recover_database_remove_orphan_inspect(ctx, db);
+}
+
+static void
+grn_db_recover_table(grn_ctx *ctx, grn_obj *table)
+{
+ if (!grn_obj_is_locked(ctx, table)) {
+ return;
+ }
+
+ {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ unsigned int name_size;
+ name_size = grn_obj_name(ctx, table, name, GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_OBJECT_CORRUPT,
+ "[db][recover] table may be broken: <%.*s>: "
+ "please truncate the table (or clear lock of the table) "
+ "and load data again",
+ (int)name_size, name);
+ }
+}
+
+static void
+grn_db_recover_data_column(grn_ctx *ctx, grn_obj *data_column)
+{
+ if (!grn_obj_is_locked(ctx, data_column)) {
+ return;
+ }
+
+ {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ unsigned int name_size;
+ name_size = grn_obj_name(ctx, data_column, name, GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_OBJECT_CORRUPT,
+ "[db][recover] column may be broken: <%.*s>: "
+ "please truncate the column (or clear lock of the column) "
+ "and load data again",
+ (int)name_size, name);
+ }
+}
+
+static void
+grn_db_recover_index_column(grn_ctx *ctx, grn_obj *index_column)
+{
+ if (!grn_obj_is_locked(ctx, index_column)) {
+ return;
+ }
+
+ 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
+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);
+ }
+
+ cursor = grn_table_cursor_open(ctx, db,
+ NULL, 0, NULL, 0,
+ 0, -1,
+ GRN_CURSOR_BY_ID);
+ if (!cursor) {
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ 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 :
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ grn_db_recover_table(ctx, object);
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ grn_db_recover_data_column(ctx, object);
+ break;
+ case GRN_COLUMN_INDEX :
+ grn_db_recover_index_column(ctx, object);
+ break;
+ default:
+ break;
+ }
+ grn_obj_unlink(ctx, object);
+ } else {
+ 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) {
+ break;
+ }
+ }
+ grn_table_cursor_close(ctx, cursor);
+
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_rc
+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;
+ grn_id id;
+
+ GRN_API_ENTER;
+
+ db = ctx->impl->db;
+ if (!db) {
+ ERR(GRN_INVALID_ARGUMENT, "DB isn't associated");
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ cursor = grn_table_cursor_open(ctx, db, NULL, 0, NULL, 0, 0, -1, 0);
+ if (!cursor) {
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
+ grn_obj *object;
+
+ if ((object = grn_ctx_at(ctx, id))) {
+ if (predicate(ctx, object)) {
+ GRN_PTR_PUT(ctx, objects_buffer, object);
+ } else {
+ grn_obj_unlink(ctx, object);
+ }
+ } else {
+ if (ctx->rc != GRN_SUCCESS) {
+ ERRCLR(ctx);
+ }
+ }
+ }
+ grn_table_cursor_close(ctx, cursor);
+
+ 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 ((unsigned long) GRN_BULK_VSIZE(stack) < (unsigned long) 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 00000000..72017fe3
--- /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-1335 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/error.c b/storage/mroonga/vendor/groonga/lib/error.c
new file mode 100644
index 00000000..9fd03291
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/error.c
@@ -0,0 +1,454 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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 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-1335 USA
+*/
+
+#include "grn_error.h"
+#include "grn_windows.h"
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif /* HAVE_ERRNO_H */
+
+#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];
+
+ 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 (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
+}
+#else
+const char *
+grn_current_error_message(void)
+{
+ return strerror(errno);
+}
+#endif
+
+const char *
+grn_strerror(int error_code)
+{
+#ifdef WIN32
+# define MESSAGE_BUFFER_SIZE 1024
+ static char message[MESSAGE_BUFFER_SIZE];
+ strerror_s(message, MESSAGE_BUFFER_SIZE, error_code);
+ return message;
+# undef MESSAGE_BUFFER_SIZE
+#else /* WIN32 */
+ 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
new file mode 100644
index 00000000..d190d3e0
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/expr.c
@@ -0,0 +1,9294 @@
+/* -*- 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-1335 USA
+*/
+#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, unsigned char flags)
+{
+ grn_obj *res = NULL;
+ grn_expr *e = (grn_expr *)expr;
+ if (e) {
+ if (e->values_curr >= e->values_size) {
+ // todo : expand values.
+ ERR(GRN_NO_MEMORY_AVAILABLE, "no more e->values");
+ return NULL;
+ }
+ res = &e->values[e->values_curr++];
+ if (e->values_curr > e->values_tail) { e->values_tail = e->values_curr; }
+ grn_obj_reinit(ctx, res, domain, flags);
+ }
+ return res;
+}
+
+grn_hash *
+grn_expr_get_vars(grn_ctx *ctx, grn_obj *expr, unsigned int *nvars)
+{
+ grn_hash *vars = NULL;
+ if (expr->header.type == GRN_PROC || expr->header.type == GRN_EXPR) {
+ grn_id id = DB_OBJ(expr)->id;
+ grn_expr *e = (grn_expr *)expr;
+ int added = 0;
+ grn_hash **vp;
+ if (grn_hash_add(ctx, ctx->impl->expr_vars, &id, sizeof(grn_id), (void **)&vp, &added)) {
+ if (!*vp) {
+ *vp = 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 (*vp) {
+ uint32_t i;
+ grn_obj *value;
+ grn_expr_var *v;
+ for (v = e->vars, i = e->nvars; i; v++, i--) {
+ grn_hash_add(ctx, *vp, v->name, v->name_size, (void **)&value, &added);
+ GRN_OBJ_INIT(value, v->value.header.type, 0, v->value.header.domain);
+ GRN_TEXT_PUT(ctx, value, GRN_TEXT_VALUE(&v->value), GRN_TEXT_LEN(&v->value));
+ }
+ }
+ }
+ vars = *vp;
+ }
+ }
+ *nvars = vars ? GRN_HASH_SIZE(vars) : 0;
+ return vars;
+}
+
+grn_rc
+grn_expr_clear_vars(grn_ctx *ctx, grn_obj *expr)
+{
+ if (expr->header.type == GRN_PROC || expr->header.type == GRN_EXPR) {
+ grn_hash **vp;
+ grn_id eid, id = DB_OBJ(expr)->id;
+ if ((eid = grn_hash_get(ctx, ctx->impl->expr_vars, &id, sizeof(grn_id), (void **)&vp))) {
+ if (*vp) {
+ grn_obj *value;
+ GRN_HASH_EACH(ctx, *vp, i, NULL, NULL, (void **)&value, {
+ GRN_OBJ_FIN(ctx, value);
+ });
+ grn_hash_close(ctx, *vp);
+ }
+ grn_hash_delete_by_id(ctx, ctx->impl->expr_vars, eid, NULL);
+ }
+ }
+ return ctx->rc;
+}
+
+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_proc_ctx *pctx = (grn_proc_ctx *)user_data;
+ if (caller) { *caller = pctx->caller; }
+ if (pctx->proc) {
+ if (vars) {
+ *vars = pctx->proc->vars;
+ // *vars = grn_expr_get_vars(ctx, (grn_obj *)pctx->proc, nvars);
+ }
+ if (nvars) { *nvars = pctx->proc->nvars; }
+ } else {
+ if (vars) { *vars = NULL; }
+ if (nvars) { *nvars = 0; }
+ }
+ return (grn_obj *)pctx->proc;
+}
+
+grn_obj *
+grn_proc_get_vars(grn_ctx *ctx, grn_user_data *user_data)
+{
+ uint32_t n;
+ grn_proc_ctx *pctx = (grn_proc_ctx *)user_data;
+ if (pctx->proc) {
+ return (grn_obj *)grn_expr_get_vars(ctx, (grn_obj *)pctx->proc, &n);
+ } else {
+ return NULL;
+ }
+}
+
+grn_obj *
+grn_proc_get_var(grn_ctx *ctx, grn_user_data *user_data, const char *name, unsigned int name_size)
+{
+ grn_proc_ctx *pctx = (grn_proc_ctx *)user_data;
+ return pctx->proc ? grn_expr_get_var(ctx, (grn_obj *)pctx->proc, name, name_size) : NULL;
+}
+
+grn_obj *
+grn_proc_get_var_by_offset(grn_ctx *ctx, grn_user_data *user_data, unsigned int offset)
+{
+ grn_proc_ctx *pctx = (grn_proc_ctx *)user_data;
+ return pctx->proc ? grn_expr_get_var_by_offset(ctx, (grn_obj *)pctx->proc, offset) : NULL;
+}
+
+grn_obj *
+grn_proc_get_or_add_var(grn_ctx *ctx, grn_user_data *user_data,
+ const char *name, unsigned int name_size)
+{
+ grn_proc_ctx *pctx = (grn_proc_ctx *)user_data;
+ return pctx->proc ? grn_expr_get_or_add_var(ctx, (grn_obj *)pctx->proc, name, name_size) : NULL;
+}
+
+grn_obj *
+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;
+}
+
+grn_proc_type
+grn_proc_get_type(grn_ctx *ctx, grn_obj *proc)
+{
+ grn_proc *proc_ = (grn_proc *)proc;
+ return proc_ ? proc_->type : GRN_PROC_INVALID;
+}
+
+grn_rc
+grn_proc_set_selector(grn_ctx *ctx, grn_obj *proc, grn_selector_func selector)
+{
+ grn_proc *proc_ = (grn_proc *)proc;
+ if (!grn_obj_is_function_proc(ctx, proc)) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ 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 *
+grn_ctx_pop(grn_ctx *ctx)
+{
+ if (ctx && ctx->impl && ctx->impl->stack_curr) {
+ return ctx->impl->stack[--ctx->impl->stack_curr];
+ }
+ return NULL;
+}
+
+grn_rc
+grn_ctx_push(grn_ctx *ctx, grn_obj *obj)
+{
+ if (ctx && ctx->impl && ctx->impl->stack_curr < GRN_STACK_SIZE) {
+ ctx->impl->stack[ctx->impl->stack_curr++] = obj;
+ return GRN_SUCCESS;
+ }
+ return GRN_STACK_OVER_FLOW;
+}
+
+grn_obj *
+grn_expr_alloc_const(grn_ctx *ctx, grn_obj *expr)
+{
+ grn_expr *e = (grn_expr *)expr;
+ 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;
+ }
+ }
+ e->nconsts++;
+ return &e->const_blks[blk_id][id];
+}
+
+void
+grn_obj_pack(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ grn_text_benc(ctx, buf, obj->header.type);
+ if (GRN_DB_OBJP(obj)) {
+ grn_text_benc(ctx, buf, DB_OBJ(obj)->id);
+ } else {
+ // todo : support vector, query, accessor, snip..
+ uint32_t vs = GRN_BULK_VSIZE(obj);
+ grn_text_benc(ctx, buf, obj->header.domain);
+ grn_text_benc(ctx, buf, vs);
+ if (vs) { GRN_TEXT_PUT(ctx, buf, GRN_BULK_HEAD(obj), vs); }
+ }
+}
+
+const uint8_t *
+grn_obj_unpack(grn_ctx *ctx, const uint8_t *p, const uint8_t *pe, uint8_t type, uint8_t flags, grn_obj *obj)
+{
+ grn_id domain;
+ uint32_t vs;
+ GRN_B_DEC(domain, p);
+ GRN_OBJ_INIT(obj, type, flags, domain);
+ GRN_B_DEC(vs, p);
+ if (pe < p + vs) {
+ ERR(GRN_INVALID_FORMAT, "benced image is corrupt");
+ return p;
+ }
+ grn_bulk_write(ctx, obj, (const char *)p, vs);
+ return p + vs;
+}
+
+typedef enum {
+ GRN_EXPR_PACK_TYPE_NULL = 0,
+ GRN_EXPR_PACK_TYPE_VARIABLE = 1,
+ GRN_EXPR_PACK_TYPE_OTHERS = 2
+} grn_expr_pack_type;
+
+void
+grn_expr_pack(grn_ctx *ctx, grn_obj *buf, grn_obj *expr)
+{
+ grn_expr_code *c;
+ grn_expr_var *v;
+ grn_expr *e = (grn_expr *)expr;
+ uint32_t i, j;
+ grn_text_benc(ctx, buf, e->nvars);
+ for (i = e->nvars, v = e->vars; i; i--, v++) {
+ grn_text_benc(ctx, buf, v->name_size);
+ if (v->name_size) { GRN_TEXT_PUT(ctx, buf, v->name, v->name_size); }
+ grn_obj_pack(ctx, buf, &v->value);
+ }
+ i = e->codes_curr;
+ grn_text_benc(ctx, buf, i);
+ for (c = e->codes; i; i--, c++) {
+ grn_text_benc(ctx, buf, c->op);
+ grn_text_benc(ctx, buf, c->nargs);
+ if (!c->value) {
+ grn_text_benc(ctx, buf, GRN_EXPR_PACK_TYPE_NULL);
+ } else {
+ for (j = 0, v = e->vars; j < e->nvars; j++, v++) {
+ if (&v->value == c->value) {
+ grn_text_benc(ctx, buf, GRN_EXPR_PACK_TYPE_VARIABLE);
+ grn_text_benc(ctx, buf, j);
+ break;
+ }
+ }
+ if (j == e->nvars) {
+ grn_text_benc(ctx, buf, GRN_EXPR_PACK_TYPE_OTHERS);
+ grn_obj_pack(ctx, buf, c->value);
+ }
+ }
+ }
+}
+
+const uint8_t *
+grn_expr_unpack(grn_ctx *ctx, const uint8_t *p, const uint8_t *pe, grn_obj *expr)
+{
+ grn_obj *v;
+ grn_expr_pack_type type;
+ uint32_t i, n, ns;
+ grn_expr_code *code;
+ grn_expr *e = (grn_expr *)expr;
+ GRN_B_DEC(n, p);
+ for (i = 0; i < n; i++) {
+ uint32_t object_type;
+ GRN_B_DEC(ns, p);
+ v = grn_expr_add_var(ctx, expr, ns ? (const char *)p : NULL, ns);
+ p += ns;
+ GRN_B_DEC(object_type, p);
+ if (GRN_TYPE <= object_type && object_type <= GRN_COLUMN_INDEX) { /* error */ }
+ p = grn_obj_unpack(ctx, p, pe, object_type, 0, v);
+ if (pe < p) {
+ ERR(GRN_INVALID_FORMAT, "benced image is corrupt");
+ return p;
+ }
+ }
+ GRN_B_DEC(n, p);
+ /* confirm e->codes_size >= n */
+ e->codes_curr = n;
+ for (i = 0, code = e->codes; i < n; i++, code++) {
+ GRN_B_DEC(code->op, p);
+ GRN_B_DEC(code->nargs, p);
+ GRN_B_DEC(type, p);
+ switch (type) {
+ case GRN_EXPR_PACK_TYPE_NULL :
+ code->value = NULL;
+ break;
+ case GRN_EXPR_PACK_TYPE_VARIABLE :
+ {
+ uint32_t offset;
+ GRN_B_DEC(offset, p);
+ code->value = &e->vars[i].value;
+ }
+ break;
+ case GRN_EXPR_PACK_TYPE_OTHERS :
+ {
+ uint32_t object_type;
+ GRN_B_DEC(object_type, p);
+ if (GRN_TYPE <= object_type && object_type <= GRN_COLUMN_INDEX) {
+ grn_id id;
+ GRN_B_DEC(id, p);
+ code->value = grn_ctx_at(ctx, id);
+ } else {
+ if (!(v = grn_expr_alloc_const(ctx, expr))) { return NULL; }
+ p = grn_obj_unpack(ctx, p, pe, object_type, GRN_OBJ_EXPRCONST, v);
+ code->value = v;
+ }
+ }
+ break;
+ }
+ if (pe < p) {
+ ERR(GRN_INVALID_FORMAT, "benced image is corrupt");
+ return p;
+ }
+ }
+ return p;
+}
+
+grn_obj *
+grn_expr_open(grn_ctx *ctx, grn_obj_spec *spec, const uint8_t *p, const uint8_t *pe)
+{
+ grn_expr *expr = NULL;
+ if ((expr = GRN_MALLOCN(grn_expr, 1))) {
+ int size = GRN_STACK_SIZE;
+ expr->const_blks = NULL;
+ expr->nconsts = 0;
+ GRN_TEXT_INIT(&expr->name_buf, 0);
+ GRN_TEXT_INIT(&expr->dfi, 0);
+ GRN_PTR_INIT(&expr->objs, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ expr->vars = NULL;
+ expr->nvars = 0;
+ GRN_DB_OBJ_SET_TYPE(expr, GRN_EXPR);
+ if ((expr->values = GRN_MALLOCN(grn_obj, size))) {
+ int i;
+ for (i = 0; i < size; i++) {
+ GRN_OBJ_INIT(&expr->values[i], GRN_BULK, GRN_OBJ_EXPRVALUE, GRN_ID_NIL);
+ }
+ expr->values_curr = 0;
+ expr->values_tail = 0;
+ expr->values_size = size;
+ if ((expr->codes = GRN_MALLOCN(grn_expr_code, size))) {
+ expr->codes_curr = 0;
+ expr->codes_size = size;
+ expr->obj.header = spec->header;
+ if (grn_expr_unpack(ctx, p, pe, (grn_obj *)expr) == pe) {
+ goto exit;
+ } else {
+ ERR(GRN_INVALID_FORMAT, "benced image is corrupt");
+ }
+ GRN_FREE(expr->codes);
+ }
+ GRN_FREE(expr->values);
+ }
+ GRN_FREE(expr);
+ expr = NULL;
+ }
+exit :
+ return (grn_obj *)expr;
+}
+
+/* Pass ownership of `obj` to `expr`. */
+void
+grn_expr_take_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj)
+{
+ grn_expr *e = (grn_expr *)expr;
+ GRN_PTR_PUT(ctx, &(e->objs), obj);
+}
+
+/* data flow info */
+typedef struct {
+ grn_expr_code *code;
+ grn_id domain;
+ unsigned char type;
+} grn_expr_dfi;
+
+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;
+ }
+}
+
+static void
+grn_expr_dfi_put(grn_ctx *ctx, grn_expr *expr, uint8_t type, grn_id domain,
+ grn_expr_code *code)
+{
+ 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 *
+grn_expr_create(grn_ctx *ctx, const char *name, unsigned int name_size)
+{
+ grn_id id;
+ grn_obj *db;
+ grn_expr *expr = NULL;
+ if (!ctx || !ctx->impl || !(db = ctx->impl->db)) {
+ ERR(GRN_INVALID_ARGUMENT, "db not initialized");
+ return NULL;
+ }
+ if (name_size) {
+ ERR(GRN_FUNCTION_NOT_IMPLEMENTED,
+ "[expr][create] named expression isn't implemented yet");
+ return NULL;
+ }
+ GRN_API_ENTER;
+ if (grn_db_check_name(ctx, name, name_size)) {
+ GRN_DB_CHECK_NAME_ERR("[expr][create]", name, name_size);
+ GRN_API_RETURN(NULL);
+ }
+ if (!GRN_DB_P(db)) {
+ ERR(GRN_INVALID_ARGUMENT, "named expr is not supported");
+ GRN_API_RETURN(NULL);
+ }
+ id = grn_obj_register(ctx, db, name, name_size);
+ if (id && (expr = GRN_MALLOCN(grn_expr, 1))) {
+ int size = GRN_STACK_SIZE;
+ expr->const_blks = NULL;
+ expr->nconsts = 0;
+ GRN_TEXT_INIT(&expr->name_buf, 0);
+ GRN_TEXT_INIT(&expr->dfi, 0);
+ GRN_PTR_INIT(&expr->objs, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ expr->code0 = NULL;
+ expr->vars = NULL;
+ expr->nvars = 0;
+ expr->cacheable = 1;
+ expr->taintable = 0;
+ expr->values_curr = 0;
+ expr->values_tail = 0;
+ expr->values_size = size;
+ expr->codes_curr = 0;
+ expr->codes_size = size;
+ GRN_DB_OBJ_SET_TYPE(expr, GRN_EXPR);
+ expr->obj.header.domain = GRN_ID_NIL;
+ expr->obj.range = GRN_ID_NIL;
+ if (!grn_db_obj_init(ctx, db, id, DB_OBJ(expr))) {
+ if ((expr->values = GRN_MALLOCN(grn_obj, size))) {
+ int i;
+ for (i = 0; i < size; i++) {
+ GRN_OBJ_INIT(&expr->values[i], GRN_BULK, GRN_OBJ_EXPRVALUE, GRN_ID_NIL);
+ }
+ if ((expr->codes = GRN_MALLOCN(grn_expr_code, size))) {
+ goto exit;
+ }
+ GRN_FREE(expr->values);
+ }
+ }
+ GRN_FREE(expr);
+ expr = NULL;
+ }
+exit :
+ GRN_API_RETURN((grn_obj *)expr);
+}
+
+grn_rc
+grn_expr_close(grn_ctx *ctx, grn_obj *expr)
+{
+ uint32_t i, j;
+ grn_expr *e = (grn_expr *)expr;
+ GRN_API_ENTER;
+ /*
+ if (e->obj.header.domain) {
+ grn_hash_delete(ctx, ctx->impl->qe, &e->obj.header.domain, sizeof(grn_id), NULL);
+ }
+ */
+ grn_expr_clear_vars(ctx, expr);
+ 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);
+ }
+ grn_obj_close(ctx, &e->name_buf);
+ grn_obj_close(ctx, &e->dfi);
+ for (;;) {
+ grn_obj *obj;
+ GRN_PTR_POP(&e->objs, obj);
+ if (obj) {
+#ifdef USE_MEMORY_DEBUG
+ 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");
+ }
+#endif
+ } else { break; }
+ }
+ grn_obj_close(ctx, &e->objs);
+ for (i = 0; i < e->nvars; i++) {
+ grn_obj_close(ctx, &e->vars[i].value);
+ }
+ if (e->vars) { GRN_FREE(e->vars); }
+ for (i = 0; i < e->values_tail; i++) {
+ grn_obj_close(ctx, &e->values[i]);
+ }
+ GRN_FREE(e->values);
+ GRN_FREE(e->codes);
+ GRN_FREE(e);
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_obj *
+grn_expr_add_var(grn_ctx *ctx, grn_obj *expr, const char *name, unsigned int name_size)
+{
+ uint32_t i;
+ char *p;
+ grn_expr_var *v;
+ grn_obj *res = NULL;
+ grn_expr *e = (grn_expr *)expr;
+ GRN_API_ENTER;
+ if (DB_OBJ(expr)->id & GRN_OBJ_TMP_OBJECT) {
+ res = grn_expr_get_or_add_var(ctx, expr, name, name_size);
+ } else {
+ if (!e->vars) {
+ if (!(e->vars = GRN_MALLOCN(grn_expr_var, GRN_STACK_SIZE))) {
+ ERR(GRN_NO_MEMORY_AVAILABLE, "malloc failed");
+ }
+ }
+ if (e->vars && e->nvars < GRN_STACK_SIZE) {
+ v = e->vars + e->nvars++;
+ if (name_size) {
+ GRN_TEXT_PUT(ctx, &e->name_buf, name, name_size);
+ } else {
+ uint32_t ol = GRN_TEXT_LEN(&e->name_buf);
+ GRN_TEXT_PUTC(ctx, &e->name_buf, '$');
+ grn_text_itoa(ctx, &e->name_buf, e->nvars);
+ name_size = GRN_TEXT_LEN(&e->name_buf) - ol;
+ }
+ v->name_size = name_size;
+ res = &v->value;
+ GRN_VOID_INIT(res);
+ for (i = e->nvars, p = GRN_TEXT_VALUE(&e->name_buf), v = e->vars; i; i--, v++) {
+ v->name = p;
+ p += v->name_size;
+ }
+ }
+ }
+ GRN_API_RETURN(res);
+}
+
+grn_obj *
+grn_expr_get_var(grn_ctx *ctx, grn_obj *expr, const char *name, unsigned int name_size)
+{
+ uint32_t n;
+ grn_obj *res = NULL;
+ grn_hash *vars = grn_expr_get_vars(ctx, expr, &n);
+ if (vars) { grn_hash_get(ctx, vars, name, name_size, (void **)&res); }
+ return res;
+}
+
+grn_obj *
+grn_expr_get_or_add_var(grn_ctx *ctx, grn_obj *expr, const char *name, unsigned int name_size)
+{
+ uint32_t n;
+ grn_obj *res = NULL;
+ grn_hash *vars = grn_expr_get_vars(ctx, expr, &n);
+ if (vars) {
+ int added = 0;
+ char name_buf[16];
+ if (!name_size) {
+ char *rest;
+ name_buf[0] = '$';
+ grn_itoa((int)GRN_HASH_SIZE(vars) + 1, name_buf + 1, name_buf + 16, &rest);
+ name_size = rest - name_buf;
+ name = name_buf;
+ }
+ grn_hash_add(ctx, vars, name, name_size, (void **)&res, &added);
+ if (added) { GRN_TEXT_INIT(res, 0); }
+ }
+ return res;
+}
+
+grn_obj *
+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, NULL); }
+ return res;
+}
+
+#define EXPRVP(x) ((x)->header.impl_flags & GRN_OBJ_EXPRVALUE)
+
+#define CONSTP(obj) ((obj) && ((obj)->header.impl_flags & GRN_OBJ_EXPRCONST))
+
+#define PUSH_CODE(e,o,v,n,c) do {\
+ (c) = &(e)->codes[e->codes_curr++];\
+ (c)->value = (v);\
+ (c)->nargs = (n);\
+ (c)->op = (o);\
+ (c)->flags = 0;\
+ (c)->modify = 0;\
+} while (0)
+
+#define APPEND_UNARY_MINUS_OP(e) do { \
+ grn_expr_code *code_; \
+ grn_id domain; \
+ unsigned char type; \
+ grn_obj *x; \
+ dfi = grn_expr_dfi_pop(e); \
+ code_ = dfi->code; \
+ domain = dfi->domain; \
+ type = dfi->type; \
+ x = code_->value; \
+ if (CONSTP(x)) { \
+ switch (domain) { \
+ case GRN_DB_INT32: \
+ { \
+ int value; \
+ value = GRN_INT32_VALUE(x); \
+ if (value == (int)0x80000000) { \
+ domain = GRN_DB_INT64; \
+ x->header.domain = domain; \
+ GRN_INT64_SET(ctx, x, -((long long int)value)); \
+ } else { \
+ GRN_INT32_SET(ctx, x, -value); \
+ } \
+ } \
+ break; \
+ case GRN_DB_UINT32: \
+ { \
+ unsigned int value; \
+ value = GRN_UINT32_VALUE(x); \
+ if (value > (unsigned int)0x80000000) { \
+ domain = GRN_DB_INT64; \
+ x->header.domain = domain; \
+ GRN_INT64_SET(ctx, x, -((long long int)value)); \
+ } else { \
+ domain = GRN_DB_INT32; \
+ x->header.domain = domain; \
+ GRN_INT32_SET(ctx, x, -((int)value)); \
+ } \
+ } \
+ break; \
+ case GRN_DB_INT64: \
+ GRN_INT64_SET(ctx, x, -GRN_INT64_VALUE(x)); \
+ break; \
+ case GRN_DB_FLOAT: \
+ GRN_FLOAT_SET(ctx, x, -GRN_FLOAT_VALUE(x)); \
+ break; \
+ default: \
+ PUSH_CODE(e, op, obj, nargs, code); \
+ break; \
+ } \
+ } else { \
+ PUSH_CODE(e, op, obj, nargs, code); \
+ } \
+ grn_expr_dfi_put(ctx, e, type, domain, code_); \
+} while (0)
+
+#define PUSH_N_ARGS_ARITHMETIC_OP(e, op, obj, nargs, code) do { \
+ PUSH_CODE(e, op, obj, nargs, code); \
+ { \
+ int i = nargs; \
+ while (i--) { \
+ dfi = grn_expr_dfi_pop(e); \
+ } \
+ } \
+ grn_expr_dfi_put(ctx, e, type, domain, code); \
+} while (0)
+
+static void
+grn_expr_append_obj_resolve_const(grn_ctx *ctx,
+ grn_obj *obj,
+ grn_id to_domain)
+{
+ grn_obj dest;
+
+ GRN_OBJ_INIT(&dest, GRN_BULK, 0, to_domain);
+ if (!grn_obj_cast(ctx, obj, &dest, GRN_FALSE)) {
+ grn_obj_reinit(ctx, obj, to_domain, 0);
+ grn_bulk_write(ctx, obj, GRN_BULK_HEAD(&dest), GRN_BULK_VSIZE(&dest));
+ }
+ GRN_OBJ_FIN(ctx, &dest);
+}
+
+grn_obj *
+grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op, int nargs)
+{
+ uint8_t type = GRN_VOID;
+ grn_id domain = GRN_ID_NIL;
+ grn_expr_dfi *dfi;
+ grn_expr_code *code;
+ grn_obj *res = NULL;
+ grn_expr *e = (grn_expr *)expr;
+ GRN_API_ENTER;
+ if (e->codes_curr >= e->codes_size) {
+ 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);
+ 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;
+ }
+ break;
+ case GRN_OP_NOP :
+ /* nop */
+ break;
+ case GRN_OP_POP :
+ if (obj) {
+ ERR(GRN_INVALID_ARGUMENT, "obj assigned for GRN_OP_POP");
+ goto exit;
+ } else {
+ PUSH_CODE(e, op, obj, nargs, code);
+ dfi = grn_expr_dfi_pop(e);
+ }
+ break;
+ case GRN_OP_CALL :
+ {
+ grn_obj *proc = NULL;
+ /*
+ * 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 - 1; i++) {
+ int rest_n_codes = 1;
+ while (rest_n_codes > 0) {
+ rest_n_codes += code->nargs;
+ if (code->value) {
+ rest_n_codes--;
+ }
+ rest_n_codes--;
+ code--;
+ }
+ }
+ proc = code->value;
+ }
+ if (!proc) {
+ ERR(GRN_INVALID_ARGUMENT, "invalid function call expression");
+ goto exit;
+ }
+ if (!(grn_obj_is_function_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);
+ switch (proc->header.type) {
+ case GRN_TABLE_HASH_KEY:
+ case GRN_TABLE_PAT_KEY:
+ case GRN_TABLE_NO_KEY:
+ case GRN_COLUMN_FIX_SIZE:
+ case GRN_COLUMN_VAR_SIZE:
+ case GRN_COLUMN_INDEX:
+ grn_inspect_name(ctx, &buffer, proc);
+ break;
+ default:
+ grn_inspect(ctx, &buffer, proc);
+ break;
+ }
+ ERR(GRN_INVALID_ARGUMENT, "invalid function: <%.*s>",
+ (int)GRN_TEXT_LEN(&buffer), GRN_TEXT_VALUE(&buffer));
+ 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;
+ }
+ }
+ break;
+ case GRN_OP_INTERN :
+ if (obj && CONSTP(obj)) {
+ grn_obj *value;
+ value = grn_expr_get_var(ctx, expr, GRN_TEXT_VALUE(obj), GRN_TEXT_LEN(obj));
+ if (!value) { value = grn_ctx_get(ctx, GRN_TEXT_VALUE(obj), GRN_TEXT_LEN(obj)); }
+ if (value) {
+ obj = value;
+ op = GRN_OP_PUSH;
+ type = obj->header.type;
+ domain = GRN_OBJ_GET_DOMAIN(obj);
+ }
+ }
+ PUSH_CODE(e, op, obj, nargs, code);
+ grn_expr_dfi_put(ctx, e, type, domain, code);
+ break;
+ case GRN_OP_EQUAL :
+ PUSH_CODE(e, op, obj, nargs, code);
+ if (nargs) {
+ grn_id xd, yd = GRN_ID_NIL;
+ grn_obj *x, *y = NULL;
+ int i = nargs - 1;
+ if (obj) {
+ xd = GRN_OBJ_GET_DOMAIN(obj);
+ x = obj;
+ } else {
+ dfi = grn_expr_dfi_pop(e);
+ x = dfi->code->value;
+ xd = dfi->domain;
+ }
+ while (i--) {
+ dfi = grn_expr_dfi_pop(e);
+ y = dfi->code->value;
+ yd = dfi->domain;
+ }
+ if (CONSTP(x)) {
+ if (CONSTP(y)) {
+ /* todo */
+ } else {
+ if (xd != yd) {
+ grn_expr_append_obj_resolve_const(ctx, x, yd);
+ }
+ }
+ } else {
+ if (CONSTP(y)) {
+ if (xd != yd) {
+ grn_expr_append_obj_resolve_const(ctx, y, xd);
+ }
+ }
+ }
+ }
+ grn_expr_dfi_put(ctx, e, type, domain, code);
+ break;
+ case GRN_OP_TABLE_CREATE :
+ case GRN_OP_EXPR_GET_VAR :
+ case GRN_OP_MATCH :
+ case GRN_OP_NEAR :
+ case GRN_OP_NEAR2 :
+ case GRN_OP_SIMILAR :
+ case GRN_OP_PREFIX :
+ case GRN_OP_SUFFIX :
+ 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_GEO_DISTANCE1 :
+ case GRN_OP_GEO_DISTANCE2 :
+ case GRN_OP_GEO_DISTANCE3 :
+ case GRN_OP_GEO_DISTANCE4 :
+ case GRN_OP_GEO_WITHINP5 :
+ case GRN_OP_GEO_WITHINP6 :
+ case GRN_OP_GEO_WITHINP8 :
+ case GRN_OP_OBJ_SEARCH :
+ case GRN_OP_TABLE_SELECT :
+ case GRN_OP_TABLE_SORT :
+ case GRN_OP_TABLE_GROUP :
+ case GRN_OP_JSON_PUT :
+ case GRN_OP_GET_REF :
+ case GRN_OP_ADJUST :
+ case GRN_OP_TERM_EXTRACT :
+ case GRN_OP_REGEXP :
+ PUSH_CODE(e, op, obj, nargs, code);
+ if (nargs) {
+ int i = nargs - 1;
+ if (!obj) { dfi = grn_expr_dfi_pop(e); }
+ while (i--) { dfi = grn_expr_dfi_pop(e); }
+ }
+ grn_expr_dfi_put(ctx, e, type, domain, code);
+ break;
+ case GRN_OP_AND :
+ case GRN_OP_OR :
+ case GRN_OP_AND_NOT :
+ PUSH_CODE(e, op, obj, nargs, code);
+ if (nargs != 2) {
+ GRN_LOG(ctx, GRN_LOG_WARNING, "nargs(%d) != 2 in relative op", nargs);
+ }
+ if (obj) {
+ GRN_LOG(ctx, GRN_LOG_WARNING, "obj assigned to relative op");
+ }
+ {
+ int i = nargs;
+ while (i--) {
+ dfi = grn_expr_dfi_pop(e);
+ if (dfi) {
+ dfi->code->flags |= GRN_EXPR_CODE_RELATIONAL_EXPRESSION;
+ } else {
+ ERR(GRN_SYNTAX_ERROR, "stack under flow in relative op");
+ }
+ }
+ }
+ grn_expr_dfi_put(ctx, e, type, domain, code);
+ break;
+ case GRN_OP_NOT :
+ if (nargs == 1) {
+ PUSH_CODE(e, op, obj, nargs, code);
+ }
+ break;
+ case GRN_OP_PLUS :
+ if (nargs > 1) {
+ PUSH_N_ARGS_ARITHMETIC_OP(e, op, obj, nargs, code);
+ }
+ break;
+ case GRN_OP_MINUS :
+ if (nargs == 1) {
+ APPEND_UNARY_MINUS_OP(e);
+ } else {
+ PUSH_N_ARGS_ARITHMETIC_OP(e, op, obj, nargs, code);
+ }
+ 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 :
+ case GRN_OP_MOD :
+ case GRN_OP_SHIFTL :
+ case GRN_OP_SHIFTR :
+ case GRN_OP_SHIFTRR :
+ case GRN_OP_BITWISE_OR :
+ case GRN_OP_BITWISE_XOR :
+ case GRN_OP_BITWISE_AND :
+ PUSH_N_ARGS_ARITHMETIC_OP(e, op, obj, nargs, code);
+ break;
+ case GRN_OP_INCR :
+ case GRN_OP_DECR :
+ case GRN_OP_INCR_POST :
+ case GRN_OP_DECR_POST :
+ {
+ dfi = grn_expr_dfi_pop(e);
+ if (dfi) {
+ type = dfi->type;
+ domain = dfi->domain;
+ if (dfi->code) {
+ if (dfi->code->op == GRN_OP_GET_VALUE) {
+ dfi->code->op = GRN_OP_GET_REF;
+ }
+ if (dfi->code->value && grn_obj_is_persistent(ctx, dfi->code->value)) {
+ e->cacheable = 0;
+ e->taintable = 1;
+ }
+ }
+ }
+ PUSH_CODE(e, op, obj, nargs, code);
+ }
+ grn_expr_dfi_put(ctx, e, type, domain, code);
+ break;
+ case GRN_OP_GET_VALUE :
+ {
+ grn_id vdomain = GRN_ID_NIL;
+ if (obj) {
+ 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 = grn_expr_dfi_pop(e);
+ vdomain = dfi->domain;
+ }
+ if (vdomain && CONSTP(obj) && obj->header.type == GRN_BULK) {
+ grn_obj *table = grn_ctx_at(ctx, vdomain);
+ grn_obj *col = grn_obj_column(ctx, table, GRN_BULK_HEAD(obj), GRN_BULK_VSIZE(obj));
+ if (col) {
+ obj = col;
+ type = col->header.type;
+ domain = grn_obj_get_range(ctx, col);
+ grn_expr_take_obj(ctx, (grn_obj *)e, col);
+ }
+ } else {
+ domain = grn_obj_get_range(ctx, obj);
+ }
+ PUSH_CODE(e, op, obj, nargs, code);
+ } else {
+ grn_expr_dfi *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 = grn_expr_dfi_pop(e);
+ vdomain = dfi->domain;
+ }
+ if (dfi0->code->op == GRN_OP_PUSH) {
+ dfi0->code->op = op;
+ dfi0->code->nargs = nargs;
+ obj = dfi0->code->value;
+ if (vdomain && obj && CONSTP(obj) && obj->header.type == GRN_BULK) {
+ grn_obj *table = grn_ctx_at(ctx, vdomain);
+ grn_obj *col = grn_obj_column(ctx, table, GRN_BULK_HEAD(obj), GRN_BULK_VSIZE(obj));
+ if (col) {
+ dfi0->code->value = col;
+ type = col->header.type;
+ domain = grn_obj_get_range(ctx, col);
+ grn_obj_unlink(ctx, col);
+ }
+ } else {
+ domain = grn_obj_get_range(ctx, obj);
+ }
+ code = dfi0->code;
+ } else {
+ PUSH_CODE(e, op, obj, nargs, code);
+ }
+ }
+ }
+ grn_expr_dfi_put(ctx, e, type, domain, code);
+ break;
+ case GRN_OP_ASSIGN :
+ case GRN_OP_STAR_ASSIGN :
+ case GRN_OP_SLASH_ASSIGN :
+ case GRN_OP_MOD_ASSIGN :
+ case GRN_OP_PLUS_ASSIGN :
+ case GRN_OP_MINUS_ASSIGN :
+ case GRN_OP_SHIFTL_ASSIGN :
+ case GRN_OP_SHIFTR_ASSIGN :
+ case GRN_OP_SHIFTRR_ASSIGN :
+ case GRN_OP_AND_ASSIGN :
+ case GRN_OP_OR_ASSIGN :
+ case GRN_OP_XOR_ASSIGN :
+ {
+ if (obj) {
+ type = obj->header.type;
+ domain = GRN_OBJ_GET_DOMAIN(obj);
+ } else {
+ dfi = grn_expr_dfi_pop(e);
+ if (dfi) {
+ type = dfi->type;
+ domain = dfi->domain;
+ }
+ }
+ 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;
+ }
+ if (dfi->code->value && grn_obj_is_persistent(ctx, dfi->code->value)) {
+ e->cacheable = 0;
+ e->taintable = 1;
+ }
+ }
+ PUSH_CODE(e, op, obj, nargs, code);
+ }
+ grn_expr_dfi_put(ctx, e, type, domain, code);
+ break;
+ case GRN_OP_JUMP :
+ dfi = grn_expr_dfi_pop(e);
+ PUSH_CODE(e, op, obj, nargs, code);
+ break;
+ case GRN_OP_CJUMP :
+ 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 = grn_expr_dfi_pop(e);
+ dfi = grn_expr_dfi_pop(e);
+ if (dfi) {
+ type = dfi->type;
+ domain = dfi->domain;
+ if (dfi->code) {
+ if (dfi->code->op == GRN_OP_GET_VALUE) {
+ dfi->code->op = GRN_OP_GET_REF;
+ }
+ }
+ }
+ PUSH_CODE(e, op, obj, nargs, code);
+ grn_expr_dfi_put(ctx, e, type, domain, code);
+ break;
+ default :
+ break;
+ }
+ }
+exit :
+ if (!ctx->rc) { res = obj; }
+ GRN_API_RETURN(res);
+}
+#undef PUSH_N_ARGS_ARITHMETIC_OP
+#undef APPEND_UNARY_MINUS_OP
+
+grn_obj *
+grn_expr_append_const(grn_ctx *ctx, grn_obj *expr, grn_obj *obj,
+ grn_operator op, int nargs)
+{
+ grn_obj *res = NULL;
+ GRN_API_ENTER;
+ if (!obj) {
+ ERR(GRN_SYNTAX_ERROR, "constant is null");
+ goto exit;
+ }
+ if (GRN_DB_OBJP(obj) || GRN_ACCESSORP(obj)) {
+ res = obj;
+ } else {
+ if ((res = grn_expr_alloc_const(ctx, expr))) {
+ switch (obj->header.type) {
+ case GRN_VOID :
+ case GRN_BULK :
+ case GRN_UVECTOR :
+ GRN_OBJ_INIT(res, obj->header.type, 0, obj->header.domain);
+ grn_bulk_write(ctx, res, GRN_BULK_HEAD(obj), GRN_BULK_VSIZE(obj));
+ break;
+ default :
+ res = NULL;
+ ERR(GRN_FUNCTION_NOT_IMPLEMENTED, "unsupported type");
+ goto exit;
+ }
+ res->header.impl_flags |= GRN_OBJ_EXPRCONST;
+ }
+ }
+ grn_expr_append_obj(ctx, expr, res, op, nargs); /* constant */
+exit :
+ GRN_API_RETURN(res);
+}
+
+static grn_obj *
+grn_expr_add_str(grn_ctx *ctx, grn_obj *expr, const char *str, unsigned int str_size)
+{
+ grn_obj *res = NULL;
+ if ((res = grn_expr_alloc_const(ctx, expr))) {
+ GRN_TEXT_INIT(res, 0);
+ grn_bulk_write(ctx, res, str, str_size);
+ res->header.impl_flags |= GRN_OBJ_EXPRCONST;
+ }
+ return res;
+}
+
+grn_obj *
+grn_expr_append_const_str(grn_ctx *ctx, grn_obj *expr, const char *str, unsigned int str_size,
+ grn_operator op, int nargs)
+{
+ grn_obj *res;
+ GRN_API_ENTER;
+ res = grn_expr_add_str(ctx, expr, str, str_size);
+ grn_expr_append_obj(ctx, expr, res, op, nargs); /* constant */
+ GRN_API_RETURN(res);
+}
+
+grn_obj *
+grn_expr_append_const_int(grn_ctx *ctx, grn_obj *expr, int i,
+ grn_operator op, int nargs)
+{
+ grn_obj *res = NULL;
+ GRN_API_ENTER;
+ if ((res = grn_expr_alloc_const(ctx, expr))) {
+ GRN_INT32_INIT(res, 0);
+ GRN_INT32_SET(ctx, res, i);
+ res->header.impl_flags |= GRN_OBJ_EXPRCONST;
+ }
+ grn_expr_append_obj(ctx, expr, res, op, nargs); /* constant */
+ GRN_API_RETURN(res);
+}
+
+grn_rc
+grn_expr_append_op(grn_ctx *ctx, grn_obj *expr, grn_operator op, int nargs)
+{
+ grn_expr_append_obj(ctx, expr, NULL, op, nargs);
+ return ctx->rc;
+}
+
+grn_rc
+grn_expr_compile(grn_ctx *ctx, grn_obj *expr)
+{
+ grn_obj_spec_save(ctx, DB_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;\
+ block\
+ vp = e->values + e->values_curr;\
+ sp = ctx->impl->stack + ctx->impl->stack_curr;\
+ s0 = sp[-1];\
+ s1 = sp[-2];\
+} while (0)
+
+#define GEO_RESOLUTION 3600000
+#define GEO_RADIOUS 6357303
+#define GEO_BES_C1 6334834
+#define GEO_BES_C2 6377397
+#define GEO_BES_C3 0.006674
+#define GEO_GRS_C1 6335439
+#define GEO_GRS_C2 6378137
+#define GEO_GRS_C3 0.006694
+#define GEO_INT2RAD(x) ((M_PI * x) / (GEO_RESOLUTION * 180))
+
+#define VAR_SET_VALUE(ctx,var,value) do {\
+ if (GRN_DB_OBJP(value)) {\
+ (var)->header.type = GRN_PTR;\
+ (var)->header.domain = DB_OBJ(value)->id;\
+ GRN_PTR_SET(ctx, (var), (value));\
+ } else {\
+ (var)->header.type = (value)->header.type;\
+ (var)->header.domain = (value)->header.domain;\
+ GRN_TEXT_SET(ctx, (var), GRN_TEXT_VALUE(value), GRN_TEXT_LEN(value));\
+ }\
+} while (0)
+
+grn_rc
+grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller)
+{
+ grn_proc_ctx pctx;
+ grn_obj *obj = NULL, **args;
+ 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]) {
+ 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]) {
+ 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]) {
+ 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);
+ GRN_API_RETURN(ctx->rc);
+}
+
+#define PUSH1(v) do {\
+ if (EXPRVP(v)) {\
+ vp++;\
+ if (vp - e->values > e->values_tail) { e->values_tail = vp - e->values; }\
+ }\
+ s1 = s0;\
+ *sp++ = s0 = v;\
+} while (0)
+
+#define POP1(v) do {\
+ if (EXPRVP(s0)) { vp--; }\
+ v = s0;\
+ s0 = s1;\
+ sp--;\
+ if (sp < s_) { ERR(GRN_INVALID_ARGUMENT, "stack underflow"); goto exit; }\
+ s1 = sp[-2];\
+} while (0)
+
+#define ALLOC1(value) do {\
+ s1 = s0;\
+ *sp++ = s0 = value = vp++;\
+ if (vp - e->values > e->values_tail) { e->values_tail = vp - e->values; }\
+} while (0)
+
+#define POP1ALLOC1(arg,value) do {\
+ arg = s0;\
+ if (EXPRVP(s0)) {\
+ value = s0;\
+ } else {\
+ if (sp < s_ + 1) { ERR(GRN_INVALID_ARGUMENT, "stack underflow"); goto exit; }\
+ sp[-1] = s0 = value = vp++;\
+ if (vp - e->values > e->values_tail) { e->values_tail = vp - e->values; }\
+ s0->header.impl_flags |= GRN_OBJ_EXPRVALUE;\
+ }\
+} while (0)
+
+#define POP2ALLOC1(arg1,arg2,value) do {\
+ if (EXPRVP(s0)) { vp--; }\
+ if (EXPRVP(s1)) { vp--; }\
+ arg2 = s0;\
+ arg1 = s1;\
+ sp--;\
+ if (sp < s_ + 1) { ERR(GRN_INVALID_ARGUMENT, "stack underflow"); goto exit; }\
+ s1 = sp[-2];\
+ sp[-1] = s0 = value = vp++;\
+ if (vp - e->values > e->values_tail) { e->values_tail = vp - e->values; }\
+ s0->header.impl_flags |= GRN_OBJ_EXPRVALUE;\
+} while (0)
+
+#define INTEGER_ARITHMETIC_OPERATION_PLUS(x, y) ((x) + (y))
+#define FLOAT_ARITHMETIC_OPERATION_PLUS(x, y) ((double)(x) + (double)(y))
+#define INTEGER_ARITHMETIC_OPERATION_MINUS(x, y) ((x) - (y))
+#define FLOAT_ARITHMETIC_OPERATION_MINUS(x, y) ((double)(x) - (double)(y))
+#define INTEGER_ARITHMETIC_OPERATION_STAR(x, y) ((x) * (y))
+#define FLOAT_ARITHMETIC_OPERATION_STAR(x, y) ((double)(x) * (double)(y))
+#define INTEGER_ARITHMETIC_OPERATION_SLASH(x, y) ((x) / (y))
+#define FLOAT_ARITHMETIC_OPERATION_SLASH(x, y) ((double)(x) / (double)(y))
+#define INTEGER_ARITHMETIC_OPERATION_MOD(x, y) ((x) % (y))
+#define FLOAT_ARITHMETIC_OPERATION_MOD(x, y) (fmod((x), (y)))
+#define INTEGER_ARITHMETIC_OPERATION_SHIFTL(x, y) ((x) << (y))
+#define FLOAT_ARITHMETIC_OPERATION_SHIFTL(x, y) \
+ ((long long int)(x) << (long long int)(y))
+#define INTEGER_ARITHMETIC_OPERATION_SHIFTR(x, y) ((x) >> (y))
+#define FLOAT_ARITHMETIC_OPERATION_SHIFTR(x, y) \
+ ((long long int)(x) >> (long long int)(y))
+#define INTEGER8_ARITHMETIC_OPERATION_SHIFTRR(x, y) \
+ ((uint8_t)(x) >> (y))
+#define INTEGER16_ARITHMETIC_OPERATION_SHIFTRR(x, y) \
+ ((uint16_t)(x) >> (y))
+#define INTEGER32_ARITHMETIC_OPERATION_SHIFTRR(x, y) \
+ ((unsigned int)(x) >> (y))
+#define INTEGER64_ARITHMETIC_OPERATION_SHIFTRR(x, y) \
+ ((long long unsigned int)(x) >> (y))
+#define FLOAT_ARITHMETIC_OPERATION_SHIFTRR(x, y) \
+ ((long long unsigned int)(x) >> (long long unsigned int)(y))
+
+#define INTEGER_ARITHMETIC_OPERATION_BITWISE_OR(x, y) ((x) | (y))
+#define FLOAT_ARITHMETIC_OPERATION_BITWISE_OR(x, y) \
+ ((long long int)(x) | (long long int)(y))
+#define INTEGER_ARITHMETIC_OPERATION_BITWISE_XOR(x, y) ((x) ^ (y))
+#define FLOAT_ARITHMETIC_OPERATION_BITWISE_XOR(x, y) \
+ ((long long int)(x) ^ (long long int)(y))
+#define INTEGER_ARITHMETIC_OPERATION_BITWISE_AND(x, y) ((x) & (y))
+#define FLOAT_ARITHMETIC_OPERATION_BITWISE_AND(x, y) \
+ ((long long int)(x) & (long long int)(y))
+
+#define INTEGER_UNARY_ARITHMETIC_OPERATION_MINUS(x) (-(x))
+#define FLOAT_UNARY_ARITHMETIC_OPERATION_MINUS(x) (-(x))
+#define INTEGER_UNARY_ARITHMETIC_OPERATION_BITWISE_NOT(x) (~(x))
+#define FLOAT_UNARY_ARITHMETIC_OPERATION_BITWISE_NOT(x) \
+ (~((long long int)(x)))
+
+#define TEXT_ARITHMETIC_OPERATION(operator) do { \
+ long long int x_; \
+ long long int y_; \
+ \
+ res->header.domain = GRN_DB_INT64; \
+ \
+ GRN_INT64_SET(ctx, res, 0); \
+ grn_obj_cast(ctx, x, res, GRN_FALSE); \
+ x_ = GRN_INT64_VALUE(res); \
+ \
+ GRN_INT64_SET(ctx, res, 0); \
+ grn_obj_cast(ctx, y, res, GRN_FALSE); \
+ y_ = GRN_INT64_VALUE(res); \
+ \
+ GRN_INT64_SET(ctx, res, x_ operator y_); \
+} while (0)
+
+#define TEXT_UNARY_ARITHMETIC_OPERATION(unary_operator) do { \
+ long long int x_; \
+ \
+ res->header.domain = GRN_DB_INT64; \
+ \
+ GRN_INT64_SET(ctx, res, 0); \
+ grn_obj_cast(ctx, x, res, GRN_FALSE); \
+ x_ = GRN_INT64_VALUE(res); \
+ \
+ GRN_INT64_SET(ctx, res, unary_operator x_); \
+} while (0)
+
+#define ARITHMETIC_OPERATION_NO_CHECK(y) do {} while (0)
+#define ARITHMETIC_OPERATION_ZERO_DIVISION_CHECK(y) do { \
+ if ((long long int)y == 0) { \
+ ERR(GRN_INVALID_ARGUMENT, "divisor should not be 0"); \
+ goto exit; \
+ } \
+} while (0)
+
+
+#define NUMERIC_ARITHMETIC_OPERATION_DISPATCH(set, get, x_, y, res, \
+ integer_operation, \
+ float_operation, \
+ right_expression_check, \
+ invalid_type_error) do { \
+ switch (y->header.domain) { \
+ case GRN_DB_INT8 : \
+ { \
+ int8_t y_; \
+ y_ = GRN_INT8_VALUE(y); \
+ right_expression_check(y_); \
+ set(ctx, res, integer_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_UINT8 : \
+ { \
+ uint8_t y_; \
+ y_ = GRN_UINT8_VALUE(y); \
+ right_expression_check(y_); \
+ set(ctx, res, integer_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_INT16 : \
+ { \
+ int16_t y_; \
+ y_ = GRN_INT16_VALUE(y); \
+ right_expression_check(y_); \
+ set(ctx, res, integer_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_UINT16 : \
+ { \
+ uint16_t y_; \
+ y_ = GRN_UINT16_VALUE(y); \
+ right_expression_check(y_); \
+ set(ctx, res, integer_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_INT32 : \
+ { \
+ int y_; \
+ y_ = GRN_INT32_VALUE(y); \
+ right_expression_check(y_); \
+ set(ctx, res, integer_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_UINT32 : \
+ { \
+ unsigned int y_; \
+ y_ = GRN_UINT32_VALUE(y); \
+ right_expression_check(y_); \
+ set(ctx, res, integer_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_TIME : \
+ { \
+ long long int y_; \
+ y_ = GRN_TIME_VALUE(y); \
+ right_expression_check(y_); \
+ set(ctx, res, integer_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_INT64 : \
+ { \
+ long long int y_; \
+ y_ = GRN_INT64_VALUE(y); \
+ right_expression_check(y_); \
+ set(ctx, res, integer_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_UINT64 : \
+ { \
+ long long unsigned int y_; \
+ y_ = GRN_UINT64_VALUE(y); \
+ right_expression_check(y_); \
+ set(ctx, res, integer_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_FLOAT : \
+ { \
+ double y_; \
+ y_ = GRN_FLOAT_VALUE(y); \
+ right_expression_check(y_); \
+ res->header.domain = GRN_DB_FLOAT; \
+ GRN_FLOAT_SET(ctx, res, float_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_SHORT_TEXT : \
+ case GRN_DB_TEXT : \
+ case GRN_DB_LONG_TEXT : \
+ set(ctx, res, 0); \
+ 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)); \
+ goto exit; \
+ } \
+ set(ctx, res, integer_operation(x_, get(res))); \
+ break; \
+ default : \
+ invalid_type_error; \
+ break; \
+ } \
+} while (0)
+
+
+#define ARITHMETIC_OPERATION_DISPATCH(x, y, res, \
+ integer8_operation, \
+ integer16_operation, \
+ integer32_operation, \
+ integer64_operation, \
+ float_operation, \
+ left_expression_check, \
+ right_expression_check, \
+ text_operation, \
+ invalid_type_error) do { \
+ switch (x->header.domain) { \
+ case GRN_DB_INT8 : \
+ { \
+ int8_t x_; \
+ x_ = GRN_INT8_VALUE(x); \
+ left_expression_check(x_); \
+ NUMERIC_ARITHMETIC_OPERATION_DISPATCH(GRN_INT8_SET, \
+ GRN_INT8_VALUE, \
+ x_, y, res, \
+ integer8_operation, \
+ float_operation, \
+ right_expression_check, \
+ invalid_type_error); \
+ } \
+ break; \
+ case GRN_DB_UINT8 : \
+ { \
+ uint8_t x_; \
+ x_ = GRN_UINT8_VALUE(x); \
+ left_expression_check(x_); \
+ NUMERIC_ARITHMETIC_OPERATION_DISPATCH(GRN_UINT8_SET, \
+ GRN_UINT8_VALUE, \
+ x_, y, res, \
+ integer8_operation, \
+ float_operation, \
+ right_expression_check, \
+ invalid_type_error); \
+ } \
+ break; \
+ case GRN_DB_INT16 : \
+ { \
+ int16_t x_; \
+ x_ = GRN_INT16_VALUE(x); \
+ left_expression_check(x_); \
+ NUMERIC_ARITHMETIC_OPERATION_DISPATCH(GRN_INT16_SET, \
+ GRN_INT16_VALUE, \
+ x_, y, res, \
+ integer16_operation, \
+ float_operation, \
+ right_expression_check, \
+ invalid_type_error); \
+ } \
+ break; \
+ case GRN_DB_UINT16 : \
+ { \
+ uint16_t x_; \
+ x_ = GRN_UINT16_VALUE(x); \
+ left_expression_check(x_); \
+ NUMERIC_ARITHMETIC_OPERATION_DISPATCH(GRN_UINT16_SET, \
+ GRN_UINT16_VALUE, \
+ x_, y, res, \
+ integer16_operation, \
+ float_operation, \
+ right_expression_check, \
+ invalid_type_error); \
+ } \
+ break; \
+ case GRN_DB_INT32 : \
+ { \
+ int x_; \
+ x_ = GRN_INT32_VALUE(x); \
+ left_expression_check(x_); \
+ NUMERIC_ARITHMETIC_OPERATION_DISPATCH(GRN_INT32_SET, \
+ GRN_INT32_VALUE, \
+ x_, y, res, \
+ integer32_operation, \
+ float_operation, \
+ right_expression_check, \
+ invalid_type_error); \
+ } \
+ break; \
+ case GRN_DB_UINT32 : \
+ { \
+ unsigned int x_; \
+ x_ = GRN_UINT32_VALUE(x); \
+ left_expression_check(x_); \
+ NUMERIC_ARITHMETIC_OPERATION_DISPATCH(GRN_UINT32_SET, \
+ GRN_UINT32_VALUE, \
+ x_, y, res, \
+ integer32_operation, \
+ float_operation, \
+ right_expression_check, \
+ invalid_type_error); \
+ } \
+ break; \
+ case GRN_DB_INT64 : \
+ { \
+ long long int x_; \
+ x_ = GRN_INT64_VALUE(x); \
+ left_expression_check(x_); \
+ NUMERIC_ARITHMETIC_OPERATION_DISPATCH(GRN_INT64_SET, \
+ GRN_INT64_VALUE, \
+ x_, y, res, \
+ integer64_operation, \
+ float_operation, \
+ right_expression_check, \
+ invalid_type_error); \
+ } \
+ break; \
+ case GRN_DB_TIME : \
+ { \
+ long long int x_; \
+ x_ = GRN_TIME_VALUE(x); \
+ left_expression_check(x_); \
+ NUMERIC_ARITHMETIC_OPERATION_DISPATCH(GRN_TIME_SET, \
+ GRN_TIME_VALUE, \
+ x_, y, res, \
+ integer64_operation, \
+ float_operation, \
+ right_expression_check, \
+ invalid_type_error); \
+ } \
+ break; \
+ case GRN_DB_UINT64 : \
+ { \
+ long long unsigned int x_; \
+ x_ = GRN_UINT64_VALUE(x); \
+ left_expression_check(x_); \
+ NUMERIC_ARITHMETIC_OPERATION_DISPATCH(GRN_UINT64_SET, \
+ GRN_UINT64_VALUE, \
+ x_, y, res, \
+ integer64_operation, \
+ float_operation, \
+ right_expression_check, \
+ invalid_type_error); \
+ } \
+ break; \
+ case GRN_DB_FLOAT : \
+ { \
+ double x_; \
+ x_ = GRN_FLOAT_VALUE(x); \
+ left_expression_check(x_); \
+ NUMERIC_ARITHMETIC_OPERATION_DISPATCH(GRN_FLOAT_SET, \
+ GRN_FLOAT_VALUE, \
+ x_, y, res, \
+ float_operation, \
+ float_operation, \
+ right_expression_check, \
+ invalid_type_error); \
+ } \
+ break; \
+ case GRN_DB_SHORT_TEXT : \
+ case GRN_DB_TEXT : \
+ case GRN_DB_LONG_TEXT : \
+ text_operation; \
+ break; \
+ default: \
+ invalid_type_error; \
+ break; \
+ } \
+ code++; \
+} while (0)
+
+#define ARITHMETIC_BINARY_OPERATION_DISPATCH(operator, \
+ integer8_operation, \
+ integer16_operation, \
+ integer32_operation, \
+ integer64_operation, \
+ float_operation, \
+ left_expression_check, \
+ right_expression_check, \
+ text_operation, \
+ invalid_type_error) do { \
+ grn_obj *x, *y; \
+ \
+ POP2ALLOC1(x, y, res); \
+ if (x->header.type == GRN_VECTOR || y->header.type == GRN_VECTOR) { \
+ grn_obj inspected_x; \
+ grn_obj inspected_y; \
+ GRN_TEXT_INIT(&inspected_x, 0); \
+ GRN_TEXT_INIT(&inspected_y, 0); \
+ grn_inspect(ctx, &inspected_x, x); \
+ grn_inspect(ctx, &inspected_y, y); \
+ ERR(GRN_INVALID_ARGUMENT, \
+ "<%s> doesn't support vector: <%.*s> %s <%.*s>", \
+ operator, \
+ (int)GRN_TEXT_LEN(&inspected_x), GRN_TEXT_VALUE(&inspected_x), \
+ operator, \
+ (int)GRN_TEXT_LEN(&inspected_y), GRN_TEXT_VALUE(&inspected_y)); \
+ GRN_OBJ_FIN(ctx, &inspected_x); \
+ GRN_OBJ_FIN(ctx, &inspected_y); \
+ goto exit; \
+ } \
+ if (y != res) { \
+ res->header.domain = x->header.domain; \
+ } \
+ ARITHMETIC_OPERATION_DISPATCH(x, y, res, \
+ integer8_operation, \
+ integer16_operation, \
+ integer32_operation, \
+ integer64_operation, \
+ float_operation, \
+ left_expression_check, \
+ right_expression_check, \
+ text_operation, \
+ invalid_type_error); \
+ if (y == res) { \
+ res->header.domain = x->header.domain; \
+ } \
+} while (0)
+
+#define SIGNED_INTEGER_DIVISION_OPERATION_SLASH(x, y) \
+ ((y == -1) ? -(x) : (x) / (y))
+#define UNSIGNED_INTEGER_DIVISION_OPERATION_SLASH(x, y) ((x) / (y))
+#define FLOAT_DIVISION_OPERATION_SLASH(x, y) ((double)(x) / (double)(y))
+#define SIGNED_INTEGER_DIVISION_OPERATION_MOD(x, y) ((y == -1) ? 0 : (x) % (y))
+#define UNSIGNED_INTEGER_DIVISION_OPERATION_MOD(x, y) ((x) % (y))
+#define FLOAT_DIVISION_OPERATION_MOD(x, y) (fmod((x), (y)))
+
+#define DIVISION_OPERATION_DISPATCH_RIGHT(set, get, x_, y, res, \
+ signed_integer_operation, \
+ unsigned_integer_operation, \
+ float_operation) do { \
+ switch (y->header.domain) { \
+ case GRN_DB_INT8 : \
+ { \
+ int y_; \
+ y_ = GRN_INT8_VALUE(y); \
+ ARITHMETIC_OPERATION_ZERO_DIVISION_CHECK(y_); \
+ set(ctx, res, signed_integer_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_UINT8 : \
+ { \
+ int y_; \
+ y_ = GRN_UINT8_VALUE(y); \
+ ARITHMETIC_OPERATION_ZERO_DIVISION_CHECK(y_); \
+ set(ctx, res, unsigned_integer_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_INT16 : \
+ { \
+ int y_; \
+ y_ = GRN_INT16_VALUE(y); \
+ ARITHMETIC_OPERATION_ZERO_DIVISION_CHECK(y_); \
+ set(ctx, res, signed_integer_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_UINT16 : \
+ { \
+ int y_; \
+ y_ = GRN_UINT16_VALUE(y); \
+ ARITHMETIC_OPERATION_ZERO_DIVISION_CHECK(y_); \
+ set(ctx, res, unsigned_integer_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_INT32 : \
+ { \
+ int y_; \
+ y_ = GRN_INT32_VALUE(y); \
+ ARITHMETIC_OPERATION_ZERO_DIVISION_CHECK(y_); \
+ set(ctx, res, signed_integer_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_UINT32 : \
+ { \
+ unsigned int y_; \
+ y_ = GRN_UINT32_VALUE(y); \
+ ARITHMETIC_OPERATION_ZERO_DIVISION_CHECK(y_); \
+ set(ctx, res, unsigned_integer_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_TIME : \
+ { \
+ long long int y_; \
+ y_ = GRN_TIME_VALUE(y); \
+ ARITHMETIC_OPERATION_ZERO_DIVISION_CHECK(y_); \
+ set(ctx, res, signed_integer_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_INT64 : \
+ { \
+ long long int y_; \
+ y_ = GRN_INT64_VALUE(y); \
+ ARITHMETIC_OPERATION_ZERO_DIVISION_CHECK(y_); \
+ set(ctx, res, signed_integer_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_UINT64 : \
+ { \
+ long long unsigned int y_; \
+ y_ = GRN_UINT64_VALUE(y); \
+ ARITHMETIC_OPERATION_ZERO_DIVISION_CHECK(y_); \
+ set(ctx, res, unsigned_integer_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_FLOAT : \
+ { \
+ double y_; \
+ y_ = GRN_FLOAT_VALUE(y); \
+ ARITHMETIC_OPERATION_ZERO_DIVISION_CHECK(y_); \
+ res->header.domain = GRN_DB_FLOAT; \
+ GRN_FLOAT_SET(ctx, res, float_operation(x_, y_)); \
+ } \
+ break; \
+ case GRN_DB_SHORT_TEXT : \
+ case GRN_DB_TEXT : \
+ case GRN_DB_LONG_TEXT : \
+ set(ctx, res, 0); \
+ 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)); \
+ goto exit; \
+ } \
+ /* The following "+ 0" is needed to suppress warnings that say */ \
+ /* comparison is always false due to limited range of data type */ \
+ set(ctx, res, signed_integer_operation(x_, (get(res) + 0))); \
+ break; \
+ default : \
+ break; \
+ } \
+} while (0)
+
+#define DIVISION_OPERATION_DISPATCH_LEFT(x, y, res, \
+ signed_integer_operation, \
+ unsigned_integer_operation, \
+ float_operation, \
+ invalid_type_error) do { \
+ switch (x->header.domain) { \
+ case GRN_DB_INT8 : \
+ { \
+ int x_; \
+ x_ = GRN_INT8_VALUE(x); \
+ DIVISION_OPERATION_DISPATCH_RIGHT(GRN_INT8_SET, \
+ GRN_INT8_VALUE, \
+ x_, y, res, \
+ signed_integer_operation, \
+ unsigned_integer_operation, \
+ float_operation); \
+ } \
+ break; \
+ case GRN_DB_UINT8 : \
+ { \
+ int x_; \
+ x_ = GRN_UINT8_VALUE(x); \
+ DIVISION_OPERATION_DISPATCH_RIGHT(GRN_UINT8_SET, \
+ (int)GRN_UINT8_VALUE, \
+ x_, y, res, \
+ signed_integer_operation, \
+ unsigned_integer_operation, \
+ float_operation); \
+ } \
+ break; \
+ case GRN_DB_INT16 : \
+ { \
+ int x_; \
+ x_ = GRN_INT16_VALUE(x); \
+ DIVISION_OPERATION_DISPATCH_RIGHT(GRN_INT16_SET, \
+ GRN_INT16_VALUE, \
+ x_, y, res, \
+ signed_integer_operation, \
+ unsigned_integer_operation, \
+ float_operation); \
+ } \
+ break; \
+ case GRN_DB_UINT16 : \
+ { \
+ int x_; \
+ x_ = GRN_UINT16_VALUE(x); \
+ DIVISION_OPERATION_DISPATCH_RIGHT(GRN_UINT16_SET, \
+ (int)GRN_UINT16_VALUE, \
+ x_, y, res, \
+ signed_integer_operation, \
+ unsigned_integer_operation, \
+ float_operation); \
+ } \
+ break; \
+ case GRN_DB_INT32 : \
+ { \
+ int x_; \
+ x_ = GRN_INT32_VALUE(x); \
+ DIVISION_OPERATION_DISPATCH_RIGHT(GRN_INT32_SET, \
+ GRN_INT32_VALUE, \
+ x_, y, res, \
+ signed_integer_operation, \
+ unsigned_integer_operation, \
+ float_operation); \
+ } \
+ break; \
+ case GRN_DB_UINT32 : \
+ { \
+ unsigned int x_; \
+ x_ = GRN_UINT32_VALUE(x); \
+ DIVISION_OPERATION_DISPATCH_RIGHT(GRN_UINT32_SET, \
+ GRN_UINT32_VALUE, \
+ x_, y, res, \
+ unsigned_integer_operation, \
+ unsigned_integer_operation, \
+ float_operation); \
+ } \
+ break; \
+ case GRN_DB_INT64 : \
+ { \
+ long long int x_; \
+ x_ = GRN_INT64_VALUE(x); \
+ DIVISION_OPERATION_DISPATCH_RIGHT(GRN_INT64_SET, \
+ GRN_INT64_VALUE, \
+ x_, y, res, \
+ signed_integer_operation, \
+ unsigned_integer_operation, \
+ float_operation); \
+ } \
+ break; \
+ case GRN_DB_TIME : \
+ { \
+ long long int x_; \
+ x_ = GRN_TIME_VALUE(x); \
+ DIVISION_OPERATION_DISPATCH_RIGHT(GRN_TIME_SET, \
+ GRN_TIME_VALUE, \
+ x_, y, res, \
+ signed_integer_operation, \
+ unsigned_integer_operation, \
+ float_operation); \
+ } \
+ break; \
+ case GRN_DB_UINT64 : \
+ { \
+ long long unsigned int x_; \
+ x_ = GRN_UINT64_VALUE(x); \
+ DIVISION_OPERATION_DISPATCH_RIGHT(GRN_UINT64_SET, \
+ GRN_UINT64_VALUE, \
+ x_, y, res, \
+ unsigned_integer_operation, \
+ unsigned_integer_operation, \
+ float_operation); \
+ } \
+ break; \
+ case GRN_DB_FLOAT : \
+ { \
+ double x_; \
+ x_ = GRN_FLOAT_VALUE(x); \
+ DIVISION_OPERATION_DISPATCH_RIGHT(GRN_FLOAT_SET, \
+ GRN_FLOAT_VALUE, \
+ x_, y, res, \
+ float_operation, \
+ float_operation, \
+ float_operation); \
+ } \
+ break; \
+ case GRN_DB_SHORT_TEXT : \
+ case GRN_DB_TEXT : \
+ case GRN_DB_LONG_TEXT : \
+ invalid_type_error; \
+ break; \
+ default: \
+ break; \
+ } \
+ code++; \
+} while (0)
+
+#define DIVISION_OPERATION_DISPATCH(signed_integer_operation, \
+ unsigned_integer_operation, \
+ float_operation, \
+ invalid_type_error) do { \
+ grn_obj *x, *y; \
+ \
+ POP2ALLOC1(x, y, res); \
+ if (y != res) { \
+ res->header.domain = x->header.domain; \
+ } \
+ DIVISION_OPERATION_DISPATCH_LEFT(x, y, res, \
+ signed_integer_operation, \
+ unsigned_integer_operation, \
+ float_operation, \
+ invalid_type_error); \
+ if (y == res) { \
+ res->header.domain = x->header.domain; \
+ } \
+} while (0)
+
+#define ARITHMETIC_UNARY_OPERATION_DISPATCH(integer_operation, \
+ float_operation, \
+ left_expression_check, \
+ right_expression_check, \
+ text_operation, \
+ invalid_type_error) do { \
+ grn_obj *x; \
+ POP1ALLOC1(x, res); \
+ res->header.domain = x->header.domain; \
+ switch (x->header.domain) { \
+ case GRN_DB_INT8 : \
+ { \
+ int8_t x_; \
+ x_ = GRN_INT8_VALUE(x); \
+ left_expression_check(x_); \
+ GRN_INT8_SET(ctx, res, integer_operation(x_)); \
+ } \
+ break; \
+ case GRN_DB_UINT8 : \
+ { \
+ int16_t x_; \
+ x_ = GRN_UINT8_VALUE(x); \
+ left_expression_check(x_); \
+ GRN_INT16_SET(ctx, res, integer_operation(x_)); \
+ res->header.domain = GRN_DB_INT16; \
+ } \
+ break; \
+ case GRN_DB_INT16 : \
+ { \
+ int16_t x_; \
+ x_ = GRN_INT16_VALUE(x); \
+ left_expression_check(x_); \
+ GRN_INT16_SET(ctx, res, integer_operation(x_)); \
+ } \
+ break; \
+ case GRN_DB_UINT16 : \
+ { \
+ int x_; \
+ x_ = GRN_UINT16_VALUE(x); \
+ left_expression_check(x_); \
+ GRN_INT32_SET(ctx, res, integer_operation(x_)); \
+ res->header.domain = GRN_DB_INT32; \
+ } \
+ break; \
+ case GRN_DB_INT32 : \
+ { \
+ int x_; \
+ x_ = GRN_INT32_VALUE(x); \
+ left_expression_check(x_); \
+ GRN_INT32_SET(ctx, res, integer_operation(x_)); \
+ } \
+ break; \
+ case GRN_DB_UINT32 : \
+ { \
+ long long int x_; \
+ x_ = GRN_UINT32_VALUE(x); \
+ left_expression_check(x_); \
+ GRN_INT64_SET(ctx, res, integer_operation(x_)); \
+ res->header.domain = GRN_DB_INT64; \
+ } \
+ break; \
+ case GRN_DB_INT64 : \
+ { \
+ long long int x_; \
+ x_ = GRN_INT64_VALUE(x); \
+ left_expression_check(x_); \
+ GRN_INT64_SET(ctx, res, integer_operation(x_)); \
+ } \
+ break; \
+ case GRN_DB_TIME : \
+ { \
+ long long int x_; \
+ x_ = GRN_TIME_VALUE(x); \
+ left_expression_check(x_); \
+ GRN_TIME_SET(ctx, res, integer_operation(x_)); \
+ } \
+ break; \
+ case GRN_DB_UINT64 : \
+ { \
+ long long unsigned int x_; \
+ x_ = GRN_UINT64_VALUE(x); \
+ left_expression_check(x_); \
+ if (x_ > (long long unsigned int)INT64_MAX) { \
+ ERR(GRN_INVALID_ARGUMENT, \
+ "too large UInt64 value to inverse sign: " \
+ "<%" GRN_FMT_LLU ">", \
+ x_); \
+ goto exit; \
+ } else { \
+ long long int signed_x_; \
+ signed_x_ = x_; \
+ GRN_INT64_SET(ctx, res, integer_operation(signed_x_)); \
+ res->header.domain = GRN_DB_INT64; \
+ } \
+ } \
+ break; \
+ case GRN_DB_FLOAT : \
+ { \
+ double x_; \
+ x_ = GRN_FLOAT_VALUE(x); \
+ left_expression_check(x_); \
+ GRN_FLOAT_SET(ctx, res, float_operation(x_)); \
+ } \
+ break; \
+ case GRN_DB_SHORT_TEXT : \
+ case GRN_DB_TEXT : \
+ case GRN_DB_LONG_TEXT : \
+ text_operation; \
+ break; \
+ default: \
+ invalid_type_error; \
+ break; \
+ } \
+ code++; \
+} while (0)
+
+#define EXEC_OPERATE(operate_sentence, assign_sentence) \
+ operate_sentence \
+ assign_sentence
+
+#define EXEC_OPERATE_POST(operate_sentence, assign_sentence) \
+ assign_sentence \
+ operate_sentence
+
+#define UNARY_OPERATE_AND_ASSIGN_DISPATCH(exec_operate, delta, \
+ set_flags) do { \
+ grn_obj *var, *col, value; \
+ grn_id rid; \
+ \
+ POP1ALLOC1(var, res); \
+ if (var->header.type != GRN_PTR) { \
+ ERR(GRN_INVALID_ARGUMENT, "invalid variable type: 0x%0x", \
+ var->header.type); \
+ goto exit; \
+ } \
+ if (GRN_BULK_VSIZE(var) != (sizeof(grn_obj *) + sizeof(grn_id))) { \
+ ERR(GRN_INVALID_ARGUMENT, \
+ "invalid variable size: " \
+ "expected: %" GRN_FMT_SIZE \
+ "actual: %" GRN_FMT_SIZE, \
+ (sizeof(grn_obj *) + sizeof(grn_id)), GRN_BULK_VSIZE(var)); \
+ goto exit; \
+ } \
+ col = GRN_PTR_VALUE(var); \
+ rid = *(grn_id *)(GRN_BULK_HEAD(var) + sizeof(grn_obj *)); \
+ res->header.type = GRN_VOID; \
+ res->header.domain = DB_OBJ(col)->range; \
+ switch (DB_OBJ(col)->range) { \
+ case GRN_DB_INT32 : \
+ GRN_INT32_INIT(&value, 0); \
+ GRN_INT32_SET(ctx, &value, delta); \
+ break; \
+ case GRN_DB_UINT32 : \
+ GRN_UINT32_INIT(&value, 0); \
+ GRN_UINT32_SET(ctx, &value, delta); \
+ break; \
+ case GRN_DB_INT64 : \
+ GRN_INT64_INIT(&value, 0); \
+ GRN_INT64_SET(ctx, &value, delta); \
+ break; \
+ case GRN_DB_UINT64 : \
+ GRN_UINT64_INIT(&value, 0); \
+ GRN_UINT64_SET(ctx, &value, delta); \
+ break; \
+ case GRN_DB_FLOAT : \
+ GRN_FLOAT_INIT(&value, 0); \
+ GRN_FLOAT_SET(ctx, &value, delta); \
+ break; \
+ case GRN_DB_TIME : \
+ GRN_TIME_INIT(&value, 0); \
+ GRN_TIME_SET(ctx, &value, GRN_TIME_PACK(delta, 0)); \
+ break; \
+ default: \
+ ERR(GRN_INVALID_ARGUMENT, \
+ "invalid increment target type: %d " \
+ "(FIXME: type name is needed)", DB_OBJ(col)->range); \
+ goto exit; \
+ break; \
+ } \
+ exec_operate(grn_obj_set_value(ctx, col, rid, &value, set_flags);, \
+ grn_obj_get_value(ctx, col, rid, res);); \
+ code++; \
+} while (0)
+
+#define ARITHMETIC_OPERATION_AND_ASSIGN_DISPATCH(integer8_operation, \
+ integer16_operation, \
+ integer32_operation, \
+ integer64_operation, \
+ float_operation, \
+ left_expression_check, \
+ right_expression_check,\
+ text_operation) do { \
+ grn_obj *value, *var, *res; \
+ if (code->value) { \
+ value = code->value; \
+ POP1ALLOC1(var, res); \
+ } else { \
+ POP2ALLOC1(var, value, res); \
+ } \
+ if (var->header.type == GRN_PTR && \
+ GRN_BULK_VSIZE(var) == (sizeof(grn_obj *) + sizeof(grn_id))) { \
+ grn_obj *col = GRN_PTR_VALUE(var); \
+ grn_id rid = *(grn_id *)(GRN_BULK_HEAD(var) + sizeof(grn_obj *)); \
+ grn_obj variable_value, casted_value; \
+ grn_id domain; \
+ \
+ value = GRN_OBJ_RESOLVE(ctx, value); \
+ \
+ domain = grn_obj_get_range(ctx, col); \
+ GRN_OBJ_INIT(&variable_value, GRN_BULK, 0, domain); \
+ grn_obj_get_value(ctx, col, rid, &variable_value); \
+ \
+ GRN_OBJ_INIT(&casted_value, GRN_BULK, 0, domain); \
+ if (grn_obj_cast(ctx, value, &casted_value, GRN_FALSE)) { \
+ ERR(GRN_INVALID_ARGUMENT, "invalid value: string"); \
+ GRN_OBJ_FIN(ctx, &variable_value); \
+ GRN_OBJ_FIN(ctx, &casted_value); \
+ POP1(res); \
+ goto exit; \
+ } \
+ grn_obj_reinit(ctx, res, domain, 0); \
+ ARITHMETIC_OPERATION_DISPATCH((&variable_value), (&casted_value), \
+ res, \
+ integer8_operation, \
+ integer16_operation, \
+ integer32_operation, \
+ integer64_operation, \
+ float_operation, \
+ left_expression_check, \
+ right_expression_check, \
+ text_operation,); \
+ grn_obj_set_value(ctx, col, rid, res, GRN_OBJ_SET); \
+ GRN_OBJ_FIN(ctx, (&variable_value)); \
+ GRN_OBJ_FIN(ctx, (&casted_value)); \
+ } else { \
+ ERR(GRN_INVALID_ARGUMENT, "left hand expression isn't column."); \
+ POP1(res); \
+ } \
+} while (0)
+
+inline static void
+grn_expr_exec_get_member_vector(grn_ctx *ctx,
+ grn_obj *expr,
+ grn_obj *column_and_record_id,
+ grn_obj *index,
+ grn_obj *result)
+{
+ grn_obj *column;
+ grn_id record_id;
+ grn_obj values;
+ int i;
+
+ column = GRN_PTR_VALUE(column_and_record_id);
+ record_id = *((grn_id *)(&(GRN_PTR_VALUE_AT(column_and_record_id, 1))));
+ GRN_TEXT_INIT(&values, 0);
+ grn_obj_get_value(ctx, column, record_id, &values);
+
+ i = GRN_UINT32_VALUE(index);
+ if (values.header.type == GRN_UVECTOR) {
+ 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) {
+#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) {
+ const char *content;
+ unsigned int content_length;
+ grn_id domain;
+
+ content_length = grn_vector_get_element(ctx, &values, i,
+ &content, NULL, &domain);
+ grn_obj_reinit(ctx, result, domain, 0);
+ grn_bulk_write(ctx, result, content, content_length);
+ }
+ }
+
+ GRN_OBJ_FIN(ctx, &values);
+}
+
+inline static void
+grn_expr_exec_get_member_table(grn_ctx *ctx,
+ grn_obj *expr,
+ grn_obj *table,
+ grn_obj *key,
+ grn_obj *result)
+{
+ grn_id id;
+
+ if (table->header.domain == key->header.domain) {
+ id = grn_table_get(ctx, table, GRN_BULK_HEAD(key), GRN_BULK_VSIZE(key));
+ } else {
+ grn_obj casted_key;
+ GRN_OBJ_INIT(&casted_key, GRN_BULK, 0, table->header.domain);
+ if (grn_obj_cast(ctx, key, &casted_key, GRN_FALSE) == GRN_SUCCESS) {
+ id = grn_table_get(ctx, table,
+ GRN_BULK_HEAD(&casted_key),
+ GRN_BULK_VSIZE(&casted_key));
+ } else {
+ id = GRN_ID_NIL;
+ }
+ GRN_OBJ_FIN(ctx, &casted_key);
+ }
+
+ grn_obj_reinit(ctx, result, DB_OBJ(table)->id, 0);
+ GRN_RECORD_SET(ctx, result, id);
+}
+
+static inline grn_bool
+grn_expr_exec_is_simple_expr(grn_ctx *ctx, grn_obj *expr)
+{
+ grn_expr *e = (grn_expr *)expr;
+
+ if (expr->header.type != GRN_EXPR) {
+ return GRN_FALSE;
+ }
+
+ if (e->codes_curr != 1) {
+ return GRN_FALSE;
+ }
+
+ switch (e->codes[0].op) {
+ case GRN_OP_PUSH :
+ return GRN_TRUE;
+ default :
+ return GRN_FALSE;
+ }
+}
+
+static inline grn_obj *
+grn_expr_exec_simple(grn_ctx *ctx, grn_obj *expr)
+{
+ grn_expr *e = (grn_expr *)expr;
+
+ return e->codes[0].value;
+}
+
+grn_obj *
+grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
+{
+ grn_obj *val = NULL;
+ uint32_t stack_curr = ctx->impl->stack_curr;
+ GRN_API_ENTER;
+ if (grn_expr_exec_is_simple_expr(ctx, expr)) {
+ val = grn_expr_exec_simple(ctx, expr);
+ GRN_API_RETURN(val);
+ }
+ if (expr->header.type == GRN_PROC) {
+ grn_proc *proc = (grn_proc *)expr;
+ if (proc->type == GRN_PROC_COMMAND) {
+ grn_command_input *input;
+ input = grn_command_input_open(ctx, expr);
+ grn_command_run(ctx, expr, input);
+ grn_command_input_close(ctx, input);
+ GRN_API_RETURN(NULL);
+ } else {
+ grn_proc_call(ctx, expr, nargs, expr);
+ }
+ } else {
+ grn_expr *e = (grn_expr *)expr;
+ 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;
+ while (code < ce) {
+ switch (code->op) {
+ case GRN_OP_NOP :
+ code++;
+ break;
+ case GRN_OP_PUSH :
+ PUSH1(code->value);
+ code++;
+ break;
+ case GRN_OP_POP :
+ {
+ grn_obj *obj;
+ POP1(obj);
+ code++;
+ }
+ break;
+ case GRN_OP_GET_REF :
+ {
+ grn_obj *col, *rec;
+ if (code->nargs == 1) {
+ rec = v0;
+ if (code->value) {
+ col = code->value;
+ ALLOC1(res);
+ } else {
+ POP1ALLOC1(col, res);
+ }
+ } else {
+ if (code->value) {
+ col = code->value;
+ POP1ALLOC1(rec, res);
+ } else {
+ POP2ALLOC1(rec, col, res);
+ }
+ }
+ if (col->header.type == GRN_BULK) {
+ grn_obj *table = grn_ctx_at(ctx, GRN_OBJ_GET_DOMAIN(rec));
+ col = grn_obj_column(ctx, table, GRN_BULK_HEAD(col), GRN_BULK_VSIZE(col));
+ if (col) { grn_expr_take_obj(ctx, (grn_obj *)e, col); }
+ }
+ if (col) {
+ res->header.type = GRN_PTR;
+ res->header.domain = GRN_ID_NIL;
+ GRN_PTR_SET(ctx, res, col);
+ GRN_UINT32_PUT(ctx, res, GRN_RECORD_VALUE(rec));
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "col resolve failed");
+ goto exit;
+ }
+ code++;
+ }
+ break;
+ case GRN_OP_CALL :
+ {
+ grn_obj *proc;
+ if (code->value) {
+ 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 - 1, expr);
+ });
+ } else {
+ int offset = code->nargs;
+ if (sp < s_ + offset) {
+ ERR(GRN_INVALID_ARGUMENT, "stack error");
+ goto exit;
+ }
+ proc = sp[-offset];
+ 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;
+ }
+ POP1(res);
+ {
+ grn_obj *proc_;
+ POP1(proc_);
+ if (proc != proc_) {
+ GRN_LOG(ctx, GRN_LOG_WARNING, "stack may be corrupt");
+ }
+ }
+ PUSH1(res);
+ }
+ }
+ code++;
+ break;
+ case GRN_OP_INTERN :
+ {
+ grn_obj *obj;
+ POP1(obj);
+ obj = GRN_OBJ_RESOLVE(ctx, obj);
+ res = grn_expr_get_var(ctx, expr, GRN_TEXT_VALUE(obj), GRN_TEXT_LEN(obj));
+ if (!res) { res = grn_ctx_get(ctx, GRN_TEXT_VALUE(obj), GRN_TEXT_LEN(obj)); }
+ if (!res) {
+ ERR(GRN_INVALID_ARGUMENT, "intern failed");
+ goto exit;
+ }
+ PUSH1(res);
+ }
+ code++;
+ break;
+ case GRN_OP_TABLE_CREATE :
+ {
+ grn_obj *value_type, *key_type, *flags, *name;
+ POP1(value_type);
+ value_type = GRN_OBJ_RESOLVE(ctx, value_type);
+ POP1(key_type);
+ key_type = GRN_OBJ_RESOLVE(ctx, key_type);
+ POP1(flags);
+ flags = GRN_OBJ_RESOLVE(ctx, flags);
+ POP1(name);
+ name = GRN_OBJ_RESOLVE(ctx, name);
+ res = grn_table_create(ctx, GRN_TEXT_VALUE(name), GRN_TEXT_LEN(name),
+ NULL, GRN_UINT32_VALUE(flags),
+ key_type, value_type);
+ PUSH1(res);
+ }
+ code++;
+ break;
+ case GRN_OP_EXPR_GET_VAR :
+ {
+ grn_obj *name, *expr;
+ POP1(name);
+ name = GRN_OBJ_RESOLVE(ctx, name);
+ POP1(expr);
+ expr = GRN_OBJ_RESOLVE(ctx, expr);
+ switch (name->header.domain) {
+ case GRN_DB_INT32 :
+ res = grn_expr_get_var_by_offset(ctx, expr, (unsigned int) GRN_INT32_VALUE(name));
+ break;
+ case GRN_DB_UINT32 :
+ res = grn_expr_get_var_by_offset(ctx, expr, (unsigned int) GRN_UINT32_VALUE(name));
+ break;
+ case GRN_DB_INT64 :
+ res = grn_expr_get_var_by_offset(ctx, expr, (unsigned int) GRN_INT64_VALUE(name));
+ break;
+ case GRN_DB_UINT64 :
+ res = grn_expr_get_var_by_offset(ctx, expr, (unsigned int) GRN_UINT64_VALUE(name));
+ break;
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ res = grn_expr_get_var(ctx, expr, GRN_TEXT_VALUE(name), GRN_TEXT_LEN(name));
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "invalid type");
+ goto exit;
+ }
+ PUSH1(res);
+ }
+ code++;
+ break;
+ case GRN_OP_ASSIGN :
+ {
+ grn_obj *value, *var;
+ if (code->value) {
+ value = code->value;
+ } else {
+ POP1(value);
+ }
+ value = GRN_OBJ_RESOLVE(ctx, value);
+ POP1(var);
+ // var = GRN_OBJ_RESOLVE(ctx, var);
+ if (var->header.type == GRN_PTR &&
+ GRN_BULK_VSIZE(var) == (sizeof(grn_obj *) + sizeof(grn_id))) {
+ grn_obj *col = GRN_PTR_VALUE(var);
+ grn_id rid = *(grn_id *)(GRN_BULK_HEAD(var) + sizeof(grn_obj *));
+ grn_obj_set_value(ctx, col, rid, value, GRN_OBJ_SET);
+ } else {
+ VAR_SET_VALUE(ctx, var, value);
+ }
+ PUSH1(value);
+ }
+ code++;
+ break;
+ case GRN_OP_STAR_ASSIGN :
+ ARITHMETIC_OPERATION_AND_ASSIGN_DISPATCH(
+ INTEGER_ARITHMETIC_OPERATION_STAR,
+ INTEGER_ARITHMETIC_OPERATION_STAR,
+ INTEGER_ARITHMETIC_OPERATION_STAR,
+ INTEGER_ARITHMETIC_OPERATION_STAR,
+ FLOAT_ARITHMETIC_OPERATION_STAR,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ {
+ ERR(GRN_INVALID_ARGUMENT, "variable *= \"string\" isn't supported");
+ goto exit;
+ });
+ break;
+ case GRN_OP_SLASH_ASSIGN :
+ ARITHMETIC_OPERATION_AND_ASSIGN_DISPATCH(
+ INTEGER_ARITHMETIC_OPERATION_SLASH,
+ INTEGER_ARITHMETIC_OPERATION_SLASH,
+ INTEGER_ARITHMETIC_OPERATION_SLASH,
+ INTEGER_ARITHMETIC_OPERATION_SLASH,
+ FLOAT_ARITHMETIC_OPERATION_SLASH,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ {
+ ERR(GRN_INVALID_ARGUMENT, "variable /= \"string\" isn't supported");
+ goto exit;
+ });
+ break;
+ case GRN_OP_MOD_ASSIGN :
+ ARITHMETIC_OPERATION_AND_ASSIGN_DISPATCH(
+ INTEGER_ARITHMETIC_OPERATION_MOD,
+ INTEGER_ARITHMETIC_OPERATION_MOD,
+ INTEGER_ARITHMETIC_OPERATION_MOD,
+ INTEGER_ARITHMETIC_OPERATION_MOD,
+ FLOAT_ARITHMETIC_OPERATION_MOD,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ {
+ ERR(GRN_INVALID_ARGUMENT, "variable %%= \"string\" isn't supported");
+ goto exit;
+ });
+ break;
+ case GRN_OP_PLUS_ASSIGN :
+ ARITHMETIC_OPERATION_AND_ASSIGN_DISPATCH(
+ INTEGER_ARITHMETIC_OPERATION_PLUS,
+ INTEGER_ARITHMETIC_OPERATION_PLUS,
+ INTEGER_ARITHMETIC_OPERATION_PLUS,
+ INTEGER_ARITHMETIC_OPERATION_PLUS,
+ FLOAT_ARITHMETIC_OPERATION_PLUS,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ {
+ ERR(GRN_INVALID_ARGUMENT, "variable += \"string\" isn't supported");
+ goto exit;
+ });
+ break;
+ case GRN_OP_MINUS_ASSIGN :
+ ARITHMETIC_OPERATION_AND_ASSIGN_DISPATCH(
+ INTEGER_ARITHMETIC_OPERATION_MINUS,
+ INTEGER_ARITHMETIC_OPERATION_MINUS,
+ INTEGER_ARITHMETIC_OPERATION_MINUS,
+ INTEGER_ARITHMETIC_OPERATION_MINUS,
+ FLOAT_ARITHMETIC_OPERATION_MINUS,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ {
+ ERR(GRN_INVALID_ARGUMENT, "variable -= \"string\" isn't supported");
+ goto exit;
+ });
+ break;
+ case GRN_OP_SHIFTL_ASSIGN :
+ ARITHMETIC_OPERATION_AND_ASSIGN_DISPATCH(
+ INTEGER_ARITHMETIC_OPERATION_SHIFTL,
+ INTEGER_ARITHMETIC_OPERATION_SHIFTL,
+ INTEGER_ARITHMETIC_OPERATION_SHIFTL,
+ INTEGER_ARITHMETIC_OPERATION_SHIFTL,
+ FLOAT_ARITHMETIC_OPERATION_SHIFTL,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ {
+ ERR(GRN_INVALID_ARGUMENT, "variable <<= \"string\" isn't supported");
+ goto exit;
+ });
+ break;
+ case GRN_OP_SHIFTR_ASSIGN :
+ ARITHMETIC_OPERATION_AND_ASSIGN_DISPATCH(
+ INTEGER_ARITHMETIC_OPERATION_SHIFTR,
+ INTEGER_ARITHMETIC_OPERATION_SHIFTR,
+ INTEGER_ARITHMETIC_OPERATION_SHIFTR,
+ INTEGER_ARITHMETIC_OPERATION_SHIFTR,
+ FLOAT_ARITHMETIC_OPERATION_SHIFTR,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ {
+ ERR(GRN_INVALID_ARGUMENT, "variable >>= \"string\" isn't supported");
+ goto exit;
+ });
+ break;
+ case GRN_OP_SHIFTRR_ASSIGN :
+ ARITHMETIC_OPERATION_AND_ASSIGN_DISPATCH(
+ INTEGER8_ARITHMETIC_OPERATION_SHIFTRR,
+ INTEGER16_ARITHMETIC_OPERATION_SHIFTRR,
+ INTEGER32_ARITHMETIC_OPERATION_SHIFTRR,
+ INTEGER64_ARITHMETIC_OPERATION_SHIFTRR,
+ FLOAT_ARITHMETIC_OPERATION_SHIFTRR,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ {
+ ERR(GRN_INVALID_ARGUMENT,
+ "variable >>>= \"string\" isn't supported");
+ goto exit;
+ });
+ break;
+ case GRN_OP_AND_ASSIGN :
+ ARITHMETIC_OPERATION_AND_ASSIGN_DISPATCH(
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_AND,
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_AND,
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_AND,
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_AND,
+ FLOAT_ARITHMETIC_OPERATION_BITWISE_AND,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ {
+ ERR(GRN_INVALID_ARGUMENT, "variable &= \"string\" isn't supported");
+ goto exit;
+ });
+ break;
+ case GRN_OP_OR_ASSIGN :
+ ARITHMETIC_OPERATION_AND_ASSIGN_DISPATCH(
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_OR,
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_OR,
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_OR,
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_OR,
+ FLOAT_ARITHMETIC_OPERATION_BITWISE_OR,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ {
+ ERR(GRN_INVALID_ARGUMENT, "variable |= \"string\" isn't supported");
+ goto exit;
+ });
+ break;
+ case GRN_OP_XOR_ASSIGN :
+ ARITHMETIC_OPERATION_AND_ASSIGN_DISPATCH(
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_XOR,
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_XOR,
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_XOR,
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_XOR,
+ FLOAT_ARITHMETIC_OPERATION_BITWISE_XOR,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ {
+ ERR(GRN_INVALID_ARGUMENT, "variable ^= \"string\" isn't supported");
+ goto exit;
+ });
+ break;
+ case GRN_OP_JUMP :
+ code += code->nargs + 1;
+ break;
+ case GRN_OP_CJUMP :
+ {
+ grn_obj *v;
+ POP1(v);
+ if (!grn_obj_is_true(ctx, v)) {
+ code += code->nargs;
+ }
+ }
+ code++;
+ break;
+ case GRN_OP_GET_VALUE :
+ {
+ grn_obj *col, *rec;
+ do {
+ if (code->nargs == 1) {
+ rec = v0;
+ if (code->value) {
+ col = code->value;
+ ALLOC1(res);
+ } else {
+ POP1ALLOC1(col, res);
+ }
+ } else {
+ if (code->value) {
+ col = code->value;
+ POP1ALLOC1(rec, res);
+ } else {
+ POP2ALLOC1(rec, col, res);
+ }
+ }
+ if (col->header.type == GRN_BULK) {
+ grn_obj *table = grn_ctx_at(ctx, GRN_OBJ_GET_DOMAIN(rec));
+ col = grn_obj_column(ctx, table, GRN_BULK_HEAD(col), GRN_BULK_VSIZE(col));
+ if (col) { grn_expr_take_obj(ctx, (grn_obj *)expr, col); }
+ }
+ if (!col) {
+ ERR(GRN_INVALID_ARGUMENT, "col resolve failed");
+ goto exit;
+ }
+ grn_obj_reinit_for(ctx, res, col);
+ grn_obj_get_value(ctx, col, GRN_RECORD_VALUE(rec), res);
+ code++;
+ } while (code < ce && code->op == GRN_OP_GET_VALUE);
+ }
+ break;
+ case GRN_OP_OBJ_SEARCH :
+ {
+ grn_obj *op, *query, *index;
+ // todo : grn_search_optarg optarg;
+ POP1(op);
+ op = GRN_OBJ_RESOLVE(ctx, op);
+ POP1(res);
+ res = GRN_OBJ_RESOLVE(ctx, res);
+ POP1(query);
+ query = GRN_OBJ_RESOLVE(ctx, query);
+ POP1(index);
+ index = GRN_OBJ_RESOLVE(ctx, index);
+ grn_obj_search(ctx, index, query, res,
+ (grn_operator)GRN_UINT32_VALUE(op), NULL);
+ }
+ code++;
+ break;
+ case GRN_OP_TABLE_SELECT :
+ {
+ grn_obj *op, *res, *expr, *table;
+ POP1(op);
+ op = GRN_OBJ_RESOLVE(ctx, op);
+ POP1(res);
+ res = GRN_OBJ_RESOLVE(ctx, res);
+ POP1(expr);
+ expr = GRN_OBJ_RESOLVE(ctx, expr);
+ POP1(table);
+ table = GRN_OBJ_RESOLVE(ctx, table);
+ WITH_SPSAVE({
+ grn_table_select(ctx, table, expr, res, (grn_operator)GRN_UINT32_VALUE(op));
+ });
+ PUSH1(res);
+ }
+ code++;
+ break;
+ case GRN_OP_TABLE_SORT :
+ {
+ grn_obj *keys_, *res, *limit, *table;
+ POP1(keys_);
+ keys_ = GRN_OBJ_RESOLVE(ctx, keys_);
+ POP1(res);
+ res = GRN_OBJ_RESOLVE(ctx, res);
+ POP1(limit);
+ limit = GRN_OBJ_RESOLVE(ctx, limit);
+ POP1(table);
+ table = GRN_OBJ_RESOLVE(ctx, table);
+ {
+ grn_table_sort_key *keys;
+ const char *p = GRN_BULK_HEAD(keys_), *tokbuf[256];
+ int n = grn_str_tok(p, GRN_BULK_VSIZE(keys_), ' ', tokbuf, 256, NULL);
+ if ((keys = GRN_MALLOCN(grn_table_sort_key, n))) {
+ int i, n_keys = 0;
+ for (i = 0; i < n; i++) {
+ uint32_t len = (uint32_t) (tokbuf[i] - p);
+ grn_obj *col = grn_obj_column(ctx, table, p, len);
+ if (col) {
+ keys[n_keys].key = col;
+ keys[n_keys].flags = GRN_TABLE_SORT_ASC;
+ keys[n_keys].offset = 0;
+ n_keys++;
+ } else {
+ if (p[0] == ':' && p[1] == 'd' && len == 2 && n_keys) {
+ keys[n_keys - 1].flags |= GRN_TABLE_SORT_DESC;
+ }
+ }
+ p = tokbuf[i] + 1;
+ }
+ WITH_SPSAVE({
+ grn_table_sort(ctx, table, 0, GRN_INT32_VALUE(limit), res, keys, n_keys);
+ });
+ for (i = 0; i < n_keys; i++) {
+ grn_obj_unlink(ctx, keys[i].key);
+ }
+ GRN_FREE(keys);
+ }
+ }
+ }
+ code++;
+ break;
+ case GRN_OP_TABLE_GROUP :
+ {
+ grn_obj *res, *keys_, *table;
+ POP1(res);
+ res = GRN_OBJ_RESOLVE(ctx, res);
+ POP1(keys_);
+ keys_ = GRN_OBJ_RESOLVE(ctx, keys_);
+ POP1(table);
+ table = GRN_OBJ_RESOLVE(ctx, table);
+ {
+ grn_table_sort_key *keys;
+ grn_table_group_result results;
+ const char *p = GRN_BULK_HEAD(keys_), *tokbuf[256];
+ int n = grn_str_tok(p, GRN_BULK_VSIZE(keys_), ' ', tokbuf, 256, NULL);
+ if ((keys = GRN_MALLOCN(grn_table_sort_key, n))) {
+ int i, n_keys = 0;
+ for (i = 0; i < n; i++) {
+ uint32_t len = (uint32_t) (tokbuf[i] - p);
+ grn_obj *col = grn_obj_column(ctx, table, p, len);
+ if (col) {
+ keys[n_keys].key = col;
+ keys[n_keys].flags = GRN_TABLE_SORT_ASC;
+ keys[n_keys].offset = 0;
+ n_keys++;
+ } else if (n_keys) {
+ if (p[0] == ':' && p[1] == 'd' && len == 2) {
+ keys[n_keys - 1].flags |= GRN_TABLE_SORT_DESC;
+ } else {
+ keys[n_keys - 1].offset = grn_atoi(p, p + len, NULL);
+ }
+ }
+ p = tokbuf[i] + 1;
+ }
+ /* todo : support multi-results */
+ results.table = res;
+ results.key_begin = 0;
+ results.key_end = 0;
+ results.limit = 0;
+ results.flags = 0;
+ results.op = GRN_OP_OR;
+ WITH_SPSAVE({
+ grn_table_group(ctx, table, keys, n_keys, &results, 1);
+ });
+ for (i = 0; i < n_keys; i++) {
+ grn_obj_unlink(ctx, keys[i].key);
+ }
+ GRN_FREE(keys);
+ }
+ }
+ }
+ code++;
+ break;
+ case GRN_OP_JSON_PUT :
+ {
+ grn_obj_format format;
+ grn_obj *str, *table, *res;
+ POP1(res);
+ res = GRN_OBJ_RESOLVE(ctx, res);
+ POP1(str);
+ str = GRN_OBJ_RESOLVE(ctx, str);
+ POP1(table);
+ table = GRN_OBJ_RESOLVE(ctx, table);
+ GRN_OBJ_FORMAT_INIT(&format, grn_table_size(ctx, table), 0, -1, 0);
+ format.flags = 0;
+ grn_obj_columns(ctx, table,
+ GRN_TEXT_VALUE(str), GRN_TEXT_LEN(str), &format.columns);
+ grn_text_otoj(ctx, res, table, &format);
+ GRN_OBJ_FORMAT_FIN(ctx, &format);
+ }
+ code++;
+ break;
+ case GRN_OP_AND :
+ {
+ grn_obj *x, *y;
+ grn_obj *result = NULL;
+ POP2ALLOC1(x, y, res);
+ if (grn_obj_is_true(ctx, x)) {
+ if (grn_obj_is_true(ctx, y)) {
+ result = y;
+ }
+ }
+ if (result) {
+ if (res != result) {
+ grn_obj_reinit(ctx, res, result->header.domain, 0);
+ grn_obj_cast(ctx, result, res, GRN_FALSE);
+ }
+ } else {
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, GRN_FALSE);
+ }
+ }
+ code++;
+ break;
+ case GRN_OP_OR :
+ {
+ grn_obj *x, *y;
+ grn_obj *result;
+ POP2ALLOC1(x, y, res);
+ if (grn_obj_is_true(ctx, x)) {
+ result = x;
+ } else {
+ if (grn_obj_is_true(ctx, y)) {
+ result = y;
+ } else {
+ result = NULL;
+ }
+ }
+ if (result) {
+ if (res != result) {
+ grn_obj_reinit(ctx, res, result->header.domain, 0);
+ grn_obj_cast(ctx, result, res, GRN_FALSE);
+ }
+ } else {
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, GRN_FALSE);
+ }
+ }
+ code++;
+ break;
+ case GRN_OP_AND_NOT :
+ {
+ grn_obj *x, *y;
+ grn_bool is_true;
+ POP2ALLOC1(x, y, res);
+ if (!grn_obj_is_true(ctx, x) || grn_obj_is_true(ctx, y)) {
+ is_true = GRN_FALSE;
+ } else {
+ is_true = GRN_TRUE;
+ }
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, is_true);
+ }
+ code++;
+ break;
+ case GRN_OP_ADJUST :
+ {
+ /* todo */
+ }
+ code++;
+ break;
+ case GRN_OP_MATCH :
+ {
+ grn_obj *x, *y;
+ grn_bool matched;
+ POP1(y);
+ POP1(x);
+ WITH_SPSAVE({
+ matched = grn_operator_exec_match(ctx, x, y);
+ });
+ ALLOC1(res);
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, matched);
+ }
+ code++;
+ break;
+ case GRN_OP_EQUAL :
+ {
+ grn_bool is_equal;
+ grn_obj *x, *y;
+ POP2ALLOC1(x, y, res);
+ is_equal = grn_operator_exec_equal(ctx, x, y);
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, is_equal);
+ }
+ code++;
+ break;
+ case GRN_OP_NOT_EQUAL :
+ {
+ grn_bool is_not_equal;
+ 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_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, is_not_equal);
+ }
+ code++;
+ break;
+ case GRN_OP_PREFIX :
+ {
+ grn_obj *x, *y;
+ grn_bool matched;
+ POP1(y);
+ POP1(x);
+ WITH_SPSAVE({
+ matched = grn_operator_exec_prefix(ctx, x, y);
+ });
+ ALLOC1(res);
+ 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);
+ 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;
+ case GRN_OP_LESS :
+ {
+ grn_bool r;
+ grn_obj *x, *y;
+ POP2ALLOC1(x, y, res);
+ r = grn_operator_exec_less(ctx, x, y);
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, r);
+ }
+ code++;
+ break;
+ case GRN_OP_GREATER :
+ {
+ grn_bool r;
+ grn_obj *x, *y;
+ POP2ALLOC1(x, y, res);
+ r = grn_operator_exec_greater(ctx, x, y);
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, r);
+ }
+ code++;
+ break;
+ case GRN_OP_LESS_EQUAL :
+ {
+ grn_bool r;
+ grn_obj *x, *y;
+ POP2ALLOC1(x, y, res);
+ r = grn_operator_exec_less_equal(ctx, x, y);
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, r);
+ }
+ code++;
+ break;
+ case GRN_OP_GREATER_EQUAL :
+ {
+ grn_bool r;
+ grn_obj *x, *y;
+ POP2ALLOC1(x, y, res);
+ r = grn_operator_exec_greater_equal(ctx, x, y);
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, r);
+ }
+ code++;
+ break;
+ case GRN_OP_GEO_DISTANCE1 :
+ {
+ grn_obj *value;
+ double lng1, lat1, lng2, lat2, x, y, d;
+ POP1(value);
+ lng1 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1(value);
+ lat1 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1(value);
+ lng2 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1ALLOC1(value, res);
+ lat2 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ x = (lng2 - lng1) * cos((lat1 + lat2) * 0.5);
+ y = (lat2 - lat1);
+ d = sqrt((x * x) + (y * y)) * GEO_RADIOUS;
+ res->header.type = GRN_BULK;
+ res->header.domain = GRN_DB_FLOAT;
+ GRN_FLOAT_SET(ctx, res, d);
+ }
+ code++;
+ break;
+ case GRN_OP_GEO_DISTANCE2 :
+ {
+ grn_obj *value;
+ double lng1, lat1, lng2, lat2, x, y, d;
+ POP1(value);
+ lng1 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1(value);
+ lat1 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1(value);
+ lng2 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1ALLOC1(value, res);
+ lat2 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ x = sin(fabs(lng2 - lng1) * 0.5);
+ y = sin(fabs(lat2 - lat1) * 0.5);
+ d = asin(sqrt((y * y) + cos(lat1) * cos(lat2) * x * x)) * 2 * GEO_RADIOUS;
+ res->header.type = GRN_BULK;
+ res->header.domain = GRN_DB_FLOAT;
+ GRN_FLOAT_SET(ctx, res, d);
+ }
+ code++;
+ break;
+ case GRN_OP_GEO_DISTANCE3 :
+ {
+ grn_obj *value;
+ double lng1, lat1, lng2, lat2, p, q, m, n, x, y, d;
+ POP1(value);
+ lng1 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1(value);
+ lat1 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1(value);
+ lng2 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1ALLOC1(value, res);
+ lat2 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ p = (lat1 + lat2) * 0.5;
+ q = (1 - GEO_BES_C3 * sin(p) * sin(p));
+ m = GEO_BES_C1 / sqrt(q * q * q);
+ n = GEO_BES_C2 / sqrt(q);
+ x = n * cos(p) * fabs(lng1 - lng2);
+ y = m * fabs(lat1 - lat2);
+ d = sqrt((x * x) + (y * y));
+ res->header.type = GRN_BULK;
+ res->header.domain = GRN_DB_FLOAT;
+ GRN_FLOAT_SET(ctx, res, d);
+ }
+ code++;
+ break;
+ case GRN_OP_GEO_DISTANCE4 :
+ {
+ grn_obj *value;
+ double lng1, lat1, lng2, lat2, p, q, m, n, x, y, d;
+ POP1(value);
+ lng1 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1(value);
+ lat1 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1(value);
+ lng2 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1ALLOC1(value, res);
+ lat2 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ p = (lat1 + lat2) * 0.5;
+ q = (1 - GEO_GRS_C3 * sin(p) * sin(p));
+ m = GEO_GRS_C1 / sqrt(q * q * q);
+ n = GEO_GRS_C2 / sqrt(q);
+ x = n * cos(p) * fabs(lng1 - lng2);
+ y = m * fabs(lat1 - lat2);
+ d = sqrt((x * x) + (y * y));
+ res->header.type = GRN_BULK;
+ res->header.domain = GRN_DB_FLOAT;
+ GRN_FLOAT_SET(ctx, res, d);
+ }
+ code++;
+ break;
+ case GRN_OP_GEO_WITHINP5 :
+ {
+ int r;
+ grn_obj *value;
+ double lng0, lat0, lng1, lat1, x, y, d;
+ POP1(value);
+ lng0 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1(value);
+ lat0 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1(value);
+ lng1 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1(value);
+ lat1 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1ALLOC1(value, res);
+ x = (lng1 - lng0) * cos((lat0 + lat1) * 0.5);
+ y = (lat1 - lat0);
+ d = sqrt((x * x) + (y * y)) * GEO_RADIOUS;
+ switch (value->header.domain) {
+ case GRN_DB_INT32 :
+ r = d <= GRN_INT32_VALUE(value);
+ break;
+ case GRN_DB_FLOAT :
+ r = d <= GRN_FLOAT_VALUE(value);
+ break;
+ default :
+ r = 0;
+ break;
+ }
+ GRN_INT32_SET(ctx, res, r);
+ res->header.type = GRN_BULK;
+ res->header.domain = GRN_DB_INT32;
+ }
+ code++;
+ break;
+ case GRN_OP_GEO_WITHINP6 :
+ {
+ int r;
+ grn_obj *value;
+ double lng0, lat0, lng1, lat1, lng2, lat2, x, y, d;
+ POP1(value);
+ lng0 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1(value);
+ lat0 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1(value);
+ lng1 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1(value);
+ lat1 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1(value);
+ lng2 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ POP1ALLOC1(value, res);
+ lat2 = GEO_INT2RAD(GRN_INT32_VALUE(value));
+ x = (lng1 - lng0) * cos((lat0 + lat1) * 0.5);
+ y = (lat1 - lat0);
+ d = (x * x) + (y * y);
+ x = (lng2 - lng1) * cos((lat1 + lat2) * 0.5);
+ y = (lat2 - lat1);
+ r = d <= (x * x) + (y * y);
+ GRN_INT32_SET(ctx, res, r);
+ res->header.type = GRN_BULK;
+ res->header.domain = GRN_DB_INT32;
+ }
+ code++;
+ break;
+ case GRN_OP_GEO_WITHINP8 :
+ {
+ int r;
+ grn_obj *value;
+ int64_t ln0, la0, ln1, la1, ln2, la2, ln3, la3;
+ POP1(value);
+ ln0 = GRN_INT32_VALUE(value);
+ POP1(value);
+ la0 = GRN_INT32_VALUE(value);
+ POP1(value);
+ ln1 = GRN_INT32_VALUE(value);
+ POP1(value);
+ la1 = GRN_INT32_VALUE(value);
+ POP1(value);
+ ln2 = GRN_INT32_VALUE(value);
+ POP1(value);
+ la2 = GRN_INT32_VALUE(value);
+ POP1(value);
+ ln3 = GRN_INT32_VALUE(value);
+ POP1ALLOC1(value, res);
+ la3 = GRN_INT32_VALUE(value);
+ r = ((ln2 <= ln0) && (ln0 <= ln3) && (la2 <= la0) && (la0 <= la3));
+ GRN_INT32_SET(ctx, res, r);
+ res->header.type = GRN_BULK;
+ res->header.domain = GRN_DB_INT32;
+ }
+ code++;
+ break;
+ case GRN_OP_PLUS :
+ ARITHMETIC_BINARY_OPERATION_DISPATCH(
+ "+",
+ INTEGER_ARITHMETIC_OPERATION_PLUS,
+ INTEGER_ARITHMETIC_OPERATION_PLUS,
+ INTEGER_ARITHMETIC_OPERATION_PLUS,
+ INTEGER_ARITHMETIC_OPERATION_PLUS,
+ FLOAT_ARITHMETIC_OPERATION_PLUS,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ {
+ if (x == res) {
+ grn_obj_cast(ctx, y, res, GRN_FALSE);
+ } else if (y == res) {
+ grn_obj buffer;
+ GRN_TEXT_INIT(&buffer, 0);
+ grn_obj_cast(ctx, x, &buffer, GRN_FALSE);
+ grn_obj_cast(ctx, y, &buffer, GRN_FALSE);
+ GRN_BULK_REWIND(res);
+ grn_obj_cast(ctx, &buffer, res, GRN_FALSE);
+ GRN_OBJ_FIN(ctx, &buffer);
+ } else {
+ GRN_BULK_REWIND(res);
+ grn_obj_cast(ctx, x, res, GRN_FALSE);
+ grn_obj_cast(ctx, y, res, GRN_FALSE);
+ }
+ }
+ ,);
+ break;
+ case GRN_OP_MINUS :
+ if (code->nargs == 1) {
+ ARITHMETIC_UNARY_OPERATION_DISPATCH(
+ INTEGER_UNARY_ARITHMETIC_OPERATION_MINUS,
+ FLOAT_UNARY_ARITHMETIC_OPERATION_MINUS,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ {
+ long long int x_;
+
+ res->header.type = GRN_BULK;
+ res->header.domain = GRN_DB_INT64;
+
+ GRN_INT64_SET(ctx, res, 0);
+ grn_obj_cast(ctx, x, res, GRN_FALSE);
+ x_ = GRN_INT64_VALUE(res);
+
+ GRN_INT64_SET(ctx, res, -x_);
+ }
+ ,);
+ } else {
+ ARITHMETIC_BINARY_OPERATION_DISPATCH(
+ "-",
+ INTEGER_ARITHMETIC_OPERATION_MINUS,
+ INTEGER_ARITHMETIC_OPERATION_MINUS,
+ INTEGER_ARITHMETIC_OPERATION_MINUS,
+ INTEGER_ARITHMETIC_OPERATION_MINUS,
+ FLOAT_ARITHMETIC_OPERATION_MINUS,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ {
+ ERR(GRN_INVALID_ARGUMENT,
+ "\"string\" - \"string\" "
+ "isn't supported");
+ goto exit;
+ }
+ ,);
+ }
+ break;
+ case GRN_OP_STAR :
+ ARITHMETIC_BINARY_OPERATION_DISPATCH(
+ "*",
+ INTEGER_ARITHMETIC_OPERATION_STAR,
+ INTEGER_ARITHMETIC_OPERATION_STAR,
+ INTEGER_ARITHMETIC_OPERATION_STAR,
+ INTEGER_ARITHMETIC_OPERATION_STAR,
+ FLOAT_ARITHMETIC_OPERATION_STAR,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ {
+ ERR(GRN_INVALID_ARGUMENT,
+ "\"string\" * \"string\" "
+ "isn't supported");
+ goto exit;
+ }
+ ,);
+ break;
+ case GRN_OP_SLASH :
+ DIVISION_OPERATION_DISPATCH(
+ SIGNED_INTEGER_DIVISION_OPERATION_SLASH,
+ UNSIGNED_INTEGER_DIVISION_OPERATION_SLASH,
+ FLOAT_DIVISION_OPERATION_SLASH,
+ {
+ ERR(GRN_INVALID_ARGUMENT,
+ "\"string\" / \"string\" "
+ "isn't supported");
+ goto exit;
+ });
+ break;
+ case GRN_OP_MOD :
+ DIVISION_OPERATION_DISPATCH(
+ SIGNED_INTEGER_DIVISION_OPERATION_MOD,
+ UNSIGNED_INTEGER_DIVISION_OPERATION_MOD,
+ FLOAT_DIVISION_OPERATION_MOD,
+ {
+ ERR(GRN_INVALID_ARGUMENT,
+ "\"string\" %% \"string\" "
+ "isn't supported");
+ goto exit;
+ });
+ break;
+ case GRN_OP_BITWISE_NOT :
+ ARITHMETIC_UNARY_OPERATION_DISPATCH(
+ INTEGER_UNARY_ARITHMETIC_OPERATION_BITWISE_NOT,
+ FLOAT_UNARY_ARITHMETIC_OPERATION_BITWISE_NOT,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ TEXT_UNARY_ARITHMETIC_OPERATION(~),);
+ break;
+ case GRN_OP_BITWISE_OR :
+ ARITHMETIC_BINARY_OPERATION_DISPATCH(
+ "|",
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_OR,
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_OR,
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_OR,
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_OR,
+ FLOAT_ARITHMETIC_OPERATION_BITWISE_OR,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ TEXT_ARITHMETIC_OPERATION(|),);
+ break;
+ case GRN_OP_BITWISE_XOR :
+ ARITHMETIC_BINARY_OPERATION_DISPATCH(
+ "^",
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_XOR,
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_XOR,
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_XOR,
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_XOR,
+ FLOAT_ARITHMETIC_OPERATION_BITWISE_XOR,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ TEXT_ARITHMETIC_OPERATION(^),);
+ break;
+ case GRN_OP_BITWISE_AND :
+ ARITHMETIC_BINARY_OPERATION_DISPATCH(
+ "&",
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_AND,
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_AND,
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_AND,
+ INTEGER_ARITHMETIC_OPERATION_BITWISE_AND,
+ FLOAT_ARITHMETIC_OPERATION_BITWISE_AND,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ TEXT_ARITHMETIC_OPERATION(&),);
+ break;
+ case GRN_OP_SHIFTL :
+ ARITHMETIC_BINARY_OPERATION_DISPATCH(
+ "<<",
+ INTEGER_ARITHMETIC_OPERATION_SHIFTL,
+ INTEGER_ARITHMETIC_OPERATION_SHIFTL,
+ INTEGER_ARITHMETIC_OPERATION_SHIFTL,
+ INTEGER_ARITHMETIC_OPERATION_SHIFTL,
+ FLOAT_ARITHMETIC_OPERATION_SHIFTL,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ TEXT_ARITHMETIC_OPERATION(<<),);
+ break;
+ case GRN_OP_SHIFTR :
+ ARITHMETIC_BINARY_OPERATION_DISPATCH(
+ ">>",
+ INTEGER_ARITHMETIC_OPERATION_SHIFTR,
+ INTEGER_ARITHMETIC_OPERATION_SHIFTR,
+ INTEGER_ARITHMETIC_OPERATION_SHIFTR,
+ INTEGER_ARITHMETIC_OPERATION_SHIFTR,
+ FLOAT_ARITHMETIC_OPERATION_SHIFTR,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ TEXT_ARITHMETIC_OPERATION(>>),);
+ break;
+ case GRN_OP_SHIFTRR :
+ ARITHMETIC_BINARY_OPERATION_DISPATCH(
+ ">>>",
+ INTEGER8_ARITHMETIC_OPERATION_SHIFTRR,
+ INTEGER16_ARITHMETIC_OPERATION_SHIFTRR,
+ INTEGER32_ARITHMETIC_OPERATION_SHIFTRR,
+ INTEGER64_ARITHMETIC_OPERATION_SHIFTRR,
+ FLOAT_ARITHMETIC_OPERATION_SHIFTRR,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ ARITHMETIC_OPERATION_NO_CHECK,
+ {
+ long long unsigned int x_;
+ long long unsigned int y_;
+
+ res->header.type = GRN_BULK;
+ res->header.domain = GRN_DB_INT64;
+
+ GRN_INT64_SET(ctx, res, 0);
+ grn_obj_cast(ctx, x, res, GRN_FALSE);
+ x_ = GRN_INT64_VALUE(res);
+
+ GRN_INT64_SET(ctx, res, 0);
+ grn_obj_cast(ctx, y, res, GRN_FALSE);
+ y_ = GRN_INT64_VALUE(res);
+
+ GRN_INT64_SET(ctx, res, x_ >> y_);
+ }
+ ,);
+ break;
+ case GRN_OP_INCR :
+ UNARY_OPERATE_AND_ASSIGN_DISPATCH(EXEC_OPERATE, 1, GRN_OBJ_INCR);
+ break;
+ case GRN_OP_DECR :
+ UNARY_OPERATE_AND_ASSIGN_DISPATCH(EXEC_OPERATE, 1, GRN_OBJ_DECR);
+ break;
+ case GRN_OP_INCR_POST :
+ UNARY_OPERATE_AND_ASSIGN_DISPATCH(EXEC_OPERATE_POST, 1, GRN_OBJ_INCR);
+ break;
+ case GRN_OP_DECR_POST :
+ UNARY_OPERATE_AND_ASSIGN_DISPATCH(EXEC_OPERATE_POST, 1, GRN_OBJ_DECR);
+ break;
+ case GRN_OP_NOT :
+ {
+ grn_obj *value;
+ grn_bool value_boolean;
+ POP1ALLOC1(value, res);
+ GRN_OBJ_IS_TRUE(ctx, value, value_boolean);
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, !value_boolean);
+ }
+ code++;
+ break;
+ case GRN_OP_GET_MEMBER :
+ {
+ grn_obj *receiver, *index_or_key;
+ POP2ALLOC1(receiver, index_or_key, res);
+ if (receiver->header.type == GRN_PTR) {
+ grn_obj *index = index_or_key;
+ grn_expr_exec_get_member_vector(ctx, expr, receiver, index, res);
+ } else {
+ grn_obj *key = index_or_key;
+ grn_expr_exec_get_member_table(ctx, expr, receiver, key, res);
+ }
+ code++;
+ }
+ break;
+ case GRN_OP_REGEXP :
+ {
+ grn_obj *target, *pattern;
+ grn_bool matched;
+ POP1(pattern);
+ POP1(target);
+ WITH_SPSAVE({
+ matched = grn_operator_exec_regexp(ctx, target, pattern);
+ });
+ ALLOC1(res);
+ grn_obj_reinit(ctx, res, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, res, matched);
+ }
+ code++;
+ break;
+ default :
+ ERR(GRN_FUNCTION_NOT_IMPLEMENTED, "not implemented operator assigned");
+ goto exit;
+ break;
+ }
+ }
+ ctx->impl->stack_curr = sp - s_;
+ }
+ if (ctx->impl->stack_curr + nargs > stack_curr) {
+ val = grn_ctx_pop(ctx);
+ }
+exit :
+ if (ctx->impl->stack_curr + nargs > stack_curr) {
+ /*
+ GRN_LOG(ctx, GRN_LOG_WARNING, "nargs=%d stack balance=%d",
+ nargs, stack_curr - ctx->impl->stack_curr);
+ */
+ ctx->impl->stack_curr = stack_curr - nargs;
+ }
+ GRN_API_RETURN(val);
+}
+
+grn_obj *
+grn_expr_get_value(grn_ctx *ctx, grn_obj *expr, int offset)
+{
+ grn_obj *res = NULL;
+ grn_expr *e = (grn_expr *)expr;
+ GRN_API_ENTER;
+ if (0 <= offset && offset < e->values_size) {
+ res = &e->values[offset];
+ }
+ GRN_API_RETURN(res);
+}
+
+#define DEFAULT_WEIGHT 5
+#define DEFAULT_DECAYSTEP 2
+#define DEFAULT_MAX_INTERVAL 10
+#define DEFAULT_SIMILARITY_THRESHOLD 0
+#define DEFAULT_TERM_EXTRACT_POLICY 0
+#define DEFAULT_WEIGHT_VECTOR_SIZE 4096
+
+#define GRN_SCAN_INFO_MAX_N_ARGS 128
+
+struct _grn_scan_info {
+ uint32_t start;
+ uint32_t end;
+ int32_t nargs;
+ int flags;
+ grn_operator op;
+ grn_operator logical_op;
+ grn_obj wv;
+ grn_obj index;
+ grn_obj *query;
+ grn_obj *args[GRN_SCAN_INFO_MAX_N_ARGS];
+ int max_interval;
+ int similarity_threshold;
+ 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 {\
+ GRN_OBJ_FIN(ctx, &(si)->wv);\
+ GRN_OBJ_FIN(ctx, &(si)->index);\
+ GRN_OBJ_FIN(ctx, &(si)->scorers);\
+ GRN_OBJ_FIN(ctx, &(si)->scorer_args_exprs);\
+ GRN_OBJ_FIN(ctx, &(si)->scorer_args_expr_offsets);\
+ 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 {\
+ SI_ALLOC_RAW(si, st);\
+ if (!(si)) {\
+ int j;\
+ for (j = 0; j < i; j++) { SI_FREE(sis[j]); }\
+ GRN_FREE(sis);\
+ return NULL;\
+ }\
+} while (0)
+
+static scan_info **
+put_logical_op(grn_ctx *ctx, scan_info **sis, int *ip, grn_operator op, int start)
+{
+ int nparens = 1, ndifops = 0, i = *ip, j = i, r = 0;
+ while (j--) {
+ scan_info *s_ = sis[j];
+ if (s_->flags & SCAN_POP) {
+ ndifops++;
+ nparens++;
+ } else {
+ if (s_->flags & SCAN_PUSH) {
+ if (!(--nparens)) {
+ if (!r) {
+ if (ndifops) {
+ if (j && op != GRN_OP_AND_NOT) {
+ nparens = 1;
+ ndifops = 0;
+ r = j;
+ } else {
+ SI_ALLOC(s_, i, start);
+ s_->flags = SCAN_POP;
+ s_->logical_op = op;
+ sis[i++] = s_;
+ *ip = i;
+ break;
+ }
+ } else {
+ s_->flags &= ~SCAN_PUSH;
+ s_->logical_op = op;
+ break;
+ }
+ } else {
+ if (ndifops) {
+ SI_ALLOC(s_, i, start);
+ s_->flags = SCAN_POP;
+ s_->logical_op = op;
+ sis[i++] = s_;
+ *ip = i;
+ } else {
+ s_->flags &= ~SCAN_PUSH;
+ s_->logical_op = op;
+ grn_memcpy(&sis[i], &sis[j], sizeof(scan_info *) * (r - j));
+ grn_memmove(&sis[j], &sis[r], sizeof(scan_info *) * (i - r));
+ grn_memcpy(&sis[i + j - r], &sis[i], sizeof(scan_info *) * (r - j));
+ }
+ break;
+ }
+ }
+ } else {
+ if ((op == GRN_OP_AND_NOT) || (op != s_->logical_op)) {
+ ndifops++;
+ }
+ }
+ }
+ }
+ if (j < 0) {
+ ERR(GRN_INVALID_ARGUMENT, "unmatched nesting level");
+ for (j = 0; j < i; j++) { SI_FREE(sis[j]); }
+ GRN_FREE(sis);
+ return NULL;
+ }
+ return sis;
+}
+
+/* TODO: Remove me if nobody doesn't want to reuse the implementation again. */
+#if 0
+static const char *opstrs[] = {
+ "PUSH",
+ "POP",
+ "NOP",
+ "CALL",
+ "INTERN",
+ "GET_REF",
+ "GET_VALUE",
+ "AND",
+ "AND_NOT",
+ "OR",
+ "ASSIGN",
+ "STAR_ASSIGN",
+ "SLASH_ASSIGN",
+ "MOD_ASSIGN",
+ "PLUS_ASSIGN",
+ "MINUS_ASSIGN",
+ "SHIFTL_ASSIGN",
+ "SHIFTR_ASSIGN",
+ "SHIFTRR_ASSIGN",
+ "AND_ASSIGN",
+ "XOR_ASSIGN",
+ "OR_ASSIGN",
+ "JUMP",
+ "CJUMP",
+ "COMMA",
+ "BITWISE_OR",
+ "BITWISE_XOR",
+ "BITWISE_AND",
+ "BITWISE_NOT",
+ "EQUAL",
+ "NOT_EQUAL",
+ "LESS",
+ "GREATER",
+ "LESS_EQUAL",
+ "GREATER_EQUAL",
+ "IN",
+ "MATCH",
+ "NEAR",
+ "NEAR2",
+ "SIMILAR",
+ "TERM_EXTRACT",
+ "SHIFTL",
+ "SHIFTR",
+ "SHIFTRR",
+ "PLUS",
+ "MINUS",
+ "STAR",
+ "SLASH",
+ "MOD",
+ "DELETE",
+ "INCR",
+ "DECR",
+ "INCR_POST",
+ "DECR_POST",
+ "NOT",
+ "ADJUST",
+ "EXACT",
+ "LCP",
+ "PARTIAL",
+ "UNSPLIT",
+ "PREFIX",
+ "SUFFIX",
+ "GEO_DISTANCE1",
+ "GEO_DISTANCE2",
+ "GEO_DISTANCE3",
+ "GEO_DISTANCE4",
+ "GEO_WITHINP5",
+ "GEO_WITHINP6",
+ "GEO_WITHINP8",
+ "OBJ_SEARCH",
+ "EXPR_GET_VAR",
+ "TABLE_CREATE",
+ "TABLE_SELECT",
+ "TABLE_SORT",
+ "TABLE_GROUP",
+ "JSON_PUT"
+};
+
+static void
+put_value(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ int len;
+ char namebuf[GRN_TABLE_MAX_KEY_SIZE];
+ if ((len = grn_column_name(ctx, obj, namebuf, GRN_TABLE_MAX_KEY_SIZE))) {
+ GRN_TEXT_PUT(ctx, buf, namebuf, len);
+ } else {
+ grn_text_otoj(ctx, buf, obj, NULL);
+ }
+}
+
+static grn_rc
+grn_expr_inspect_internal(grn_ctx *ctx, grn_obj *buf, grn_obj *expr)
+{
+ uint32_t i, j;
+ grn_expr_var *var;
+ grn_expr_code *code;
+ grn_expr *e = (grn_expr *)expr;
+ grn_hash *vars = grn_expr_get_vars(ctx, expr, &i);
+ GRN_TEXT_PUTS(ctx, buf, "noname");
+ GRN_TEXT_PUTC(ctx, buf, '(');
+ {
+ int i = 0;
+ grn_obj *value;
+ const char *name;
+ uint32_t name_len;
+ GRN_HASH_EACH(ctx, vars, id, &name, &name_len, &value, {
+ if (i++) { GRN_TEXT_PUTC(ctx, buf, ','); }
+ GRN_TEXT_PUT(ctx, buf, name, name_len);
+ GRN_TEXT_PUTC(ctx, buf, ':');
+ put_value(ctx, buf, value);
+ });
+ }
+ GRN_TEXT_PUTC(ctx, buf, ')');
+ GRN_TEXT_PUTC(ctx, buf, '{');
+ for (j = 0, code = e->codes; j < e->codes_curr; j++, code++) {
+ if (j) { GRN_TEXT_PUTC(ctx, buf, ','); }
+ grn_text_itoa(ctx, buf, code->modify);
+ if (code->op == GRN_OP_PUSH) {
+ for (i = 0, var = e->vars; i < e->nvars; i++, var++) {
+ if (&var->value == code->value) {
+ GRN_TEXT_PUTC(ctx, buf, '?');
+ if (var->name_size) {
+ GRN_TEXT_PUT(ctx, buf, var->name, var->name_size);
+ } else {
+ grn_text_itoa(ctx, buf, (int)i);
+ }
+ break;
+ }
+ }
+ if (i == e->nvars) {
+ put_value(ctx, buf, code->value);
+ }
+ } else {
+ if (code->value) {
+ put_value(ctx, buf, code->value);
+ GRN_TEXT_PUTC(ctx, buf, ' ');
+ }
+ GRN_TEXT_PUTS(ctx, buf, opstrs[code->op]);
+ }
+ }
+ GRN_TEXT_PUTC(ctx, buf, '}');
+ return GRN_SUCCESS;
+}
+
+#define EXPRLOG(name,expr) do {\
+ grn_obj strbuf;\
+ GRN_TEXT_INIT(&strbuf, 0);\
+ grn_expr_inspect_internal(ctx, &strbuf, (expr));\
+ GRN_TEXT_PUTC(ctx, &strbuf, '\0');\
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "%s=(%s)", (name), GRN_TEXT_VALUE(&strbuf));\
+ GRN_OBJ_FIN(ctx, &strbuf);\
+} while (0)
+#endif
+
+
+static void
+scan_info_put_index(grn_ctx *ctx, scan_info *si,
+ grn_obj *index, uint32_t sid, int32_t weight,
+ grn_obj *scorer,
+ grn_obj *scorer_args_expr,
+ uint32_t scorer_args_expr_offset)
+{
+ GRN_PTR_PUT(ctx, &si->index, index);
+ GRN_UINT32_PUT(ctx, &si->wv, sid);
+ GRN_INT32_PUT(ctx, &si->wv, weight);
+ GRN_PTR_PUT(ctx, &si->scorers, scorer);
+ GRN_PTR_PUT(ctx, &si->scorer_args_exprs, scorer_args_expr);
+ GRN_UINT32_PUT(ctx, &si->scorer_args_expr_offsets, scorer_args_expr_offset);
+ {
+ int i, ni = (GRN_BULK_VSIZE(&si->index) / sizeof(grn_obj *)) - 1;
+ grn_obj **pi = &GRN_PTR_VALUE_AT(&si->index, ni);
+ for (i = 0; i < ni; i++, pi--) {
+ if (index == pi[-1]) {
+ if (i) {
+ int32_t *pw = &GRN_INT32_VALUE_AT(&si->wv, (ni - i) * 2);
+ grn_memmove(pw + 2, pw, sizeof(int32_t) * 2 * i);
+ pw[0] = (int32_t) sid;
+ pw[1] = weight;
+ grn_memmove(pi + 1, pi, sizeof(grn_obj *) * i);
+ pi[0] = index;
+ }
+ return;
+ }
+ }
+ }
+}
+
+static int32_t
+get_weight(grn_ctx *ctx, grn_expr_code *ec, uint32_t *offset)
+{
+ if (ec->modify == 2 && ec[2].op == GRN_OP_STAR &&
+ ec[1].value && ec[1].value->header.type == GRN_BULK) {
+ if (offset) {
+ *offset = 2;
+ }
+ if (ec[1].value->header.domain == GRN_DB_INT32 ||
+ ec[1].value->header.domain == GRN_DB_UINT32) {
+ return GRN_INT32_VALUE(ec[1].value);
+ } else {
+ int32_t weight = 1;
+ grn_obj weight_buffer;
+ GRN_INT32_INIT(&weight_buffer, 0);
+ if (!grn_obj_cast(ctx, ec[1].value, &weight_buffer, GRN_FALSE)) {
+ weight = GRN_INT32_VALUE(&weight_buffer);
+ }
+ grn_obj_unlink(ctx, &weight_buffer);
+ return weight;
+ }
+ } else {
+ if (offset) {
+ *offset = 0;
+ }
+ return 1;
+ }
+}
+
+scan_info *
+grn_scan_info_open(grn_ctx *ctx, int start)
+{
+ scan_info *si = GRN_MALLOCN(scan_info, 1);
+
+ if (!si) {
+ 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 = 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;
+}
+
+void
+grn_scan_info_close(grn_ctx *ctx, scan_info *si)
+{
+ SI_FREE(si);
+}
+
+void
+grn_scan_info_put_index(grn_ctx *ctx, scan_info *si,
+ grn_obj *index, uint32_t sid, int32_t weight,
+ grn_obj *scorer,
+ grn_obj *scorer_args_expr,
+ uint32_t scorer_args_expr_offset)
+{
+ scan_info_put_index(ctx, si, index, sid, weight,
+ scorer,
+ scorer_args_expr,
+ scorer_args_expr_offset);
+}
+
+scan_info **
+grn_scan_info_put_logical_op(grn_ctx *ctx, scan_info **sis, int *ip,
+ grn_operator op, int start)
+{
+ return put_logical_op(ctx, sis, ip, op, start);
+}
+
+int32_t
+grn_expr_code_get_weight(grn_ctx *ctx, grn_expr_code *ec, uint32_t *offset)
+{
+ return get_weight(ctx, ec, offset);
+}
+
+int
+grn_scan_info_get_flags(scan_info *si)
+{
+ return si->flags;
+}
+
+void
+grn_scan_info_set_flags(scan_info *si, int flags)
+{
+ si->flags = flags;
+}
+
+grn_operator
+grn_scan_info_get_logical_op(scan_info *si)
+{
+ return si->logical_op;
+}
+
+void
+grn_scan_info_set_logical_op(scan_info *si, grn_operator logical_op)
+{
+ si->logical_op = logical_op;
+}
+
+grn_operator
+grn_scan_info_get_op(scan_info *si)
+{
+ return si->op;
+}
+
+void
+grn_scan_info_set_op(scan_info *si, grn_operator op)
+{
+ si->op = op;
+}
+
+void
+grn_scan_info_set_end(scan_info *si, uint32_t end)
+{
+ si->end = end;
+}
+
+void
+grn_scan_info_set_query(scan_info *si, grn_obj *query)
+{
+ si->query = query;
+}
+
+int
+grn_scan_info_get_max_interval(scan_info *si)
+{
+ return si->max_interval;
+}
+
+void
+grn_scan_info_set_max_interval(scan_info *si, int max_interval)
+{
+ si->max_interval = max_interval;
+}
+
+int
+grn_scan_info_get_similarity_threshold(scan_info *si)
+{
+ return si->similarity_threshold;
+}
+
+void
+grn_scan_info_set_similarity_threshold(scan_info *si, int similarity_threshold)
+{
+ si->similarity_threshold = similarity_threshold;
+}
+
+grn_bool
+grn_scan_info_push_arg(scan_info *si, grn_obj *arg)
+{
+ if (si->nargs >= GRN_SCAN_INFO_MAX_N_ARGS) {
+ return GRN_FALSE;
+ }
+
+ si->args[si->nargs++] = arg;
+ return GRN_TRUE;
+}
+
+grn_obj *
+grn_scan_info_get_arg(grn_ctx *ctx, scan_info *si, int i)
+{
+ if (i >= si->nargs) {
+ return NULL;
+ }
+ 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,
+ grn_obj **index,
+ int *sid)
+{
+ grn_expr_code *ec;
+ uint32_t offset = 1;
+ grn_index_datum index_datum;
+ unsigned int n_index_data = 0;
+
+ ec = &(expr->codes[i]);
+ switch (ec->value->header.type) {
+ case GRN_ACCESSOR :
+ n_index_data = grn_column_find_index_data(ctx, ec->value, si->op,
+ &index_datum, 1);
+ if (n_index_data > 0) {
+ grn_accessor *a = (grn_accessor *)(ec->value);
+ *sid = index_datum.section;
+ if (a->next && a->obj != index_datum.index) {
+ *index = ec->value;
+ } else {
+ *index = index_datum.index;
+ }
+ }
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ n_index_data = grn_column_find_index_data(ctx, ec->value, si->op,
+ &index_datum, 1);
+ if (n_index_data > 0) {
+ *index = index_datum.index;
+ *sid = index_datum.section;
+ }
+ break;
+ case GRN_COLUMN_INDEX :
+ {
+ uint32_t n_rest_codes;
+
+ *index = ec->value;
+
+ n_rest_codes = expr->codes_curr - i;
+ if (n_rest_codes >= 2 &&
+ ec[1].value &&
+ (ec[1].value->header.domain == GRN_DB_INT32 ||
+ ec[1].value->header.domain == GRN_DB_UINT32) &&
+ ec[2].op == GRN_OP_GET_MEMBER) {
+ if (ec[1].value->header.domain == GRN_DB_INT32) {
+ *sid = GRN_INT32_VALUE(ec[1].value) + 1;
+ } else {
+ *sid = GRN_UINT32_VALUE(ec[1].value) + 1;
+ }
+ offset += 2;
+ }
+ }
+ break;
+ default :
+ break;
+ }
+
+ return offset;
+}
+
+static uint32_t
+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;
+ int sid = 0;
+ uint32_t offset = 0;
+
+ ec = &(expr->codes[i]);
+ if (!ec->value) {
+ return i + 1;
+ }
+
+ switch (ec->value->header.type) {
+ case GRN_ACCESSOR :
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ case GRN_COLUMN_INDEX :
+ offset = scan_info_build_match_expr_codes_find_index(ctx, si, expr, i,
+ &index, &sid);
+ i += offset - 1;
+ if (index) {
+ if (ec->value->header.type == GRN_ACCESSOR) {
+ si->flags |= SCAN_ACCESSOR;
+ }
+ scan_info_put_index(ctx, si, index, sid,
+ get_weight(ctx, &(expr->codes[i]), &offset) + weight,
+ NULL, NULL, 0);
+ i += offset;
+ }
+ break;
+ case GRN_PROC :
+ if (!grn_obj_is_scorer_proc(ctx, ec->value)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, ec->value);
+ ERR(GRN_INVALID_ARGUMENT,
+ "procedure must be scorer: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ return expr->codes_curr;
+ }
+ i++;
+ offset = scan_info_build_match_expr_codes_find_index(ctx, si, expr, i,
+ &index, &sid);
+ i += offset;
+ if (index) {
+ uint32_t scorer_args_expr_offset = 0;
+ if (expr->codes[i].op != GRN_OP_CALL) {
+ scorer_args_expr_offset = i;
+ }
+ while (i < expr->codes_curr && expr->codes[i].op != GRN_OP_CALL) {
+ i++;
+ }
+ scan_info_put_index(ctx, si, index, sid,
+ get_weight(ctx, &(expr->codes[i]), &offset) + weight,
+ ec->value,
+ (grn_obj *)expr,
+ scorer_args_expr_offset);
+ i += offset;
+ }
+ break;
+ default :
+ {
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+ name_size = grn_obj_name(ctx, ec->value, name, GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_INVALID_ARGUMENT,
+ "invalid match target: <%.*s>",
+ name_size, name);
+ return expr->codes_curr;
+ }
+ break;
+ }
+
+ return i + 1;
+}
+
+static void
+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, weight);
+ }
+}
+
+static grn_bool
+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 ||
+ regexp->header.domain == GRN_DB_LONG_TEXT)) {
+ return GRN_FALSE;
+ }
+
+ regexp_raw = GRN_TEXT_VALUE(regexp);
+ regexp_raw_end = regexp_raw + GRN_TEXT_LEN(regexp);
+
+ while (regexp_raw < regexp_raw_end) {
+ unsigned int char_len;
+
+ char_len = grn_charlen(ctx, regexp_raw, regexp_raw_end);
+ if (char_len == 0) {
+ return GRN_FALSE;
+ }
+
+ if (char_len == 1) {
+ if (escaping) {
+ escaping = GRN_FALSE;
+ switch (regexp_raw[0]) {
+ case 'Z' :
+ case 'b' :
+ case 'B' :
+ case 'd' :
+ case 'D' :
+ case 'h' :
+ case 'H' :
+ case 'p' :
+ case 's' :
+ case 'S' :
+ case 'w' :
+ case 'W' :
+ case 'X' :
+ case 'k' :
+ case 'g' :
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ case '8' :
+ case '9' :
+ return GRN_FALSE;
+ default :
+ break;
+ }
+ } 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 '$' :
+ case '(' :
+ case ')' :
+ 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;
+ }
+ }
+ } else {
+ escaping = GRN_FALSE;
+ }
+
+ regexp_raw += char_len;
+ }
+
+ return GRN_TRUE;
+}
+
+static void
+scan_info_build_match(grn_ctx *ctx, scan_info *si, int32_t weight)
+{
+ grn_obj **p, **pe;
+
+ if (si->op == GRN_OP_REGEXP) {
+ p = si->args;
+ pe = si->args + si->nargs;
+ for (; p < pe; p++) {
+ if ((*p)->header.type == GRN_BULK &&
+ !is_index_searchable_regexp(ctx, *p)) {
+ return;
+ }
+ }
+ }
+
+ p = si->args;
+ 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), 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;
+ n_index_data = grn_column_find_index_data(ctx, *p, si->op,
+ &index_datum, 1);
+ if (n_index_data > 0) {
+ scan_info_put_index(ctx, si,
+ index_datum.index, index_datum.section, 1 + weight,
+ NULL, NULL, 0);
+ }
+ } else if (GRN_ACCESSORP(*p)) {
+ grn_index_datum index_datum;
+ unsigned int n_index_data;
+ si->flags |= SCAN_ACCESSOR;
+ n_index_data = grn_column_find_index_data(ctx, *p, si->op,
+ &index_datum, 1);
+ if (n_index_data > 0) {
+ grn_obj *index;
+ if (((grn_accessor *)(*p))->next) {
+ index = *p;
+ } else {
+ index = index_datum.index;
+ }
+ scan_info_put_index(ctx, si,
+ index, index_datum.section, 1 + weight,
+ NULL, NULL, 0);
+ }
+ } else {
+ switch (si->op) {
+ case GRN_OP_NEAR :
+ case GRN_OP_NEAR2 :
+ if (si->nargs == 3 &&
+ *p == si->args[2] &&
+ (*p)->header.domain == GRN_DB_INT32) {
+ si->max_interval = GRN_INT32_VALUE(*p);
+ } else {
+ si->query = *p;
+ }
+ break;
+ case GRN_OP_SIMILAR :
+ if (si->nargs == 3 &&
+ *p == si->args[2] &&
+ (*p)->header.domain == GRN_DB_INT32) {
+ si->similarity_threshold = GRN_INT32_VALUE(*p);
+ } else {
+ si->query = *p;
+ }
+ break;
+ default :
+ si->query = *p;
+ break;
+ }
+ }
+ }
+}
+
+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 **
+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;
+ 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) {
+ case GRN_OP_MATCH :
+ case GRN_OP_NEAR :
+ case GRN_OP_NEAR2 :
+ 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_GEO_WITHINP5 :
+ case GRN_OP_GEO_WITHINP6 :
+ case GRN_OP_GEO_WITHINP8 :
+ case GRN_OP_TERM_EXTRACT :
+ case GRN_OP_REGEXP :
+ if (stat < SCAN_COL1 || SCAN_CONST < stat) { return NULL; }
+ stat = SCAN_START;
+ m++;
+ break;
+ case GRN_OP_BITWISE_OR :
+ case GRN_OP_BITWISE_XOR :
+ case GRN_OP_BITWISE_AND :
+ case GRN_OP_BITWISE_NOT :
+ case GRN_OP_SHIFTL :
+ case GRN_OP_SHIFTR :
+ case GRN_OP_SHIFTRR :
+ case GRN_OP_PLUS :
+ case GRN_OP_MINUS :
+ case GRN_OP_STAR :
+ case GRN_OP_MOD :
+ if (stat < SCAN_COL1 || SCAN_CONST < stat) { return NULL; }
+ stat = SCAN_START;
+ if (m != o + 1) { return NULL; }
+ break;
+ case GRN_OP_AND :
+ case GRN_OP_OR :
+ case GRN_OP_AND_NOT :
+ case GRN_OP_ADJUST :
+ 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 :
+ {
+ 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) {
+ case SCAN_START :
+ case SCAN_CONST :
+ case SCAN_VAR :
+ stat = SCAN_COL1;
+ break;
+ case SCAN_COL1 :
+ stat = SCAN_COL2;
+ break;
+ case SCAN_COL2 :
+ break;
+ default :
+ return NULL;
+ break;
+ }
+ break;
+ case GRN_OP_CALL :
+ if ((c->flags & GRN_EXPR_CODE_RELATIONAL_EXPRESSION) || c + 1 == ce) {
+ stat = SCAN_START;
+ m++;
+ } else {
+ 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 + 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++) {
+ grn_operator code_op;
+ if (next_code_op == (grn_operator)-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 :
+ 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_GEO_WITHINP5 :
+ case GRN_OP_GEO_WITHINP6 :
+ case GRN_OP_GEO_WITHINP8 :
+ case GRN_OP_TERM_EXTRACT :
+ case GRN_OP_REGEXP :
+ stat = SCAN_START;
+ si->op = code_op;
+ si->end = c - e->codes;
+ sis[i++] = 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]); }
+ GRN_FREE(sis);
+ return NULL;
+ }
+ si = NULL;
+ break;
+ case GRN_OP_AND :
+ case GRN_OP_OR :
+ case GRN_OP_AND_NOT :
+ case GRN_OP_ADJUST :
+ 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 :
+ if (!si) { SI_ALLOC(si, i, c - e->codes); }
+ if (c->value == var) {
+ stat = SCAN_VAR;
+ } else {
+ if (si->nargs < GRN_SCAN_INFO_MAX_N_ARGS) {
+ si->args[si->nargs++] = c->value;
+ }
+ 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) {
+ case SCAN_START :
+ if (!si) { SI_ALLOC(si, i, c - e->codes); }
+ // fallthru
+ case SCAN_CONST :
+ case SCAN_VAR :
+ stat = SCAN_COL1;
+ if (si->nargs < GRN_SCAN_INFO_MAX_N_ARGS) {
+ si->args[si->nargs++] = c->value;
+ }
+ break;
+ case SCAN_COL1 :
+ {
+ int j;
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ GRN_TEXT_PUTS(ctx, &inspected, "<");
+ grn_inspect_name(ctx, &inspected, c->value);
+ GRN_TEXT_PUTS(ctx, &inspected, ">: <");
+ grn_inspect(ctx, &inspected, expr);
+ GRN_TEXT_PUTS(ctx, &inspected, ">");
+ ERR(GRN_INVALID_ARGUMENT,
+ "invalid expression: can't use column as a value: %.*s",
+ (int)GRN_TEXT_LEN(&inspected), GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ SI_FREE(si);
+ for (j = 0; j < i; j++) { SI_FREE(sis[j]); }
+ GRN_FREE(sis);
+ return NULL;
+ }
+ stat = SCAN_COL2;
+ break;
+ case SCAN_COL2 :
+ break;
+ default :
+ break;
+ }
+ break;
+ case GRN_OP_CALL :
+ 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 = code_op;
+ si->end = c - e->codes;
+ sis[i++] = si;
+ /* better index resolving framework for functions should be implemented */
+ 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, selector_op,
+ &index_datum, 1);
+ if (n_index_data > 0) {
+ scan_info_put_index(ctx, si,
+ index_datum.index, index_datum.section, 1,
+ NULL, NULL, 0);
+ }
+ } else if (GRN_ACCESSORP(*p)) {
+ grn_index_datum index_datum;
+ unsigned int n_index_data;
+ si->flags |= SCAN_ACCESSOR;
+ 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,
+ index_datum.index, index_datum.section, 1,
+ NULL, NULL, 0);
+ }
+ } else {
+ si->query = *p;
+ }
+ }
+ }
+ si = NULL;
+ } else {
+ 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 && !record_exist) {
+ // for debug
+ if (!(sis[0]->flags & SCAN_PUSH) || (sis[0]->logical_op != op)) {
+ int j;
+ ERR(GRN_INVALID_ARGUMENT, "invalid expr");
+ for (j = 0; j < i; j++) { SI_FREE(sis[j]); }
+ GRN_FREE(sis);
+ return NULL;
+ } else {
+ sis[0]->flags &= ~SCAN_PUSH;
+ sis[0]->logical_op = op;
+ }
+ } else {
+ if (!put_logical_op(ctx, sis, &i, op, c - e->codes)) { return NULL; }
+ }
+ *n = i;
+ 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)
+{
+ int i;
+
+ for (i = 0; i < n; i++) {
+ scan_info *si = sis[i];
+
+ grn_text_printf(ctx, buffer, "[%d]\n", i);
+ grn_text_printf(ctx, buffer,
+ " op: <%s>\n",
+ grn_operator_to_string(si->op));
+ grn_text_printf(ctx, buffer,
+ " logical_op: <%s>\n",
+ grn_operator_to_string(si->logical_op));
+
+ 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);
+ }
+}
+
+void
+grn_p_scan_info_list(grn_ctx *ctx, scan_info **sis, int n)
+{
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect_scan_info_list(ctx, &inspected, sis, n);
+ printf("%.*s\n",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+}
+
+inline static int32_t
+exec_result_to_score(grn_ctx *ctx, grn_obj *result, grn_obj *score_buffer)
+{
+ if (!result) {
+ return 0;
+ }
+
+ switch (result->header.type) {
+ case GRN_VOID :
+ return 0;
+ case GRN_BULK :
+ 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);
+ }
+ case GRN_UVECTOR :
+ case GRN_PVECTOR :
+ case GRN_VECTOR :
+ return 1;
+ default :
+ return 1; /* TODO: 1 is reasonable? */
+ }
+}
+
+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_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))) {
+ result = grn_expr_executor_exec(ctx, executor, id);
+ if (ctx->rc) {
+ break;
+ }
+ 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)) {
+ grn_table_add_subrec(res, ri, score, (grn_rset_posinfo *)&id, 1);
+ }
+ }
+ }
+ grn_table_cursor_close(ctx, tc);
+ }
+ break;
+ case GRN_OP_AND :
+ 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);
+ result = grn_expr_executor_exec(ctx, executor, *idp);
+ if (ctx->rc) {
+ break;
+ }
+ 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);
+ grn_table_add_subrec(res, ri, score, (grn_rset_posinfo *)idp, 1);
+ } else {
+ grn_hash_cursor_delete(ctx, hc, NULL);
+ }
+ }
+ grn_hash_cursor_close(ctx, hc);
+ }
+ break;
+ case GRN_OP_AND_NOT :
+ 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);
+ result = grn_expr_executor_exec(ctx, executor, *idp);
+ if (ctx->rc) {
+ break;
+ }
+ score = exec_result_to_score(ctx, result, &score_buffer);
+ if (score > 0) {
+ grn_hash_cursor_delete(ctx, hc, NULL);
+ }
+ }
+ grn_hash_cursor_close(ctx, hc);
+ }
+ break;
+ case GRN_OP_ADJUST :
+ 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);
+ result = grn_expr_executor_exec(ctx, executor, *idp);
+ if (ctx->rc) {
+ break;
+ }
+ 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);
+ grn_table_add_subrec(res, ri, score, (grn_rset_posinfo *)idp, 1);
+ }
+ }
+ grn_hash_cursor_close(ctx, hc);
+ }
+ break;
+ default :
+ 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
+grn_table_select_index_range_column(grn_ctx *ctx, grn_obj *table,
+ grn_obj *index,
+ 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;
+
+ index_table = grn_ctx_at(ctx, index->header.domain);
+ if (!index_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;
+ 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, "[range]", index);
+
+ switch (si->op) {
+ case GRN_OP_LESS :
+ flags |= GRN_CURSOR_LT;
+ max = GRN_BULK_HEAD(&range);
+ max_size = GRN_BULK_VSIZE(&range);
+ break;
+ case GRN_OP_GREATER :
+ flags |= GRN_CURSOR_GT;
+ min = GRN_BULK_HEAD(&range);
+ min_size = GRN_BULK_VSIZE(&range);
+ break;
+ case GRN_OP_LESS_EQUAL :
+ flags |= GRN_CURSOR_LE;
+ max = GRN_BULK_HEAD(&range);
+ max_size = GRN_BULK_VSIZE(&range);
+ break;
+ case GRN_OP_GREATER_EQUAL :
+ flags |= GRN_CURSOR_GE;
+ min = GRN_BULK_HEAD(&range);
+ min_size = GRN_BULK_VSIZE(&range);
+ break;
+ default :
+ break;
+ }
+ cursor = grn_table_cursor_open(ctx, index_table,
+ min, min_size, max, max_size,
+ offset, limit, flags);
+ if (cursor) {
+ grn_id tid;
+ uint32_t sid;
+ int32_t weight;
+ grn_ii *ii = (grn_ii *)index;
+
+ sid = GRN_UINT32_VALUE_AT(&(si->wv), 0);
+ weight = GRN_INT32_VALUE_AT(&(si->wv), 1);
+ 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);
+ }
+ }
+ grn_ii_cursor_close(ctx, ii_cursor);
+ }
+ processed = GRN_TRUE;
+ grn_table_cursor_close(ctx, cursor);
+ }
+
+ grn_ii_resolve_sel_and(ctx, (grn_hash *)res, logical_op);
+ }
+ GRN_OBJ_FIN(ctx, &range);
+
+ grn_obj_unlink(ctx, index_table);
+
+ return processed;
+}
+
+static inline grn_bool
+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_bool have_resolver = GRN_FALSE;
+ grn_obj *base_res = NULL;
+
+ for (a = (grn_accessor *)accessor; a; a = a->next) {
+ if (!a->next) {
+ last_obj = a->obj;
+ }
+ }
+ 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;
+ }
+ }
+
+ {
+ grn_obj *index;
+ grn_obj *range;
+
+ 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 (!grn_table_select_index_range_key(ctx, last_obj, si, GRN_OP_OR,
+ base_res)) {
+ grn_obj_unlink(ctx, base_res);
+ return GRN_FALSE;
+ }
+ } else {
+ if (grn_column_index(ctx, last_obj, si->op, &index, 1, NULL) == 0) {
+ return GRN_FALSE;
+ }
+
+ 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_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 rc == GRN_SUCCESS;
+}
+
+static inline grn_bool
+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) {
+ 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;
+ }
+ } else {
+ return grn_table_select_index_range_column(ctx, table, index, si,
+ si->logical_op, res);
+ }
+}
+
+static inline grn_bool
+grn_table_select_index(grn_ctx *ctx, grn_obj *table, scan_info *si,
+ 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 :
+ 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_PREFIX :
+ 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 :
+ processed = grn_table_select_index_match(ctx,
+ table,
+ index,
+ si,
+ res,
+ min_id);
+ break;
+ case GRN_OP_TERM_EXTRACT :
+ if (si->flags & SCAN_ACCESSOR) {
+ if (index->header.type == GRN_ACCESSOR &&
+ !((grn_accessor *)index)->next) {
+ 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);
+ processed = GRN_TRUE;
+ break;
+ }
+ }
+ }
+ break;
+ case GRN_OP_CALL :
+ if (grn_obj_is_selector_proc(ctx, si->args[0])) {
+ processed = grn_table_select_index_call_selector(ctx,
+ table,
+ index,
+ si,
+ si->args[0],
+ res);
+ }
+ break;
+ case GRN_OP_LESS :
+ case GRN_OP_GREATER :
+ case GRN_OP_LESS_EQUAL :
+ case GRN_OP_GREATER_EQUAL :
+ processed = grn_table_select_index_range(ctx, table, index, si, res);
+ break;
+ default :
+ /* todo : implement */
+ /* todo : handle SCAN_PRE_CONST */
+ break;
+ }
+ } else {
+ switch (si->op) {
+ 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]);
+ 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) {
+ if (rc == GRN_FUNCTION_NOT_IMPLEMENTED) {
+ ERRCLR(ctx);
+ } else {
+ /* TODO: report error */
+ }
+ } else {
+ processed = GRN_TRUE;
+ }
+ }
+ default :
+ break;
+ }
+ }
+ return processed;
+}
+
+grn_obj *
+grn_table_select(grn_ctx *ctx, grn_obj *table, grn_obj *expr,
+ grn_obj *res, grn_operator op)
+{
+ grn_obj *v;
+ unsigned int res_size;
+ grn_bool res_created = GRN_FALSE;
+ if (res) {
+ if (res->header.type != GRN_TABLE_HASH_KEY ||
+ (res->header.domain != DB_OBJ(table)->id)) {
+ ERR(GRN_INVALID_ARGUMENT, "hash table required");
+ return NULL;
+ }
+ } else {
+ if (!(res = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, table, NULL))) {
+ return NULL;
+ }
+ res_created = GRN_TRUE;
+ }
+ if (!(v = grn_expr_get_var_by_offset(ctx, expr, 0))) {
+ ERR(GRN_INVALID_ARGUMENT, "at least one variable must be defined");
+ return NULL;
+ }
+ GRN_API_ENTER;
+ res_size = GRN_HASH_SIZE((grn_hash *)res);
+ if (op == GRN_OP_OR || 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 *)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 < 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) {
+ grn_obj *res_ = NULL;
+ res_ = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, table, NULL);
+ if (!res_) {
+ break;
+ }
+ GRN_PTR_PUT(ctx, &res_stack, res);
+ res = res_;
+ min_id = GRN_ID_NIL;
+ }
+ 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, (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) {
+ if (res_created) {
+ grn_obj_close(ctx, res);
+ }
+ res = NULL;
+ break;
+ }
+ }
+
+ 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);
+ 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;
+ }
+ }
+ }
+ }
+ GRN_API_RETURN(res);
+}
+
+/* grn_expr_parse */
+
+grn_obj *
+grn_ptr_value_at(grn_obj *obj, int offset)
+{
+ int size = GRN_BULK_VSIZE(obj) / sizeof(grn_obj *);
+ if (offset < 0) { offset = size + offset; }
+ return (0 <= offset && offset < size)
+ ? (((grn_obj **)GRN_BULK_HEAD(obj))[offset])
+ : NULL;
+}
+
+int32_t
+grn_int32_value_at(grn_obj *obj, int offset)
+{
+ int size = GRN_BULK_VSIZE(obj) / sizeof(int32_t);
+ if (offset < 0) { offset = size + offset; }
+ return (0 <= offset && offset < size)
+ ? (((int32_t *)GRN_BULK_HEAD(obj))[offset])
+ : 0;
+}
+
+/* grn_expr_create_from_str */
+
+#include "grn_snip.h"
+
+typedef struct {
+ grn_ctx *ctx;
+ grn_obj *e;
+ grn_obj *v;
+ const char *str;
+ const char *cur;
+ const char *str_end;
+ grn_obj *table;
+ grn_obj *default_column;
+ grn_obj buf;
+ grn_obj token_stack;
+ grn_obj column_stack;
+ grn_obj op_stack;
+ 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;
+ grn_expr_flags flags;
+ grn_expr_flags default_flags;
+ int escalation_threshold;
+ int escalation_decaystep;
+ 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 {
+ grn_operator op;
+ int weight;
+} efs_op;
+
+inline static void
+skip_space(grn_ctx *ctx, efs_info *q)
+{
+ unsigned int len;
+ while (q->cur < q->str_end && grn_isspace(q->cur, ctx->encoding)) {
+ /* null check and length check */
+ if (!(len = grn_charlen(ctx, q->cur, q->str_end))) {
+ q->cur = q->str_end;
+ break;
+ }
+ q->cur += len;
+ }
+}
+
+static grn_bool
+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;
+ switch (*end) {
+ case 'S' :
+ *mode = GRN_OP_SIMILAR;
+ start = ++end;
+ *option = grn_atoi(start, q->str_end, (const char **)&end);
+ if (start == end) { *option = DEFAULT_SIMILARITY_THRESHOLD; }
+ q->cur = end;
+ break;
+ case 'N' :
+ *mode = GRN_OP_NEAR;
+ start = ++end;
+ *option = grn_atoi(start, q->str_end, (const char **)&end);
+ if (start == end) { *option = DEFAULT_MAX_INTERVAL; }
+ q->cur = end;
+ break;
+ case 'n' :
+ *mode = GRN_OP_NEAR2;
+ start = ++end;
+ *option = grn_atoi(start, q->str_end, (const char **)&end);
+ if (start == end) { *option = DEFAULT_MAX_INTERVAL; }
+ q->cur = end;
+ break;
+ case 'T' :
+ *mode = GRN_OP_TERM_EXTRACT;
+ start = ++end;
+ *option = grn_atoi(start, q->str_end, (const char **)&end);
+ if (start == end) { *option = DEFAULT_TERM_EXTRACT_POLICY; }
+ q->cur = end;
+ break;
+ case 'X' : /* force exact mode */
+ op->op = GRN_OP_AND;
+ *mode = GRN_OP_EXACT;
+ *option = 0;
+ start = ++end;
+ q->cur = end;
+ break;
+ default :
+ found = GRN_FALSE;
+ break;
+ }
+ return found;
+}
+
+#define DISABLE_UNUSED_CODE 1
+#ifndef DISABLE_UNUSED_CODE
+static const char *
+get_weight_vector(grn_ctx *ctx, efs_info *query, const char *source)
+{
+ const char *p;
+
+ if (!query->opt.weight_vector &&
+ !query->weight_set &&
+ !(query->opt.weight_vector = GRN_CALLOC(sizeof(int) * DEFAULT_WEIGHT_VECTOR_SIZE))) {
+ GRN_LOG(ctx, GRN_LOG_ALERT, "get_weight_vector malloc fail");
+ return source;
+ }
+ for (p = source; p < query->str_end; ) {
+ unsigned int key;
+ int value;
+
+ /* key, key is not zero */
+ key = grn_atoui(p, query->str_end, &p);
+ if (!key || key > GRN_ID_MAX) { break; }
+
+ /* value */
+ if (*p == ':') {
+ p++;
+ value = grn_atoi(p, query->str_end, &p);
+ } else {
+ value = 1;
+ }
+
+ if (query->weight_set) {
+ int *pval;
+ if (grn_hash_add(ctx, query->weight_set, &key, sizeof(unsigned int), (void **)&pval, NULL)) {
+ *pval = value;
+ }
+ } else if (key < DEFAULT_WEIGHT_VECTOR_SIZE) {
+ query->opt.weight_vector[key - 1] = value;
+ } else {
+ GRN_FREE(query->opt.weight_vector);
+ query->opt.weight_vector = NULL;
+ if (!(query->weight_set = grn_hash_create(ctx, NULL, sizeof(unsigned int), sizeof(int),
+ 0))) {
+ return source;
+ }
+ p = source; /* reparse */
+ continue;
+ }
+ if (*p != ',') { break; }
+ p++;
+ }
+ return p;
+}
+
+static void
+get_pragma(grn_ctx *ctx, efs_info *q)
+{
+ const char *start, *end = q->cur;
+ while (end < q->str_end && *end == GRN_QUERY_PREFIX) {
+ if (++end >= q->str_end) { break; }
+ switch (*end) {
+ case 'E' :
+ start = ++end;
+ q->escalation_threshold = grn_atoi(start, q->str_end, (const char **)&end);
+ while (end < q->str_end && (('0' <= *end && *end <= '9') || *end == '-')) { end++; }
+ if (*end == ',') {
+ start = ++end;
+ q->escalation_decaystep = grn_atoi(start, q->str_end, (const char **)&end);
+ }
+ q->cur = end;
+ break;
+ case 'D' :
+ start = ++end;
+ while (end < q->str_end && *end != GRN_QUERY_PREFIX && !grn_isspace(end, ctx->encoding)) {
+ end++;
+ }
+ if (end > start) {
+ switch (*start) {
+ case 'O' :
+ q->default_op = GRN_OP_OR;
+ break;
+ case GRN_QUERY_AND :
+ q->default_op = GRN_OP_AND;
+ break;
+ case GRN_QUERY_AND_NOT :
+ q->default_op = GRN_OP_AND_NOT;
+ break;
+ case GRN_QUERY_ADJ_INC :
+ q->default_op = GRN_OP_ADJUST;
+ break;
+ }
+ }
+ q->cur = end;
+ break;
+ case 'W' :
+ start = ++end;
+ end = (char *)get_weight_vector(ctx, q, start);
+ q->cur = end;
+ break;
+ }
+ }
+}
+
+static int
+section_weight_cb(grn_ctx *ctx, grn_hash *r, const void *rid, int sid, void *arg)
+{
+ int *w;
+ grn_hash *s = (grn_hash *)arg;
+ if (s && grn_hash_get(ctx, s, &sid, sizeof(grn_id), (void **)&w)) {
+ return *w;
+ } else {
+ return 0;
+ }
+}
+#endif
+
+#include "grn_ecmascript.h"
+#include "grn_ecmascript.c"
+
+static grn_rc
+grn_expr_parser_open(grn_ctx *ctx)
+{
+ if (!ctx->impl->parser) {
+ ctx->impl->parser = grn_expr_parserAlloc(malloc);
+ }
+ return ctx->rc;
+}
+
+#define PARSE(token) grn_expr_parser(ctx->impl->parser, (token), 0, q)
+
+static void
+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));
+ {
+ efs_info *q = efsi;
+ PARSE(GRN_EXPR_TOKEN_QSTRING);
+ }
+
+ GRN_PTR_POP(&efsi->token_stack, token);
+ column = grn_ptr_value_at(&efsi->column_stack, -1);
+ grn_expr_append_const(efsi->ctx, efsi->e, column, GRN_OP_GET_VALUE, 1);
+ 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 :
+ {
+ int max_interval;
+ 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);
+ 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 :
+ {
+ int similarity_threshold;
+ similarity_threshold =
+ grn_int32_value_at(&efsi->similarity_threshold_stack, -1);
+ grn_expr_append_const_int(efsi->ctx, efsi->e, similarity_threshold,
+ GRN_OP_PUSH, 1);
+ 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 :
+ 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
+parse_query_word(grn_ctx *ctx, efs_info *q)
+{
+ const char *end;
+ unsigned int len;
+ GRN_BULK_REWIND(&q->buf);
+ for (end = q->cur;; ) {
+ /* null check and length check */
+ if (!(len = grn_charlen(ctx, end, q->str_end))) {
+ q->cur = q->str_end;
+ break;
+ }
+ if (grn_isspace(end, ctx->encoding) ||
+ *end == GRN_QUERY_PARENL || *end == GRN_QUERY_PARENR) {
+ q->cur = end;
+ break;
+ }
+ if (q->flags & GRN_EXPR_ALLOW_COLUMN && *end == GRN_QUERY_COLUMN) {
+ grn_operator mode;
+ grn_obj *c = grn_obj_column(ctx, q->table,
+ GRN_TEXT_VALUE(&q->buf),
+ GRN_TEXT_LEN(&q->buf));
+ if (c && end + 1 < q->str_end) {
+ switch (end[1]) {
+ case '!' :
+ mode = GRN_OP_NOT_EQUAL;
+ q->cur = end + 2;
+ break;
+ case '=' :
+ if (q->flags & GRN_EXPR_ALLOW_UPDATE) {
+ mode = GRN_OP_ASSIGN;
+ q->cur = end + 2;
+ } else {
+ mode = GRN_OP_EQUAL;
+ q->cur = end + 1;
+ }
+ break;
+ case '<' :
+ if (end + 2 < q->str_end && end[2] == '=') {
+ mode = GRN_OP_LESS_EQUAL;
+ q->cur = end + 3;
+ } else {
+ mode = GRN_OP_LESS;
+ q->cur = end + 2;
+ }
+ break;
+ case '>' :
+ if (end + 2 < q->str_end && end[2] == '=') {
+ mode = GRN_OP_GREATER_EQUAL;
+ q->cur = end + 3;
+ } else {
+ mode = GRN_OP_GREATER;
+ q->cur = end + 2;
+ }
+ break;
+ case '@' :
+ mode = GRN_OP_MATCH;
+ q->cur = end + 2;
+ break;
+ case '^' :
+ mode = GRN_OP_PREFIX;
+ q->cur = end + 2;
+ break;
+ case '$' :
+ mode = GRN_OP_SUFFIX;
+ q->cur = end + 2;
+ break;
+ case '~' :
+ mode = GRN_OP_REGEXP;
+ q->cur = end + 2;
+ break;
+ default :
+ mode = GRN_OP_EQUAL;
+ 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);
+
+ grn_expr_take_obj(ctx, q->e, c);
+ GRN_PTR_PUT(ctx, &q->column_stack, c);
+ GRN_INT32_PUT(ctx, &q->mode_stack, mode);
+
+ return GRN_SUCCESS;
+ } else if (GRN_TEXT_LEN(&q->buf) > 0 && *end == GRN_QUERY_PREFIX) {
+ q->cur = end + 1;
+ GRN_INT32_PUT(ctx, &q->mode_stack, GRN_OP_PREFIX);
+ break;
+ } else if (*end == GRN_QUERY_ESCAPE) {
+ end += len;
+ if (!(len = grn_charlen(ctx, end, q->str_end))) {
+ q->cur = q->str_end;
+ break;
+ }
+ }
+ GRN_TEXT_PUT(ctx, &q->buf, end, len);
+ end += len;
+ }
+ 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;
+}
+
+static grn_rc
+parse_query(grn_ctx *ctx, efs_info *q)
+{
+ int option = 0;
+ 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 GRN_QUERY_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);
+ while (1) {
+ unsigned int len;
+ if (s >= q->str_end) {
+ q->cur = s;
+ break;
+ }
+ len = grn_charlen(ctx, s, q->str_end);
+ if (len == 0) {
+ /* invalid string containing malformed multibyte char */
+ goto exit;
+ } 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++;
+ len = grn_charlen(ctx, s, q->str_end);
+ }
+ }
+ GRN_TEXT_PUT(ctx, &q->buf, s, len);
+ s += len;
+ }
+ 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 (parse_query_op(q, op, &mode, &option)) {
+ switch (mode) {
+ case GRN_OP_NEAR :
+ case GRN_OP_NEAR2 :
+ GRN_INT32_PUT(ctx, &q->max_interval_stack, option);
+ break;
+ case GRN_OP_SIMILAR :
+ GRN_INT32_PUT(ctx, &q->similarity_threshold_stack, option);
+ break;
+ default :
+ 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--;
+ parse_query_word(ctx, q);
+ }
+ break;
+ case GRN_QUERY_AND :
+ if (first_token) {
+ only_first_and = GRN_TRUE;
+ } else {
+ op->op = GRN_OP_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) {
+ 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_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_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_query_accept_adjust(ctx,
+ q,
+ q->cur, 1,
+ GRN_EXPR_TOKEN_ADJUST,
+ op->weight);
+ q->cur++;
+ break;
+ case GRN_QUERY_ADJ_NEG :
+ 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 + 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 :
+ 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;
+}
+
+static grn_rc
+get_string(grn_ctx *ctx, efs_info *q, char quote)
+{
+ const char *s;
+ unsigned int len;
+ grn_rc rc = GRN_END_OF_DATA;
+ GRN_BULK_REWIND(&q->buf);
+ for (s = q->cur + 1; s < q->str_end; s += len) {
+ if (!(len = grn_charlen(ctx, s, q->str_end))) { break; }
+ if (len == 1) {
+ if (*s == quote) {
+ s++;
+ rc = GRN_SUCCESS;
+ break;
+ }
+ if (*s == GRN_QUERY_ESCAPE && s + 1 < q->str_end) {
+ s++;
+ if (!(len = grn_charlen(ctx, s, q->str_end))) { break; }
+ }
+ }
+ GRN_TEXT_PUT(ctx, &q->buf, s, len);
+ }
+ q->cur = s;
+ return rc;
+}
+
+static grn_obj *
+resolve_top_level_name(grn_ctx *ctx, const char *name, unsigned int name_size)
+{
+ unsigned int i;
+ unsigned int first_delimiter_position = 0;
+ unsigned int n_delimiters = 0;
+ grn_obj *top_level_object;
+ grn_obj *object;
+
+ for (i = 0; i < name_size; i++) {
+ if (name[i] != GRN_DB_DELIMITER) {
+ continue;
+ }
+
+ if (n_delimiters == 0) {
+ first_delimiter_position = i;
+ }
+ n_delimiters++;
+ }
+
+ if (n_delimiters < 2) {
+ return grn_ctx_get(ctx, name, name_size);
+ }
+
+ top_level_object = grn_ctx_get(ctx, name, first_delimiter_position);
+ if (!top_level_object) {
+ return NULL;
+ }
+ object = grn_obj_column(ctx, top_level_object,
+ name + first_delimiter_position + 1,
+ name_size - first_delimiter_position - 1);
+ grn_obj_unlink(ctx, top_level_object);
+ return object;
+}
+
+static grn_rc
+get_identifier(grn_ctx *ctx, efs_info *q, grn_obj *name_resolve_context)
+{
+ const char *s;
+ unsigned int len;
+ grn_rc rc = GRN_SUCCESS;
+ for (s = q->cur; s < q->str_end; s += len) {
+ if (!(len = grn_charlen(ctx, s, q->str_end))) {
+ rc = GRN_END_OF_DATA;
+ goto exit;
+ }
+ if (grn_isspace(s, ctx->encoding)) { goto done; }
+ if (len == 1) {
+ switch (*s) {
+ case '\0' : case '(' : case ')' : case '{' : case '}' :
+ case '[' : case ']' : case ',' : case ':' : case '@' :
+ case '?' : case '"' : case '*' : case '+' : case '-' :
+ case '|' : case '/' : case '%' : case '!' : case '^' :
+ case '&' : case '>' : case '<' : case '=' : case '~' :
+ /* case '.' : */
+ goto done;
+ break;
+ }
+ }
+ }
+done :
+ len = s - q->cur;
+ switch (*q->cur) {
+ case 'd' :
+ if (len == 6 && !memcmp(q->cur, "delete", 6)) {
+ PARSE(GRN_EXPR_TOKEN_DELETE);
+ goto exit;
+ }
+ break;
+ case 'f' :
+ if (len == 5 && !memcmp(q->cur, "false", 5)) {
+ grn_obj buf;
+ PARSE(GRN_EXPR_TOKEN_BOOLEAN);
+ GRN_BOOL_INIT(&buf, 0);
+ GRN_BOOL_SET(ctx, &buf, 0);
+ grn_expr_append_const(ctx, q->e, &buf, GRN_OP_PUSH, 1);
+ GRN_OBJ_FIN(ctx, &buf);
+ goto exit;
+ }
+ break;
+ case 'i' :
+ if (len == 2 && !memcmp(q->cur, "in", 2)) {
+ PARSE(GRN_EXPR_TOKEN_IN);
+ goto exit;
+ }
+ break;
+ case 'n' :
+ if (len == 4 && !memcmp(q->cur, "null", 4)) {
+ grn_obj buf;
+ PARSE(GRN_EXPR_TOKEN_NULL);
+ GRN_VOID_INIT(&buf);
+ grn_expr_append_const(ctx, q->e, &buf, GRN_OP_PUSH, 1);
+ GRN_OBJ_FIN(ctx, &buf);
+ goto exit;
+ }
+ break;
+ case 't' :
+ if (len == 4 && !memcmp(q->cur, "true", 4)) {
+ grn_obj buf;
+ PARSE(GRN_EXPR_TOKEN_BOOLEAN);
+ GRN_BOOL_INIT(&buf, 0);
+ GRN_BOOL_SET(ctx, &buf, 1);
+ grn_expr_append_const(ctx, q->e, &buf, GRN_OP_PUSH, 1);
+ GRN_OBJ_FIN(ctx, &buf);
+ goto exit;
+ }
+ break;
+ }
+ {
+ grn_obj *obj;
+ const char *name = q->cur;
+ unsigned int name_size = s - q->cur;
+ if (name_resolve_context) {
+ if ((obj = grn_obj_column(ctx, name_resolve_context, name, name_size))) {
+ 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;
+ }
+ }
+ if ((obj = grn_expr_get_var(ctx, q->e, name, name_size))) {
+ PARSE(GRN_EXPR_TOKEN_IDENTIFIER);
+ grn_expr_append_obj(ctx, q->e, obj, GRN_OP_PUSH, 1);
+ goto exit;
+ }
+ if ((obj = grn_obj_column(ctx, q->table, name, name_size))) {
+ 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))) {
+ 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;
+ }
+ if (q->flags & GRN_EXPR_SYNTAX_OUTPUT_COLUMNS) {
+ PARSE(GRN_EXPR_TOKEN_NONEXISTENT_COLUMN);
+ } else {
+ rc = GRN_SYNTAX_ERROR;
+ ERR(rc,
+ "[expr][parse] unknown identifier: <%.*s>",
+ (int)name_size,
+ name);
+ }
+ }
+exit :
+ q->cur = s;
+ return rc;
+}
+
+static void
+set_tos_minor_to_curr(grn_ctx *ctx, efs_info *q)
+{
+ yyParser *parser = ctx->impl->parser;
+ yyStackEntry *yytos = parser->yytos;
+ yytos->minor.yy0 = ((grn_expr *)(q->e))->codes_curr;
+}
+
+static grn_obj *
+parse_script_extract_name_resolve_context(grn_ctx *ctx, efs_info *q)
+{
+ grn_expr *expr = (grn_expr *)(q->e);
+ grn_expr_code *code_start;
+ grn_expr_code *code_last;
+
+ if (expr->codes_curr == 0) {
+ return NULL;
+ }
+
+ code_start = expr->codes;
+ code_last = code_start + (expr->codes_curr - 1);
+ switch (code_last->op) {
+ case GRN_OP_GET_MEMBER :
+ {
+ unsigned int n_used_codes_for_key;
+ grn_expr_code *code_key;
+ grn_expr_code *code_receiver;
+
+ code_key = code_last - 1;
+ if (code_key < code_start) {
+ return NULL;
+ }
+
+ n_used_codes_for_key = grn_expr_code_n_used_codes(ctx,
+ code_start,
+ code_key);
+ if (n_used_codes_for_key == 0) {
+ return NULL;
+ }
+ code_receiver = code_key - n_used_codes_for_key;
+ if (code_receiver < code_start) {
+ return NULL;
+ }
+ return code_receiver->value;
+ }
+ break;
+ default :
+ /* TODO: Support other operators. */
+ return NULL;
+ break;
+ }
+}
+
+static grn_rc
+parse_script(grn_ctx *ctx, efs_info *q)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *name_resolve_context = NULL;
+ for (;;) {
+ grn_obj *current_name_resolve_context = name_resolve_context;
+ name_resolve_context = NULL;
+ skip_space(ctx, q);
+ if (q->cur >= q->str_end) { rc = GRN_END_OF_DATA; goto exit; }
+ switch (*q->cur) {
+ case '\0' :
+ rc = GRN_END_OF_DATA;
+ goto exit;
+ break;
+ case '(' :
+ PARSE(GRN_EXPR_TOKEN_PARENL);
+ q->cur++;
+ break;
+ case ')' :
+ PARSE(GRN_EXPR_TOKEN_PARENR);
+ q->cur++;
+ break;
+ case '{' :
+ PARSE(GRN_EXPR_TOKEN_BRACEL);
+ q->cur++;
+ break;
+ case '}' :
+ PARSE(GRN_EXPR_TOKEN_BRACER);
+ q->cur++;
+ break;
+ case '[' :
+ PARSE(GRN_EXPR_TOKEN_BRACKETL);
+ q->cur++;
+ break;
+ case ']' :
+ PARSE(GRN_EXPR_TOKEN_BRACKETR);
+ q->cur++;
+ break;
+ case ',' :
+ PARSE(GRN_EXPR_TOKEN_COMMA);
+ q->cur++;
+ break;
+ case '.' :
+ PARSE(GRN_EXPR_TOKEN_DOT);
+ name_resolve_context = parse_script_extract_name_resolve_context(ctx, q);
+ q->cur++;
+ break;
+ case ':' :
+ PARSE(GRN_EXPR_TOKEN_COLON);
+ q->cur++;
+ set_tos_minor_to_curr(ctx, q);
+ grn_expr_append_op(ctx, q->e, GRN_OP_JUMP, 0);
+ break;
+ case '@' :
+ switch (q->cur[1]) {
+ case '^' :
+ PARSE(GRN_EXPR_TOKEN_PREFIX);
+ q->cur += 2;
+ break;
+ case '$' :
+ PARSE(GRN_EXPR_TOKEN_SUFFIX);
+ q->cur += 2;
+ break;
+ case '~' :
+ PARSE(GRN_EXPR_TOKEN_REGEXP);
+ q->cur += 2;
+ break;
+ default :
+ PARSE(GRN_EXPR_TOKEN_MATCH);
+ q->cur++;
+ break;
+ }
+ break;
+ case '~' :
+ PARSE(GRN_EXPR_TOKEN_BITWISE_NOT);
+ q->cur++;
+ break;
+ case '?' :
+ PARSE(GRN_EXPR_TOKEN_QUESTION);
+ q->cur++;
+ set_tos_minor_to_curr(ctx, q);
+ grn_expr_append_op(ctx, q->e, GRN_OP_CJUMP, 0);
+ break;
+ case '"' :
+ if ((rc = get_string(ctx, q, '"'))) { goto exit; }
+ PARSE(GRN_EXPR_TOKEN_STRING);
+ grn_expr_append_const(ctx, q->e, &q->buf, GRN_OP_PUSH, 1);
+ break;
+ case '\'' :
+ if ((rc = get_string(ctx, q, '\''))) { goto exit; }
+ PARSE(GRN_EXPR_TOKEN_STRING);
+ grn_expr_append_const(ctx, q->e, &q->buf, GRN_OP_PUSH, 1);
+ break;
+ case '*' :
+ switch (q->cur[1]) {
+ case 'N' :
+ {
+ 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);
+ q->cur += 2;
+ break;
+ case 'T' :
+ PARSE(GRN_EXPR_TOKEN_TERM_EXTRACT);
+ q->cur += 2;
+ break;
+ case '>' :
+ PARSE(GRN_EXPR_TOKEN_ADJUST);
+ q->cur += 2;
+ break;
+ case '<' :
+ PARSE(GRN_EXPR_TOKEN_ADJUST);
+ q->cur += 2;
+ break;
+ case '~' :
+ PARSE(GRN_EXPR_TOKEN_ADJUST);
+ q->cur += 2;
+ break;
+ case '=' :
+ if (q->flags & GRN_EXPR_ALLOW_UPDATE) {
+ PARSE(GRN_EXPR_TOKEN_STAR_ASSIGN);
+ q->cur += 2;
+ } else {
+ ERR(GRN_UPDATE_NOT_ALLOWED,
+ "'*=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
+ }
+ break;
+ default :
+ PARSE(GRN_EXPR_TOKEN_STAR);
+ q->cur++;
+ break;
+ }
+ break;
+ case '+' :
+ switch (q->cur[1]) {
+ case '+' :
+ if (q->flags & GRN_EXPR_ALLOW_UPDATE) {
+ PARSE(GRN_EXPR_TOKEN_INCR);
+ q->cur += 2;
+ } else {
+ ERR(GRN_UPDATE_NOT_ALLOWED,
+ "'++' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
+ }
+ break;
+ case '=' :
+ if (q->flags & GRN_EXPR_ALLOW_UPDATE) {
+ PARSE(GRN_EXPR_TOKEN_PLUS_ASSIGN);
+ q->cur += 2;
+ } else {
+ ERR(GRN_UPDATE_NOT_ALLOWED,
+ "'+=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
+ }
+ break;
+ default :
+ PARSE(GRN_EXPR_TOKEN_PLUS);
+ q->cur++;
+ break;
+ }
+ break;
+ case '-' :
+ switch (q->cur[1]) {
+ case '-' :
+ if (q->flags & GRN_EXPR_ALLOW_UPDATE) {
+ PARSE(GRN_EXPR_TOKEN_DECR);
+ q->cur += 2;
+ } else {
+ ERR(GRN_UPDATE_NOT_ALLOWED,
+ "'--' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
+ }
+ break;
+ case '=' :
+ if (q->flags & GRN_EXPR_ALLOW_UPDATE) {
+ PARSE(GRN_EXPR_TOKEN_MINUS_ASSIGN);
+ q->cur += 2;
+ } else {
+ ERR(GRN_UPDATE_NOT_ALLOWED,
+ "'-=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
+ }
+ break;
+ default :
+ PARSE(GRN_EXPR_TOKEN_MINUS);
+ q->cur++;
+ break;
+ }
+ break;
+ case '|' :
+ switch (q->cur[1]) {
+ case '|' :
+ PARSE(GRN_EXPR_TOKEN_LOGICAL_OR);
+ q->cur += 2;
+ break;
+ case '=' :
+ if (q->flags & GRN_EXPR_ALLOW_UPDATE) {
+ PARSE(GRN_EXPR_TOKEN_OR_ASSIGN);
+ q->cur += 2;
+ } else {
+ ERR(GRN_UPDATE_NOT_ALLOWED,
+ "'|=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
+ }
+ break;
+ default :
+ PARSE(GRN_EXPR_TOKEN_BITWISE_OR);
+ q->cur++;
+ break;
+ }
+ break;
+ case '/' :
+ switch (q->cur[1]) {
+ case '=' :
+ if (q->flags & GRN_EXPR_ALLOW_UPDATE) {
+ PARSE(GRN_EXPR_TOKEN_SLASH_ASSIGN);
+ q->cur += 2;
+ } else {
+ ERR(GRN_UPDATE_NOT_ALLOWED,
+ "'/=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
+ }
+ break;
+ default :
+ PARSE(GRN_EXPR_TOKEN_SLASH);
+ q->cur++;
+ break;
+ }
+ break;
+ case '%' :
+ switch (q->cur[1]) {
+ case '=' :
+ if (q->flags & GRN_EXPR_ALLOW_UPDATE) {
+ PARSE(GRN_EXPR_TOKEN_MOD_ASSIGN);
+ q->cur += 2;
+ } else {
+ ERR(GRN_UPDATE_NOT_ALLOWED,
+ "'%%=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
+ }
+ break;
+ default :
+ PARSE(GRN_EXPR_TOKEN_MOD);
+ q->cur++;
+ break;
+ }
+ break;
+ case '!' :
+ switch (q->cur[1]) {
+ case '=' :
+ PARSE(GRN_EXPR_TOKEN_NOT_EQUAL);
+ q->cur += 2;
+ break;
+ default :
+ PARSE(GRN_EXPR_TOKEN_NOT);
+ q->cur++;
+ break;
+ }
+ break;
+ case '^' :
+ switch (q->cur[1]) {
+ case '=' :
+ if (q->flags & GRN_EXPR_ALLOW_UPDATE) {
+ q->cur += 2;
+ PARSE(GRN_EXPR_TOKEN_XOR_ASSIGN);
+ } else {
+ ERR(GRN_UPDATE_NOT_ALLOWED,
+ "'^=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
+ }
+ break;
+ default :
+ PARSE(GRN_EXPR_TOKEN_BITWISE_XOR);
+ q->cur++;
+ break;
+ }
+ break;
+ case '&' :
+ switch (q->cur[1]) {
+ case '&' :
+ PARSE(GRN_EXPR_TOKEN_LOGICAL_AND);
+ q->cur += 2;
+ break;
+ case '=' :
+ if (q->flags & GRN_EXPR_ALLOW_UPDATE) {
+ PARSE(GRN_EXPR_TOKEN_AND_ASSIGN);
+ q->cur += 2;
+ } else {
+ ERR(GRN_UPDATE_NOT_ALLOWED,
+ "'&=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
+ }
+ break;
+ case '!' :
+ PARSE(GRN_EXPR_TOKEN_LOGICAL_AND_NOT);
+ q->cur += 2;
+ break;
+ default :
+ PARSE(GRN_EXPR_TOKEN_BITWISE_AND);
+ q->cur++;
+ break;
+ }
+ break;
+ case '>' :
+ switch (q->cur[1]) {
+ case '>' :
+ switch (q->cur[2]) {
+ case '>' :
+ switch (q->cur[3]) {
+ case '=' :
+ if (q->flags & GRN_EXPR_ALLOW_UPDATE) {
+ PARSE(GRN_EXPR_TOKEN_SHIFTRR_ASSIGN);
+ q->cur += 4;
+ } else {
+ ERR(GRN_UPDATE_NOT_ALLOWED,
+ "'>>>=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
+ }
+ break;
+ default :
+ PARSE(GRN_EXPR_TOKEN_SHIFTRR);
+ q->cur += 3;
+ break;
+ }
+ break;
+ case '=' :
+ if (q->flags & GRN_EXPR_ALLOW_UPDATE) {
+ PARSE(GRN_EXPR_TOKEN_SHIFTR_ASSIGN);
+ q->cur += 3;
+ } else {
+ ERR(GRN_UPDATE_NOT_ALLOWED,
+ "'>>=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
+ }
+ break;
+ default :
+ PARSE(GRN_EXPR_TOKEN_SHIFTR);
+ q->cur += 2;
+ break;
+ }
+ break;
+ case '=' :
+ PARSE(GRN_EXPR_TOKEN_GREATER_EQUAL);
+ q->cur += 2;
+ break;
+ default :
+ PARSE(GRN_EXPR_TOKEN_GREATER);
+ q->cur++;
+ break;
+ }
+ break;
+ case '<' :
+ switch (q->cur[1]) {
+ case '<' :
+ switch (q->cur[2]) {
+ case '=' :
+ if (q->flags & GRN_EXPR_ALLOW_UPDATE) {
+ PARSE(GRN_EXPR_TOKEN_SHIFTL_ASSIGN);
+ q->cur += 3;
+ } else {
+ ERR(GRN_UPDATE_NOT_ALLOWED,
+ "'<<=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
+ }
+ break;
+ default :
+ PARSE(GRN_EXPR_TOKEN_SHIFTL);
+ q->cur += 2;
+ break;
+ }
+ break;
+ case '=' :
+ PARSE(GRN_EXPR_TOKEN_LESS_EQUAL);
+ q->cur += 2;
+ break;
+ default :
+ PARSE(GRN_EXPR_TOKEN_LESS);
+ q->cur++;
+ break;
+ }
+ break;
+ case '=' :
+ switch (q->cur[1]) {
+ case '=' :
+ PARSE(GRN_EXPR_TOKEN_EQUAL);
+ q->cur += 2;
+ break;
+ default :
+ if (q->flags & GRN_EXPR_ALLOW_UPDATE) {
+ PARSE(GRN_EXPR_TOKEN_ASSIGN);
+ q->cur++;
+ } else {
+ ERR(GRN_UPDATE_NOT_ALLOWED,
+ "'=' is not allowed: <%.*s>", (int)(q->str_end - q->str), q->str);
+ }
+ break;
+ }
+ break;
+ case '0' : case '1' : case '2' : case '3' : case '4' :
+ case '5' : case '6' : case '7' : case '8' : case '9' :
+ {
+ 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 least
+ // one char.)
+ if (q->str_end != rest &&
+ (*rest == '.' || *rest == 'e' || *rest == 'E' ||
+ (*rest >= '0' && *rest <= '9'))) {
+ char *rest_float;
+ double d = strtod(q->cur, &rest_float);
+ grn_obj floatbuf;
+ GRN_FLOAT_INIT(&floatbuf, 0);
+ GRN_FLOAT_SET(ctx, &floatbuf, d);
+ grn_expr_append_const(ctx, q->e, &floatbuf, GRN_OP_PUSH, 1);
+ rest = rest_float;
+ } else {
+ const char *rest64 = rest;
+ grn_atoui(q->cur, q->str_end, &rest);
+ // checks to see grn_atoi failed (see above NOTE)
+ if ((int64 > UINT32_MAX) ||
+ (q->str_end != rest && *rest >= '0' && *rest <= '9')) {
+ grn_obj int64buf;
+ GRN_INT64_INIT(&int64buf, 0);
+ GRN_INT64_SET(ctx, &int64buf, int64);
+ grn_expr_append_const(ctx, q->e, &int64buf, GRN_OP_PUSH, 1);
+ rest = rest64;
+ } else if (int64 > INT32_MAX || int64 < INT32_MIN) {
+ grn_obj int64buf;
+ GRN_INT64_INIT(&int64buf, 0);
+ GRN_INT64_SET(ctx, &int64buf, int64);
+ grn_expr_append_const(ctx, q->e, &int64buf, GRN_OP_PUSH, 1);
+ } else {
+ grn_obj int32buf;
+ GRN_INT32_INIT(&int32buf, 0);
+ GRN_INT32_SET(ctx, &int32buf, (int32_t)int64);
+ grn_expr_append_const(ctx, q->e, &int32buf, GRN_OP_PUSH, 1);
+ }
+ }
+ PARSE(GRN_EXPR_TOKEN_DECIMAL);
+ q->cur = rest;
+ }
+ break;
+ default :
+ if ((rc = get_identifier(ctx, q, current_name_resolve_context))) {
+ goto exit;
+ }
+ break;
+ }
+ if (ctx->rc) { rc = ctx->rc; break; }
+ }
+exit :
+ PARSE(0);
+ return rc;
+}
+
+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,
+ grn_operator default_op, grn_expr_flags flags)
+{
+ efs_info efsi;
+ if (grn_expr_parser_open(ctx)) { return ctx->rc; }
+ GRN_API_ENTER;
+ efsi.ctx = ctx;
+ efsi.str = str;
+ if ((efsi.v = grn_expr_get_var_by_offset(ctx, expr, 0)) &&
+ (efsi.table = grn_ctx_at(ctx, efsi.v->header.domain))) {
+ GRN_TEXT_INIT(&efsi.buf, 0);
+ GRN_INT32_INIT(&efsi.op_stack, GRN_OBJ_VECTOR);
+ 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;
+ efsi.str = str;
+ efsi.cur = str;
+ efsi.str_end = str + str_size;
+ efsi.default_column = default_column;
+ 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 |
+ GRN_EXPR_SYNTAX_ADJUSTER)) {
+ efs_info *q = &efsi;
+ if (flags & GRN_EXPR_SYNTAX_OUTPUT_COLUMNS) {
+ PARSE(GRN_EXPR_TOKEN_START_OUTPUT_COLUMNS);
+ } else if (flags & GRN_EXPR_SYNTAX_ADJUSTER) {
+ PARSE(GRN_EXPR_TOKEN_START_ADJUSTER);
+ }
+ parse_script(ctx, &efsi);
+ } else {
+ parse_query(ctx, &efsi);
+ }
+
+ /*
+ grn_obj strbuf;
+ GRN_TEXT_INIT(&strbuf, 0);
+ grn_expr_inspect_internal(ctx, &strbuf, expr);
+ GRN_TEXT_PUTC(ctx, &strbuf, '\0');
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "query=(%s)", GRN_TEXT_VALUE(&strbuf));
+ GRN_OBJ_FIN(ctx, &strbuf);
+ */
+
+ /*
+ efsi.opt.vector_size = DEFAULT_WEIGHT_VECTOR_SIZE;
+ efsi.opt.func = efsi.weight_set ? section_weight_cb : NULL;
+ efsi.opt.func_arg = efsi.weight_set;
+ efsi.snip_conds = NULL;
+ */
+ GRN_OBJ_FIN(ctx, &efsi.op_stack);
+ 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");
+ }
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_rc
+grn_expr_parser_close(grn_ctx *ctx)
+{
+ if (ctx->impl->parser) {
+ 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 = 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);
+ for (i = n; i--;) {
+ si = sis[i];
+ if (si->flags & SCAN_POP) {
+ nparens++;
+ if (si->logical_op == GRN_OP_AND_NOT) {
+ GRN_UINT32_PUT(ctx, &but_stack, npbut);
+ npbut = nparens;
+ butp = 1 - butp;
+ }
+ } else {
+ 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) {
+ if (nparens == npbut) {
+ butp = 1 - butp;
+ GRN_UINT32_POP(&but_stack, npbut);
+ }
+ nparens--;
+ }
+ }
+ }
+ GRN_OBJ_FIN(ctx, &but_stack);
+ for (i = n; i--;) { SI_FREE(sis[i]); }
+ GRN_FREE(sis);
+ }
+ GRN_API_RETURN(GRN_SUCCESS);
+}
+
+grn_rc
+grn_expr_snip_add_conditions(grn_ctx *ctx, grn_obj *expr, grn_obj *snip,
+ unsigned int n_tags,
+ const char **opentags, unsigned int *opentag_lens,
+ const char **closetags, unsigned int *closetag_lens)
+{
+ grn_rc rc;
+ grn_obj keywords;
+
+ GRN_API_ENTER;
+
+ GRN_PTR_INIT(&keywords, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ rc = grn_expr_get_keywords(ctx, expr, &keywords);
+ if (rc != GRN_SUCCESS) {
+ GRN_OBJ_FIN(ctx, &keywords);
+ GRN_API_RETURN(rc);
+ }
+
+ if (n_tags) {
+ int i;
+ for (i = 0;; i = (i + 1) % n_tags) {
+ grn_obj *keyword;
+ GRN_PTR_POP(&keywords, keyword);
+ if (!keyword) { break; }
+ grn_snip_add_cond(ctx, snip,
+ GRN_TEXT_VALUE(keyword), GRN_TEXT_LEN(keyword),
+ opentags[i], opentag_lens[i],
+ closetags[i], closetag_lens[i]);
+ }
+ } else {
+ for (;;) {
+ grn_obj *keyword;
+ GRN_PTR_POP(&keywords, keyword);
+ if (!keyword) { break; }
+ grn_snip_add_cond(ctx, snip,
+ GRN_TEXT_VALUE(keyword), GRN_TEXT_LEN(keyword),
+ NULL, 0, NULL, 0);
+ }
+ }
+ GRN_OBJ_FIN(ctx, &keywords);
+
+ GRN_API_RETURN(GRN_SUCCESS);
+}
+
+grn_obj *
+grn_expr_snip(grn_ctx *ctx, grn_obj *expr, int flags,
+ unsigned int width, unsigned int max_results,
+ unsigned int n_tags,
+ const char **opentags, unsigned int *opentag_lens,
+ const char **closetags, unsigned int *closetag_lens,
+ grn_snip_mapping *mapping)
+{
+ grn_obj *res = NULL;
+ GRN_API_ENTER;
+ if ((res = grn_snip_open(ctx, flags, width, max_results,
+ NULL, 0, NULL, 0, mapping))) {
+ grn_expr_snip_add_conditions(ctx, expr, res,
+ n_tags,
+ opentags, opentag_lens,
+ closetags, closetag_lens);
+ }
+ GRN_API_RETURN(res);
+}
+
+/*
+ So far, grn_column_filter() is nothing but a very rough prototype.
+ Although GRN_COLUMN_EACH() can accelerate many range queries,
+ the following stuff must be resolved one by one.
+
+ * support accessors as column
+ * support tables which have deleted records
+ * support various operators
+ * support various column types
+*/
+grn_rc
+grn_column_filter(grn_ctx *ctx, grn_obj *column,
+ grn_operator operator,
+ grn_obj *value, grn_obj *result_set,
+ grn_operator set_operation)
+{
+ uint32_t *vp;
+ grn_posting posting;
+ uint32_t value_ = grn_atoui(GRN_TEXT_VALUE(value), GRN_BULK_CURR(value), NULL);
+ posting.sid = 1;
+ posting.pos = 0;
+ posting.weight = 0;
+ GRN_COLUMN_EACH(ctx, column, id, vp, {
+ if (*vp < value_) {
+ posting.rid = id;
+ grn_ii_posting_add(ctx, &posting, (grn_hash *)result_set, set_operation);
+ }
+ });
+ grn_ii_resolve_sel_and(ctx, (grn_hash *)result_set, set_operation);
+ return ctx->rc;
+}
+
+grn_rc
+grn_expr_syntax_escape(grn_ctx *ctx, const char *string, int string_size,
+ const char *target_characters,
+ char escape_character,
+ grn_obj *escaped_string)
+{
+ grn_rc rc = GRN_SUCCESS;
+ const char *current, *string_end;
+
+ if (!string) {
+ return GRN_INVALID_ARGUMENT;
+ }
+
+ GRN_API_ENTER;
+ if (string_size < 0) {
+ string_size = strlen(string);
+ }
+ string_end = string + string_size;
+
+ current = string;
+ while (current < string_end) {
+ unsigned int char_size;
+ char_size = grn_charlen(ctx, current, string_end);
+ switch (char_size) {
+ case 0 :
+ /* string includes malformed multibyte character. */
+ return GRN_INVALID_ARGUMENT;
+ break;
+ case 1 :
+ if (strchr(target_characters, *current)) {
+ GRN_TEXT_PUTC(ctx, escaped_string, escape_character);
+ }
+ GRN_TEXT_PUT(ctx, escaped_string, current, char_size);
+ current += char_size;
+ break;
+ default :
+ GRN_TEXT_PUT(ctx, escaped_string, current, char_size);
+ current += char_size;
+ break;
+ }
+ }
+
+ GRN_API_RETURN(rc);
+}
+
+grn_rc
+grn_expr_syntax_escape_query(grn_ctx *ctx, const char *query, int query_size,
+ grn_obj *escaped_query)
+{
+ const char target_characters[] = {
+ GRN_QUERY_AND,
+ GRN_QUERY_AND_NOT,
+ GRN_QUERY_ADJ_INC,
+ GRN_QUERY_ADJ_DEC,
+ GRN_QUERY_ADJ_NEG,
+ GRN_QUERY_PREFIX,
+ GRN_QUERY_PARENL,
+ GRN_QUERY_PARENR,
+ GRN_QUERY_QUOTEL,
+ GRN_QUERY_ESCAPE,
+ GRN_QUERY_COLUMN,
+ '\0',
+ };
+ return grn_expr_syntax_escape(ctx, query, query_size,
+ target_characters, GRN_QUERY_ESCAPE,
+ escaped_query);
+}
+
+grn_rc
+grn_expr_dump_plan(grn_ctx *ctx, grn_obj *expr, grn_obj *buffer)
+{
+ int n;
+ scan_info **sis;
+
+ GRN_API_ENTER;
+ 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);
+ for (i = 0; i < n; i++) {
+ SI_FREE(sis[i]);
+ }
+ GRN_FREE(sis);
+ } else {
+ GRN_TEXT_PUTS(ctx, buffer, "sequential search\n");
+ }
+ GRN_API_RETURN(GRN_SUCCESS);
+}
+
+static unsigned int
+grn_expr_estimate_size_raw(grn_ctx *ctx, grn_obj *expr, grn_obj *table)
+{
+ return grn_table_size(ctx, table);
+}
+
+unsigned int
+grn_expr_estimate_size(grn_ctx *ctx, grn_obj *expr)
+{
+ grn_obj *table;
+ grn_obj *variable;
+ unsigned int size;
+
+ variable = grn_expr_get_var_by_offset(ctx, expr, 0);
+ if (!variable) {
+ ERR(GRN_INVALID_ARGUMENT, "at least one variable must be defined");
+ return 0;
+ }
+
+ table = grn_ctx_at(ctx, variable->header.domain);
+ if (!table) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "variable refers unknown domain: <%u>", variable->header.domain);
+ return 0;
+ }
+
+ 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 {
+ size = grn_expr_estimate_size_raw(ctx, expr, table);
+ }
+#else
+ size = grn_expr_estimate_size_raw(ctx, expr, table);
+#endif
+ GRN_API_RETURN(size);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/expr_code.c b/storage/mroonga/vendor/groonga/lib/expr_code.c
new file mode 100644
index 00000000..a2dfc60b
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/expr_code.c
@@ -0,0 +1,55 @@
+/* -*- c-basic-offset: 2 -*- */
+/* 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
+ 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-1335 USA
+*/
+
+#include "grn_expr_code.h"
+
+unsigned int
+grn_expr_code_n_used_codes(grn_ctx *ctx,
+ grn_expr_code *start,
+ grn_expr_code *target)
+{
+ unsigned int n_codes;
+ int i, n_args;
+ grn_expr_code *sub_code;
+
+ if (start == target) {
+ return 0;
+ }
+
+ n_args = target->nargs;
+ if (target->value) {
+ n_args--;
+ if (n_args == 0) {
+ return 1;
+ }
+ }
+
+ n_codes = 1;
+ sub_code = target - 1;
+ for (i = 0; i < n_args; i++) {
+ int sub_n_codes;
+ sub_n_codes = grn_expr_code_n_used_codes(ctx, start, sub_code);
+ n_codes += sub_n_codes;
+ sub_code -= sub_n_codes;
+ 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 00000000..bc78a650
--- /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-1335 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 00000000..3cf8acf1
--- /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-1335 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 00000000..0ba23274
--- /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-1335 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
new file mode 100644
index 00000000..26aca445
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/geo.c
@@ -0,0 +1,2788 @@
+/* -*- 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-1335 USA
+*/
+
+#include "grn_geo.h"
+#include "grn_pat.h"
+#include "grn_util.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#define GRN_GEO_POINT_IN_NORTH_EAST(point) \
+ ((point)->latitude >= 0 && (point)->longitude >= 0)
+#define GRN_GEO_POINT_IN_NORTH_WEST(point) \
+ ((point)->latitude >= 0 && (point)->longitude < 0)
+#define GRN_GEO_POINT_IN_SOUTH_WEST(point) \
+ ((point)->latitude < 0 && (point)->longitude < 0)
+#define GRN_GEO_POINT_IN_SOUTH_EAST(point) \
+ ((point)->latitude < 0 && (point)->longitude >= 0)
+
+#define GRN_GEO_LONGITUDE_IS_WRAPPED(top_left, bottom_right) \
+ ((top_left)->longitude > 0 && (bottom_right)->longitude < 0)
+
+typedef struct {
+ grn_id id;
+ double d;
+} geo_entry;
+
+typedef struct
+{
+ grn_geo_point key;
+ int key_size;
+} mesh_entry;
+
+typedef struct {
+ grn_obj *pat;
+ grn_obj top_left_point_buffer;
+ grn_obj bottom_right_point_buffer;
+ grn_geo_point *top_left;
+ grn_geo_point *bottom_right;
+} in_rectangle_data;
+
+typedef struct {
+ grn_geo_point min;
+ grn_geo_point max;
+ int rectangle_common_bit;
+ uint8_t rectangle_common_key[sizeof(grn_geo_point)];
+} in_rectangle_area_data;
+
+static int
+compute_diff_bit(uint8_t *geo_key1, uint8_t *geo_key2)
+{
+ int i, j, diff_bit = 0;
+
+ for (i = 0; i < sizeof(grn_geo_point); i++) {
+ if (geo_key1[i] != geo_key2[i]) {
+ diff_bit = 8;
+ for (j = 0; j < 8; j++) {
+ if ((geo_key1[i] & (1 << (7 - j))) != (geo_key2[i] & (1 << (7 - j)))) {
+ diff_bit = j;
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ return i * 8 + diff_bit;
+}
+
+static void
+compute_min_and_max_key(uint8_t *key_base, int diff_bit,
+ uint8_t *key_min, uint8_t *key_max)
+{
+ int diff_byte, diff_bit_mask;
+
+ diff_byte = diff_bit / 8;
+ diff_bit_mask = 0xff >> (diff_bit % 8);
+
+ if (diff_byte == sizeof(grn_geo_point)) {
+ if (key_min) { grn_memcpy(key_min, key_base, diff_byte); }
+ if (key_max) { grn_memcpy(key_max, key_base, diff_byte); }
+ } else {
+ if (key_min) {
+ grn_memcpy(key_min, key_base, diff_byte + 1);
+ key_min[diff_byte] &= ~diff_bit_mask;
+ memset(key_min + diff_byte + 1, 0,
+ sizeof(grn_geo_point) - diff_byte - 1);
+ }
+
+ if (key_max) {
+ grn_memcpy(key_max, key_base, diff_byte + 1);
+ key_max[diff_byte] |= diff_bit_mask;
+ memset(key_max + diff_byte + 1, 0xff,
+ sizeof(grn_geo_point) - diff_byte - 1);
+ }
+ }
+}
+
+static void
+compute_min_and_max(grn_geo_point *base_point, int diff_bit,
+ grn_geo_point *geo_min, grn_geo_point *geo_max)
+{
+ uint8_t geo_key_base[sizeof(grn_geo_point)];
+ uint8_t geo_key_min[sizeof(grn_geo_point)];
+ uint8_t geo_key_max[sizeof(grn_geo_point)];
+
+ grn_gton(geo_key_base, base_point, sizeof(grn_geo_point));
+ compute_min_and_max_key(geo_key_base, diff_bit,
+ geo_min ? geo_key_min : NULL,
+ geo_max ? geo_key_max : NULL);
+ if (geo_min) {
+ grn_ntog((uint8_t *)geo_min, geo_key_min, sizeof(grn_geo_point));
+ }
+ if (geo_max) {
+ grn_ntog((uint8_t *)geo_max, geo_key_max, sizeof(grn_geo_point));
+ }
+}
+
+/* #define GEO_DEBUG */
+
+#ifdef GEO_DEBUG
+#include <stdio.h>
+
+static void
+inspect_mesh(grn_ctx *ctx, grn_geo_point *key, int key_size, int n)
+{
+ grn_geo_point min, max;
+
+ printf("mesh: %d:%d\n", n, key_size);
+
+ printf("key: ");
+ grn_p_geo_point(ctx, key);
+
+ compute_min_and_max(key, key_size, &min, &max);
+ printf("min: ");
+ grn_p_geo_point(ctx, &min);
+ printf("max: ");
+ grn_p_geo_point(ctx, &max);
+}
+
+static void
+inspect_mesh_entry(grn_ctx *ctx, mesh_entry *entries, int n)
+{
+ mesh_entry *entry;
+
+ entry = entries + n;
+ inspect_mesh(ctx, &(entry->key), entry->key_size, n);
+}
+
+static void
+inspect_tid(grn_ctx *ctx, grn_id tid, grn_geo_point *point, double d)
+{
+ printf("tid: %d:%g", tid, d);
+ grn_p_geo_point(ctx, point);
+}
+
+static void
+inspect_key(grn_ctx *ctx, uint8_t *key)
+{
+ int i;
+ for (i = 0; i < 8; i++) {
+ int j;
+ for (j = 0; j < 8; j++) {
+ printf("%d", (key[i] & (1 << (7 - j))) >> (7 - j));
+ }
+ printf(" ");
+ }
+ printf("\n");
+}
+
+static void
+print_key_mark(grn_ctx *ctx, int target_bit)
+{
+ int i;
+
+ for (i = 0; i < target_bit; i++) {
+ printf(" ");
+ if (i > 0 && i % 8 == 0) {
+ printf(" ");
+ }
+ }
+ if (i > 0 && i % 8 == 0) {
+ printf(" ");
+ }
+ printf("^\n");
+}
+
+static void
+inspect_cursor_entry(grn_ctx *ctx, grn_geo_cursor_entry *entry)
+{
+ grn_geo_point point;
+
+ printf("entry: ");
+ grn_ntog((uint8_t *)&point, entry->key, sizeof(grn_geo_point));
+ grn_p_geo_point(ctx, &point);
+ inspect_key(ctx, entry->key);
+ print_key_mark(ctx, entry->target_bit);
+
+ printf(" target bit: %d\n", entry->target_bit);
+
+#define INSPECT_STATUS_FLAG(name) \
+ ((entry->status_flags & GRN_GEO_CURSOR_ENTRY_STATUS_ ## name) ? "true" : "false")
+
+ printf(" top included: %s\n", INSPECT_STATUS_FLAG(TOP_INCLUDED));
+ printf("bottom included: %s\n", INSPECT_STATUS_FLAG(BOTTOM_INCLUDED));
+ printf(" left included: %s\n", INSPECT_STATUS_FLAG(LEFT_INCLUDED));
+ printf(" right included: %s\n", INSPECT_STATUS_FLAG(RIGHT_INCLUDED));
+ printf(" latitude inner: %s\n", INSPECT_STATUS_FLAG(LATITUDE_INNER));
+ printf("longitude inner: %s\n", INSPECT_STATUS_FLAG(LONGITUDE_INNER));
+
+#undef INSPECT_STATUS_FLAG
+}
+
+static void
+inspect_cursor_entry_targets(grn_ctx *ctx, grn_geo_cursor_entry *entry,
+ uint8_t *top_left_key, uint8_t *bottom_right_key,
+ grn_geo_cursor_entry *next_entry0,
+ grn_geo_cursor_entry *next_entry1)
+{
+ printf("entry: ");
+ inspect_key(ctx, entry->key);
+ printf("top-left: ");
+ inspect_key(ctx, top_left_key);
+ printf("bottom-right: ");
+ inspect_key(ctx, bottom_right_key);
+ printf("next-entry-0: ");
+ inspect_key(ctx, next_entry0->key);
+ printf("next-entry-1: ");
+ inspect_key(ctx, next_entry1->key);
+ printf(" ");
+ print_key_mark(ctx, entry->target_bit + 1);
+}
+#else
+# define inspect_mesh(...)
+# define inspect_mesh_entry(...)
+# define inspect_tid(...)
+# define inspect_key(...)
+# define print_key_mark(...)
+# define inspect_cursor_entry(...)
+# define inspect_cursor_entry_targets(...)
+#endif
+
+static int
+grn_geo_table_sort_detect_far_point(grn_ctx *ctx, grn_obj *table, grn_obj *index,
+ grn_pat *pat, geo_entry *entries,
+ grn_pat_cursor *pc, int n,
+ grn_bool accessorp,
+ grn_geo_point *base_point,
+ double *d_far, int *diff_bit)
+{
+ int i = 0, diff_bit_prev, diff_bit_current;
+ grn_id tid;
+ geo_entry *ep, *p;
+ double d;
+ uint8_t geo_key_prev[sizeof(grn_geo_point)];
+ uint8_t geo_key_curr[sizeof(grn_geo_point)];
+ grn_geo_point point;
+
+ *d_far = 0.0;
+ grn_gton(geo_key_curr, base_point, sizeof(grn_geo_point));
+ *diff_bit = sizeof(grn_geo_point) * 8;
+ diff_bit_current = sizeof(grn_geo_point) * 8;
+ grn_memcpy(&point, base_point, sizeof(grn_geo_point));
+ ep = entries;
+ inspect_mesh(ctx, &point, *diff_bit, -1);
+ 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_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));
+ d = grn_geo_distance_rectangle_raw(ctx, base_point, &point);
+ inspect_tid(ctx, tid, &point, d);
+
+ diff_bit_prev = diff_bit_current;
+ diff_bit_current = compute_diff_bit(geo_key_curr, geo_key_prev);
+#ifdef GEO_DEBUG
+ printf("diff: %d:%d:%d\n", *diff_bit, diff_bit_prev, diff_bit_current);
+#endif
+ if ((diff_bit_current % 2) == 1) {
+ diff_bit_current--;
+ }
+ if (diff_bit_current < diff_bit_prev && *diff_bit > diff_bit_current) {
+ if (i == n) {
+ grn_ii_cursor_close(ctx, ic);
+ break;
+ }
+ *diff_bit = diff_bit_current;
+ }
+
+ if (d > *d_far) {
+ *d_far = d;
+ }
+ while ((posting = grn_ii_cursor_next(ctx, ic))) {
+ grn_id rid = accessorp
+ ? grn_table_get(ctx, table, &posting->rid, sizeof(grn_id))
+ : posting->rid;
+ if (rid) {
+ for (p = ep; entries < p && p[-1].d > d; p--) {
+ p->id = p[-1].id;
+ p->d = p[-1].d;
+ }
+ p->id = rid;
+ p->d = d;
+ if (i < n) {
+ ep++;
+ i++;
+ }
+ }
+ }
+ grn_ii_cursor_close(ctx, ic);
+ }
+ }
+
+ return i;
+}
+
+typedef enum {
+ MESH_LEFT_TOP,
+ MESH_RIGHT_TOP,
+ MESH_RIGHT_BOTTOM,
+ MESH_LEFT_BOTTOM
+} mesh_position;
+
+/*
+ meshes should have
+ 86 >= spaces when include_base_point_hash == GRN_FALSE,
+ 87 >= spaces when include_base_point_hash == GRN_TRUE.
+*/
+static int
+grn_geo_get_meshes_for_circle(grn_ctx *ctx, grn_geo_point *base_point,
+ double d_far, int diff_bit,
+ int include_base_point_mesh,
+ mesh_entry *meshes)
+{
+ double d;
+ int n_meshes;
+ int lat_diff, lng_diff;
+ mesh_position position;
+ grn_geo_point geo_base, geo_min, geo_max;
+
+ compute_min_and_max(base_point, diff_bit - 2, &geo_min, &geo_max);
+
+ lat_diff = (geo_max.latitude - geo_min.latitude + 1) / 2;
+ lng_diff = (geo_max.longitude - geo_min.longitude + 1) / 2;
+ geo_base.latitude = geo_min.latitude + lat_diff;
+ geo_base.longitude = geo_min.longitude + lng_diff;
+ if (base_point->latitude >= geo_base.latitude) {
+ if (base_point->longitude >= geo_base.longitude) {
+ position = MESH_RIGHT_TOP;
+ } else {
+ position = MESH_LEFT_TOP;
+ }
+ } else {
+ if (base_point->longitude >= geo_base.longitude) {
+ position = MESH_RIGHT_BOTTOM;
+ } else {
+ position = MESH_LEFT_BOTTOM;
+ }
+ }
+ /*
+ base_point: b
+ geo_min: i
+ geo_max: a
+ geo_base: x: must be at the left bottom in the top right mesh.
+
+ e.g.: base_point is at the left bottom mesh case:
+ +------+------+
+ | | a|
+ | |x |
+ ^+------+------+
+ || | |
+ lng_diff || b | |
+ \/i------+------+
+ <------>
+ lat_diff
+
+ grn_min + lat_diff -> the right mesh.
+ grn_min + lng_diff -> the top mesh.
+ */
+#ifdef GEO_DEBUG
+ grn_p_geo_point(ctx, base_point);
+ printf("base: ");
+ grn_p_geo_point(ctx, &geo_base);
+ printf("min: ");
+ grn_p_geo_point(ctx, &geo_min);
+ printf("max: ");
+ grn_p_geo_point(ctx, &geo_max);
+ printf("diff: %d (%d, %d)\n", diff_bit, lat_diff, lng_diff);
+ switch (position) {
+ case MESH_LEFT_TOP :
+ printf("position: left-top\n");
+ break;
+ case MESH_RIGHT_TOP :
+ printf("position: right-top\n");
+ break;
+ case MESH_RIGHT_BOTTOM :
+ printf("position: right-bottom\n");
+ break;
+ case MESH_LEFT_BOTTOM :
+ printf("position: left-bottom\n");
+ break;
+ }
+#endif
+
+ n_meshes = 0;
+
+#define add_mesh(lat_diff_,lng_diff_,key_size_) do {\
+ meshes[n_meshes].key.latitude = geo_base.latitude + (lat_diff_);\
+ meshes[n_meshes].key.longitude = geo_base.longitude + (lng_diff_);\
+ meshes[n_meshes].key_size = key_size_;\
+ n_meshes++;\
+} while (0)
+
+ if (include_base_point_mesh || position != MESH_LEFT_TOP) {
+ add_mesh(0, -lng_diff, diff_bit);
+ }
+ if (include_base_point_mesh || position != MESH_RIGHT_TOP) {
+ add_mesh(0, 0, diff_bit);
+ }
+ if (include_base_point_mesh || position != MESH_RIGHT_BOTTOM) {
+ add_mesh(-lat_diff, 0, diff_bit);
+ }
+ if (include_base_point_mesh || position != MESH_LEFT_BOTTOM) {
+ add_mesh(-lat_diff, -lng_diff, diff_bit);
+ }
+
+ /*
+ b: base_point
+ x: geo_base
+ 0-83: sub meshes. 0-83 are added order.
+
+ j: -5 -4 -3 -2 -1 0 1 2 3 4
+ +---+---+---+---+---+---+---+---+---+---+
+ |74 |75 |76 |77 |78 |79 |80 |81 |82 |83 | 4
+ +---+---+---+---+---+---+---+---+---+---+
+ |64 |65 |66 |67 |68 |69 |70 |71 |72 |73 | 3
+ +---+---+---+---+---+---+---+---+---+---+
+ |54 |55 |56 |57 |58 |59 |60 |61 |62 |63 | 2
+ +---+---+---+---+---+---+---+---+---+---+
+ |48 |49 |50 | b | |51 |52 |53 | 1
+ +---+---+---+ | +---+---+---+
+ |42 |43 |44 | |x |45 |46 |47 | 0
+ +---+---+---+-------+-------+---+---+---+
+ |36 |37 |38 | | |39 |40 |41 | -1
+ +---+---+---+ base meshes +---+---+---+
+ |30 |31 |32 | | |33 |34 |35 | -2
+ +---+---+---+---+---+---+---+---+---+---+
+ |20 |21 |22 |23 |24 |25 |26 |27 |28 |29 | -3
+ +---+---+---+---+---+---+---+---+---+---+
+ |10 |11 |12 |13 |14 |15 |16 |17 |18 |19 | -4
+ +---+---+---+---+---+---+---+---+---+---+
+ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -5
+ +---+---+---+---+---+---+---+---+---+---+
+ i
+ */
+ {
+ int i, j, n_sub_meshes, lat, lat_min, lat_max, lng, lng_min, lng_max;
+ n_sub_meshes = 0;
+ for (i = -5; i < 5; i++) {
+ lat_min = ((lat_diff + 1) / 2) * i;
+ lat_max = ((lat_diff + 1) / 2) * (i + 1) - 1;
+ for (j = -5; j < 5; j++) {
+ if (-3 < i && i < 2 && -3 < j && j < 2) {
+ continue;
+ }
+ lng_min = ((lng_diff + 1) / 2) * j;
+ lng_max = ((lng_diff + 1) / 2) * (j + 1) - 1;
+ if (base_point->latitude <= geo_base.latitude + lat_min) {
+ lat = geo_base.latitude + lat_min;
+ } else if (geo_base.latitude + lat_max < base_point->latitude) {
+ lat = geo_base.latitude + lat_max;
+ } else {
+ lat = base_point->latitude;
+ }
+ if (base_point->longitude <= geo_base.longitude + lng_min) {
+ lng = geo_base.longitude + lng_min;
+ } else if (geo_base.longitude + lng_max < base_point->longitude) {
+ lng = geo_base.longitude + lng_max;
+ } else {
+ lng = base_point->longitude;
+ }
+ meshes[n_meshes].key.latitude = lat;
+ meshes[n_meshes].key.longitude = lng;
+ d = grn_geo_distance_rectangle_raw(ctx, base_point,
+ &(meshes[n_meshes].key));
+ if (d < d_far) {
+#ifdef GEO_DEBUG
+ printf("sub-mesh: %d: (%d,%d): (%d,%d;%d,%d)\n",
+ n_sub_meshes, base_point->latitude, base_point->longitude,
+ geo_base.latitude + lat_min,
+ geo_base.latitude + lat_max,
+ geo_base.longitude + lng_min,
+ geo_base.longitude + lng_max);
+ grn_p_geo_point(ctx, &(meshes[n_meshes].key));
+#endif
+ meshes[n_meshes].key_size = diff_bit + 2;
+ n_meshes++;
+ }
+ n_sub_meshes++;
+ }
+ }
+ }
+
+#undef add_mesh
+
+ return n_meshes;
+}
+
+static int
+grn_geo_table_sort_collect_points(grn_ctx *ctx, grn_obj *table, grn_obj *index,
+ grn_pat *pat,
+ geo_entry *entries, int n_entries,
+ int n, grn_bool accessorp,
+ grn_geo_point *base_point,
+ double d_far, int diff_bit)
+{
+ int n_meshes;
+ mesh_entry meshes[86];
+ geo_entry *ep, *p;
+
+ n_meshes = grn_geo_get_meshes_for_circle(ctx, base_point, d_far, diff_bit,
+ GRN_FALSE, meshes);
+
+ ep = entries + n_entries;
+ while (n_meshes--) {
+ grn_id tid;
+ grn_pat_cursor *pc = grn_pat_cursor_open(ctx, pat,
+ &(meshes[n_meshes].key),
+ meshes[n_meshes].key_size,
+ NULL, 0,
+ 0, -1,
+ GRN_CURSOR_PREFIX|GRN_CURSOR_SIZE_BY_BIT);
+ inspect_mesh_entry(ctx, meshes, n_meshes);
+ if (pc) {
+ 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) {
+ double d;
+ grn_geo_point pos;
+ 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);
+ while ((posting = grn_ii_cursor_next(ctx, ic))) {
+ grn_id rid = accessorp
+ ? grn_table_get(ctx, table, &posting->rid, sizeof(grn_id))
+ : posting->rid;
+ if (rid) {
+ for (p = ep; entries < p && p[-1].d > d; p--) {
+ p->id = p[-1].id;
+ p->d = p[-1].d;
+ }
+ p->id = rid;
+ p->d = d;
+ if (n_entries < n) {
+ ep++;
+ n_entries++;
+ }
+ }
+ }
+ grn_ii_cursor_close(ctx, ic);
+ }
+ }
+ grn_pat_cursor_close(ctx, pc);
+ }
+ }
+ return n_entries;
+}
+
+static inline grn_obj *
+find_geo_sort_index(grn_ctx *ctx, grn_obj *key)
+{
+ grn_obj *index = NULL;
+
+ if (GRN_ACCESSORP(key)) {
+ grn_accessor *accessor = (grn_accessor *)key;
+ if (accessor->action != GRN_ACCESSOR_GET_KEY) {
+ return NULL;
+ }
+ if (!(DB_OBJ(accessor->obj)->id & GRN_OBJ_TMP_OBJECT)) {
+ return NULL;
+ }
+ if (accessor->obj->header.type != GRN_TABLE_HASH_KEY) {
+ return NULL;
+ }
+ if (!accessor->next) {
+ return NULL;
+ }
+ grn_column_index(ctx, accessor->next->obj, GRN_OP_LESS, &index, 1, NULL);
+ } else {
+ grn_column_index(ctx, key, GRN_OP_LESS, &index, 1, NULL);
+ }
+
+ return index;
+}
+
+static inline int
+grn_geo_table_sort_by_distance(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *index,
+ grn_pat *pat,
+ grn_pat_cursor *pc,
+ grn_bool accessorp,
+ grn_geo_point *base_point,
+ int offset,
+ int limit,
+ grn_obj *result)
+{
+ int n_entries = 0, e = offset + limit;
+ geo_entry *entries;
+
+ if ((entries = GRN_MALLOC(sizeof(geo_entry) * (e + 1)))) {
+ int n, diff_bit;
+ double d_far;
+ geo_entry *ep;
+ grn_bool need_not_indexed_records;
+ grn_hash *indexed_records = NULL;
+
+ n = grn_geo_table_sort_detect_far_point(ctx, table, index, pat,
+ entries, pc, e, accessorp,
+ base_point,
+ &d_far, &diff_bit);
+ if (diff_bit > 0) {
+ n = grn_geo_table_sort_collect_points(ctx, table, index, pat,
+ entries, n, e, accessorp,
+ base_point, d_far, diff_bit);
+ }
+ need_not_indexed_records = offset + limit > n;
+ if (need_not_indexed_records) {
+ indexed_records = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY);
+ }
+ for (ep = entries + offset;
+ n_entries < limit && ep < entries + n;
+ n_entries++, ep++) {
+ grn_id *sorted_id;
+ if (!grn_array_add(ctx, (grn_array *)result, (void **)&sorted_id)) {
+ if (indexed_records) {
+ grn_hash_close(ctx, indexed_records);
+ indexed_records = NULL;
+ }
+ break;
+ }
+ *sorted_id = ep->id;
+ if (indexed_records) {
+ grn_hash_add(ctx, indexed_records, &(ep->id), sizeof(grn_id),
+ NULL, NULL);
+ }
+ }
+ GRN_FREE(entries);
+ if (indexed_records) {
+ GRN_TABLE_EACH(ctx, table, GRN_ID_NIL, GRN_ID_MAX, id, NULL, NULL, NULL, {
+ if (!grn_hash_get(ctx, indexed_records, &id, sizeof(grn_id), NULL)) {
+ grn_id *sorted_id;
+ if (grn_array_add(ctx, (grn_array *)result, (void **)&sorted_id)) {
+ *sorted_id = id;
+ }
+ n_entries++;
+ if (n_entries == limit) {
+ break;
+ }
+ };
+ });
+ grn_hash_close(ctx, indexed_records);
+ }
+ }
+
+ return n_entries;
+}
+
+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)
+{
+ grn_obj *index;
+ 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_pat *pat = (grn_pat *)grn_ctx_at(ctx, index->header.domain);
+ 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_posting *posting;
+ while (i < e && (posting = grn_ii_cursor_next(ctx, ic))) {
+ if (offset <= i) {
+ grn_id *v;
+ if (!grn_array_add(ctx, (grn_array *)result, (void **)&v)) { break; }
+ *v = posting->rid;
+ }
+ i++;
+ }
+ grn_ii_cursor_close(ctx, ic);
+ }
+ }
+ } else {
+ 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,
+ GRN_ACCESSORP(column),
+ base_point,
+ offset, limit, result);
+ }
+ grn_pat_cursor_close(ctx, pc);
+ }
+ }
+ GRN_API_RETURN(i);
+}
+
+grn_rc
+grn_geo_resolve_approximate_type(grn_ctx *ctx, grn_obj *type_name,
+ grn_geo_approximate_type *type)
+{
+ grn_rc rc;
+ grn_obj approximate_type;
+
+ GRN_TEXT_INIT(&approximate_type, 0);
+ rc = grn_obj_cast(ctx, type_name, &approximate_type, GRN_FALSE);
+ if (rc == GRN_SUCCESS) {
+ const char *name;
+ unsigned int size;
+ name = GRN_TEXT_VALUE(&approximate_type);
+ size = GRN_TEXT_LEN(&approximate_type);
+ if ((strncmp("rectangle", name, size) == 0) ||
+ (strncmp("rect", name, size) == 0)) {
+ *type = GRN_GEO_APPROXIMATE_RECTANGLE;
+ } else if ((strncmp("sphere", name, size) == 0) ||
+ (strncmp("sphr", name, size) == 0)) {
+ *type = GRN_GEO_APPROXIMATE_SPHERE;
+ } else if ((strncmp("ellipsoid", name, size) == 0) ||
+ (strncmp("ellip", name, size) == 0)) {
+ *type = GRN_GEO_APPROXIMATE_ELLIPSOID;
+ } else {
+ ERR(GRN_INVALID_ARGUMENT,
+ "geo distance approximate type must be one of "
+ "[rectangle, rect, sphere, sphr, ellipsoid, ellip]"
+ ": <%.*s>",
+ size, name);
+ }
+ }
+ GRN_OBJ_FIN(ctx, &approximate_type);
+
+ return rc;
+}
+
+typedef double (*grn_geo_distance_raw_func)(grn_ctx *ctx,
+ grn_geo_point *point1,
+ grn_geo_point *point2);
+
+grn_rc
+grn_selector_geo_in_circle(grn_ctx *ctx, grn_obj *table, grn_obj *index,
+ int nargs, grn_obj **args,
+ grn_obj *res, grn_operator op)
+{
+ grn_geo_approximate_type type = GRN_GEO_APPROXIMATE_RECTANGLE;
+
+ if (!(nargs == 4 || nargs == 5)) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "geo_in_circle(): requires 3 or 4 arguments but was <%d> arguments",
+ nargs - 1);
+ return ctx->rc;
+ }
+
+ if (!index) {
+ grn_obj *point_column;
+ char column_name[GRN_TABLE_MAX_KEY_SIZE];
+ int column_name_size;
+ point_column = args[1];
+ column_name_size = grn_obj_name(ctx, point_column,
+ column_name, GRN_TABLE_MAX_KEY_SIZE);
+ ERR(GRN_FUNCTION_NOT_IMPLEMENTED,
+ "geo_in_circle(): index for <%.*s> is missing",
+ column_name_size, column_name);
+ return ctx->rc;
+ }
+
+ if (nargs == 5) {
+ if (grn_geo_resolve_approximate_type(ctx, args[4], &type) != GRN_SUCCESS) {
+ return ctx->rc;
+ }
+ }
+
+ {
+ grn_obj *center_point, *distance;
+ center_point = args[2];
+ distance = args[3];
+ grn_geo_select_in_circle(ctx, index, center_point, distance, type, res, op);
+ }
+
+ return ctx->rc;
+}
+
+static grn_geo_distance_raw_func
+grn_geo_resolve_distance_raw_func (grn_ctx *ctx,
+ grn_geo_approximate_type approximate_type,
+ grn_id domain)
+{
+ grn_geo_distance_raw_func distance_raw_func = NULL;
+
+ switch (approximate_type) {
+ case GRN_GEO_APPROXIMATE_RECTANGLE :
+ distance_raw_func = grn_geo_distance_rectangle_raw;
+ break;
+ case GRN_GEO_APPROXIMATE_SPHERE :
+ distance_raw_func = grn_geo_distance_sphere_raw;
+ break;
+ case GRN_GEO_APPROXIMATE_ELLIPSOID :
+ if (domain == GRN_DB_WGS84_GEO_POINT) {
+ distance_raw_func = grn_geo_distance_ellipsoid_raw_wgs84;
+ } else {
+ distance_raw_func = grn_geo_distance_ellipsoid_raw_tokyo;
+ }
+ break;
+ default :
+ break;
+ }
+
+ return distance_raw_func;
+}
+
+grn_rc
+grn_geo_select_in_circle(grn_ctx *ctx, grn_obj *index,
+ grn_obj *center_point, grn_obj *distance,
+ grn_geo_approximate_type approximate_type,
+ grn_obj *res, grn_operator op)
+{
+ grn_id domain;
+ double center_longitude, center_latitude;
+ double d;
+ grn_obj *pat, *point_on_circle = NULL, center_point_, point_on_circle_;
+ 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];
+ int name_size = 0;
+ grn_obj *domain_object;
+ domain_object = grn_ctx_at(ctx, domain);
+ if (domain_object) {
+ name_size = grn_obj_name(ctx, domain_object, name, GRN_TABLE_MAX_KEY_SIZE);
+ grn_obj_unlink(ctx, domain_object);
+ } else {
+ grn_strcpy(name, GRN_TABLE_MAX_KEY_SIZE, "(null)");
+ name_size = strlen(name);
+ }
+ ERR(GRN_INVALID_ARGUMENT,
+ "geo_in_circle(): index table must be "
+ "TokyoGeoPoint or WGS84GeoPoint key type table: <%.*s>",
+ name_size, name);
+ goto exit;
+ }
+
+ if (center_point->header.domain != domain) {
+ GRN_OBJ_INIT(&center_point_, GRN_BULK, 0, domain);
+ if (grn_obj_cast(ctx, center_point, &center_point_, GRN_FALSE)) { goto exit; }
+ center_point = &center_point_;
+ }
+ center = GRN_GEO_POINT_VALUE_RAW(center_point);
+ center_longitude = GRN_GEO_INT2RAD(center->longitude);
+ center_latitude = GRN_GEO_INT2RAD(center->latitude);
+
+ distance_raw_func = grn_geo_resolve_distance_raw_func(ctx,
+ approximate_type,
+ domain);
+ if (!distance_raw_func) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "unknown approximate type: <%d>", approximate_type);
+ goto exit;
+ }
+
+ switch (distance->header.domain) {
+ case GRN_DB_INT32 :
+ d = GRN_INT32_VALUE(distance);
+ on_circle.latitude = center->latitude + GRN_GEO_RAD2INT(d / (double)GRN_GEO_RADIUS);
+ on_circle.longitude = center->longitude;
+ break;
+ case GRN_DB_UINT32 :
+ d = GRN_UINT32_VALUE(distance);
+ on_circle.latitude = center->latitude + GRN_GEO_RAD2INT(d / (double)GRN_GEO_RADIUS);
+ on_circle.longitude = center->longitude;
+ break;
+ case GRN_DB_INT64 :
+ d = GRN_INT64_VALUE(distance);
+ on_circle.latitude = center->latitude + GRN_GEO_RAD2INT(d / (double)GRN_GEO_RADIUS);
+ on_circle.longitude = center->longitude;
+ break;
+ case GRN_DB_UINT64 :
+ d = GRN_UINT64_VALUE(distance);
+ on_circle.latitude = center->latitude + GRN_GEO_RAD2INT(d / (double)GRN_GEO_RADIUS);
+ on_circle.longitude = center->longitude;
+ break;
+ case GRN_DB_FLOAT :
+ d = GRN_FLOAT_VALUE(distance);
+ on_circle.latitude = center->latitude + GRN_GEO_RAD2INT(d / (double)GRN_GEO_RADIUS);
+ on_circle.longitude = center->longitude;
+ break;
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ GRN_OBJ_INIT(&point_on_circle_, GRN_BULK, 0, domain);
+ if (grn_obj_cast(ctx, distance, &point_on_circle_, GRN_FALSE)) { goto exit; }
+ point_on_circle = &point_on_circle_;
+ /* fallthru */
+ case GRN_DB_TOKYO_GEO_POINT :
+ case GRN_DB_WGS84_GEO_POINT :
+ if (!point_on_circle) {
+ if (domain != distance->header.domain) { /* todo */ goto exit; }
+ point_on_circle = distance;
+ }
+ GRN_GEO_POINT_VALUE(point_on_circle,
+ on_circle.latitude, on_circle.longitude);
+ d = distance_raw_func(ctx, center, &on_circle);
+ if (point_on_circle == &point_on_circle_) {
+ grn_obj_unlink(ctx, point_on_circle);
+ }
+ break;
+ default :
+ goto exit;
+ }
+ {
+ int n_meshes, diff_bit;
+ double d_far;
+ mesh_entry meshes[87];
+ uint8_t geo_key1[sizeof(grn_geo_point)];
+ uint8_t geo_key2[sizeof(grn_geo_point)];
+
+ d_far = grn_geo_distance_rectangle_raw(ctx, center, &on_circle);
+ grn_gton(geo_key1, center, sizeof(grn_geo_point));
+ grn_gton(geo_key2, &on_circle, sizeof(grn_geo_point));
+ diff_bit = compute_diff_bit(geo_key1, geo_key2);
+#ifdef GEO_DEBUG
+ printf("center point: ");
+ grn_p_geo_point(ctx, center);
+ printf("point on circle: ");
+ grn_p_geo_point(ctx, &on_circle);
+ printf("diff: %d\n", diff_bit);
+#endif
+ if ((diff_bit % 2) == 1) {
+ diff_bit--;
+ }
+ n_meshes = grn_geo_get_meshes_for_circle(ctx, center,
+ d_far, diff_bit, GRN_TRUE,
+ meshes);
+ while (n_meshes--) {
+ grn_table_cursor *tc;
+ tc = grn_table_cursor_open(ctx, pat,
+ &(meshes[n_meshes].key),
+ meshes[n_meshes].key_size,
+ NULL, 0,
+ 0, -1,
+ GRN_CURSOR_PREFIX|GRN_CURSOR_SIZE_BY_BIT);
+ inspect_mesh_entry(ctx, meshes, n_meshes);
+ if (tc) {
+ grn_id tid;
+ grn_geo_point point;
+ while ((tid = grn_table_cursor_next(ctx, tc))) {
+ double point_distance;
+ grn_table_get_key(ctx, pat, tid, &point, sizeof(grn_geo_point));
+ point_distance = distance_raw_func(ctx, &point, center);
+ if (point_distance <= d) {
+ inspect_tid(ctx, tid, &point, point_distance);
+ grn_ii_at(ctx, (grn_ii *)index, tid, (grn_hash *)res, op);
+ }
+ }
+ grn_table_cursor_close(ctx, tc);
+ }
+ }
+ }
+exit :
+ grn_ii_resolve_sel_and(ctx, (grn_hash *)res, op);
+ return ctx->rc;
+}
+
+grn_rc
+grn_selector_geo_in_rectangle(grn_ctx *ctx, grn_obj *table, grn_obj *index,
+ int nargs, grn_obj **args,
+ grn_obj *res, grn_operator op)
+{
+ if (nargs == 4) {
+ grn_obj *top_left_point, *bottom_right_point;
+ top_left_point = args[2];
+ bottom_right_point = args[3];
+ grn_geo_select_in_rectangle(ctx, index,
+ top_left_point, bottom_right_point,
+ res, op);
+ } else {
+ ERR(GRN_INVALID_ARGUMENT,
+ "geo_in_rectangle(): requires 3 arguments but was <%d> arguments",
+ nargs - 1);
+ }
+ return ctx->rc;
+}
+
+static void
+in_rectangle_data_fill(grn_ctx *ctx, grn_obj *index,
+ grn_obj *top_left_point,
+ grn_obj *bottom_right_point,
+ const char *process_name,
+ in_rectangle_data *data)
+{
+ grn_id domain;
+ 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];
+ int name_size = 0;
+ grn_obj *domain_object;
+ domain_object = grn_ctx_at(ctx, domain);
+ if (domain_object) {
+ name_size = grn_obj_name(ctx, domain_object, name, GRN_TABLE_MAX_KEY_SIZE);
+ grn_obj_unlink(ctx, domain_object);
+ } else {
+ grn_strcpy(name, GRN_TABLE_MAX_KEY_SIZE, "(null)");
+ name_size = strlen(name);
+ }
+ ERR(GRN_INVALID_ARGUMENT,
+ "%s: index table must be "
+ "TokyoGeoPoint or WGS84GeoPoint key type table: <%.*s>",
+ process_name, name_size, name);
+ return;
+ }
+
+ if (domain == GRN_DB_TOKYO_GEO_POINT) {
+ domain_name = "TokyoGeoPoint";
+ } else {
+ domain_name = "WGS84GeoPoint";
+ }
+
+ if (top_left_point->header.domain != domain) {
+ grn_obj_reinit(ctx, &(data->top_left_point_buffer), domain, GRN_BULK);
+ if (grn_obj_cast(ctx, top_left_point, &(data->top_left_point_buffer),
+ GRN_FALSE)) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "%s: failed to cast to %s: <%.*s>",
+ process_name, domain_name,
+ (int)GRN_TEXT_LEN(top_left_point),
+ GRN_TEXT_VALUE(top_left_point));
+ return;
+ }
+ top_left_point = &(data->top_left_point_buffer);
+ }
+ data->top_left = GRN_GEO_POINT_VALUE_RAW(top_left_point);
+
+ if (bottom_right_point->header.domain != domain) {
+ grn_obj_reinit(ctx, &(data->bottom_right_point_buffer), domain, GRN_BULK);
+ if (grn_obj_cast(ctx, bottom_right_point, &(data->bottom_right_point_buffer),
+ GRN_FALSE)) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "%s: failed to cast to %s: <%.*s>",
+ process_name, domain_name,
+ (int)GRN_TEXT_LEN(bottom_right_point),
+ GRN_TEXT_VALUE(bottom_right_point));
+ return;
+ }
+ bottom_right_point = &(data->bottom_right_point_buffer);
+ }
+ data->bottom_right = GRN_GEO_POINT_VALUE_RAW(bottom_right_point);
+}
+
+static void
+in_rectangle_data_validate(grn_ctx *ctx,
+ const char *process_name,
+ in_rectangle_data *data)
+{
+ grn_geo_point *top_left, *bottom_right;
+
+ top_left = data->top_left;
+ bottom_right = data->bottom_right;
+
+ if (top_left->latitude >= GRN_GEO_MAX_LATITUDE) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "%s: top left point's latitude is too big: "
+ "<%d>(max:%d): (%d,%d) (%d,%d)",
+ process_name,
+ GRN_GEO_MAX_LATITUDE, top_left->latitude,
+ top_left->latitude, top_left->longitude,
+ bottom_right->latitude, bottom_right->longitude);
+ return;
+ }
+
+ if (top_left->latitude <= GRN_GEO_MIN_LATITUDE) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "%s: top left point's latitude is too small: "
+ "<%d>(min:%d): (%d,%d) (%d,%d)",
+ process_name,
+ GRN_GEO_MIN_LATITUDE, top_left->latitude,
+ top_left->latitude, top_left->longitude,
+ bottom_right->latitude, bottom_right->longitude);
+ return;
+ }
+
+ if (top_left->longitude >= GRN_GEO_MAX_LONGITUDE) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "%s: top left point's longitude is too big: "
+ "<%d>(max:%d): (%d,%d) (%d,%d)",
+ process_name,
+ GRN_GEO_MAX_LONGITUDE, top_left->longitude,
+ top_left->latitude, top_left->longitude,
+ bottom_right->latitude, bottom_right->longitude);
+ return;
+ }
+
+ if (top_left->longitude <= GRN_GEO_MIN_LONGITUDE) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "%s: top left point's longitude is too small: "
+ "<%d>(min:%d): (%d,%d) (%d,%d)",
+ process_name,
+ GRN_GEO_MIN_LONGITUDE, top_left->longitude,
+ top_left->latitude, top_left->longitude,
+ bottom_right->latitude, bottom_right->longitude);
+ return;
+ }
+
+ if (bottom_right->latitude >= GRN_GEO_MAX_LATITUDE) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "%s: bottom right point's latitude is too big: "
+ "<%d>(max:%d): (%d,%d) (%d,%d)",
+ process_name,
+ GRN_GEO_MAX_LATITUDE, bottom_right->latitude,
+ top_left->latitude, top_left->longitude,
+ bottom_right->latitude, bottom_right->longitude);
+ return;
+ }
+
+ if (bottom_right->latitude <= GRN_GEO_MIN_LATITUDE) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "%s: bottom right point's latitude is too small: "
+ "<%d>(min:%d): (%d,%d) (%d,%d)",
+ process_name,
+ GRN_GEO_MIN_LATITUDE, bottom_right->latitude,
+ top_left->latitude, top_left->longitude,
+ bottom_right->latitude, bottom_right->longitude);
+ return;
+ }
+
+ if (bottom_right->longitude >= GRN_GEO_MAX_LONGITUDE) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "%s: bottom right point's longitude is too big: "
+ "<%d>(max:%d): (%d,%d) (%d,%d)",
+ process_name,
+ GRN_GEO_MAX_LONGITUDE, bottom_right->longitude,
+ top_left->latitude, top_left->longitude,
+ bottom_right->latitude, bottom_right->longitude);
+ return;
+ }
+
+ if (bottom_right->longitude <= GRN_GEO_MIN_LONGITUDE) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "%s: bottom right point's longitude is too small: "
+ "<%d>(min:%d): (%d,%d) (%d,%d)",
+ process_name,
+ GRN_GEO_MIN_LONGITUDE, bottom_right->longitude,
+ top_left->latitude, top_left->longitude,
+ bottom_right->latitude, bottom_right->longitude);
+ return;
+ }
+}
+
+static void
+in_rectangle_area_data_compute(grn_ctx *ctx,
+ grn_geo_point *top_left,
+ grn_geo_point *bottom_right,
+ in_rectangle_area_data *data)
+{
+ int latitude_distance, longitude_distance;
+ int diff_bit;
+ grn_geo_point base;
+ grn_geo_point *geo_point_input;
+ uint8_t geo_key_input[sizeof(grn_geo_point)];
+ uint8_t geo_key_base[sizeof(grn_geo_point)];
+ uint8_t geo_key_top_left[sizeof(grn_geo_point)];
+ uint8_t geo_key_bottom_right[sizeof(grn_geo_point)];
+
+ latitude_distance = top_left->latitude - bottom_right->latitude;
+ longitude_distance = bottom_right->longitude - top_left->longitude;
+ if (latitude_distance > longitude_distance) {
+ geo_point_input = bottom_right;
+ base.latitude = bottom_right->latitude;
+ base.longitude = bottom_right->longitude - longitude_distance;
+ } else {
+ geo_point_input = top_left;
+ base.latitude = top_left->latitude - latitude_distance;
+ base.longitude = top_left->longitude;
+ }
+ grn_gton(geo_key_input, geo_point_input, sizeof(grn_geo_point));
+ grn_gton(geo_key_base, &base, sizeof(grn_geo_point));
+ diff_bit = compute_diff_bit(geo_key_input, geo_key_base);
+ compute_min_and_max(&base, diff_bit, &(data->min), &(data->max));
+
+ grn_gton(geo_key_top_left, top_left, sizeof(grn_geo_point));
+ grn_gton(geo_key_bottom_right, bottom_right, sizeof(grn_geo_point));
+ data->rectangle_common_bit =
+ compute_diff_bit(geo_key_top_left, geo_key_bottom_right) - 1;
+ compute_min_and_max_key(geo_key_top_left, data->rectangle_common_bit + 1,
+ data->rectangle_common_key, NULL);
+
+#ifdef GEO_DEBUG
+ printf("base: ");
+ grn_p_geo_point(ctx, &base);
+ printf("min: ");
+ grn_p_geo_point(ctx, &(data->min));
+ printf("max: ");
+ grn_p_geo_point(ctx, &(data->max));
+ printf("top-left: ");
+ grn_p_geo_point(ctx, top_left);
+ printf("bottom-right: ");
+ grn_p_geo_point(ctx, bottom_right);
+ printf("rectangle-common-bit:%10d\n", data->rectangle_common_bit);
+ printf("distance(latitude): %10d\n", latitude_distance);
+ printf("distance(longitude): %10d\n", longitude_distance);
+#endif
+}
+
+static grn_rc
+in_rectangle_data_prepare(grn_ctx *ctx, grn_obj *index,
+ grn_obj *top_left_point,
+ grn_obj *bottom_right_point,
+ const char *process_name,
+ in_rectangle_data *data)
+{
+ if (!index) {
+ ERR(GRN_FUNCTION_NOT_IMPLEMENTED,
+ "%s: index column is missing", process_name);
+ goto exit;
+ }
+
+ in_rectangle_data_fill(ctx, index, top_left_point, bottom_right_point,
+ process_name, data);
+ if (ctx->rc != GRN_SUCCESS) {
+ goto exit;
+ }
+
+ in_rectangle_data_validate(ctx, process_name, data);
+ if (ctx->rc != GRN_SUCCESS) {
+ goto exit;
+ }
+
+exit :
+ return ctx->rc;
+}
+
+#define SAME_BIT_P(a, b, n_bit)\
+ ((((uint8_t *)(a))[(n_bit) / 8] & (1 << (7 - ((n_bit) % 8)))) ==\
+ (((uint8_t *)(b))[(n_bit) / 8] & (1 << (7 - ((n_bit) % 8)))))
+
+#define CURSOR_ENTRY_UPDATE_STATUS(entry, name, other_key) do {\
+ if (SAME_BIT_P((entry)->key, (other_key), (entry)->target_bit)) {\
+ (entry)->status_flags |= GRN_GEO_CURSOR_ENTRY_STATUS_ ## name;\
+ } else {\
+ (entry)->status_flags &= ~GRN_GEO_CURSOR_ENTRY_STATUS_ ## name;\
+ }\
+} while (0)
+
+#define CURSOR_ENTRY_CHECK_STATUS(entry, name)\
+ ((entry)->status_flags & GRN_GEO_CURSOR_ENTRY_STATUS_ ## name)
+#define CURSOR_ENTRY_IS_INNER(entry)\
+ (((entry)->status_flags &\
+ (GRN_GEO_CURSOR_ENTRY_STATUS_LATITUDE_INNER |\
+ GRN_GEO_CURSOR_ENTRY_STATUS_LONGITUDE_INNER)) ==\
+ (GRN_GEO_CURSOR_ENTRY_STATUS_LATITUDE_INNER |\
+ GRN_GEO_CURSOR_ENTRY_STATUS_LONGITUDE_INNER))
+#define CURSOR_ENTRY_INCLUDED_IN_LATITUDE_DIRECTION(entry)\
+ ((entry)->status_flags &\
+ (GRN_GEO_CURSOR_ENTRY_STATUS_LATITUDE_INNER |\
+ GRN_GEO_CURSOR_ENTRY_STATUS_TOP_INCLUDED |\
+ GRN_GEO_CURSOR_ENTRY_STATUS_BOTTOM_INCLUDED))
+#define CURSOR_ENTRY_INCLUDED_IN_LONGITUDE_DIRECTION(entry)\
+ ((entry)->status_flags &\
+ (GRN_GEO_CURSOR_ENTRY_STATUS_LONGITUDE_INNER |\
+ GRN_GEO_CURSOR_ENTRY_STATUS_LEFT_INCLUDED |\
+ GRN_GEO_CURSOR_ENTRY_STATUS_RIGHT_INCLUDED))
+
+#define SET_N_BIT(a, n_bit)\
+ (((uint8_t *)(a))[((n_bit) / 8)] ^= (1 << (7 - ((n_bit) % 8))))
+
+#define N_BIT(a, n_bit)\
+ ((((uint8_t *)(a))[((n_bit) / 8)] &\
+ (1 << (7 - ((n_bit) % 8)))) >> (1 << (7 - ((n_bit) % 8))))
+
+static grn_bool
+extract_rectangle_in_area(grn_ctx *ctx,
+ grn_geo_area_type area_type,
+ const grn_geo_point *top_left,
+ const grn_geo_point *bottom_right,
+ grn_geo_point *area_top_left,
+ grn_geo_point *area_bottom_right)
+{
+ grn_bool out_of_area = GRN_FALSE;
+ grn_bool cover_all_areas = GRN_FALSE;
+
+ if ((GRN_GEO_POINT_IN_NORTH_WEST(top_left) &&
+ GRN_GEO_POINT_IN_SOUTH_EAST(bottom_right)) ||
+ (GRN_GEO_POINT_IN_NORTH_EAST(top_left) &&
+ GRN_GEO_POINT_IN_SOUTH_WEST(bottom_right))) {
+ cover_all_areas = GRN_TRUE;
+ }
+
+ switch (area_type) {
+ case GRN_GEO_AREA_NORTH_EAST :
+ if (cover_all_areas ||
+ GRN_GEO_POINT_IN_NORTH_EAST(top_left) ||
+ GRN_GEO_POINT_IN_NORTH_EAST(bottom_right)) {
+ area_top_left->latitude = MAX(top_left->latitude, 0);
+ area_bottom_right->latitude = MAX(bottom_right->latitude, 0);
+ if (GRN_GEO_LONGITUDE_IS_WRAPPED(top_left, bottom_right)) {
+ area_top_left->longitude = top_left->longitude;
+ area_bottom_right->longitude = GRN_GEO_MAX_LONGITUDE;
+ } else {
+ area_top_left->longitude = MAX(top_left->longitude, 0);
+ area_bottom_right->longitude = MAX(bottom_right->longitude, 0);
+ }
+ } else {
+ out_of_area = GRN_TRUE;
+ }
+ break;
+ case GRN_GEO_AREA_NORTH_WEST :
+ if (cover_all_areas ||
+ GRN_GEO_POINT_IN_NORTH_WEST(top_left) ||
+ GRN_GEO_POINT_IN_NORTH_WEST(bottom_right)) {
+ area_top_left->latitude = MAX(top_left->latitude, 0);
+ area_bottom_right->latitude = MAX(bottom_right->latitude, 0);
+ if (GRN_GEO_LONGITUDE_IS_WRAPPED(top_left, bottom_right)) {
+ area_top_left->longitude = GRN_GEO_MIN_LONGITUDE;
+ area_bottom_right->longitude = bottom_right->longitude;
+ } else {
+ area_top_left->longitude = MIN(top_left->longitude, -1);
+ area_bottom_right->longitude = MIN(bottom_right->longitude, -1);
+ }
+ } else {
+ out_of_area = GRN_TRUE;
+ }
+ break;
+ case GRN_GEO_AREA_SOUTH_WEST :
+ if (cover_all_areas ||
+ GRN_GEO_POINT_IN_SOUTH_WEST(top_left) ||
+ GRN_GEO_POINT_IN_SOUTH_WEST(bottom_right)) {
+ area_top_left->latitude = MIN(top_left->latitude, -1);
+ area_bottom_right->latitude = MIN(bottom_right->latitude, -1);
+ if (GRN_GEO_LONGITUDE_IS_WRAPPED(top_left, bottom_right)) {
+ area_top_left->longitude = GRN_GEO_MIN_LONGITUDE;
+ area_bottom_right->longitude = bottom_right->longitude;
+ } else {
+ area_top_left->longitude = MIN(top_left->longitude, -1);
+ area_bottom_right->longitude = MIN(bottom_right->longitude, -1);
+ }
+ } else {
+ out_of_area = GRN_TRUE;
+ }
+ break;
+ case GRN_GEO_AREA_SOUTH_EAST :
+ if (cover_all_areas ||
+ GRN_GEO_POINT_IN_SOUTH_EAST(top_left) ||
+ GRN_GEO_POINT_IN_SOUTH_EAST(bottom_right)) {
+ area_top_left->latitude = MIN(top_left->latitude, -1);
+ area_bottom_right->latitude = MIN(bottom_right->latitude, -1);
+ if (GRN_GEO_LONGITUDE_IS_WRAPPED(top_left, bottom_right)) {
+ area_top_left->longitude = top_left->longitude;
+ area_bottom_right->longitude = GRN_GEO_MAX_LONGITUDE;
+ } else {
+ area_top_left->longitude = MAX(top_left->longitude, 0);
+ area_bottom_right->longitude = MAX(bottom_right->longitude, 0);
+ }
+ } else {
+ out_of_area = GRN_TRUE;
+ }
+ break;
+ default :
+ out_of_area = GRN_TRUE;
+ break;
+ }
+
+ return out_of_area;
+}
+
+static void
+grn_geo_cursor_area_init(grn_ctx *ctx,
+ grn_geo_cursor_area *area,
+ grn_geo_area_type area_type,
+ const grn_geo_point *top_left,
+ const grn_geo_point *bottom_right)
+{
+ grn_geo_point area_top_left, area_bottom_right;
+ in_rectangle_area_data data;
+ grn_geo_cursor_entry *entry;
+ grn_bool out_of_area;
+
+ out_of_area = extract_rectangle_in_area(ctx,
+ area_type,
+ top_left,
+ bottom_right,
+ &area_top_left,
+ &area_bottom_right);
+ if (out_of_area) {
+ area->current_entry = -1;
+ return;
+ }
+
+ area->current_entry = 0;
+ grn_memcpy(&(area->top_left), &area_top_left, sizeof(grn_geo_point));
+ grn_memcpy(&(area->bottom_right), &area_bottom_right, sizeof(grn_geo_point));
+ grn_gton(area->top_left_key, &area_top_left, sizeof(grn_geo_point));
+ grn_gton(area->bottom_right_key, &area_bottom_right, sizeof(grn_geo_point));
+
+ entry = &(area->entries[area->current_entry]);
+ in_rectangle_area_data_compute(ctx,
+ &area_top_left,
+ &area_bottom_right,
+ &data);
+ entry->target_bit = data.rectangle_common_bit;
+ grn_memcpy(entry->key, data.rectangle_common_key, sizeof(grn_geo_point));
+ entry->status_flags =
+ GRN_GEO_CURSOR_ENTRY_STATUS_TOP_INCLUDED |
+ GRN_GEO_CURSOR_ENTRY_STATUS_BOTTOM_INCLUDED |
+ GRN_GEO_CURSOR_ENTRY_STATUS_LEFT_INCLUDED |
+ GRN_GEO_CURSOR_ENTRY_STATUS_RIGHT_INCLUDED;
+ if (data.min.latitude == area_bottom_right.latitude &&
+ data.max.latitude == area_top_left.latitude) {
+ entry->status_flags |= GRN_GEO_CURSOR_ENTRY_STATUS_LATITUDE_INNER;
+ }
+ if (data.min.longitude == area_top_left.longitude &&
+ data.max.longitude == area_bottom_right.longitude) {
+ entry->status_flags |= GRN_GEO_CURSOR_ENTRY_STATUS_LONGITUDE_INNER;
+ }
+}
+
+grn_obj *
+grn_geo_cursor_open_in_rectangle(grn_ctx *ctx,
+ grn_obj *index,
+ grn_obj *top_left_point,
+ grn_obj *bottom_right_point,
+ int offset,
+ int limit)
+{
+ grn_geo_cursor_in_rectangle *cursor = NULL;
+ in_rectangle_data data;
+
+ GRN_API_ENTER;
+ GRN_VOID_INIT(&(data.top_left_point_buffer));
+ GRN_VOID_INIT(&(data.bottom_right_point_buffer));
+ if (in_rectangle_data_prepare(ctx, index, top_left_point, bottom_right_point,
+ "geo_in_rectangle()", &data)) {
+ goto exit;
+ }
+
+ cursor = GRN_MALLOCN(grn_geo_cursor_in_rectangle, 1);
+ if (!cursor) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[geo][cursor][in-rectangle] failed to allocate memory for geo cursor");
+ goto exit;
+ }
+
+ cursor->pat = data.pat;
+ cursor->index = index;
+ grn_memcpy(&(cursor->top_left), data.top_left, sizeof(grn_geo_point));
+ grn_memcpy(&(cursor->bottom_right), data.bottom_right, sizeof(grn_geo_point));
+ cursor->pat_cursor = NULL;
+ cursor->ii_cursor = NULL;
+ cursor->offset = offset;
+ cursor->rest = limit;
+
+ cursor->current_area = GRN_GEO_AREA_NORTH_EAST;
+ {
+ grn_geo_area_type area_type;
+ const grn_geo_point *top_left = &(cursor->top_left);
+ const grn_geo_point *bottom_right = &(cursor->bottom_right);
+ for (area_type = GRN_GEO_AREA_NORTH_EAST;
+ area_type < GRN_GEO_AREA_LAST;
+ area_type++) {
+ grn_geo_cursor_area_init(ctx, &(cursor->areas[area_type]),
+ area_type, top_left, bottom_right);
+ }
+ }
+ {
+ char minimum_reduce_bit_env[GRN_ENV_BUFFER_SIZE];
+ cursor->minimum_reduce_bit = 0;
+ grn_getenv("GRN_GEO_IN_RECTANGLE_MINIMUM_REDUCE_BIT",
+ minimum_reduce_bit_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (minimum_reduce_bit_env[0]) {
+ cursor->minimum_reduce_bit = atoi(minimum_reduce_bit_env);
+ }
+ if (cursor->minimum_reduce_bit < 1) {
+ cursor->minimum_reduce_bit = 1;
+ }
+ }
+ GRN_DB_OBJ_SET_TYPE(cursor, GRN_CURSOR_COLUMN_GEO_INDEX);
+ {
+ grn_obj *db;
+ grn_id id;
+ db = grn_ctx_db(ctx);
+ id = grn_obj_register(ctx, db, NULL, 0);
+ DB_OBJ(cursor)->header.domain = GRN_ID_NIL;
+ DB_OBJ(cursor)->range = GRN_ID_NIL;
+ grn_db_obj_init(ctx, db, id, DB_OBJ(cursor));
+ }
+
+exit :
+ grn_obj_unlink(ctx, &(data.top_left_point_buffer));
+ grn_obj_unlink(ctx, &(data.bottom_right_point_buffer));
+ GRN_API_RETURN((grn_obj *)cursor);
+}
+
+static inline grn_bool
+grn_geo_cursor_entry_next_push(grn_ctx *ctx,
+ grn_geo_cursor_in_rectangle *cursor,
+ grn_geo_cursor_entry *entry)
+{
+ grn_geo_cursor_entry *next_entry;
+ grn_geo_point entry_base;
+ grn_table_cursor *pat_cursor;
+ grn_bool pushed = GRN_FALSE;
+
+ grn_ntog((uint8_t*)(&entry_base), entry->key, sizeof(grn_geo_point));
+ pat_cursor = grn_table_cursor_open(ctx,
+ cursor->pat,
+ &entry_base,
+ entry->target_bit + 1,
+ NULL, 0,
+ 0, -1,
+ GRN_CURSOR_PREFIX|GRN_CURSOR_SIZE_BY_BIT);
+ if (pat_cursor) {
+ if (grn_table_cursor_next(ctx, pat_cursor)) {
+ grn_geo_cursor_area *area;
+ area = &(cursor->areas[cursor->current_area]);
+ next_entry = &(area->entries[++area->current_entry]);
+ grn_memcpy(next_entry, entry, sizeof(grn_geo_cursor_entry));
+ pushed = GRN_TRUE;
+ }
+ grn_table_cursor_close(ctx, pat_cursor);
+ }
+
+ return pushed;
+}
+
+static inline grn_bool
+grn_geo_cursor_entry_next(grn_ctx *ctx,
+ grn_geo_cursor_in_rectangle *cursor,
+ grn_geo_cursor_entry *entry)
+{
+ uint8_t *top_left_key;
+ uint8_t *bottom_right_key;
+ int max_target_bit = GRN_GEO_KEY_MAX_BITS - cursor->minimum_reduce_bit;
+ grn_geo_cursor_area *area = NULL;
+
+ while (cursor->current_area < GRN_GEO_AREA_LAST) {
+ area = &(cursor->areas[cursor->current_area]);
+ if (area->current_entry >= 0) {
+ break;
+ }
+ cursor->current_area++;
+ area = NULL;
+ }
+
+ if (!area) {
+ return GRN_FALSE;
+ }
+
+ top_left_key = area->top_left_key;
+ bottom_right_key = area->bottom_right_key;
+ grn_memcpy(entry,
+ &(area->entries[area->current_entry--]),
+ sizeof(grn_geo_cursor_entry));
+ while (GRN_TRUE) {
+ grn_geo_cursor_entry next_entry0, next_entry1;
+ grn_bool pushed = GRN_FALSE;
+
+ /*
+ top_left_key: tl
+ bottom_right_key: br
+
+ e.g.: top_left_key is at the top left sub mesh and
+ bottom_right_key is at the bottom right sub mesh.
+ top_left_key is also at the top left - bottom right
+ sub-sub mesh and
+ bottom_right_key is at the bottom right - bottom left
+ sub-sub mesh.
+
+ ^latitude +----+----+----+----+
+ | 1 |1010|1011|1110|1111|
+ | | | | | |
+ | 1 +----+----+----+----+
+ \/ 0 |1000|1001|1100|1101|
+ | | tl | | |
+ +----+----+----+----+
+ 1 |0010|0011|0110|0111|
+ | | | | |
+ 0 +----+----+----+----+
+ 0 |0000|0001|0100|0101|
+ | | | br | |
+ +----+----+----+----+
+ 0 1 0 1
+ |-------| |-------|
+ 0 1
+ <------>
+ longitude
+
+ entry.target_bit + 1 -> next_entry0
+ entry.target_bit + 1 and entry.key ^ (entry.target_bit + 1) in bit
+ -> next_entry1
+
+ entry: represents the biggest mesh.
+ (1010, 1011, 1110, 1111,
+ 1000, 1001, 1100, 1101,
+ 0010, 0011, 0110, 0111,
+ 0000, 0001, 0100, 0101)
+ next_entry0: represents bottom sub-mesh.
+ (0010, 0011, 0110, 0111,
+ 0000, 0001, 0100, 0101)
+ next_entry1: represents top sub-mesh.
+ (1010, 1011, 1110, 1111,
+ 1000, 1001, 1100, 1101)
+
+ entry->status_flags = TOP_INCLUDED |
+ BOTTOM_INCLUDED |
+ LEFT_INCLUDED |
+ RIGHT_INCLUDED
+ next_entry0->status_flags = BOTTOM_INCLUDED |
+ LEFT_INCLUDED |
+ RIGHT_INCLUDED
+ next_entry1->status_flags = TOP_INCLUDED |
+ LEFT_INCLUDED |
+ RIGHT_INCLUDED
+
+ Both next_entry1 and next_entry0 are pushed to the stack in cursor.
+ */
+
+#ifdef GEO_DEBUG
+ inspect_cursor_entry(ctx, entry);
+#endif
+
+ if (entry->target_bit >= max_target_bit) {
+#ifdef GEO_DEBUG
+ printf("%d: force stopping to reduce a mesh\n", entry->target_bit);
+#endif
+ break;
+ }
+
+ if (CURSOR_ENTRY_IS_INNER(entry)) {
+#ifdef GEO_DEBUG
+ printf("%d: inner entries\n", entry->target_bit);
+#endif
+ break;
+ }
+
+ grn_memcpy(&next_entry0, entry, sizeof(grn_geo_cursor_entry));
+ next_entry0.target_bit++;
+ grn_memcpy(&next_entry1, entry, sizeof(grn_geo_cursor_entry));
+ next_entry1.target_bit++;
+ SET_N_BIT(next_entry1.key, next_entry1.target_bit);
+
+#ifdef GEO_DEBUG
+ inspect_cursor_entry_targets(ctx, entry, top_left_key, bottom_right_key,
+ &next_entry0, &next_entry1);
+#endif
+
+ if ((entry->target_bit + 1) % 2 == 0) {
+ if (CURSOR_ENTRY_CHECK_STATUS(entry, TOP_INCLUDED)) {
+ CURSOR_ENTRY_UPDATE_STATUS(&next_entry0, TOP_INCLUDED, top_left_key);
+ CURSOR_ENTRY_UPDATE_STATUS(&next_entry1, TOP_INCLUDED, top_left_key);
+ }
+ if (CURSOR_ENTRY_CHECK_STATUS(entry, BOTTOM_INCLUDED)) {
+ CURSOR_ENTRY_UPDATE_STATUS(&next_entry0, BOTTOM_INCLUDED,
+ bottom_right_key);
+ CURSOR_ENTRY_UPDATE_STATUS(&next_entry1, BOTTOM_INCLUDED,
+ bottom_right_key);
+ }
+
+ if (CURSOR_ENTRY_CHECK_STATUS(entry, TOP_INCLUDED) &&
+ !CURSOR_ENTRY_CHECK_STATUS(entry, BOTTOM_INCLUDED) &&
+ CURSOR_ENTRY_CHECK_STATUS(&next_entry1, TOP_INCLUDED)) {
+ next_entry0.status_flags |= GRN_GEO_CURSOR_ENTRY_STATUS_LATITUDE_INNER;
+ } else if (!CURSOR_ENTRY_CHECK_STATUS(entry, TOP_INCLUDED) &&
+ CURSOR_ENTRY_CHECK_STATUS(entry, BOTTOM_INCLUDED) &&
+ CURSOR_ENTRY_CHECK_STATUS(&next_entry0, BOTTOM_INCLUDED)) {
+ next_entry1.status_flags |= GRN_GEO_CURSOR_ENTRY_STATUS_LATITUDE_INNER;
+ }
+
+ if (CURSOR_ENTRY_INCLUDED_IN_LATITUDE_DIRECTION(&next_entry1)) {
+ if (grn_geo_cursor_entry_next_push(ctx, cursor, &next_entry1)) {
+ pushed = GRN_TRUE;
+#ifdef GEO_DEBUG
+ printf("%d: latitude: push 1\n", next_entry1.target_bit);
+#endif
+ }
+ }
+ if (CURSOR_ENTRY_INCLUDED_IN_LATITUDE_DIRECTION(&next_entry0)) {
+ if (grn_geo_cursor_entry_next_push(ctx, cursor, &next_entry0)) {
+ pushed = GRN_TRUE;
+#ifdef GEO_DEBUG
+ printf("%d: latitude: push 0\n", next_entry0.target_bit);
+#endif
+ }
+ }
+ } else {
+ if (CURSOR_ENTRY_CHECK_STATUS(entry, RIGHT_INCLUDED)) {
+ CURSOR_ENTRY_UPDATE_STATUS(&next_entry0, RIGHT_INCLUDED,
+ bottom_right_key);
+ CURSOR_ENTRY_UPDATE_STATUS(&next_entry1, RIGHT_INCLUDED,
+ bottom_right_key);
+ }
+ if (CURSOR_ENTRY_CHECK_STATUS(entry, LEFT_INCLUDED)) {
+ CURSOR_ENTRY_UPDATE_STATUS(&next_entry0, LEFT_INCLUDED, top_left_key);
+ CURSOR_ENTRY_UPDATE_STATUS(&next_entry1, LEFT_INCLUDED, top_left_key);
+ }
+
+ if (CURSOR_ENTRY_CHECK_STATUS(entry, LEFT_INCLUDED) &&
+ !CURSOR_ENTRY_CHECK_STATUS(entry, RIGHT_INCLUDED) &&
+ CURSOR_ENTRY_CHECK_STATUS(&next_entry0, LEFT_INCLUDED)) {
+ next_entry1.status_flags |= GRN_GEO_CURSOR_ENTRY_STATUS_LONGITUDE_INNER;
+ } else if (!CURSOR_ENTRY_CHECK_STATUS(entry, LEFT_INCLUDED) &&
+ CURSOR_ENTRY_CHECK_STATUS(entry, RIGHT_INCLUDED) &&
+ CURSOR_ENTRY_CHECK_STATUS(&next_entry1, RIGHT_INCLUDED)) {
+ next_entry0.status_flags |= GRN_GEO_CURSOR_ENTRY_STATUS_LONGITUDE_INNER;
+ }
+
+ if (CURSOR_ENTRY_INCLUDED_IN_LONGITUDE_DIRECTION(&next_entry1)) {
+ if (grn_geo_cursor_entry_next_push(ctx, cursor, &next_entry1)) {
+ pushed = GRN_TRUE;
+#ifdef GEO_DEBUG
+ printf("%d: longitude: push 1\n", next_entry1.target_bit);
+#endif
+ }
+ }
+ if (CURSOR_ENTRY_INCLUDED_IN_LONGITUDE_DIRECTION(&next_entry0)) {
+ if (grn_geo_cursor_entry_next_push(ctx, cursor, &next_entry0)) {
+ pushed = GRN_TRUE;
+#ifdef GEO_DEBUG
+ printf("%d: longitude: push 0\n", next_entry0.target_bit);
+#endif
+ }
+ }
+ }
+
+ if (pushed) {
+#ifdef GEO_DEBUG
+ int i;
+
+ printf("%d: pushed\n", entry->target_bit);
+ printf("stack:\n");
+ for (i = area->current_entry; i >= 0; i--) {
+ grn_geo_cursor_entry *stack_entry;
+ stack_entry = &(area->entries[i]);
+ printf("%2d: ", i);
+ inspect_key(ctx, stack_entry->key);
+ printf(" ");
+ print_key_mark(ctx, stack_entry->target_bit);
+ }
+#endif
+ grn_memcpy(entry,
+ &(area->entries[area->current_entry--]),
+ sizeof(grn_geo_cursor_entry));
+#ifdef GEO_DEBUG
+ printf("%d: pop entry\n", entry->target_bit);
+#endif
+ } else {
+ break;
+ }
+ }
+
+#ifdef GEO_DEBUG
+ printf("found:\n");
+ inspect_cursor_entry(ctx, entry);
+#endif
+
+ return GRN_TRUE;
+}
+
+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,
+ grn_geo_cursor_callback callback, void *user_data)
+{
+ grn_geo_cursor_in_rectangle *cursor;
+ grn_obj *pat;
+ grn_table_cursor *pat_cursor;
+ grn_ii *ii;
+ grn_ii_cursor *ii_cursor;
+ grn_posting *posting = NULL;
+ grn_geo_point *current, *top_left, *bottom_right;
+ grn_id index_id;
+
+ cursor = (grn_geo_cursor_in_rectangle *)geo_cursor;
+ if (cursor->rest == 0) {
+ return;
+ }
+
+ pat = cursor->pat;
+ pat_cursor = cursor->pat_cursor;
+ ii = (grn_ii *)(cursor->index);
+ ii_cursor = cursor->ii_cursor;
+ current = &(cursor->current);
+ top_left = &(cursor->top_left);
+ bottom_right = &(cursor->bottom_right);
+
+ while (GRN_TRUE) {
+ if (!pat_cursor) {
+ grn_geo_cursor_entry entry;
+ grn_geo_point entry_base;
+ if (!grn_geo_cursor_entry_next(ctx, cursor, &entry)) {
+ cursor->rest = 0;
+ return;
+ }
+ grn_ntog((uint8_t*)(&entry_base), entry.key, sizeof(grn_geo_point));
+ if (!(cursor->pat_cursor = pat_cursor =
+ grn_table_cursor_open(ctx,
+ pat,
+ &entry_base,
+ entry.target_bit + 1,
+ NULL, 0,
+ 0, -1,
+ GRN_CURSOR_PREFIX|GRN_CURSOR_SIZE_BY_BIT))) {
+ cursor->rest = 0;
+ return;
+ }
+#ifdef GEO_DEBUG
+ inspect_mesh(ctx, &entry_base, entry.target_bit, 0);
+#endif
+ }
+
+ while (ii_cursor || (index_id = grn_table_cursor_next(ctx, pat_cursor))) {
+ if (!ii_cursor) {
+ grn_table_get_key(ctx, pat, index_id, current, sizeof(grn_geo_point));
+ if (grn_geo_in_rectangle_raw(ctx, current, top_left, bottom_right)) {
+ inspect_tid(ctx, index_id, current, 0);
+ if (!(cursor->ii_cursor = ii_cursor =
+ grn_ii_cursor_open(ctx,
+ ii,
+ index_id,
+ GRN_ID_NIL,
+ GRN_ID_MAX,
+ ii->n_elements,
+ 0))) {
+ continue;
+ }
+ } else {
+ continue;
+ }
+ }
+
+ while ((posting = grn_ii_cursor_next(ctx, ii_cursor))) {
+ if (cursor->offset == 0) {
+ grn_bool keep_each;
+ keep_each = callback(ctx, posting, user_data);
+ if (cursor->rest > 0) {
+ if (--(cursor->rest) == 0) {
+ keep_each = GRN_FALSE;
+ }
+ }
+ if (!keep_each) {
+ return;
+ }
+ } else {
+ cursor->offset--;
+ }
+ }
+ grn_ii_cursor_close(ctx, ii_cursor);
+ cursor->ii_cursor = ii_cursor = NULL;
+ }
+ grn_table_cursor_close(ctx, pat_cursor);
+ cursor->pat_cursor = pat_cursor = NULL;
+ }
+}
+
+static grn_bool
+grn_geo_cursor_next_callback(grn_ctx *ctx, grn_posting *posting,
+ void *user_data)
+{
+ grn_posting **return_posting = user_data;
+ *return_posting = posting;
+ return GRN_FALSE;
+}
+
+grn_posting *
+grn_geo_cursor_next(grn_ctx *ctx, grn_obj *geo_cursor)
+{
+ grn_posting *posting = NULL;
+ grn_geo_cursor_each(ctx, geo_cursor, grn_geo_cursor_next_callback, &posting);
+ return (grn_posting *)posting;
+}
+
+grn_rc
+grn_geo_cursor_close(grn_ctx *ctx, grn_obj *geo_cursor)
+{
+ grn_geo_cursor_in_rectangle *cursor;
+
+ if (!geo_cursor) { return GRN_INVALID_ARGUMENT; }
+
+ cursor = (grn_geo_cursor_in_rectangle *)geo_cursor;
+ if (cursor->pat) { grn_obj_unlink(ctx, cursor->pat); }
+ if (cursor->index) { grn_obj_unlink(ctx, cursor->index); }
+ if (cursor->pat_cursor) { grn_table_cursor_close(ctx, cursor->pat_cursor); }
+ if (cursor->ii_cursor) { grn_ii_cursor_close(ctx, cursor->ii_cursor); }
+ GRN_FREE(cursor);
+
+ return GRN_SUCCESS;
+}
+
+typedef struct {
+ grn_hash *res;
+ grn_operator op;
+} grn_geo_select_in_rectangle_data;
+
+static grn_bool
+grn_geo_select_in_rectangle_callback(grn_ctx *ctx, grn_posting *posting,
+ void *user_data)
+{
+ grn_geo_select_in_rectangle_data *data = user_data;
+ grn_ii_posting_add(ctx, posting, data->res, data->op);
+ return GRN_TRUE;
+}
+
+grn_rc
+grn_geo_select_in_rectangle(grn_ctx *ctx, grn_obj *index,
+ grn_obj *top_left_point,
+ grn_obj *bottom_right_point,
+ grn_obj *res, grn_operator op)
+{
+ grn_obj *cursor;
+
+ cursor = grn_geo_cursor_open_in_rectangle(ctx, index,
+ top_left_point, bottom_right_point,
+ 0, -1);
+ if (cursor) {
+ grn_geo_select_in_rectangle_data data;
+ data.res = (grn_hash *)res;
+ data.op = op;
+ grn_geo_cursor_each(ctx, cursor, grn_geo_select_in_rectangle_callback,
+ &data);
+ grn_obj_unlink(ctx, cursor);
+ grn_ii_resolve_sel_and(ctx, (grn_hash *)res, op);
+ }
+
+ return ctx->rc;
+}
+
+static grn_rc
+geo_point_get(grn_ctx *ctx, grn_obj *pat, int flags, grn_geo_point *geo_point)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_id id;
+ grn_table_cursor *cursor = NULL;
+
+ cursor = grn_table_cursor_open(ctx, pat,
+ NULL, 0,
+ NULL, 0,
+ 0, 1,
+ GRN_CURSOR_BY_KEY | flags);
+ if (!cursor) {
+ rc = ctx->rc;
+ goto exit;
+ }
+
+ id = grn_table_cursor_next(ctx, cursor);
+ if (id == GRN_ID_NIL) {
+ rc = GRN_END_OF_DATA;
+ } else {
+ void *key;
+ int key_size;
+ key_size = grn_table_cursor_get_key(ctx, cursor, &key);
+ grn_memcpy(geo_point, key, key_size);
+ }
+
+exit:
+ if (cursor) {
+ grn_table_cursor_close(ctx, cursor);
+ }
+ return rc;
+}
+
+uint32_t
+grn_geo_estimate_size_in_rectangle(grn_ctx *ctx,
+ grn_obj *index,
+ grn_obj *top_left_point,
+ grn_obj *bottom_right_point)
+{
+ uint32_t n = 0;
+ int total_records;
+ grn_rc rc;
+ in_rectangle_data data;
+
+ GRN_VOID_INIT(&(data.top_left_point_buffer));
+ GRN_VOID_INIT(&(data.bottom_right_point_buffer));
+ if (in_rectangle_data_prepare(ctx, index, top_left_point, bottom_right_point,
+ "grn_geo_estimate_in_rectangle()", &data)) {
+ goto exit;
+ }
+
+ total_records = grn_table_size(ctx, data.pat);
+ if (total_records > 0) {
+ grn_geo_point min, max;
+ int select_latitude_distance, select_longitude_distance;
+ int total_latitude_distance, total_longitude_distance;
+ double select_ratio;
+ double estimated_n_records;
+ in_rectangle_area_data area_data;
+
+ rc = geo_point_get(ctx, data.pat, GRN_CURSOR_ASCENDING, &min);
+ if (!rc) {
+ rc = geo_point_get(ctx, data.pat, GRN_CURSOR_DESCENDING, &max);
+ }
+ if (rc) {
+ if (rc == GRN_END_OF_DATA) {
+ n = total_records;
+ rc = GRN_SUCCESS;
+ }
+ goto exit;
+ }
+
+ in_rectangle_area_data_compute(ctx,
+ data.top_left,
+ data.bottom_right,
+ &area_data);
+ select_latitude_distance =
+ abs(area_data.max.latitude - area_data.min.latitude);
+ select_longitude_distance =
+ abs(area_data.max.longitude - area_data.min.longitude);
+ total_latitude_distance = abs(max.latitude - min.latitude);
+ total_longitude_distance = abs(max.longitude - min.longitude);
+
+ select_ratio = 1.0;
+ if (select_latitude_distance < total_latitude_distance) {
+ select_ratio *= ((double)select_latitude_distance /
+ (double)total_latitude_distance);
+ }
+ if (select_longitude_distance < total_longitude_distance) {
+ select_ratio *= ((double)select_longitude_distance /
+ (double)total_longitude_distance);
+ }
+ estimated_n_records = ceil(total_records * select_ratio);
+ n = (uint32_t)estimated_n_records;
+ }
+
+exit :
+ grn_obj_unlink(ctx, &(data.top_left_point_buffer));
+ grn_obj_unlink(ctx, &(data.bottom_right_point_buffer));
+ return n;
+}
+
+int
+grn_geo_estimate_in_rectangle(grn_ctx *ctx,
+ grn_obj *index,
+ grn_obj *top_left_point,
+ grn_obj *bottom_right_point)
+{
+ uint32_t size;
+
+ size = grn_geo_estimate_size_in_rectangle(ctx,
+ index,
+ top_left_point,
+ bottom_right_point);
+ if (ctx->rc != GRN_SUCCESS) {
+ return -1;
+ }
+
+ return size;
+}
+
+grn_bool
+grn_geo_in_circle(grn_ctx *ctx, grn_obj *point, grn_obj *center,
+ grn_obj *radius_or_point,
+ grn_geo_approximate_type approximate_type)
+{
+ grn_bool r = GRN_FALSE;
+ grn_obj center_, radius_or_point_;
+ grn_id domain = point->header.domain;
+ if (domain == GRN_DB_TOKYO_GEO_POINT || domain == GRN_DB_WGS84_GEO_POINT) {
+ grn_geo_distance_raw_func distance_raw_func;
+ double d;
+ if (center->header.domain != domain) {
+ GRN_OBJ_INIT(&center_, GRN_BULK, 0, domain);
+ if (grn_obj_cast(ctx, center, &center_, GRN_FALSE)) { goto exit; }
+ center = &center_;
+ }
+
+ distance_raw_func = grn_geo_resolve_distance_raw_func(ctx,
+ approximate_type,
+ domain);
+ if (!distance_raw_func) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "unknown approximate type: <%d>", approximate_type);
+ goto exit;
+ }
+ d = distance_raw_func(ctx,
+ GRN_GEO_POINT_VALUE_RAW(point),
+ GRN_GEO_POINT_VALUE_RAW(center));
+ switch (radius_or_point->header.domain) {
+ case GRN_DB_INT32 :
+ r = d <= GRN_INT32_VALUE(radius_or_point);
+ break;
+ case GRN_DB_UINT32 :
+ r = d <= GRN_UINT32_VALUE(radius_or_point);
+ break;
+ case GRN_DB_INT64 :
+ r = d <= GRN_INT64_VALUE(radius_or_point);
+ break;
+ case GRN_DB_UINT64 :
+ r = d <= GRN_UINT64_VALUE(radius_or_point);
+ break;
+ case GRN_DB_FLOAT :
+ r = d <= GRN_FLOAT_VALUE(radius_or_point);
+ break;
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ GRN_OBJ_INIT(&radius_or_point_, GRN_BULK, 0, domain);
+ if (grn_obj_cast(ctx, radius_or_point, &radius_or_point_, GRN_FALSE)) { goto exit; }
+ radius_or_point = &radius_or_point_;
+ /* fallthru */
+ case GRN_DB_TOKYO_GEO_POINT :
+ case GRN_DB_WGS84_GEO_POINT :
+ if (domain != radius_or_point->header.domain) { /* todo */ goto exit; }
+ r = d <= distance_raw_func(ctx,
+ GRN_GEO_POINT_VALUE_RAW(radius_or_point),
+ GRN_GEO_POINT_VALUE_RAW(center));
+ break;
+ default :
+ goto exit;
+ }
+ } else {
+ /* todo */
+ }
+exit :
+ return r;
+}
+
+grn_bool
+grn_geo_in_rectangle_raw(grn_ctx *ctx, grn_geo_point *point,
+ grn_geo_point *top_left, grn_geo_point *bottom_right)
+{
+ if (point->latitude > top_left->latitude) {
+ return GRN_FALSE;
+ }
+ if (point->latitude < bottom_right->latitude) {
+ return GRN_FALSE;
+ }
+
+ if (GRN_GEO_LONGITUDE_IS_WRAPPED(top_left, bottom_right)) {
+ if (point->longitude >= top_left->longitude) {
+ return GRN_TRUE;
+ }
+ if (point->longitude <= bottom_right->longitude) {
+ return GRN_TRUE;
+ }
+ return GRN_FALSE;
+ } else {
+ if (point->longitude < top_left->longitude) {
+ return GRN_FALSE;
+ }
+ if (point->longitude > bottom_right->longitude) {
+ return GRN_FALSE;
+ }
+ return GRN_TRUE;
+ }
+}
+
+grn_bool
+grn_geo_in_rectangle(grn_ctx *ctx, grn_obj *point,
+ grn_obj *top_left, grn_obj *bottom_right)
+{
+ grn_bool r = GRN_FALSE;
+ grn_obj top_left_, bottom_right_;
+ grn_id domain = point->header.domain;
+ if (domain == GRN_DB_TOKYO_GEO_POINT || domain == GRN_DB_WGS84_GEO_POINT) {
+ if (top_left->header.domain != domain) {
+ GRN_OBJ_INIT(&top_left_, GRN_BULK, 0, domain);
+ if (grn_obj_cast(ctx, top_left, &top_left_, GRN_FALSE)) { goto exit; }
+ top_left = &top_left_;
+ }
+ if (bottom_right->header.domain != domain) {
+ GRN_OBJ_INIT(&bottom_right_, GRN_BULK, 0, domain);
+ if (grn_obj_cast(ctx, bottom_right, &bottom_right_, GRN_FALSE)) { goto exit; }
+ bottom_right = &bottom_right_;
+ }
+ r = grn_geo_in_rectangle_raw(ctx,
+ GRN_GEO_POINT_VALUE_RAW(point),
+ GRN_GEO_POINT_VALUE_RAW(top_left),
+ GRN_GEO_POINT_VALUE_RAW(bottom_right));
+ } else {
+ /* todo */
+ }
+exit :
+ return r;
+}
+
+typedef enum {
+ LONGITUDE_SHORT,
+ LONGITUDE_LONG,
+} distance_type;
+
+typedef enum {
+ QUADRANT_1ST,
+ QUADRANT_2ND,
+ QUADRANT_3RD,
+ QUADRANT_4TH,
+ QUADRANT_1ST_TO_2ND,
+ QUADRANT_1ST_TO_3RD,
+ QUADRANT_1ST_TO_4TH,
+ QUADRANT_2ND_TO_1ST,
+ QUADRANT_2ND_TO_3RD,
+ QUADRANT_2ND_TO_4TH,
+ QUADRANT_3RD_TO_1ST,
+ QUADRANT_3RD_TO_2ND,
+ QUADRANT_3RD_TO_4TH,
+ QUADRANT_4TH_TO_1ST,
+ QUADRANT_4TH_TO_2ND,
+ QUADRANT_4TH_TO_3RD,
+} quadrant_type;
+
+static distance_type
+geo_longitude_distance_type(int start_longitude, int end_longitude)
+{
+ int diff_longitude;
+ int east_to_west;
+ int west_to_east;
+ if (start_longitude >= 0) {
+ diff_longitude = abs(start_longitude - end_longitude);
+ } else {
+ diff_longitude = abs(end_longitude - start_longitude);
+ }
+ east_to_west = start_longitude > 0 && end_longitude < 0;
+ west_to_east = start_longitude < 0 && end_longitude > 0;
+ if (start_longitude != end_longitude &&
+ (east_to_west || west_to_east) &&
+ diff_longitude > 180 * GRN_GEO_RESOLUTION) {
+ return LONGITUDE_LONG;
+ } else {
+ return LONGITUDE_SHORT;
+ }
+}
+
+static inline quadrant_type
+geo_quadrant_type(grn_geo_point *point1, grn_geo_point *point2)
+{
+#define QUADRANT_1ST_WITH_AXIS(point) \
+ (point->longitude >= 0) && (point->latitude >= 0)
+#define QUADRANT_2ND_WITH_AXIS(point) \
+ (point->longitude <= 0) && (point->latitude >= 0)
+#define QUADRANT_3RD_WITH_AXIS(point) \
+ (point->longitude <= 0) && (point->latitude <= 0)
+#define QUADRANT_4TH_WITH_AXIS(point) \
+ (point->longitude >= 0) && (point->latitude <= 0)
+
+ if (QUADRANT_1ST_WITH_AXIS(point1) && QUADRANT_1ST_WITH_AXIS(point2)) {
+ return QUADRANT_1ST;
+ } else if (QUADRANT_2ND_WITH_AXIS(point1) && QUADRANT_2ND_WITH_AXIS(point2)) {
+ return QUADRANT_2ND;
+ } else if (QUADRANT_3RD_WITH_AXIS(point1) && QUADRANT_3RD_WITH_AXIS(point2)) {
+ return QUADRANT_3RD;
+ } else if (QUADRANT_4TH_WITH_AXIS(point1) && QUADRANT_4TH_WITH_AXIS(point2)) {
+ return QUADRANT_4TH;
+ } else {
+ if (point1->longitude > 0 && point2->longitude < 0 &&
+ point1->latitude >= 0 && point2->latitude >= 0) {
+ return QUADRANT_1ST_TO_2ND;
+ } else if (point1->longitude < 0 && point2->longitude > 0 &&
+ point1->latitude >= 0 && point2->latitude >= 0) {
+ return QUADRANT_2ND_TO_1ST;
+ } else if (point1->longitude < 0 && point2->longitude > 0 &&
+ point1->latitude <= 0 && point2->latitude <= 0) {
+ return QUADRANT_3RD_TO_4TH;
+ } else if (point1->longitude > 0 && point2->longitude < 0 &&
+ point1->latitude <= 0 && point2->latitude <= 0) {
+ return QUADRANT_4TH_TO_3RD;
+ } else if (point1->longitude >= 0 && point2->longitude >= 0 &&
+ point1->latitude > 0 && point2->latitude < 0) {
+ return QUADRANT_1ST_TO_4TH;
+ } else if (point1->longitude >= 0 && point2->longitude >= 0 &&
+ point1->latitude < 0 && point2->latitude > 0) {
+ return QUADRANT_4TH_TO_1ST;
+ } else if (point1->longitude <= 0 && point2->longitude <= 0 &&
+ point1->latitude > 0 && point2->latitude < 0) {
+ return QUADRANT_2ND_TO_3RD;
+ } else if (point1->longitude <= 0 && point2->longitude <= 0 &&
+ point1->latitude < 0 && point2->latitude > 0) {
+ return QUADRANT_3RD_TO_2ND;
+ } else if (point1->longitude >= 0 && point2->longitude <= 0 &&
+ point1->latitude > 0 && point2->latitude < 0) {
+ return QUADRANT_1ST_TO_3RD;
+ } else if (point1->longitude <= 0 && point2->longitude >= 0 &&
+ point1->latitude < 0 && point2->latitude > 0) {
+ return QUADRANT_3RD_TO_1ST;
+ } else if (point1->longitude <= 0 && point2->longitude >= 0 &&
+ point1->latitude > 0 && point2->latitude < 0) {
+ return QUADRANT_2ND_TO_4TH;
+ } else if (point1->longitude >= 0 && point2->longitude <= 0 &&
+ point1->latitude < 0 && point2->latitude > 0) {
+ return QUADRANT_4TH_TO_2ND;
+ } else {
+ /* FIXME */
+ return QUADRANT_1ST;
+ }
+ }
+#undef QUADRANT_1ST_WITH_AXIS
+#undef QUADRANT_2ND_WITH_AXIS
+#undef QUADRANT_3RD_WITH_AXIS
+#undef QUADRANT_4TH_WITH_AXIS
+}
+
+static inline double
+geo_distance_rectangle_square_root(double start_longitude, double start_latitude,
+ double end_longitude, double end_latitude)
+{
+ double diff_longitude;
+ double x, y;
+
+ diff_longitude = end_longitude - start_longitude;
+ x = diff_longitude * cos((start_latitude + end_latitude) * 0.5);
+ y = end_latitude - start_latitude;
+ return sqrt((x * x) + (y * y));
+}
+
+static inline double
+geo_distance_rectangle_short_dist_type(quadrant_type quad_type,
+ double lng1, double lat1,
+ double lng2, double lat2)
+{
+ double distance;
+ double longitude_delta, latitude_delta;
+
+ if (quad_type == QUADRANT_1ST_TO_4TH ||
+ quad_type == QUADRANT_4TH_TO_1ST ||
+ quad_type == QUADRANT_2ND_TO_3RD ||
+ quad_type == QUADRANT_3RD_TO_2ND) {
+ longitude_delta = lng2 - lng1;
+ if (longitude_delta > 0 || longitude_delta < 0) {
+ if (lat2 > lat1) {
+ distance = geo_distance_rectangle_square_root(lng1,
+ lat1,
+ lng2,
+ lat2) * GRN_GEO_RADIUS;
+ } else {
+ distance = geo_distance_rectangle_square_root(lng2,
+ lat2,
+ lng1,
+ lat1) * GRN_GEO_RADIUS;
+ }
+ } else {
+ latitude_delta = fabs(lat1) + fabs(lat2);
+ distance = sqrt(latitude_delta * latitude_delta) * GRN_GEO_RADIUS;
+ }
+ } else if (quad_type == QUADRANT_1ST_TO_3RD ||
+ quad_type == QUADRANT_2ND_TO_4TH) {
+ distance = geo_distance_rectangle_square_root(lng1,
+ lat1,
+ lng2,
+ lat2) * GRN_GEO_RADIUS;
+ } else if (quad_type == QUADRANT_3RD_TO_1ST ||
+ quad_type == QUADRANT_4TH_TO_2ND) {
+ distance = geo_distance_rectangle_square_root(lng2,
+ lat2,
+ lng1,
+ lat1) * GRN_GEO_RADIUS;
+ } else if (quad_type == QUADRANT_1ST_TO_2ND ||
+ quad_type == QUADRANT_2ND_TO_1ST ||
+ quad_type == QUADRANT_3RD_TO_4TH ||
+ quad_type == QUADRANT_4TH_TO_3RD) {
+ if (lat2 > lat1) {
+ distance = geo_distance_rectangle_square_root(lng1,
+ lat1,
+ lng2,
+ lat2) * GRN_GEO_RADIUS;
+ } else if (lat2 < lat1) {
+ distance = geo_distance_rectangle_square_root(lng2,
+ lat2,
+ lng1,
+ lat1) * GRN_GEO_RADIUS;
+ } else {
+ longitude_delta = lng2 - lng1;
+ distance = longitude_delta * cos(lat1);
+ distance = sqrt(distance * distance) * GRN_GEO_RADIUS;
+ }
+ } else {
+ distance = geo_distance_rectangle_square_root(lng1,
+ lat1,
+ lng2,
+ lat2) * GRN_GEO_RADIUS;
+ }
+ return distance;
+}
+
+static inline double
+geo_distance_rectangle_long_dist_type(quadrant_type quad_type,
+ double lng1, double lat1,
+ double lng2, double lat2)
+{
+#define M_2PI 6.28318530717958647692
+
+ double distance;
+
+ if (quad_type == QUADRANT_1ST_TO_2ND ||
+ quad_type == QUADRANT_4TH_TO_3RD) {
+ if (lat1 > lat2) {
+ distance = geo_distance_rectangle_square_root(lng2 + M_2PI,
+ lat2,
+ lng1,
+ lat1) * GRN_GEO_RADIUS;
+ } else {
+ distance = geo_distance_rectangle_square_root(lng1,
+ lat1,
+ lng2 + M_2PI,
+ lat2) * GRN_GEO_RADIUS;
+ }
+ } else if (quad_type == QUADRANT_2ND_TO_1ST ||
+ quad_type == QUADRANT_3RD_TO_4TH) {
+ if (lat1 > lat2) {
+ distance = geo_distance_rectangle_square_root(lng2,
+ lat2,
+ lng1 + M_2PI,
+ lat1) * GRN_GEO_RADIUS;
+ } else {
+ distance = geo_distance_rectangle_square_root(lng1 + M_2PI,
+ lat1,
+ lng2,
+ lat2) * GRN_GEO_RADIUS;
+ }
+ } else if (quad_type == QUADRANT_1ST_TO_3RD) {
+ distance = geo_distance_rectangle_square_root(lng2 + M_2PI,
+ lat2,
+ lng1,
+ lat1) * GRN_GEO_RADIUS;
+ } else if (quad_type == QUADRANT_3RD_TO_1ST) {
+ distance = geo_distance_rectangle_square_root(lng1 + M_2PI,
+ lat1,
+ lng2,
+ lat2) * GRN_GEO_RADIUS;
+ } else if (quad_type == QUADRANT_2ND_TO_4TH) {
+ distance = geo_distance_rectangle_square_root(lng2,
+ lat2,
+ lng1 + M_2PI,
+ lat1) * GRN_GEO_RADIUS;
+ } else if (quad_type == QUADRANT_4TH_TO_2ND) {
+ distance = geo_distance_rectangle_square_root(lng1,
+ lat1,
+ lng2 + M_2PI,
+ lat2) * GRN_GEO_RADIUS;
+ } else {
+ if (lng1 > lng2) {
+ distance = geo_distance_rectangle_square_root(lng1,
+ lat1,
+ lng2 + M_2PI,
+ lat2) * GRN_GEO_RADIUS;
+ } else {
+ distance = geo_distance_rectangle_square_root(lng2,
+ lat2,
+ lng1 + M_2PI,
+ lat1) * GRN_GEO_RADIUS;
+ }
+ }
+ return distance;
+#undef M_2PI
+}
+
+double
+grn_geo_distance_rectangle_raw(grn_ctx *ctx,
+ grn_geo_point *point1, grn_geo_point *point2)
+{
+
+ double lng1, lat1, lng2, lat2, distance;
+ distance_type dist_type;
+ quadrant_type quad_type;
+
+ lat1 = GRN_GEO_INT2RAD(point1->latitude);
+ lng1 = GRN_GEO_INT2RAD(point1->longitude);
+ lat2 = GRN_GEO_INT2RAD(point2->latitude);
+ lng2 = GRN_GEO_INT2RAD(point2->longitude);
+ quad_type = geo_quadrant_type(point1, point2);
+ if (quad_type <= QUADRANT_4TH) {
+ distance = geo_distance_rectangle_square_root(lng1,
+ lat1,
+ lng2,
+ lat2) * GRN_GEO_RADIUS;
+ } else {
+ dist_type = geo_longitude_distance_type(point1->longitude,
+ point2->longitude);
+ if (dist_type == LONGITUDE_SHORT) {
+ distance = geo_distance_rectangle_short_dist_type(quad_type,
+ lng1, lat1,
+ lng2, lat2);
+ } else {
+ distance = geo_distance_rectangle_long_dist_type(quad_type,
+ lng1, lat1,
+ lng2, lat2);
+ }
+ }
+ return distance;
+}
+
+double
+grn_geo_distance_sphere_raw(grn_ctx *ctx,
+ grn_geo_point *point1, grn_geo_point *point2)
+{
+ double lng1, lat1, lng2, lat2, x, y;
+
+ lat1 = GRN_GEO_INT2RAD(point1->latitude);
+ lng1 = GRN_GEO_INT2RAD(point1->longitude);
+ lat2 = GRN_GEO_INT2RAD(point2->latitude);
+ lng2 = GRN_GEO_INT2RAD(point2->longitude);
+ x = sin(fabs(lng2 - lng1) * 0.5);
+ y = sin(fabs(lat2 - lat1) * 0.5);
+ return asin(sqrt((y * y) + cos(lat1) * cos(lat2) * x * x)) * 2 * GRN_GEO_RADIUS;
+}
+
+double
+grn_geo_distance_ellipsoid_raw(grn_ctx *ctx,
+ grn_geo_point *point1, grn_geo_point *point2,
+ int c1, int c2, double c3)
+{
+ double lng1, lat1, lng2, lat2, p, q, r, m, n, x, y;
+
+ lat1 = GRN_GEO_INT2RAD(point1->latitude);
+ lng1 = GRN_GEO_INT2RAD(point1->longitude);
+ lat2 = GRN_GEO_INT2RAD(point2->latitude);
+ lng2 = GRN_GEO_INT2RAD(point2->longitude);
+ p = (lat1 + lat2) * 0.5;
+ q = (1 - c3 * sin(p) * sin(p));
+ r = sqrt(q);
+ m = c1 / (q * r);
+ n = c2 / r;
+ x = n * cos(p) * fabs(lng1 - lng2);
+ y = m * fabs(lat1 - lat2);
+ return sqrt((x * x) + (y * y));
+}
+
+double
+grn_geo_distance_ellipsoid_raw_tokyo(grn_ctx *ctx,
+ grn_geo_point *point1,
+ grn_geo_point *point2)
+{
+ return grn_geo_distance_ellipsoid_raw(ctx, point1, point2,
+ GRN_GEO_BES_C1,
+ GRN_GEO_BES_C2,
+ GRN_GEO_BES_C3);
+}
+
+double
+grn_geo_distance_ellipsoid_raw_wgs84(grn_ctx *ctx,
+ grn_geo_point *point1,
+ grn_geo_point *point2)
+{
+ return grn_geo_distance_ellipsoid_raw(ctx, point1, point2,
+ GRN_GEO_GRS_C1,
+ GRN_GEO_GRS_C2,
+ GRN_GEO_GRS_C3);
+}
+
+double
+grn_geo_distance(grn_ctx *ctx, grn_obj *point1, grn_obj *point2,
+ grn_geo_approximate_type type)
+{
+ double d = 0.0;
+
+ switch (type) {
+ case GRN_GEO_APPROXIMATE_RECTANGLE :
+ d = grn_geo_distance_rectangle(ctx, point1, point2);
+ break;
+ case GRN_GEO_APPROXIMATE_SPHERE :
+ d = grn_geo_distance_sphere(ctx, point1, point2);
+ break;
+ case GRN_GEO_APPROXIMATE_ELLIPSOID :
+ d = grn_geo_distance_ellipsoid(ctx, point1, point2);
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "unknown approximate type: <%d>", type);
+ break;
+ }
+ return d;
+}
+
+double
+grn_geo_distance_rectangle(grn_ctx *ctx, grn_obj *point1, grn_obj *point2)
+{
+ double d = 0;
+ grn_bool point1_initialized = GRN_FALSE;
+ grn_bool point2_initialized = GRN_FALSE;
+ grn_obj point1_, point2_;
+ grn_id domain1 = point1->header.domain;
+ grn_id domain2 = point2->header.domain;
+ if (domain1 == GRN_DB_TOKYO_GEO_POINT || domain1 == GRN_DB_WGS84_GEO_POINT) {
+ if (domain1 != domain2) {
+ GRN_OBJ_INIT(&point2_, GRN_BULK, 0, domain1);
+ point2_initialized = GRN_TRUE;
+ if (grn_obj_cast(ctx, point2, &point2_, GRN_FALSE)) { goto exit; }
+ point2 = &point2_;
+ }
+ } else if (domain2 == GRN_DB_TOKYO_GEO_POINT ||
+ domain2 == GRN_DB_WGS84_GEO_POINT) {
+ GRN_OBJ_INIT(&point1_, GRN_BULK, 0, domain2);
+ point1_initialized = GRN_TRUE;
+ if (grn_obj_cast(ctx, point1, &point1_, GRN_FALSE)) { goto exit; }
+ point1 = &point1_;
+ } else if ((GRN_DB_SHORT_TEXT <= domain1 && domain1 <= GRN_DB_LONG_TEXT) &&
+ (GRN_DB_SHORT_TEXT <= domain2 && domain2 <= GRN_DB_LONG_TEXT)) {
+ GRN_OBJ_INIT(&point1_, GRN_BULK, 0, GRN_DB_WGS84_GEO_POINT);
+ point1_initialized = GRN_TRUE;
+ if (grn_obj_cast(ctx, point1, &point1_, GRN_FALSE)) { goto exit; }
+ point1 = &point1_;
+
+ GRN_OBJ_INIT(&point2_, GRN_BULK, 0, GRN_DB_WGS84_GEO_POINT);
+ point2_initialized = GRN_TRUE;
+ if (grn_obj_cast(ctx, point2, &point2_, GRN_FALSE)) { goto exit; }
+ point2 = &point2_;
+ } else {
+ goto exit;
+ }
+ d = grn_geo_distance_rectangle_raw(ctx,
+ GRN_GEO_POINT_VALUE_RAW(point1),
+ GRN_GEO_POINT_VALUE_RAW(point2));
+exit :
+ if (point1_initialized) {
+ GRN_OBJ_FIN(ctx, &point1_);
+ }
+ if (point2_initialized) {
+ GRN_OBJ_FIN(ctx, &point2_);
+ }
+ return d;
+}
+
+double
+grn_geo_distance_sphere(grn_ctx *ctx, grn_obj *point1, grn_obj *point2)
+{
+ double d = 0;
+ grn_bool point2_initialized = GRN_FALSE;
+ grn_obj point2_;
+ grn_id domain = point1->header.domain;
+ if (domain == GRN_DB_TOKYO_GEO_POINT || domain == GRN_DB_WGS84_GEO_POINT) {
+ if (point2->header.domain != domain) {
+ GRN_OBJ_INIT(&point2_, GRN_BULK, 0, domain);
+ point2_initialized = GRN_TRUE;
+ if (grn_obj_cast(ctx, point2, &point2_, GRN_FALSE)) { goto exit; }
+ point2 = &point2_;
+ }
+ d = grn_geo_distance_sphere_raw(ctx,
+ GRN_GEO_POINT_VALUE_RAW(point1),
+ GRN_GEO_POINT_VALUE_RAW(point2));
+ } else {
+ /* todo */
+ }
+exit :
+ if (point2_initialized) {
+ GRN_OBJ_FIN(ctx, &point2_);
+ }
+ return d;
+}
+
+double
+grn_geo_distance_ellipsoid(grn_ctx *ctx, grn_obj *point1, grn_obj *point2)
+{
+ double d = 0;
+ grn_bool point2_initialized = GRN_FALSE;
+ grn_obj point2_;
+ grn_id domain = point1->header.domain;
+ if (domain == GRN_DB_TOKYO_GEO_POINT || domain == GRN_DB_WGS84_GEO_POINT) {
+ if (point2->header.domain != domain) {
+ GRN_OBJ_INIT(&point2_, GRN_BULK, 0, domain);
+ point2_initialized = GRN_TRUE;
+ if (grn_obj_cast(ctx, point2, &point2_, GRN_FALSE)) { goto exit; }
+ point2 = &point2_;
+ }
+ if (domain == GRN_DB_TOKYO_GEO_POINT) {
+ d = grn_geo_distance_ellipsoid_raw_tokyo(ctx,
+ GRN_GEO_POINT_VALUE_RAW(point1),
+ GRN_GEO_POINT_VALUE_RAW(point2));
+ } else {
+ d = grn_geo_distance_ellipsoid_raw_wgs84(ctx,
+ GRN_GEO_POINT_VALUE_RAW(point1),
+ GRN_GEO_POINT_VALUE_RAW(point2));
+ }
+ } else {
+ /* todo */
+ }
+exit :
+ if (point2_initialized) {
+ GRN_OBJ_FIN(ctx, &point2_);
+ }
+ return d;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/grn.h b/storage/mroonga/vendor/groonga/lib/grn.h
new file mode 100644
index 00000000..17a8c4e6
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn.h
@@ -0,0 +1,759 @@
+/* -*- 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 as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+#pragma once
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#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>
+#include <stdint.h>
+
+#include <sys/types.h>
+
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif /* HAVE_SYS_PARAM_H */
+
+#ifdef HAVE_SYS_MMAN_H
+# include <sys/mman.h>
+#endif /* HAVE_SYS_MMAN_H */
+
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif /* HAVE_SYS_TIME_H */
+
+#ifdef HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif /* HAVE_SYS_RESOURCE_H */
+
+#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 */
+#else
+# define GRN_API
+# define GRN_VAR extern
+#endif
+
+#ifdef WIN32
+# include <basetsd.h>
+# include <process.h>
+# include <winsock2.h>
+# include <ws2tcpip.h>
+# include <windows.h>
+# include <stddef.h>
+# include <windef.h>
+# include <float.h>
+# include <time.h>
+# include <sys/types.h>
+
+# ifndef __GNUC__
+# define PATH_MAX (MAX_PATH - 1)
+# ifndef __cplusplus
+# define inline _inline
+# endif
+# endif
+
+# ifndef __GNUC__
+typedef SSIZE_T ssize_t;
+typedef int pid_t;
+typedef int64_t off64_t;
+# endif
+
+# undef MSG_WAITALL
+# define MSG_WAITALL 0 /* before Vista, not supported... */
+# define SHUT_RDWR SD_BOTH
+
+typedef SOCKET grn_sock;
+# define grn_sock_close(sock) closesocket(sock)
+
+# define CALLBACK __stdcall
+
+# ifndef __GNUC__
+# include <intrin.h>
+# include <sys/timeb.h>
+# include <errno.h>
+# endif
+
+#else /* WIN32 */
+
+# define GROONGA_API
+
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif /* HAVE_UNISTD_H */
+
+# ifndef __off64_t_defined
+typedef off_t off64_t;
+# endif
+
+# ifndef PATH_MAX
+# if defined(MAXPATHLEN)
+# define PATH_MAX MAXPATHLEN
+# else /* MAXPATHLEN */
+# define PATH_MAX 1024
+# endif /* MAXPATHLEN */
+# endif /* PATH_MAX */
+# ifndef INT_LEAST8_MAX
+typedef char int_least8_t;
+# endif /* INT_LEAST8_MAX */
+# ifndef UINT_LEAST8_MAX
+typedef unsigned char uint_least8_t;
+# endif /* UINT_LEAST8_MAX */
+typedef int grn_sock;
+# define grn_sock_close(sock) close(sock)
+# define CALLBACK
+
+#endif /* WIN32 */
+
+#ifndef INT8_MAX
+# define INT8_MAX (127)
+#endif /* INT8_MAX */
+
+#ifndef INT8_MIN
+# define INT8_MIN (-128)
+#endif /* INT8_MIN */
+
+#ifndef INT16_MAX
+# define INT16_MAX (32767)
+#endif /* INT16_MAX */
+
+#ifndef INT16_MIN
+# define INT16_MIN (-32768)
+#endif /* INT16_MIN */
+
+#ifndef INT32_MAX
+# define INT32_MAX (2147483647)
+#endif /* INT32_MAX */
+
+#ifndef INT32_MIN
+# define INT32_MIN (-2147483648)
+#endif /* INT32_MIN */
+
+#ifndef UINT32_MAX
+# define UINT32_MAX (4294967295)
+#endif /* UINT32_MAX */
+
+#ifndef INT64_MAX
+# define INT64_MAX (9223372036854775807)
+#endif /* INT64_MAX */
+
+#ifndef INT64_MIN
+# define INT64_MIN (-9223372036854775808)
+#endif /* INT64_MIN */
+
+
+#ifdef WIN32
+# define grn_lseek(fd, offset, whence) _lseeki64(fd, offset, whence)
+#else /* WIN32 */
+# define grn_lseek(fd, offset, whence) lseek(fd, offset, whence)
+#endif /* WIN32 */
+
+
+#ifdef HAVE_PTHREAD_H
+# include <pthread.h>
+typedef pthread_t grn_thread;
+typedef void * grn_thread_func_result;
+# define GRN_THREAD_FUNC_RETURN_VALUE NULL
+# define THREAD_CREATE(thread,func,arg) \
+ (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_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;\
+ pthread_mutexattr_init(&mutexattr);\
+ pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);\
+ pthread_mutex_init(&m, &mutexattr);\
+} while (0)
+# else
+# define MUTEX_INIT_SHARED MUTEX_INIT
+# endif /* HAVE_PTHREAD_MUTEXATTR_SETPSHARED */
+
+typedef pthread_mutex_t grn_critical_section;
+# define CRITICAL_SECTION_INIT(cs) pthread_mutex_init(&(cs), NULL)
+# define CRITICAL_SECTION_ENTER(cs) pthread_mutex_lock(&(cs))
+# define CRITICAL_SECTION_LEAVE(cs) pthread_mutex_unlock(&(cs))
+# define CRITICAL_SECTION_FIN(cs)
+
+typedef pthread_cond_t grn_cond;
+# define COND_INIT(c) pthread_cond_init(&c, NULL)
+# define COND_SIGNAL(c) pthread_cond_signal(&c)
+# define COND_WAIT(c,m) pthread_cond_wait(&c, &m)
+# define COND_BROADCAST(c) pthread_cond_broadcast(&c)
+# ifdef HAVE_PTHREAD_CONDATTR_SETPSHARED
+# define COND_INIT_SHARED(c) do {\
+ pthread_condattr_t condattr;\
+ pthread_condattr_init(&condattr);\
+ pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED);\
+ pthread_cond_init(&c, &condattr);\
+} while (0)
+# 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)
+# define THREAD_KEY_DELETE(key) pthread_key_delete(key)
+# define THREAD_SETSPECIFIC(key, value) pthread_setspecific(key, value)
+# define THREAD_GETSPECIFIC(key) pthread_getspecific(key)
+
+#if defined(USE_UYIELD)
+ extern int grn_uyield_count;
+ #define GRN_TEST_YIELD() do {\
+ if (((++grn_uyield_count) & (0x20 - 1)) == 0) {\
+ sched_yield();\
+ if (grn_uyield_count > 0x1000) {\
+ grn_uyield_count = (uint32_t)time(NULL) % 0x1000;\
+ }\
+ }\
+ } while (0)
+
+ #undef assert
+ #define assert(assert_expr) do {\
+ if (!(assert_expr)){\
+ fprintf(stderr, "assertion failed: %s\n", #assert_expr);\
+ abort();\
+ }\
+ GRN_TEST_YIELD();\
+ } while (0)
+
+ #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))
+
+ #if !defined(_POSIX_PRIORITY_SCHEDULING)
+ #define sched_yield() grn_nanosleep(1000000 * 20)
+ #endif
+# else /* USE_UYIELD */
+ #define GRN_TEST_YIELD() do {} while (0)
+# endif /* USE_UYIELD */
+
+#else /* HAVE_PTHREAD_H */
+
+/* todo */
+typedef int grn_thread_key;
+# define THREAD_KEY_CREATE(key,destr)
+# define THREAD_KEY_DELETE(key)
+# define THREAD_SETSPECIFIC(key)
+# define THREAD_GETSPECIFIC(key,value)
+
+# ifdef WIN32
+typedef uintptr_t grn_thread;
+typedef unsigned int grn_thread_func_result;
+# define GRN_THREAD_FUNC_RETURN_VALUE 0
+# define THREAD_CREATE(thread,func,arg) \
+ (((thread)=_beginthreadex(NULL, 0, (func), (arg), 0, NULL)) == (grn_thread)0)
+# 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_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))
+# define CRITICAL_SECTION_LEAVE(cs) LeaveCriticalSection(&(cs))
+# define CRITICAL_SECTION_FIN(cs) DeleteCriticalSection(&(cs))
+
+typedef struct
+{
+ int waiters_count_;
+ HANDLE waiters_count_lock_;
+ HANDLE sema_;
+ HANDLE waiters_done_;
+ size_t was_broadcast_;
+} grn_cond;
+
+# define COND_INIT(c) do { \
+ (c).waiters_count_ = 0; \
+ (c).sema_ = CreateSemaphore(NULL, 0, 0x7fffffff, NULL); \
+ MUTEX_INIT((c).waiters_count_lock_); \
+ (c).waiters_done_ = CreateEvent(NULL, FALSE, FALSE, NULL); \
+} while (0)
+
+# define COND_SIGNAL(c) do { \
+ MUTEX_LOCK((c).waiters_count_lock_); \
+ { \
+ int have_waiters = (c).waiters_count_ > 0; \
+ MUTEX_UNLOCK((c).waiters_count_lock_); \
+ if (have_waiters) { \
+ ReleaseSemaphore((c).sema_, 1, 0); \
+ } \
+ } \
+} while (0)
+
+# define COND_BROADCAST(c) do { \
+ MUTEX_LOCK((c).waiters_count_lock_); \
+ { \
+ int have_waiters = (c).waiters_count_ > 0; \
+ if ((c).waiters_count_ > 0) { \
+ (c).was_broadcast_ = 1; \
+ have_waiters = 1; \
+ } \
+ if (have_waiters) { \
+ ReleaseSemaphore((c).sema_, (c).waiters_count_, 0); \
+ MUTEX_UNLOCK((c).waiters_count_lock_); \
+ WaitForSingleObject((c).waiters_done_, INFINITE); \
+ (c).was_broadcast_ = 0; \
+ } \
+ else { \
+ MUTEX_UNLOCK((c).waiters_count_lock_); \
+ } \
+ } \
+} while (0)
+
+# define COND_WAIT(c,m) do { \
+ MUTEX_LOCK((c).waiters_count_lock_); \
+ (c).waiters_count_++; \
+ MUTEX_UNLOCK((c).waiters_count_lock_); \
+ SignalObjectAndWait((m), (c).sema_, INFINITE, FALSE); \
+ MUTEX_LOCK((c).waiters_count_lock_); \
+ (c).waiters_count_--; \
+ { \
+ int last_waiter = (c).was_broadcast_ && (c).waiters_count_ == 0; \
+ MUTEX_UNLOCK((c).waiters_count_lock_); \
+ if (last_waiter) { \
+ SignalObjectAndWait((c).waiters_done_, (m), INFINITE, FALSE); \
+ } \
+ else { \
+ WaitForSingleObject((m), FALSE); \
+ } \
+ } \
+} 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;
+# define COND_INIT(c) ((c) = 0)
+# define COND_SIGNAL(c)
+# define COND_WAIT(c,m) do { \
+ MUTEX_UNLOCK(m); \
+ grn_nanosleep(1000000); \
+ MUTEX_LOCK(m); \
+} while (0)
+# define COND_FIN(c)
+/* todo : must be enhanced! */
+
+# endif /* WIN32 */
+
+# define MUTEX_INIT_SHARED MUTEX_INIT
+# define COND_INIT_SHARED COND_INIT
+
+# define GRN_TEST_YIELD() do {} while (0)
+
+#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>
+# define GRN_FMT_INT32D PRId32
+# define GRN_FMT_INT32U PRIu32
+# define GRN_FMT_INT64D PRId64
+# define GRN_FMT_INT64U PRIu64
+#else /* HAVE_INTTYPES_H */
+# ifdef WIN32
+# define GRN_FMT_INT32D "I32d"
+# define GRN_FMT_INT32U "I32u"
+# define GRN_FMT_INT64D "I64d"
+# define GRN_FMT_INT64U "I64u"
+# else /* WIN32 */
+# define GRN_FMT_INT32D "d"
+# define GRN_FMT_INT32U "u"
+# ifdef __x86_64__
+# define GRN_FMT_INT64D "ld"
+# define GRN_FMT_INT64U "lu"
+# else /* __x86_64__ */
+# define GRN_FMT_INT64D "lld"
+# define GRN_FMT_INT64U "llu"
+# endif /* __x86_64__ */
+# endif /* WIN32 */
+#endif /* HAVE_INTTYPES_H */
+
+#ifdef WIN32
+# define GRN_FMT_LLD "I64d"
+# define GRN_FMT_LLU "I64u"
+# define GRN_FMT_SIZE "Iu"
+# 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 GRN_FMT_INT32U
+# define GRN_FMT_DWORD "u"
+# endif /* WIN64 */
+# define GRN_FMT_OFF64_T GRN_FMT_LLD
+#else /* WIN32 */
+# define GRN_FMT_LLD "lld"
+# define GRN_FMT_LLU "llu"
+# define GRN_FMT_SIZE "zu"
+# define GRN_FMT_SSIZE "zd"
+# define GRN_FMT_SOCKET "d"
+# define GRN_FMT_OFF64_T "jd"
+#endif /* WIN32 */
+
+#ifdef __GNUC__
+# if (defined(__i386__) || defined(__x86_64__)) /* ATOMIC ADD */
+/*
+ * GRN_ATOMIC_ADD_EX() performs { r = *p; *p += i; } atomically.
+ */
+# define GRN_ATOMIC_ADD_EX(p, i, r) \
+ __asm__ __volatile__ ("lock xaddl %0, %1" : "=r"(r), "+m"(*p) : "0"(i))
+/*
+ * GRN_BIT_SCAN_REV() finds the most significant 1 bit of `v'. Then, `r' is set
+ * to the index of the found bit. Note that `v' must not be 0.
+ */
+# define GRN_BIT_SCAN_REV(v, r) \
+ __asm__ __volatile__ ("bsrl %1, %%eax; movl %%eax, %0" : "=r"(r) : "r"(v) : "%eax")
+/*
+ * GRN_BIT_SCAN_REV0() is similar to GRN_BIT_SCAN_REV() but if `v' is 0, `r' is
+ * set to 0.
+ */
+# define GRN_BIT_SCAN_REV0(v, r) \
+ __asm__ __volatile__ ("bsrl %1, %%eax; cmovzl %1, %%eax; movl %%eax, %0" : "=r"(r) : "r"(v) : "%eax", "cc")
+# elif (defined(__PPC__) || defined(__ppc__)) /* ATOMIC ADD */
+# define GRN_ATOMIC_ADD_EX(p,i,r) \
+ __asm__ __volatile__ ("\n1:\n\tlwarx %0, 0, %1\n\tadd %0, %0, %2\n\tstwcx. %0, 0, %1\n\tbne- 1b\n\tsub %0, %0, %2" : "=&r" (r) : "r" (p), "r" (i) : "cc", "memory")
+/* todo */
+# define GRN_BIT_SCAN_REV(v,r) for (r = 31; r && !((1 << r) & v); r--)
+# define GRN_BIT_SCAN_REV0(v,r) GRN_BIT_SCAN_REV(v,r)
+# elif (defined(__sun) && defined(__SVR4)) /* ATOMIC ADD */
+# include <atomic.h>
+# define GRN_ATOMIC_ADD_EX(p,i,r) \
+ (r = atomic_add_32_nv(p, i) - i)
+/* todo */
+# define GRN_BIT_SCAN_REV(v,r) for (r = 31; r && !((1 << r) & v); r--)
+# define GRN_BIT_SCAN_REV0(v,r) GRN_BIT_SCAN_REV(v,r)
+# elif defined(__ATOMIC_SEQ_CST) /* GCC atomic builtins */
+# define GRN_ATOMIC_ADD_EX(p,i,r) \
+ (r = __atomic_fetch_add(p, i, __ATOMIC_SEQ_CST))
+# define GRN_BIT_SCAN_REV(v,r) for (r = 31; r && !((1 << r) & v); r--)
+# define GRN_BIT_SCAN_REV0(v,r) GRN_BIT_SCAN_REV(v,r)
+# else /* ATOMIC ADD */
+/* todo */
+# define GRN_BIT_SCAN_REV(v,r) for (r = 31; r && !((1 << r) & v); r--)
+# define GRN_BIT_SCAN_REV0(v,r) GRN_BIT_SCAN_REV(v,r)
+# endif /* ATOMIC ADD */
+
+# ifdef __i386__ /* ATOMIC 64BIT SET */
+# define GRN_SET_64BIT(p,v) \
+ __asm__ __volatile__ ("\txchgl %%esi, %%ebx\n1:\n\tmovl (%0), %%eax\n\tmovl 4(%0), %%edx\n\tlock; cmpxchg8b (%0)\n\tjnz 1b\n\txchgl %%ebx, %%esi" : : "D"(p), "S"(*(((uint32_t *)&(v))+0)), "c"(*(((uint32_t *)&(v))+1)) : "ax", "dx", "memory")
+# elif defined(__x86_64__) /* ATOMIC 64BIT SET */
+# define GRN_SET_64BIT(p,v) \
+ (*(p) = (v))
+# elif (defined(__sun) && defined(__SVR4)) /* ATOMIC 64BIT SET */
+/* todo */
+# define GRN_SET_64BIT(p,v) \
+ (void)atomic_swap_64(p, v)
+# elif defined(__ATOMIC_SEQ_CST) /* GCC atomic builtins */
+# define GRN_SET_64BIT(p,v) \
+ __atomic_store_n(p, v, __ATOMIC_SEQ_CST)
+# else
+# warning Need atomic 64bit operation support. The current implementation may break data.
+# define GRN_SET_64BIT(p,v) \
+ (*(p) = (v))
+# endif /* ATOMIC 64BIT SET */
+
+#elif (defined(WIN32) || defined (_WIN64)) /* __GNUC__ */
+
+# define GRN_ATOMIC_ADD_EX(p,i,r) \
+ ((r) = InterlockedExchangeAdd((p), (i)))
+# if defined(_WIN64) /* ATOMIC 64BIT SET */
+# define GRN_SET_64BIT(p,v) \
+ (*(p) = (v))
+# else /* ATOMIC 64BIT SET */
+# define GRN_SET_64BIT(p,v) do {\
+ uint32_t v1, v2; \
+ uint64_t *p2= (p); \
+ v1 = *(((uint32_t *)&(v))+0);\
+ v2 = *(((uint32_t *)&(v))+1);\
+ __asm _set_loop: \
+ __asm mov esi, p2 \
+ __asm mov ebx, v1 \
+ __asm mov ecx, v2 \
+ __asm mov eax, dword ptr [esi] \
+ __asm mov edx, dword ptr [esi + 4] \
+ __asm lock cmpxchg8b qword ptr [esi] \
+ __asm jnz _set_loop \
+} while (0)
+/* TODO: use _InterlockedCompareExchange64 or inline asm */
+# endif /* ATOMIC 64BIT SET */
+
+/* todo */
+# define GRN_BIT_SCAN_REV(v,r) for (r = 31; r && !((1 << r) & v); r--)
+# define GRN_BIT_SCAN_REV0(v,r) GRN_BIT_SCAN_REV(v,r)
+
+#else /* __GNUC__ */
+
+# if (defined(__sun) && defined(__SVR4)) /* ATOMIC ADD */
+# define __FUNCTION__ ""
+# include <atomic.h>
+# define GRN_ATOMIC_ADD_EX(p,i,r) \
+ (r = atomic_add_32_nv(p, i) - i)
+/* todo */
+# define GRN_SET_64BIT(p,v) \
+ (void)atomic_swap_64(p, v)
+# endif /* ATOMIC ADD */
+/* todo */
+# define GRN_BIT_SCAN_REV(v,r) for (r = 31; r && !((1 << r) & v); r--)
+# define GRN_BIT_SCAN_REV0(v,r) GRN_BIT_SCAN_REV(v,r)
+
+#endif /* __GNUC__ */
+
+typedef uint8_t byte;
+
+#define GRN_ID_WIDTH 30
+
+#ifdef __GNUC__
+inline static int
+grn_str_greater(const uint8_t *ap, uint32_t as, const uint8_t *bp, uint32_t bs)
+{
+ for (;; ap++, bp++, as--, bs--) {
+ if (!as) { return 0; }
+ if (!bs) { return 1; }
+ if (*ap < *bp) { return 0; }
+ if (*ap > *bp) { return 1; }
+ }
+}
+#else /* __GNUC__ */
+# define grn_str_greater(ap,as,bp,bs)\
+ (((as) > (bs)) ? (memcmp((ap), (bp), (bs)) >= 0) : (memcmp((ap), (bp), (as)) > 0))
+#endif /* __GNUC__ */
+
+#ifdef WORDS_BIGENDIAN
+# define grn_hton(buf,key,size) do {\
+ uint32_t size_ = (uint32_t)size;\
+ uint8_t *buf_ = (uint8_t *)buf;\
+ uint8_t *key_ = (uint8_t *)key;\
+ while (size_--) { *buf_++ = *key_++; }\
+} while (0)
+# define grn_ntohi(buf,key,size) do {\
+ uint32_t size_ = (uint32_t)size;\
+ uint8_t *buf_ = (uint8_t *)buf;\
+ uint8_t *key_ = (uint8_t *)key;\
+ if (size_) { *buf_++ = 0x80 ^ *key_++; size_--; }\
+ while (size_) { *buf_++ = *key_++; size_--; }\
+} while (0)
+#else /* WORDS_BIGENDIAN */
+# define grn_hton(buf,key,size) do {\
+ uint32_t size_ = (uint32_t)size;\
+ uint8_t *buf_ = (uint8_t *)buf;\
+ uint8_t *key_ = (uint8_t *)key + size;\
+ while (size_--) { *buf_++ = *(--key_); }\
+} while (0)
+# define grn_ntohi(buf,key,size) do {\
+ uint32_t size_ = (uint32_t)size;\
+ uint8_t *buf_ = (uint8_t *)buf;\
+ uint8_t *key_ = (uint8_t *)key + size;\
+ while (size_ > 1) { *buf_++ = *(--key_); size_--; }\
+ if (size_) { *buf_ = 0x80 ^ *(--key_); } \
+} while (0)
+#endif /* WORDS_BIGENDIAN */
+#define grn_ntoh(buf,key,size) grn_hton(buf,key,size)
+
+#ifndef __GNUC_PREREQ
+# if defined(__GNUC__) && defined(__GNUC_MINOR__)
+# define __GNUC_PREREQ(maj, min) \
+ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+# else
+# define __GNUC_PREREQ(maj, min) 0
+# endif /* defined(__GNUC__) && defined(__GNUC_MINOR__) */
+#endif /* __GNUC_PREREQ */
+
+#ifdef _MSC_VER
+# define grn_bswap_uint64(in, out) ((out) = _byteswap_uint64(in))
+#else /* _MSC_VER */
+# if defined(__GNUC__) && __GNUC_PREREQ(4, 3)
+# define grn_bswap_uint64(in, out) ((out) = __builtin_bswap64(in))
+# else /* defined(__GNUC__) && __GNUC_PREREQ(4, 3) */
+# define grn_bswap_uint64(in, out) do {\
+ uint64_t temp_ = (in);\
+ (out) = (temp_ << 56) |\
+ ((temp_ & (0xFFULL << 8)) << 40) |\
+ ((temp_ & (0xFFULL << 16)) << 24) |\
+ ((temp_ & (0xFFULL << 24)) << 8) |\
+ ((temp_ & (0xFFULL << 32)) >> 8) |\
+ ((temp_ & (0xFFULL << 40)) >> 24) |\
+ ((temp_ & (0xFFULL << 48)) >> 40) |\
+ (temp_ >> 56);\
+} while (0)
+# endif /* __GNUC__ */
+#endif /* _MSC_VER */
+
+#ifdef WORDS_BIGENDIAN
+# define grn_hton_uint64(in, out) ((out) = (in))
+#else /* WORDS_BIGENDIAN */
+# define grn_hton_uint64(in, out) grn_bswap_uint64(in, out)
+#endif /* WORDS_BIGENDIAN */
+#define grn_ntoh_uint64(in, out) grn_hton_uint64(in, out)
+
+#define grn_gton(keybuf,key,size) do {\
+ const grn_geo_point *point_ = (const grn_geo_point *)key;\
+ uint64_t la_ = (uint32_t)point_->latitude;\
+ uint64_t lo_ = (uint32_t)point_->longitude;\
+ uint64_t result_;\
+ la_ = (la_ | (la_ << 16)) & 0x0000FFFF0000FFFFULL;\
+ la_ = (la_ | (la_ << 8)) & 0x00FF00FF00FF00FFULL;\
+ la_ = (la_ | (la_ << 4)) & 0x0F0F0F0F0F0F0F0FULL;\
+ la_ = (la_ | (la_ << 2)) & 0x3333333333333333ULL;\
+ la_ = (la_ | (la_ << 1)) & 0x5555555555555555ULL;\
+ lo_ = (lo_ | (lo_ << 16)) & 0x0000FFFF0000FFFFULL;\
+ lo_ = (lo_ | (lo_ << 8)) & 0x00FF00FF00FF00FFULL;\
+ lo_ = (lo_ | (lo_ << 4)) & 0x0F0F0F0F0F0F0F0FULL;\
+ lo_ = (lo_ | (lo_ << 2)) & 0x3333333333333333ULL;\
+ lo_ = (lo_ | (lo_ << 1)) & 0x5555555555555555ULL;\
+ result_ = (la_ << 1) | lo_;\
+ grn_hton_uint64(result_, result_);\
+ grn_memcpy(keybuf, &result_, sizeof(result_));\
+} while (0)
+
+#define grn_ntog(keybuf,key,size) do {\
+ grn_geo_point *point_ = (grn_geo_point *)keybuf;\
+ uint64_t key_ = *(const uint64_t *)key;\
+ uint64_t la_, lo_;\
+ grn_ntoh_uint64(key_, key_);\
+ la_ = (key_ >> 1) & 0x5555555555555555ULL;\
+ lo_ = key_ & 0x5555555555555555ULL;\
+ la_ = (la_ | (la_ >> 1)) & 0x3333333333333333ULL;\
+ la_ = (la_ | (la_ >> 2)) & 0x0F0F0F0F0F0F0F0FULL;\
+ la_ = (la_ | (la_ >> 4)) & 0x00FF00FF00FF00FFULL;\
+ la_ = (la_ | (la_ >> 8)) & 0x0000FFFF0000FFFFULL;\
+ la_ = (la_ | (la_ >> 16)) & 0x00000000FFFFFFFFULL;\
+ lo_ = (lo_ | (lo_ >> 1)) & 0x3333333333333333ULL;\
+ lo_ = (lo_ | (lo_ >> 2)) & 0x0F0F0F0F0F0F0F0FULL;\
+ lo_ = (lo_ | (lo_ >> 4)) & 0x00FF00FF00FF00FFULL;\
+ lo_ = (lo_ | (lo_ >> 8)) & 0x0000FFFF0000FFFFULL;\
+ lo_ = (lo_ | (lo_ >> 16)) & 0x00000000FFFFFFFFULL;\
+ point_->latitude = la_;\
+ point_->longitude = lo_;\
+} while (0)
+
+#ifdef HAVE__STRTOUI64
+# define strtoull(nptr,endptr,base) _strtoui64(nptr,endptr,base)
+#endif /* HAVE__STRTOUI64 */
+
+#ifdef USE_FUTEX
+# include <linux/futex.h>
+# include <sys/syscall.h>
+
+# define GRN_FUTEX_WAIT(p) do {\
+ int err;\
+ struct timespec timeout = {1, 0};\
+ while (1) {\
+ if (!(err = syscall(SYS_futex, p, FUTEX_WAIT, *p, &timeout))) {\
+ break;\
+ }\
+ if (err == ETIMEDOUT) {\
+ GRN_LOG(ctx, GRN_LOG_CRIT, "timeout in GRN_FUTEX_WAIT(%p)", p);\
+ break;\
+ } else if (err != EWOULDBLOCK) {\
+ GRN_LOG(ctx, GRN_LOG_CRIT, "error %d in GRN_FUTEX_WAIT(%p)", err);\
+ break;\
+ }\
+ }\
+} while(0)
+
+# define GRN_FUTEX_WAKE(p) syscall(SYS_futex, p, FUTEX_WAKE, 1)
+#else /* USE_FUTEX */
+# define GRN_FUTEX_WAIT(p) grn_nanosleep(1000000)
+# define GRN_FUTEX_WAKE(p)
+#endif /* USE_FUTEX */
+
+#ifndef HOST_NAME_MAX
+# ifdef _POSIX_HOST_NAME_MAX
+# define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
+# else /* POSIX_HOST_NAME_MAX */
+# define HOST_NAME_MAX 128
+# 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>
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 00000000..c9059113
--- /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-1335 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 00000000..a0cb9c37
--- /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-1335 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
new file mode 100644
index 00000000..505e87a5
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_com.h
@@ -0,0 +1,250 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include "grn_str.h"
+#include "grn_hash.h"
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif /* HAVE_NETDB_H */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******* grn_com_queue ********/
+
+typedef struct _grn_com_queue grn_com_queue;
+typedef struct _grn_com_queue_entry grn_com_queue_entry;
+
+#define GRN_COM_QUEUE_BINSIZE (0x100)
+
+struct _grn_com_queue_entry {
+ grn_obj obj;
+ struct _grn_com_queue_entry *next;
+};
+
+struct _grn_com_queue {
+ grn_com_queue_entry *bins[GRN_COM_QUEUE_BINSIZE];
+ grn_com_queue_entry *next;
+ grn_com_queue_entry **tail;
+ uint8_t first;
+ uint8_t last;
+ grn_critical_section cs;
+};
+
+#define GRN_COM_QUEUE_INIT(q) do {\
+ (q)->next = NULL;\
+ (q)->tail = &(q)->next;\
+ (q)->first = 0;\
+ (q)->last = 0;\
+ CRITICAL_SECTION_INIT((q)->cs);\
+} while (0)
+
+#define GRN_COM_QUEUE_EMPTYP(q) (((q)->first == (q)->last) && !(q)->next)
+
+GRN_API grn_rc grn_com_queue_enque(grn_ctx *ctx, grn_com_queue *q, grn_com_queue_entry *e);
+GRN_API grn_com_queue_entry *grn_com_queue_deque(grn_ctx *ctx, grn_com_queue *q);
+
+/******* grn_com ********/
+
+#ifdef USE_SELECT
+# ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+# endif /* HAVE_SYS_SELECT_H */
+# define GRN_COM_POLLIN 1
+# define GRN_COM_POLLOUT 2
+#else /* USE_SELECT */
+# ifdef USE_EPOLL
+# include <sys/epoll.h>
+# define GRN_COM_POLLIN EPOLLIN
+# define GRN_COM_POLLOUT EPOLLOUT
+# else /* USE_EPOLL */
+# ifdef USE_KQUEUE
+# include <sys/event.h>
+# define GRN_COM_POLLIN EVFILT_READ
+# define GRN_COM_POLLOUT EVFILT_WRITE
+# else /* USE_KQUEUE */
+# include <poll.h>
+# define GRN_COM_POLLIN POLLIN
+# define GRN_COM_POLLOUT POLLOUT
+# endif /* USE_KQUEUE */
+# endif /* USE_EPOLL */
+#endif /* USE_SELECT */
+
+typedef struct _grn_com grn_com;
+typedef struct _grn_com_event grn_com_event;
+typedef struct _grn_com_addr grn_com_addr;
+typedef void grn_com_callback(grn_ctx *ctx, grn_com_event *, grn_com *);
+typedef void grn_msg_handler(grn_ctx *ctx, grn_obj *msg);
+
+enum {
+ grn_com_ok = 0,
+ grn_com_emem,
+ grn_com_erecv_head,
+ grn_com_erecv_body,
+ grn_com_eproto,
+};
+
+struct _grn_com_addr {
+ uint32_t addr;
+ uint16_t port;
+ uint16_t sid;
+};
+
+struct _grn_com {
+ grn_sock fd;
+ int events;
+ uint16_t sid;
+ uint8_t has_sid;
+ uint8_t closed;
+ grn_com_queue new_;
+ grn_com_event *ev;
+ void *opaque;
+ grn_bool accepting;
+};
+
+struct _grn_com_event {
+ struct _grn_hash *hash;
+ int max_nevents;
+ grn_ctx *ctx;
+ grn_mutex mutex;
+ grn_cond cond;
+ grn_com_queue recv_old;
+ grn_msg_handler *msg_handler;
+ grn_com_addr curr_edge_id;
+ grn_com *acceptor;
+ void *opaque;
+#ifndef USE_SELECT
+#ifdef USE_EPOLL
+ int epfd;
+ struct epoll_event *events;
+#else /* USE_EPOLL */
+#ifdef USE_KQUEUE
+ int kqfd;
+ struct kevent *events;
+#else /* USE_KQUEUE */
+ int dummy; /* dummy */
+ struct pollfd *events;
+#endif /* USE_KQUEUE */
+#endif /* USE_EPOLL */
+#endif /* USE_SELECT */
+};
+
+grn_rc grn_com_init(void);
+void grn_com_fin(void);
+GRN_API grn_rc grn_com_event_init(grn_ctx *ctx, grn_com_event *ev, int max_nevents, int data_size);
+GRN_API grn_rc grn_com_event_fin(grn_ctx *ctx, grn_com_event *ev);
+GRN_API grn_rc grn_com_event_start_accept(grn_ctx *ctx, grn_com_event *ev);
+grn_rc grn_com_event_stop_accept(grn_ctx *ctx, grn_com_event *ev);
+grn_rc grn_com_event_add(grn_ctx *ctx, grn_com_event *ev, grn_sock fd, int events, grn_com **com);
+grn_rc grn_com_event_mod(grn_ctx *ctx, grn_com_event *ev, grn_sock fd, int events, grn_com **com);
+GRN_API grn_rc grn_com_event_del(grn_ctx *ctx, grn_com_event *ev, grn_sock fd);
+GRN_API grn_rc grn_com_event_poll(grn_ctx *ctx, grn_com_event *ev, int timeout);
+grn_rc grn_com_event_each(grn_ctx *ctx, grn_com_event *ev, grn_com_callback *func);
+
+/******* grn_com_gqtp ********/
+
+#define GRN_COM_PROTO_HTTP 0x47
+#define GRN_COM_PROTO_GQTP 0xc7
+#define GRN_COM_PROTO_MBREQ 0x80
+#define GRN_COM_PROTO_MBRES 0x81
+
+typedef struct _grn_com_header grn_com_header;
+
+struct _grn_com_header {
+ uint8_t proto;
+ uint8_t qtype;
+ uint16_t keylen;
+ uint8_t level;
+ uint8_t flags;
+ uint16_t status;
+ uint32_t size;
+ uint32_t opaque;
+ uint64_t cas;
+};
+
+GRN_API grn_com *grn_com_copen(grn_ctx *ctx, grn_com_event *ev, const char *dest, int port);
+GRN_API grn_rc grn_com_sopen(grn_ctx *ctx, grn_com_event *ev,
+ const char *bind_address, int port,
+ grn_msg_handler *func, struct hostent *he);
+
+GRN_API void grn_com_close_(grn_ctx *ctx, grn_com *com);
+GRN_API grn_rc grn_com_close(grn_ctx *ctx, grn_com *com);
+
+GRN_API grn_rc grn_com_send(grn_ctx *ctx, grn_com *cs,
+ grn_com_header *header, const char *body, uint32_t size, int flags);
+grn_rc grn_com_recv(grn_ctx *ctx, grn_com *cs, grn_com_header *header, grn_obj *buf);
+GRN_API grn_rc grn_com_send_http(grn_ctx *ctx, grn_com *cs, const char *path, uint32_t path_len, int flags);
+
+/******* grn_msg ********/
+
+typedef struct _grn_msg grn_msg;
+
+struct _grn_msg {
+ grn_com_queue_entry qe;
+ union {
+ grn_com *peer;
+ grn_sock fd;
+ } u;
+ grn_ctx *ctx;
+ grn_com_queue *old;
+ grn_com_header header;
+ grn_com_addr edge_id;
+ grn_com *acceptor;
+};
+
+GRN_API grn_rc grn_msg_send(grn_ctx *ctx, grn_obj *msg, int flags);
+GRN_API grn_obj *grn_msg_open_for_reply(grn_ctx *ctx, grn_obj *query, grn_com_queue *old);
+GRN_API grn_obj *grn_msg_open(grn_ctx *ctx, grn_com *com, grn_com_queue *old);
+GRN_API grn_rc grn_msg_set_property(grn_ctx *ctx, grn_obj *obj,
+ uint16_t status, uint32_t key_size, uint8_t extra_size);
+GRN_API grn_rc grn_msg_close(grn_ctx *ctx, grn_obj *msg);
+
+/******* grn_edge ********/
+
+#define GRN_EDGE_WORKER 0
+#define GRN_EDGE_COMMUNICATOR 1
+
+typedef struct {
+ grn_com_queue_entry eq;
+ grn_ctx ctx;
+ grn_com_queue recv_new;
+ grn_com_queue send_old;
+ grn_com *com;
+ grn_com_addr *addr;
+ grn_msg *msg;
+ uint8_t stat;
+ uint8_t flags;
+ grn_id id;
+} grn_edge;
+
+GRN_VAR grn_hash *grn_edges;
+GRN_API void grn_edges_init(grn_ctx *ctx, void (*dispatcher)(grn_ctx *ctx, grn_edge *edge));
+GRN_API void grn_edges_fin(grn_ctx *ctx);
+GRN_API grn_edge *grn_edges_add(grn_ctx *ctx, grn_com_addr *addr, int *added);
+grn_edge *grn_edges_add_communicator(grn_ctx *ctx, grn_com_addr *addr);
+GRN_API void grn_edges_delete(grn_ctx *ctx, grn_edge *edge);
+void grn_edge_dispatch(grn_ctx *ctx, grn_edge *edge, grn_obj *msg);
+
+#ifdef __cplusplus
+}
+#endif
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 00000000..75e23a46
--- /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-1335 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
new file mode 100644
index 00000000..9e82785f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_ctx.h
@@ -0,0 +1,501 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include "grn_error.h"
+
+#include <errno.h>
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#define GRN_BREAK_POINT raise(SIGTRAP)
+#endif /* HAVE_SIGNAL_H */
+
+#ifdef HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif /* HAVE_EXECINFO_H */
+
+#include "grn_io.h"
+#include "grn_alloc.h"
+#include "grn_time.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**** api in/out ****/
+
+#define GRN_API_ENTER do {\
+ if ((ctx)->seqno & 1) {\
+ (ctx)->subno++;\
+ } else {\
+ (ctx)->errlvl = GRN_OK;\
+ if ((ctx)->rc != GRN_CANCEL) {\
+ (ctx)->rc = GRN_SUCCESS;\
+ }\
+ (ctx)->seqno++;\
+ }\
+ GRN_TEST_YIELD();\
+} while (0)
+
+/* CAUTION!! : pass only variables or constants as r */
+#define GRN_API_RETURN(r) do {\
+ if (ctx->subno) {\
+ ctx->subno--;\
+ } else {\
+ ctx->seqno++;\
+ }\
+ GRN_TEST_YIELD();\
+ return r;\
+} while (0)
+
+/**** error handling ****/
+
+#define GRN_EMERG GRN_LOG_EMERG
+#define GRN_ALERT GRN_LOG_ALERT
+#define GRN_CRIT GRN_LOG_CRIT
+#define GRN_ERROR GRN_LOG_ERROR
+#define GRN_WARN GRN_LOG_WARNING
+#define GRN_OK GRN_LOG_NOTICE
+
+#define ERRCLR(ctx) do {\
+ if (ctx) {\
+ ((grn_ctx *)ctx)->errlvl = GRN_OK;\
+ 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;\
+ grn_gctx.rc = GRN_SUCCESS;\
+} while (0)
+
+#ifdef HAVE_BACKTRACE
+#define BACKTRACE(ctx) ((ctx)->ntrace = (unsigned char)backtrace((ctx)->trace, 16))
+#else /* HAVE_BACKTRACE */
+#define BACKTRACE(ctx)
+#endif /* HAVE_BACKTRACE */
+
+GRN_API grn_bool grn_ctx_impl_should_log(grn_ctx *ctx);
+GRN_API void grn_ctx_impl_set_current_error_message(grn_ctx *ctx);
+
+#ifdef HAVE_BACKTRACE
+#define LOGTRACE(ctx,lvl) do {\
+ int i;\
+ char **p;\
+ BACKTRACE(ctx);\
+ p = backtrace_symbols((ctx)->trace, (ctx)->ntrace);\
+ 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);\
+ }\
+} while (0)
+#else /* HAVE_BACKTRACE */
+#define LOGTRACE(ctx,msg)
+#endif /* HAVE_BACKTRACE */
+
+#define ERRSET(ctx,lvl,r,...) do {\
+ grn_ctx *ctx_ = (grn_ctx *)ctx;\
+ ctx_->errlvl = (lvl);\
+ if (ctx_->rc != GRN_CANCEL) {\
+ ctx_->rc = (r);\
+ }\
+ ctx_->errfile = __FILE__;\
+ ctx_->errline = __LINE__;\
+ ctx_->errfunc = __FUNCTION__;\
+ grn_ctx_log(ctx, __VA_ARGS__);\
+ if (grn_ctx_impl_should_log(ctx)) {\
+ grn_ctx_impl_set_current_error_message(ctx);\
+ GRN_LOG(ctx, lvl, __VA_ARGS__);\
+ if (lvl <= GRN_LOG_ERROR) { LOGTRACE(ctx, lvl); }\
+ }\
+} while (0)
+
+#define ERRP(ctx,lvl) \
+ (((ctx) && ((grn_ctx *)(ctx))->errlvl <= (lvl)) || (grn_gctx.errlvl <= (lvl)))
+
+#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__)
+#define ALERT(...) ERRSET(ctx, GRN_ALERT, GRN_SUCCESS, __VA_ARGS__)
+
+#define ERR_CAST(column, range, element) do {\
+ grn_obj inspected;\
+ char column_name[GRN_TABLE_MAX_KEY_SIZE];\
+ int column_name_size;\
+ char range_name[GRN_TABLE_MAX_KEY_SIZE];\
+ int range_name_size;\
+ GRN_TEXT_INIT(&inspected, 0);\
+ grn_inspect(ctx, &inspected, element);\
+ column_name_size = grn_obj_name(ctx, column, column_name,\
+ GRN_TABLE_MAX_KEY_SIZE);\
+ range_name_size = grn_obj_name(ctx, range, range_name,\
+ GRN_TABLE_MAX_KEY_SIZE);\
+ ERR(GRN_INVALID_ARGUMENT, "<%.*s>: failed to cast to <%.*s>: <%.*s>",\
+ column_name_size, column_name,\
+ range_name_size, range_name,\
+ (int)GRN_TEXT_LEN(&inspected), GRN_TEXT_VALUE(&inspected));\
+ GRN_OBJ_FIN(ctx, &inspected);\
+} while (0)
+
+#define USER_MESSAGE_SIZE 1024
+
+#ifdef WIN32
+
+#define SERR(...) do {\
+ grn_rc rc;\
+ int error_code;\
+ const char *system_message;\
+ char user_message[USER_MESSAGE_SIZE];\
+ error_code = GetLastError();\
+ system_message = grn_current_error_message();\
+ 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(...) do {\
+ grn_rc rc;\
+ const char *m;\
+ char user_message[USER_MESSAGE_SIZE];\
+ int e = WSAGetLastError();\
+ switch (e) {\
+ case WSANOTINITIALISED :\
+ rc = GRN_SOCKET_NOT_INITIALIZED;\
+ m = "please call grn_com_init first";\
+ break;\
+ case WSAEFAULT :\
+ rc = GRN_BAD_ADDRESS;\
+ m = "bad address";\
+ break;\
+ case WSAEINVAL :\
+ rc = GRN_INVALID_ARGUMENT;\
+ m = "invalid argument";\
+ break;\
+ case WSAEMFILE :\
+ rc = GRN_TOO_MANY_OPEN_FILES;\
+ m = "too many sockets";\
+ break;\
+ case WSAEWOULDBLOCK :\
+ rc = GRN_OPERATION_WOULD_BLOCK;\
+ m = "operation would block";\
+ break;\
+ case WSAENOTSOCK :\
+ rc = GRN_NOT_SOCKET;\
+ m = "given fd is not socket fd";\
+ break;\
+ case WSAEOPNOTSUPP :\
+ rc = GRN_OPERATION_NOT_SUPPORTED;\
+ m = "operation is not supported";\
+ break;\
+ case WSAEADDRINUSE :\
+ rc = GRN_ADDRESS_IS_IN_USE;\
+ m = "address is already in use";\
+ break;\
+ case WSAEADDRNOTAVAIL :\
+ rc = GRN_ADDRESS_IS_NOT_AVAILABLE;\
+ m = "address is not available";\
+ break;\
+ case WSAENETDOWN :\
+ rc = GRN_NETWORK_IS_DOWN;\
+ m = "network is down";\
+ break;\
+ case WSAENOBUFS :\
+ rc = GRN_NO_BUFFER;\
+ m = "no buffer";\
+ break;\
+ case WSAEISCONN :\
+ rc = GRN_SOCKET_IS_ALREADY_CONNECTED;\
+ m = "socket is already connected";\
+ break;\
+ case WSAENOTCONN :\
+ rc = GRN_SOCKET_IS_NOT_CONNECTED;\
+ m = "socket is not connected";\
+ break;\
+ case WSAESHUTDOWN :\
+ rc = GRN_SOCKET_IS_ALREADY_SHUTDOWNED;\
+ m = "socket is already shutdowned";\
+ break;\
+ case WSAETIMEDOUT :\
+ rc = GRN_OPERATION_TIMEOUT;\
+ m = "connection time out";\
+ break;\
+ case WSAECONNREFUSED :\
+ rc = GRN_CONNECTION_REFUSED;\
+ m = "connection refused";\
+ break;\
+ case WSAEINTR :\
+ rc = GRN_INTERRUPTED_FUNCTION_CALL;\
+ m = "interrupted function call";\
+ break;\
+ default:\
+ rc = GRN_UNKNOWN_ERROR;\
+ m = "unknown error";\
+ break;\
+ }\
+ 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(...) 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;\
+ case ENOENT : rc = GRN_NO_SUCH_FILE_OR_DIRECTORY; break;\
+ case ESRCH : rc = GRN_NO_SUCH_PROCESS; break;\
+ case EINTR : rc = GRN_INTERRUPTED_FUNCTION_CALL; break;\
+ case EIO : rc = GRN_INPUT_OUTPUT_ERROR; break;\
+ case E2BIG : rc = GRN_ARG_LIST_TOO_LONG; break;\
+ case ENOEXEC : rc = GRN_EXEC_FORMAT_ERROR; break;\
+ case EBADF : rc = GRN_BAD_FILE_DESCRIPTOR; break;\
+ case ECHILD : rc = GRN_NO_CHILD_PROCESSES; break;\
+ case EAGAIN: rc = GRN_OPERATION_WOULD_BLOCK; break;\
+ case ENOMEM : rc = GRN_NO_MEMORY_AVAILABLE; break;\
+ case EACCES : rc = GRN_PERMISSION_DENIED; break;\
+ case EFAULT : rc = GRN_BAD_ADDRESS; break;\
+ case EEXIST : rc = GRN_FILE_EXISTS; break;\
+ /* case EXDEV : */\
+ case ENODEV : rc = GRN_NO_SUCH_DEVICE; break;\
+ case ENOTDIR : rc = GRN_NOT_A_DIRECTORY; break;\
+ case EISDIR : rc = GRN_IS_A_DIRECTORY; break;\
+ case EINVAL : rc = GRN_INVALID_ARGUMENT; break;\
+ case EMFILE : rc = GRN_TOO_MANY_OPEN_FILES; break;\
+ case ENOTTY : rc = GRN_INAPPROPRIATE_I_O_CONTROL_OPERATION; break;\
+ case EFBIG : rc = GRN_FILE_TOO_LARGE; break;\
+ case ENOSPC : rc = GRN_NO_SPACE_LEFT_ON_DEVICE; break;\
+ case ESPIPE : rc = GRN_INVALID_SEEK; break;\
+ case EROFS : rc = GRN_READ_ONLY_FILE_SYSTEM; break;\
+ case EMLINK : rc = GRN_TOO_MANY_LINKS; break;\
+ case EPIPE : rc = GRN_BROKEN_PIPE; break;\
+ case EDOM : rc = GRN_DOMAIN_ERROR; break;\
+ case ERANGE : rc = GRN_RANGE_ERROR; break;\
+ case EDEADLOCK : rc = GRN_RESOURCE_DEADLOCK_AVOIDED; break;\
+ case ENAMETOOLONG : rc = GRN_FILENAME_TOO_LONG; break;\
+ case EILSEQ : rc = GRN_ILLEGAL_BYTE_SEQUENCE; break;\
+ /* case STRUNCATE : */\
+ default :\
+ rc = GRN_UNKNOWN_ERROR;\
+ show_errno = GRN_TRUE;\
+ break;\
+ }\
+ grn_snprintf(user_message,\
+ USER_MESSAGE_SIZE, USER_MESSAGE_SIZE,\
+ __VA_ARGS__);\
+ if (show_errno) {\
+ ERR(rc, "system call error[%d]: %s: %s",\
+ errno_keep, system_message, user_message);\
+ } else {\
+ ERR(rc, "system call error: %s: %s",\
+ system_message, user_message);\
+ }\
+} while (0)
+
+#else /* WIN32 */
+
+#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;\
+ case ENOENT : rc = GRN_NO_SUCH_FILE_OR_DIRECTORY; break;\
+ case ENOMEM : rc = GRN_NO_MEMORY_AVAILABLE; break;\
+ case ENOTDIR : rc = GRN_NOT_A_DIRECTORY; break;\
+ case EPERM : rc = GRN_OPERATION_NOT_PERMITTED; break;\
+ case ESRCH : rc = GRN_NO_SUCH_PROCESS; break;\
+ case EINTR : rc = GRN_INTERRUPTED_FUNCTION_CALL; break;\
+ case EIO : rc = GRN_INPUT_OUTPUT_ERROR; break;\
+ case ENXIO : rc = GRN_NO_SUCH_DEVICE_OR_ADDRESS; break;\
+ case E2BIG : rc = GRN_ARG_LIST_TOO_LONG; break;\
+ case ENOEXEC : rc = GRN_EXEC_FORMAT_ERROR; break;\
+ case EBADF : rc = GRN_BAD_FILE_DESCRIPTOR; break;\
+ case ECHILD : rc = GRN_NO_CHILD_PROCESSES; break;\
+ case EACCES : rc = GRN_PERMISSION_DENIED; break;\
+ case EFAULT : rc = GRN_BAD_ADDRESS; break;\
+ case EBUSY : rc = GRN_RESOURCE_BUSY; break;\
+ case EEXIST : rc = GRN_FILE_EXISTS; break;\
+ case ENODEV : rc = GRN_NO_SUCH_DEVICE; break;\
+ case EISDIR : rc = GRN_IS_A_DIRECTORY; break;\
+ case EINVAL : rc = GRN_INVALID_ARGUMENT; break;\
+ case EMFILE : rc = GRN_TOO_MANY_OPEN_FILES; break;\
+ case EFBIG : rc = GRN_FILE_TOO_LARGE; break;\
+ case ENOSPC : rc = GRN_NO_SPACE_LEFT_ON_DEVICE; break;\
+ case EROFS : rc = GRN_READ_ONLY_FILE_SYSTEM; break;\
+ case EMLINK : rc = GRN_TOO_MANY_LINKS; break;\
+ case EPIPE : rc = GRN_BROKEN_PIPE; break;\
+ case EDOM : rc = GRN_DOMAIN_ERROR; break;\
+ case ERANGE : rc = GRN_RANGE_ERROR; break;\
+ case ENOTSOCK : rc = GRN_NOT_SOCKET; break;\
+ case EADDRINUSE : rc = GRN_ADDRESS_IS_IN_USE; break;\
+ case ENETDOWN : rc = GRN_NETWORK_IS_DOWN; break;\
+ case ENOBUFS : rc = GRN_NO_BUFFER; break;\
+ case EISCONN : rc = GRN_SOCKET_IS_ALREADY_CONNECTED; break;\
+ case ENOTCONN : rc = GRN_SOCKET_IS_NOT_CONNECTED; break;\
+ /*\
+ case ESOCKTNOSUPPORT :\
+ case EOPNOTSUPP :\
+ case EPFNOSUPPORT :\
+ */\
+ case EPROTONOSUPPORT : rc = GRN_OPERATION_NOT_SUPPORTED; break;\
+ case ESHUTDOWN : rc = GRN_SOCKET_IS_ALREADY_SHUTDOWNED; break;\
+ case ETIMEDOUT : rc = GRN_OPERATION_TIMEOUT; break;\
+ case ECONNREFUSED: rc = GRN_CONNECTION_REFUSED; break;\
+ case EAGAIN: rc = GRN_OPERATION_WOULD_BLOCK; break;\
+ default :\
+ rc = GRN_UNKNOWN_ERROR;\
+ show_errno = GRN_TRUE;\
+ break;\
+ }\
+ grn_snprintf(user_message,\
+ USER_MESSAGE_SIZE, USER_MESSAGE_SIZE,\
+ __VA_ARGS__);\
+ if (show_errno) {\
+ ERR(rc, "system call error[%d]: %s: %s",\
+ errno_keep, system_message, user_message);\
+ } else {\
+ ERR(rc, "system call error: %s: %s",\
+ system_message, user_message);\
+ }\
+} while (0)
+
+#define SOERR(...) SERR(__VA_ARGS__)
+
+#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__)
+
+#ifdef DEBUG
+#define GRN_ASSERT(s) grn_assert(ctx,(s),__FILE__,__LINE__,__FUNCTION__)
+#else
+#define GRN_ASSERT(s)
+#endif
+
+void grn_assert(grn_ctx *ctx, int cond, const char* file, int line, const char* func);
+
+/**** grn_ctx ****/
+
+GRN_VAR grn_ctx grn_gctx;
+extern int grn_pagesize;
+extern grn_critical_section grn_glock;
+extern uint32_t grn_gtick;
+extern int grn_lock_timeout;
+
+#define GRN_CTX_ALLOCATED (0x80)
+#define GRN_CTX_TEMPORARY_DISABLE_II_RESOLVE_SEL_AND (0x40)
+
+extern grn_timeval grn_starttime;
+
+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);
+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 ****/
+
+/* flag values used for grn_obj.header.impl_flags */
+
+#define GRN_OBJ_ALLOCATED (0x01<<2) /* allocated by ctx */
+#define GRN_OBJ_EXPRVALUE (0x01<<3) /* value allocated by grn_expr */
+#define GRN_OBJ_EXPRCONST (0x01<<4) /* constant allocated by grn_expr */
+
+typedef struct _grn_hook grn_hook;
+
+typedef struct {
+ grn_obj_header header;
+ grn_id range; /* table: type of subrecords, column: type of values */
+ /* -- compatible with grn_accessor -- */
+ grn_id id;
+ grn_obj *db;
+ grn_user_data user_data;
+ grn_proc_func *finalizer;
+ grn_hook *hooks[5];
+ void *source;
+ uint32_t source_size;
+ uint32_t max_n_subrecs;
+ uint8_t subrec_size;
+ uint8_t subrec_offset;
+ uint8_t record_unit;
+ uint8_t subrec_unit;
+ union {
+ grn_table_group_flags group;
+ } flags;
+ // grn_obj_flags flags;
+} grn_db_obj;
+
+#define GRN_DB_OBJ_SET_TYPE(db_obj,obj_type) do {\
+ (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;\
+ (db_obj)->obj.hooks[0] = NULL;\
+ (db_obj)->obj.hooks[1] = NULL;\
+ (db_obj)->obj.hooks[2] = NULL;\
+ (db_obj)->obj.hooks[3] = NULL;\
+ (db_obj)->obj.hooks[4] = NULL;\
+ (db_obj)->obj.source = NULL;\
+ (db_obj)->obj.source_size = 0;\
+} while (0)
+
+/**** receive handler ****/
+
+GRN_API void grn_ctx_stream_out_func(grn_ctx *c, int flags, void *stream);
+
+grn_rc grn_db_init_builtin_procs(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_ctx_impl.h b/storage/mroonga/vendor/groonga/lib/grn_ctx_impl.h
new file mode 100644
index 00000000..8f300f09
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_ctx_impl.h
@@ -0,0 +1,237 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#ifndef GRN_CTX_H
+# include "grn_ctx.h"
+#endif /* GRN_CTX_H */
+
+#ifndef GRN_COM_H
+# include "grn_com.h"
+#endif /* GRN_COM_H */
+
+#include "grn_msgpack.h"
+
+#ifdef GRN_WITH_MRUBY
+# include <mruby.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**** grn_expr ****/
+
+#define GRN_EXPR_MISSING_NAME "expr_missing"
+
+/**** grn_ctx_impl ****/
+
+#define GRN_CTX_INITED 0x00
+#define GRN_CTX_QUITTING 0x0f
+
+typedef enum {
+ GRN_LOADER_BEGIN = 0,
+ GRN_LOADER_TOKEN,
+ GRN_LOADER_STRING,
+ GRN_LOADER_SYMBOL,
+ GRN_LOADER_NUMBER,
+ GRN_LOADER_STRING_ESC,
+ GRN_LOADER_UNICODE0,
+ GRN_LOADER_UNICODE1,
+ GRN_LOADER_UNICODE2,
+ GRN_LOADER_UNICODE3,
+ 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 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;
+ grn_obj *each;
+ uint32_t unichar;
+ uint32_t values_size;
+ 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
+
+#ifdef USE_MEMORY_DEBUG
+typedef struct _grn_alloc_info grn_alloc_info;
+struct _grn_alloc_info
+{
+ void *address;
+ int freed;
+ size_t size;
+ char alloc_backtrace[4096];
+ char free_backtrace[4096];
+ char *file;
+ int line;
+ char *func;
+ grn_alloc_info *next;
+};
+#endif
+
+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;
+ struct RClass *object_class;
+ grn_hash *checked_procs;
+ grn_hash *registered_plugins;
+ struct {
+ grn_obj from;
+ grn_obj to;
+ } buffer;
+ struct {
+ struct RClass *time_class;
+ } builtin;
+ struct {
+ struct RClass *operator_class;
+ } groonga;
+#endif
+};
+
+struct _grn_ctx_impl {
+ grn_encoding encoding;
+
+ /* memory pool portion */
+ int32_t lifoseg;
+ int32_t currseg;
+ grn_critical_section lock;
+ grn_io_mapinfo segs[GRN_CTX_N_SEGMENTS];
+
+#ifdef USE_DYNAMIC_MALLOC_CHANGE
+ /* memory allocation portion */
+ grn_malloc_func malloc_func;
+ grn_calloc_func calloc_func;
+ grn_realloc_func realloc_func;
+ grn_strdup_func strdup_func;
+ grn_free_func free_func;
+#endif
+
+#ifdef USE_MEMORY_DEBUG
+ /* memory debug portion */
+ grn_alloc_info *alloc_info;
+#endif
+
+ /* expression portion */
+ grn_obj *stack[GRN_STACK_SIZE];
+ uint32_t stack_curr;
+ grn_hash *expr_vars;
+ grn_obj *curr_expr;
+ grn_obj current_request_id;
+ void *current_request_timer_id;
+ void *parser;
+ grn_timeval tv;
+
+ /* loader portion */
+ grn_edge *edge;
+ grn_loader loader;
+
+ /* plugin portion */
+ const char *plugin_path;
+
+ /* output portion */
+ 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;
+
+ 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;
+
+ /* lifetime portion */
+ grn_proc_func *finalizer;
+
+ grn_obj *db;
+ grn_array *values; /* temporary objects */
+ grn_pat *temporary_columns;
+ grn_hash *ios; /* IOs */
+ grn_com *com;
+ unsigned int com_status;
+
+ grn_obj query_log_buf;
+
+ char previous_errbuf[GRN_CTX_MSGSIZE];
+ unsigned int n_same_error_messages;
+
+ grn_mrb_data mrb;
+
+ struct {
+ grn_obj stack;
+ grn_obj *current;
+ } temporary_open_spaces;
+};
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_ctx_impl_mrb.h b/storage/mroonga/vendor/groonga/lib/grn_ctx_impl_mrb.h
new file mode 100644
index 00000000..e3d619ab
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_ctx_impl_mrb.h
@@ -0,0 +1,35 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include "grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+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
diff --git a/storage/mroonga/vendor/groonga/lib/grn_dat.h b/storage/mroonga/vendor/groonga/lib/grn_dat.h
new file mode 100644
index 00000000..7d0d0c8d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_dat.h
@@ -0,0 +1,95 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include "grn_db.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _grn_dat {
+ grn_db_obj obj;
+ grn_io *io;
+ struct grn_dat_header *header;
+ uint32_t file_id;
+ grn_encoding encoding;
+ void *trie;
+ void *old_trie;
+ grn_obj *tokenizer;
+ grn_obj *normalizer;
+ grn_obj token_filters;
+ grn_critical_section lock;
+ grn_bool is_dirty;
+};
+
+struct grn_dat_header {
+ uint32_t flags;
+ grn_encoding encoding;
+ grn_id tokenizer;
+ uint32_t file_id;
+ grn_id normalizer;
+ uint32_t n_dirty_opens;
+ uint32_t reserved[234];
+};
+
+struct _grn_dat_cursor {
+ grn_db_obj obj;
+ grn_dat *dat;
+ void *cursor;
+ const void *key;
+ grn_id curr_rec;
+};
+
+GRN_API grn_id grn_dat_curr_id(grn_ctx *ctx, grn_dat *dat);
+
+/*
+ Currently, grn_dat_truncate() is available if the grn_dat object is
+ associated with a file.
+ */
+GRN_API grn_rc grn_dat_truncate(grn_ctx *ctx, grn_dat *dat);
+
+GRN_API const char *_grn_dat_key(grn_ctx *ctx, grn_dat *dat, grn_id id,
+ uint32_t *key_size);
+GRN_API grn_id grn_dat_next(grn_ctx *ctx, grn_dat *dat, grn_id id);
+GRN_API grn_id grn_dat_at(grn_ctx *ctx, grn_dat *dat, grn_id id);
+
+GRN_API grn_rc grn_dat_clear_status_flags(grn_ctx *ctx, grn_dat *dat);
+
+/*
+ Currently, grn_dat_repair() is available if the grn_dat object is associated
+ with a file.
+ */
+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
diff --git a/storage/mroonga/vendor/groonga/lib/grn_db.h b/storage/mroonga/vendor/groonga/lib/grn_db.h
new file mode 100644
index 00000000..d3a6b48b
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_db.h
@@ -0,0 +1,493 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include "grn_ctx.h"
+#include "grn_store.h"
+#include "grn_rset.h"
+
+#include <groonga/command.h>
+#include <groonga/token_filter.h>
+#include <groonga/scorer.h>
+
+#include <float.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GRN_DB_DELIMITER '.'
+#define GRN_DB_PSEUDO_COLUMN_PREFIX '_'
+
+#define GRN_N_RESERVED_TYPES 256
+
+typedef struct _grn_db grn_db;
+typedef struct _grn_proc grn_proc;
+
+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);
+
+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);
+
+grn_id grn_table_get_v(grn_ctx *ctx, grn_obj *table, const void *key, int key_size,
+ 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_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);
+const char *_grn_table_key(grn_ctx *ctx, grn_obj *table, grn_id id, uint32_t *key_size);
+
+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);
+
+grn_table_cursor *grn_table_cursor_open_by_id(grn_ctx *ctx, grn_obj *table,
+ grn_id min, grn_id max, int flags);
+
+void grn_table_add_subrec(grn_obj *table, grn_rset_recinfo *ri, double score,
+ grn_rset_posinfo *pi, int dir);
+
+grn_obj *grn_obj_graft(grn_ctx *ctx, grn_obj *obj);
+
+grn_rc grn_column_name_(grn_ctx *ctx, grn_obj *obj, grn_obj *buf);
+
+
+typedef enum {
+ PROC_INIT = 0,
+ PROC_NEXT,
+ PROC_FIN
+} grn_proc_phase;
+
+struct _grn_type {
+ grn_db_obj obj;
+};
+
+#define GRN_TYPE_SIZE(type) ((type)->range)
+
+#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 &&\
+ ((GRN_SNIP == ((grn_db_obj *)obj)->header.type) ||\
+ ((GRN_CURSOR_TABLE_HASH_KEY <= ((grn_db_obj *)obj)->header.type) &&\
+ (((grn_db_obj *)obj)->header.type <= GRN_COLUMN_INDEX))))
+
+#define GRN_OBJ_TABLEP(obj) \
+ (obj &&\
+ (GRN_TABLE_HASH_KEY <= ((grn_db_obj *)obj)->header.type) &&\
+ (((grn_db_obj *)obj)->header.type <= GRN_DB))
+
+#define GRN_OBJ_INDEX_COLUMNP(obj) \
+ (obj &&\
+ DB_OBJ(obj)->header.type == GRN_COLUMN_INDEX)
+
+#define GRN_OBJ_VECTOR_COLUMNP(obj) \
+ (obj &&\
+ DB_OBJ(obj)->header.type == GRN_COLUMN_VAR_SIZE &&\
+ (DB_OBJ(obj)->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) == GRN_OBJ_COLUMN_VECTOR)
+
+#define GRN_OBJ_WEIGHT_VECTOR_COLUMNP(obj) \
+ (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 {
+ grn_user_data user_data;
+ grn_proc *proc;
+ grn_obj *caller;
+ // grn_obj *obj;
+ grn_hook *hooks;
+ grn_hook *currh;
+ grn_proc_phase phase;
+ unsigned short nargs;
+ unsigned short offset;
+ grn_user_data data[16];
+};
+
+struct _grn_proc {
+ grn_db_obj obj;
+ grn_obj name_buf;
+ grn_expr_var *vars;
+ uint32_t nvars;
+ /* -- compatible with grn_expr -- */
+ grn_proc_type type;
+ grn_proc_func *funcs[3];
+
+ union {
+ struct {
+ grn_selector_func *selector;
+ grn_operator selector_op;
+ grn_bool is_stable;
+ } function;
+ struct {
+ grn_command_run_func *run;
+ } command;
+ struct {
+ grn_token_filter_init_func *init;
+ grn_token_filter_filter_func *filter;
+ grn_token_filter_fin_func *fin;
+ } token_filter;
+ struct {
+ grn_scorer_score_func *score;
+ } scorer;
+ grn_window_function_func *window_function;
+ } callbacks;
+
+ void *user_data;
+
+ grn_id module;
+ // uint32_t nargs;
+ // uint32_t nresults;
+ // grn_obj results[16];
+};
+
+#define GRN_PROC_GET_VARS() (grn_proc_get_vars(ctx, user_data))
+#define GRN_PROC_GET_VAR(name) (grn_proc_get_var(ctx, user_data, name, strlen(name)))
+#define GRN_PROC_GET_VAR_BY_OFFSET(offset) (grn_proc_get_var_by_offset(ctx, user_data, offset))
+#define GRN_PROC_GET_OR_ADD_VAR(name) (grn_proc_get_or_add_var(ctx, user_data, name, strlen(name)))
+#define GRN_PROC_ALLOC(domain, flags) (grn_proc_alloc(ctx, user_data, domain, flags))
+
+grn_obj *grn_proc_get_vars(grn_ctx *ctx, grn_user_data *user_data);
+
+grn_obj *grn_proc_get_var(grn_ctx *ctx, grn_user_data *user_data,
+ const char *name, unsigned int name_size);
+
+GRN_API grn_obj *grn_proc_get_var_by_offset(grn_ctx *ctx, grn_user_data *user_data,
+ unsigned int offset);
+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, unsigned char flags);
+
+GRN_API grn_rc grn_proc_call(grn_ctx *ctx, grn_obj *proc,
+ int nargs, grn_obj *caller);
+
+grn_obj *grn_expr_get_or_add_var(grn_ctx *ctx, grn_obj *expr,
+ const char *name, unsigned int name_size);
+
+
+typedef struct _grn_accessor grn_accessor;
+
+struct _grn_accessor {
+ grn_obj_header header;
+ grn_id range;
+ /* -- compatible with grn_db_obj -- */
+ uint8_t action;
+ int offset;
+ grn_obj *obj;
+ grn_accessor *next;
+};
+
+enum {
+ GRN_ACCESSOR_VOID = 0,
+ GRN_ACCESSOR_GET_ID,
+ GRN_ACCESSOR_GET_KEY,
+ GRN_ACCESSOR_GET_VALUE,
+ GRN_ACCESSOR_GET_SCORE,
+ GRN_ACCESSOR_GET_NSUBRECS,
+ GRN_ACCESSOR_GET_MAX,
+ GRN_ACCESSOR_GET_MIN,
+ GRN_ACCESSOR_GET_SUM,
+ GRN_ACCESSOR_GET_AVG,
+ GRN_ACCESSOR_GET_COLUMN_VALUE,
+ GRN_ACCESSOR_GET_DB_OBJ,
+ GRN_ACCESSOR_LOOKUP,
+ GRN_ACCESSOR_FUNCALL
+};
+
+#define DB_OBJ(obj) ((grn_db_obj *)obj)
+
+GRN_API const char *grn_obj_get_value_(grn_ctx *ctx, grn_obj *obj, grn_id id, uint32_t *size);
+
+/* vector */
+
+/*
+typedef struct _grn_vector grn_vector;
+
+struct _grn_vector {
+ grn_obj str;
+ uint32_t *offsets;
+ int n_entries;
+};
+
+const char *grn_vector_fetch(grn_ctx *ctx, grn_obj *vector, int i, unsigned int *size);
+int grn_vector_delimit(grn_ctx *ctx, grn_obj *vector);
+int grn_vector_size(grn_ctx *ctx, grn_obj *vector);
+*/
+
+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);
+
+
+grn_rc grn_db_init_builtin_types(grn_ctx *ctx);
+
+/* flag value used for grn_obj.header.flags */
+
+#define GRN_OBJ_CUSTOM_NAME (0x01<<12) /* db_obj which has custom name */
+
+#define GRN_OBJ_RESOLVE(ctx,obj) \
+ (((obj)->header.type != GRN_PTR)\
+ ? (obj)\
+ : GRN_PTR_VALUE(obj)\
+ ? GRN_PTR_VALUE(obj)\
+ : grn_ctx_at((ctx), (obj)->header.domain))
+
+/* expr */
+
+typedef struct _grn_expr grn_expr;
+
+#define GRN_EXPR_CODE_RELATIONAL_EXPRESSION (0x01)
+
+typedef struct {
+ grn_obj *value;
+ int32_t nargs;
+ grn_operator op;
+ uint8_t flags;
+ 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;
+ grn_expr_var *vars;
+ uint32_t nvars;
+ /* -- compatible with grn_proc -- */
+
+ uint16_t cacheable;
+ uint16_t taintable;
+ grn_obj **const_blks;
+ grn_obj *values;
+ grn_expr_code *codes;
+ uint32_t nconsts;
+ uint32_t values_curr;
+ uint32_t values_tail;
+ uint32_t values_size;
+ uint32_t codes_curr;
+ uint32_t codes_size;
+
+ grn_obj objs;
+ grn_obj dfi;
+ grn_expr_code *code0;
+};
+
+grn_rc grn_expr_parser_close(grn_ctx *ctx);
+
+/**
+ * grn_table_open:
+ * @name: The table name to be opened. `NULL` means anonymous table.
+ * @path: The path of the table to be opened.
+ *
+ * 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,
+ const char *path);
+
+/**
+ * grn_column_open:
+ * @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.
+ *
+ * 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,
+ const char *path, grn_obj *type);
+
+/**
+ * grn_obj_path_rename:
+ * @old_path: The current file path.
+ * @new_path: The new file 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);
+
+grn_rc grn_db_check_name(grn_ctx *ctx, const char *name, unsigned int name_size);
+#define GRN_DB_CHECK_NAME_ERR(error_context, name, name_size) \
+ ERR(GRN_INVALID_ARGUMENT,\
+ "%s name can't start with '%c' and contains only 0-9, A-Z, a-z, #, @, - or _: <%.*s>",\
+ error_context, GRN_DB_PSEUDO_COLUMN_PREFIX, name_size, name)
+
+#define GRN_DB_P(s) ((s) && ((grn_db *)s)->obj.header.type == GRN_DB)
+#define GRN_DB_PERSISTENT_P(s) (((grn_db *)s)->specs)
+
+#define GRN_OBJ_GET_VALUE_IMD (0xffffffffU)
+
+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))
+
+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);
+
+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 grn_rc grn_table_group_with_range_gap(grn_ctx *ctx, grn_obj *table,
+ grn_table_sort_key *group_key,
+ grn_obj *result_set,
+ uint32_t range_gap);
+
+GRN_API grn_rc grn_column_filter(grn_ctx *ctx, grn_obj *column,
+ grn_operator op,
+ grn_obj *value, grn_obj *result_set,
+ grn_operator set_op);
+
+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
diff --git a/storage/mroonga/vendor/groonga/lib/grn_ecmascript.c b/storage/mroonga/vendor/groonga/lib/grn_ecmascript.c
new file mode 100644
index 00000000..cfabcc91
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_ecmascript.c
@@ -0,0 +1,2542 @@
+/*
+** 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:
+*/
+#include <stdio.h>
+/************ Begin %include sections from the grammar ************************/
+#line 4 "grn_ecmascript.lemon"
+
+#ifdef assert
+# undef assert
+#endif
+#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 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
+** (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 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
+** 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 115
+#define YYACTIONTYPE unsigned short int
+#define grn_expr_parserTOKENTYPE int
+typedef union {
+ int yyinit;
+ grn_expr_parserTOKENTYPE yy0;
+ void * yy217;
+} YYMINORTYPE;
+#ifndef YYSTACKDEPTH
+#define YYSTACKDEPTH 100
+#endif
+#define grn_expr_parserARG_SDECL efs_info *efsi ;
+#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 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.
+**
+** Applications can choose to define yytestcase() in the %include section
+** to a macro that can assist in verifying code coverage. For production
+** code the yytestcase() macro should be turned off. But it is useful
+** for testing.
+*/
+#ifndef yytestcase
+# define yytestcase(X)
+#endif
+
+
+/* Next are the tables used to determine what action to take based on the
+** current state and lookahead token. These tables are used to implement
+** functions that take a state number and lookahead value and return an
+** action integer.
+**
+** Suppose the action integer is N. Then the action is determined as
+** follows
+**
+** 0 <= N <= YY_MAX_SHIFT Shift N. That is, push the lookahead
+** token onto the stack and goto state N.
+**
+** 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 == YY_ERROR_ACTION A syntax error has occurred.
+**
+** N == YY_ACCEPT_ACTION The parser accepts its input.
+**
+** 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 either:
+**
+** (A) N = yy_action[ yy_shift_ofst[S] + X ]
+** (B) N = yy_default[S]
+**
+** 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 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
+** YY_SHIFT_USE_DFLT.
+**
+** The following are the tables generated in this section:
+**
+** yy_action[] A single table containing all actions.
+** yy_lookahead[] A table containing the lookahead for each entry in
+** yy_action. Used to detect hash collisions.
+** yy_shift_ofst[] For each state, the offset into yy_action for
+** shifting terminals.
+** 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.
+**
+*********** Begin parsing tables **********************************************/
+#define YY_ACTTAB_COUNT (1794)
+static const YYACTIONTYPE yy_action[] = {
+ /* 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, 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 */ 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, 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 (1794)
+#define YY_SHIFT_COUNT (144)
+#define YY_SHIFT_MIN (-60)
+#define YY_SHIFT_MAX (1166)
+static const short yy_shift_ofst[] = {
+ /* 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 (-106)
+#define YY_REDUCE_COUNT (87)
+#define YY_REDUCE_MIN (-105)
+#define YY_REDUCE_MAX (1689)
+static const short yy_reduce_ofst[] = {
+ /* 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 */ 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 (terminal symbols) into fallback tokens.
+** If a construct like the following:
+**
+** %fallback ID X Y Z.
+**
+** appears in the grammar, then ID becomes a fallback token for X, Y,
+** 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[] = {
+};
+#endif /* YYFALLBACK */
+
+/* The following structure represents a single element of the
+** parser's stack. Information stored includes:
+**
+** + The state number for the parser at this level of the stack.
+**
+** + The value of the token stored at this level of the stack.
+** (In other words, the "major" token.)
+**
+** + 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, 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
+ ** is the value of the token */
+};
+typedef struct yyStackEntry yyStackEntry;
+
+/* The state of the parser is completely contained in an instance of
+** the following structure */
+struct yyParser {
+ yyStackEntry *yytos; /* Pointer to top element of the stack */
+#ifdef YYTRACKMAXSTACKDEPTH
+ 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
+};
+typedef struct yyParser yyParser;
+
+#ifndef NDEBUG
+#include <stdio.h>
+static FILE *yyTraceFILE = 0;
+static char *yyTracePrompt = 0;
+#endif /* NDEBUG */
+
+#ifndef NDEBUG
+/*
+** Turn parser tracing on by giving a stream to which to write the trace
+** and a prompt to preface each trace message. Tracing is turned off
+** by making either argument NULL
+**
+** Inputs:
+** <ul>
+** <li> A FILE* to which trace output should be written.
+** If NULL, then tracing is turned off.
+** <li> A prefix string written at the beginning of every
+** line of trace output. If NULL, then tracing is
+** turned off.
+** </ul>
+**
+** Outputs:
+** None.
+*/
+void grn_expr_parserTrace(FILE *TraceFILE, char *zTracePrompt){
+ yyTraceFILE = TraceFILE;
+ yyTracePrompt = zTracePrompt;
+ if( yyTraceFILE==0 ) yyTracePrompt = 0;
+ else if( yyTracePrompt==0 ) yyTraceFILE = 0;
+}
+#endif /* NDEBUG */
+
+#ifndef NDEBUG
+/* For tracing shifts, the names of all terminals and nonterminals
+** 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", "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 */
+
+#ifndef NDEBUG
+/* For tracing reduce actions, the names of all rules are required.
+*/
+static const char *const yyRuleName[] = {
+ /* 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. Return the number
+** of errors. Return 0 on success.
+*/
+static int yyGrowStack(yyParser *p){
+ int newSize;
+ int idx;
+ yyStackEntry *pNew;
+
+ newSize = p->yystksz*2 + 100;
+ 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->yytos = &p->yystack[idx];
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ 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
+** malloc.
+**
+** Inputs:
+** A pointer to the function used to allocate memory.
+**
+** Outputs:
+** 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)(YYMALLOCARGTYPE)){
+ yyParser *pParser;
+ pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) );
+ if( pParser ) grn_expr_parserInit(pParser);
+ return pParser;
+}
+#endif /* grn_expr_parser_ENGINEALWAYSONSTACK */
+
+
+/* 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 */
+ YYCODETYPE yymajor, /* Type code for object to destroy */
+ YYMINORTYPE *yypminor /* The object to be destroyed */
+){
+ grn_expr_parserARG_FETCH;
+ switch( yymajor ){
+ /* Here is inserted the actions which take place when a
+ ** terminal or non-terminal is destroyed. This can happen
+ ** when the symbol is popped from the stack during a
+ ** reduce or during error processing or when a parser is
+ ** 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
+ ** inside the C code.
+ */
+/********* Begin destructor definitions ***************************************/
+ case 76: /* suppress_unused_variable_warning */
+{
+#line 14 "grn_ecmascript.lemon"
+
+ (void)efsi;
+
+#line 1006 "grn_ecmascript.c"
+}
+ break;
+/********* End destructor definitions *****************************************/
+ default: break; /* If no destructor action specified: do nothing */
+ }
+}
+
+/*
+** Pop the parser's stack once.
+**
+** If there is a destructor routine associated with the token which
+** is popped from the stack, then call it.
+*/
+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 ){
+ fprintf(yyTraceFILE,"%sPopping %s\n",
+ yyTracePrompt,
+ yyTokenName[yytos->major]);
+ }
+#endif
+ 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 called for
+** all stack elements before shutting the parser down.
+**
+** 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 */
+){
+#ifndef YYPARSEFREENEVERNULL
+ if( p==0 ) return;
+#endif
+ grn_expr_parserFinalize(p);
+ (*freeProc)(p);
+}
+#endif /* grn_expr_parser_ENGINEALWAYSONSTACK */
+
+/*
+** Return the peak depth of the stack for a parser.
+*/
+#ifdef YYTRACKMAXSTACKDEPTH
+int grn_expr_parserStackPeak(void *p){
+ yyParser *pParser = (yyParser*)p;
+ return pParser->yyhwm;
+}
+#endif
+
+/*
+** Find the appropriate action for a parser given the terminal
+** look-ahead token iLookAhead.
+*/
+static unsigned int yy_find_shift_action(
+ yyParser *pParser, /* The parser */
+ YYCODETYPE iLookAhead /* The look-ahead token */
+){
+ int i;
+ int stateno = pParser->yytos->stateno;
+
+ 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])
+ && (iFallback = yyFallback[iLookAhead])!=0 ){
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
+ yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
+ }
+#endif
+ assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */
+ iLookAhead = iFallback;
+ continue;
+ }
+#endif
+#ifdef YYWILDCARD
+ {
+ int j = i - iLookAhead + YYWILDCARD;
+ if(
+#if YY_SHIFT_MIN+YYWILDCARD<0
+ j>=0 &&
+#endif
+#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
+ j<YY_ACTTAB_COUNT &&
+#endif
+ yy_lookahead[j]==YYWILDCARD && iLookAhead>0
+ ){
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
+ yyTracePrompt, yyTokenName[iLookAhead],
+ yyTokenName[YYWILDCARD]);
+ }
+#endif /* NDEBUG */
+ return yy_action[j];
+ }
+ }
+#endif /* YYWILDCARD */
+ 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.
+*/
+static int yy_find_reduce_action(
+ int stateno, /* Current state number */
+ YYCODETYPE iLookAhead /* The look-ahead token */
+){
+ int i;
+#ifdef YYERRORSYMBOL
+ if( stateno>YY_REDUCE_COUNT ){
+ return yy_default[stateno];
+ }
+#else
+ assert( stateno<=YY_REDUCE_COUNT );
+#endif
+ i = yy_reduce_ofst[stateno];
+ assert( i!=YY_REDUCE_USE_DFLT );
+ assert( iLookAhead!=YYNOCODE );
+ i += iLookAhead;
+#ifdef YYERRORSYMBOL
+ if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
+ return yy_default[stateno];
+ }
+#else
+ assert( i>=0 && i<YY_ACTTAB_COUNT );
+ assert( yy_lookahead[i]==iLookAhead );
+#endif
+ return yy_action[i];
+}
+
+/*
+** The following routine is called if the stack overflows.
+*/
+static void yyStackOverflow(yyParser *yypParser){
+ grn_expr_parserARG_FETCH;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
+ }
+#endif
+ 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 */
+ grn_expr_parserTOKENTYPE yyMinor /* The minor token to shift in */
+){
+ yyStackEntry *yytos;
+ yypParser->yytos++;
+#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] ){
+ yypParser->yytos--;
+ yyStackOverflow(yypParser);
+ return;
+ }
+#else
+ if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){
+ if( yyGrowStack(yypParser) ){
+ yypParser->yytos--;
+ yyStackOverflow(yypParser);
+ return;
+ }
+ }
+#endif
+ 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.yy0 = yyMinor;
+ yyTraceShift(yypParser, yyNewState);
+}
+
+/* The following table contains information about every rule that
+** is used during the reduce.
+*/
+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[] = {
+ { 78, 2 },
+ { 78, 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, 3 },
+ { 88, 3 },
+ { 89, 3 },
+ { 90, 3 },
+ { 91, 3 },
+ { 92, 3 },
+ { 92, 3 },
+ { 93, 3 },
+ { 93, 3 },
+ { 93, 3 },
+ { 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, 3 },
+ { 95, 3 },
+ { 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 },
+ { 98, 2 },
+ { 98, 2 },
+ { 99, 2 },
+ { 103, 3 },
+ { 107, 0 },
+ { 108, 3 },
+ { 102, 3 },
+ { 101, 3 },
+ { 110, 0 },
+ { 110, 1 },
+ { 110, 3 },
+ { 80, 0 },
+ { 80, 1 },
+ { 80, 2 },
+ { 80, 3 },
+ { 111, 1 },
+ { 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 */
+
+/*
+** Perform a reduce action and the shift that must immediately
+** follow the reduce.
+*/
+static void yy_reduce(
+ yyParser *yypParser, /* The parser */
+ unsigned int yyruleno /* Number of the rule by which to reduce */
+){
+ int yygoto; /* The next state */
+ int yyact; /* The next action */
+ yyStackEntry *yymsp; /* The top of the parser's stack */
+ int yysize; /* Amount to pop the stack */
+ grn_expr_parserARG_FETCH;
+ yymsp = yypParser->yytos;
+#ifndef NDEBUG
+ 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 */
+
+ /* 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
+ ** follows:
+ ** case 0:
+ ** #line <lineno> <grammarfile>
+ ** { ... } // User supplied code
+ ** #line <lineno> <thisfile>
+ ** break;
+ */
+/********** 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 1462 "grn_ecmascript.c"
+ break;
+ 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 1470 "grn_ecmascript.c"
+ break;
+ 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 1478 "grn_ecmascript.c"
+ break;
+ 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 1486 "grn_ecmascript.c"
+ break;
+ 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 1511 "grn_ecmascript.c"
+ break;
+ case 7: /* query_element ::= IDENTIFIER RELATIVE_OP query_element */
+#line 82 "grn_ecmascript.lemon"
+{
+ int mode;
+ grn_obj *c;
+ GRN_PTR_POP(&efsi->column_stack, c);
+ GRN_INT32_POP(&efsi->mode_stack, mode);
+ switch (mode) {
+ case GRN_OP_NEAR :
+ case GRN_OP_NEAR2 :
+ {
+ int max_interval;
+ GRN_INT32_POP(&efsi->max_interval_stack, max_interval);
+ }
+ break;
+ case GRN_OP_SIMILAR :
+ {
+ int similarity_threshold;
+ GRN_INT32_POP(&efsi->similarity_threshold_stack, similarity_threshold);
+ }
+ break;
+ default :
+ break;
+ }
+}
+#line 1538 "grn_ecmascript.c"
+ break;
+ 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 1546 "grn_ecmascript.c"
+ break;
+ 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 1553 "grn_ecmascript.c"
+ break;
+ 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 1560 "grn_ecmascript.c"
+ break;
+ 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 1567 "grn_ecmascript.c"
+ break;
+ 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 1574 "grn_ecmascript.c"
+ break;
+ 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 1581 "grn_ecmascript.c"
+ break;
+ 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 1588 "grn_ecmascript.c"
+ break;
+ 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 1595 "grn_ecmascript.c"
+ break;
+ 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 1602 "grn_ecmascript.c"
+ break;
+ 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 1609 "grn_ecmascript.c"
+ break;
+ 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 1616 "grn_ecmascript.c"
+ break;
+ 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 1623 "grn_ecmascript.c"
+ break;
+ 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 1630 "grn_ecmascript.c"
+ break;
+ 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 1637 "grn_ecmascript.c"
+ break;
+ 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 1646 "grn_ecmascript.c"
+ break;
+ 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 1653 "grn_ecmascript.c"
+ break;
+ 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 1660 "grn_ecmascript.c"
+ break;
+ 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 1667 "grn_ecmascript.c"
+ break;
+ 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 1674 "grn_ecmascript.c"
+ break;
+ 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 1681 "grn_ecmascript.c"
+ break;
+ 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 1688 "grn_ecmascript.c"
+ break;
+ 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 1695 "grn_ecmascript.c"
+ break;
+ 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 1702 "grn_ecmascript.c"
+ break;
+ 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 1709 "grn_ecmascript.c"
+ break;
+ 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 1716 "grn_ecmascript.c"
+ break;
+ 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 1724 "grn_ecmascript.c"
+ break;
+ case 38: /* relational_expression ::= relational_expression NEAR shift_expression */
+#line 217 "grn_ecmascript.lemon"
+{
+ {
+ 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 1737 "grn_ecmascript.c"
+ break;
+ 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 1744 "grn_ecmascript.c"
+ break;
+ 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 1751 "grn_ecmascript.c"
+ break;
+ 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 1758 "grn_ecmascript.c"
+ break;
+ 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 1765 "grn_ecmascript.c"
+ break;
+ 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 1772 "grn_ecmascript.c"
+ break;
+ 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 1779 "grn_ecmascript.c"
+ break;
+ 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 1786 "grn_ecmascript.c"
+ break;
+ 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 1793 "grn_ecmascript.c"
+ break;
+ 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 1800 "grn_ecmascript.c"
+ break;
+ 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 1807 "grn_ecmascript.c"
+ break;
+ 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 1815 "grn_ecmascript.c"
+ break;
+ 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 1822 "grn_ecmascript.c"
+ break;
+ 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 1830 "grn_ecmascript.c"
+ break;
+ 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 1837 "grn_ecmascript.c"
+ break;
+ 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 1844 "grn_ecmascript.c"
+ break;
+ 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 1851 "grn_ecmascript.c"
+ break;
+ 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_ = grn_expr_dfi_pop(e);
+ const_p = CONSTP(dfi_->code->value);
+ 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>",
+ (int)(efsi->str_end - efsi->str), efsi->str);
+ } else {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_INCR, 1);
+ }
+}
+#line 1872 "grn_ecmascript.c"
+ break;
+ 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_ = grn_expr_dfi_pop(e);
+ const_p = CONSTP(dfi_->code->value);
+ 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>",
+ (int)(efsi->str_end - efsi->str), efsi->str);
+ } else {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DECR, 1);
+ }
+}
+#line 1893 "grn_ecmascript.c"
+ break;
+ 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 1900 "grn_ecmascript.c"
+ break;
+ 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 1907 "grn_ecmascript.c"
+ break;
+ 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 1914 "grn_ecmascript.c"
+ break;
+ 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 1921 "grn_ecmascript.c"
+ break;
+ 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 1928 "grn_ecmascript.c"
+ break;
+ 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 1935 "grn_ecmascript.c"
+ break;
+ 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 1942 "grn_ecmascript.c"
+ break;
+ 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 1949 "grn_ecmascript.c"
+ break;
+ 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_ = grn_expr_dfi_pop(e);
+ const_p = CONSTP(dfi_->code->value);
+ 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>",
+ (int)(efsi->str_end - efsi->str), efsi->str);
+ } else {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_INCR_POST, 1);
+ }
+}
+#line 1970 "grn_ecmascript.c"
+ break;
+ 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_ = grn_expr_dfi_pop(e);
+ const_p = CONSTP(dfi_->code->value);
+ 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>",
+ (int)(efsi->str_end - efsi->str), efsi->str);
+ } else {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DECR_POST, 1);
+ }
+}
+#line 1991 "grn_ecmascript.c"
+ break;
+ 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 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 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 2077 "grn_ecmascript.c"
+ break;
+ 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 73: /* argument_list ::= */
+#line 481 "grn_ecmascript.lemon"
+{ yymsp[1].minor.yy0 = 0; }
+#line 2087 "grn_ecmascript.c"
+ break;
+ case 74: /* argument_list ::= assignment_expression */
+#line 482 "grn_ecmascript.lemon"
+{ yymsp[0].minor.yy0 = 1; }
+#line 2092 "grn_ecmascript.c"
+ break;
+ 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 76: /* output_columns ::= */
+#line 485 "grn_ecmascript.lemon"
+{
+ yymsp[1].minor.yy0 = 0;
+}
+#line 2105 "grn_ecmascript.c"
+ break;
+ case 77: /* output_columns ::= output_column */
+#line 488 "grn_ecmascript.lemon"
+{
+ 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 2120 "grn_ecmascript.c"
+ yymsp[-1].minor.yy0 = yylhsminor.yy0;
+ break;
+ case 79: /* output_columns ::= output_columns COMMA output_column */
+#line 498 "grn_ecmascript.lemon"
+{
+ 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[0].minor.yy0 == 1) {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_COMMA, 2);
+ }
+ yylhsminor.yy0 = 1;
+ }
+}
+#line 2137 "grn_ecmascript.c"
+ yymsp[-2].minor.yy0 = yylhsminor.yy0;
+ break;
+ case 80: /* output_column ::= STAR */
+#line 511 "grn_ecmascript.lemon"
+{
+ grn_ctx *ctx = efsi->ctx;
+ grn_obj *expr = efsi->e;
+ 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;
+
+ 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);
+
+ 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_OBJ_FIN(ctx, &columns_buffer);
+
+ yymsp[0].minor.yy0 = n_columns;
+ } else {
+ /* TODO: report error */
+ yymsp[0].minor.yy0 = 0;
+ }
+}
+#line 2192 "grn_ecmascript.c"
+ break;
+ case 81: /* output_column ::= NONEXISTENT_COLUMN */
+#line 561 "grn_ecmascript.lemon"
+{
+ yymsp[0].minor.yy0 = 0;
+}
+#line 2199 "grn_ecmascript.c"
+ break;
+ case 82: /* output_column ::= assignment_expression */
+#line 564 "grn_ecmascript.lemon"
+{
+ yymsp[0].minor.yy0 = 1;
+}
+#line 2206 "grn_ecmascript.c"
+ break;
+ default:
+ /* (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;
+ yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
+ 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 == YY_ACCEPT_ACTION );
+ yypParser->yytos -= yysize;
+ yy_accept(yypParser);
+ }
+}
+
+/*
+** The following code executes when the parse fails
+*/
+#ifndef YYNOERRORRECOVERY
+static void yy_parse_failed(
+ yyParser *yypParser /* The parser */
+){
+ grn_expr_parserARG_FETCH;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
+ }
+#endif
+ 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 */
+
+/*
+** The following code executes when a syntax error first occurs.
+*/
+static void yy_syntax_error(
+ yyParser *yypParser, /* The parser */
+ int yymajor, /* The major type of the error token */
+ grn_expr_parserTOKENTYPE yyminor /* The minor type of the error token */
+){
+ grn_expr_parserARG_FETCH;
+#define TOKEN yyminor
+/************ Begin %syntax_error code ****************************************/
+#line 20 "grn_ecmascript.lemon"
+
+ {
+ grn_ctx *ctx = efsi->ctx;
+ 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, '|');
+ 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));
+ } 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 2341 "grn_ecmascript.c"
+/************ End %syntax_error code ******************************************/
+ grn_expr_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+}
+
+/*
+** The following is executed when the parser accepts
+*/
+static void yy_accept(
+ yyParser *yypParser /* The parser */
+){
+ grn_expr_parserARG_FETCH;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
+ }
+#endif
+#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 */
+}
+
+/* The main parser program.
+** The first argument is a pointer to a structure obtained from
+** "grn_expr_parserAlloc" which describes the current state of the parser.
+** The second argument is the major token number. The third is
+** the minor token. The fourth optional argument is whatever the
+** user wants (and specified in the grammar) and is available for
+** use by the action routines.
+**
+** Inputs:
+** <ul>
+** <li> A pointer to the parser (an opaque structure.)
+** <li> The major token number.
+** <li> The minor token number.
+** <li> An option argument of a grammar-specified type.
+** </ul>
+**
+** Outputs:
+** None.
+*/
+void grn_expr_parser(
+ void *yyp, /* The parser */
+ int yymajor, /* The major token code number */
+ grn_expr_parserTOKENTYPE yyminor /* The value for the token */
+ grn_expr_parserARG_PDECL /* Optional %extra_argument parameter */
+){
+ YYMINORTYPE yyminorunion;
+ 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 */
+
+ yypParser = (yyParser*)yyp;
+ 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]);
+ }
+#endif
+
+ do{
+ yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
+ if( yyact <= YY_MAX_SHIFTREDUCE ){
+ yy_shift(yypParser,yyact,yymajor,yyminor);
+#ifndef YYNOERRORRECOVERY
+ yypParser->yyerrcnt--;
+#endif
+ yymajor = YYNOCODE;
+ }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
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt);
+ }
+#endif
+#ifdef YYERRORSYMBOL
+ /* A syntax error has occurred.
+ ** The response to an error depends upon whether or not the
+ ** grammar defines an error token "ERROR".
+ **
+ ** This is what we do if the grammar does define ERROR:
+ **
+ ** * Call the %syntax_error function.
+ **
+ ** * Begin popping the stack until we enter a state where
+ ** it is legal to shift the error symbol, then shift
+ ** the error symbol.
+ **
+ ** * Set the error count to three.
+ **
+ ** * Begin accepting and shifting new tokens. No new error
+ ** processing will occur until three tokens have been
+ ** shifted successfully.
+ **
+ */
+ if( yypParser->yyerrcnt<0 ){
+ yy_syntax_error(yypParser,yymajor,yyminor);
+ }
+ yymx = yypParser->yytos->major;
+ if( yymx==YYERRORSYMBOL || yyerrorhit ){
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sDiscard input token %s\n",
+ yyTracePrompt,yyTokenName[yymajor]);
+ }
+#endif
+ yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
+ yymajor = YYNOCODE;
+ }else{
+ 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->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 ){
+ yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor);
+ }
+ }
+ yypParser->yyerrcnt = 3;
+ yyerrorhit = 1;
+#elif defined(YYNOERRORRECOVERY)
+ /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to
+ ** do any kind of error recovery. Instead, simply invoke the syntax
+ ** error routine and continue going as if nothing had happened.
+ **
+ ** 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, yyminor);
+ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
+ yymajor = YYNOCODE;
+
+#else /* YYERRORSYMBOL is not defined */
+ /* This is what we do if the grammar does not define ERROR:
+ **
+ ** * Report an error message, and throw away the input token.
+ **
+ ** * If the input token is $, then fail the parse.
+ **
+ ** As before, subsequent error messages are suppressed until
+ ** three input tokens have been successfully shifted.
+ */
+ if( yypParser->yyerrcnt<=0 ){
+ 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->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
new file mode 100644
index 00000000..15272b0a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_ecmascript.h
@@ -0,0 +1,74 @@
+#define GRN_EXPR_TOKEN_START_OUTPUT_COLUMNS 1
+#define GRN_EXPR_TOKEN_START_ADJUSTER 2
+#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_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
new file mode 100644
index 00000000..234ea41c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_ecmascript.lemon
@@ -0,0 +1,581 @@
+/* -*- mode: c; c-basic-offset: 2 -*- */
+%name grn_expr_parser
+%token_prefix GRN_EXPR_TOKEN_
+%include {
+#ifdef assert
+# undef assert
+#endif
+#define assert GRN_ASSERT
+}
+
+%token_type { int }
+
+%type suppress_unused_variable_warning { void * }
+%destructor suppress_unused_variable_warning {
+ (void)efsi;
+}
+
+%extra_argument { efs_info *efsi }
+
+%syntax_error {
+ {
+ grn_ctx *ctx = efsi->ctx;
+ 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, '|');
+ 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));
+ } else {
+ ERR(ctx->rc, "Syntax error: <%.*s>: %s",
+ (int)GRN_TEXT_LEN(&message), GRN_TEXT_VALUE(&message),
+ ctx->errbuf);
+ }
+ GRN_OBJ_FIN(ctx, &message);
+ }
+}
+
+input ::= query.
+input ::= expression.
+input ::= START_OUTPUT_COLUMNS output_columns.
+input ::= START_ADJUSTER adjuster.
+
+query ::= query_element.
+query ::= query query_element. {
+ grn_expr_append_op(efsi->ctx, efsi->e, grn_int32_value_at(&efsi->op_stack, -1), 2);
+}
+query ::= query LOGICAL_AND query_element. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND, 2);
+}
+query ::= query LOGICAL_AND_NOT query_element.{
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND_NOT, 2);
+}
+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);
+}
+query_element ::= IDENTIFIER RELATIVE_OP query_element. {
+ int mode;
+ grn_obj *c;
+ GRN_PTR_POP(&efsi->column_stack, c);
+ GRN_INT32_POP(&efsi->mode_stack, mode);
+ switch (mode) {
+ case GRN_OP_NEAR :
+ case GRN_OP_NEAR2 :
+ {
+ int max_interval;
+ GRN_INT32_POP(&efsi->max_interval_stack, max_interval);
+ }
+ break;
+ case GRN_OP_SIMILAR :
+ {
+ int similarity_threshold;
+ GRN_INT32_POP(&efsi->similarity_threshold_stack, similarity_threshold);
+ }
+ break;
+ default :
+ break;
+ }
+}
+query_element ::= BRACEL expression BRACER. {
+ efsi->flags = efsi->default_flags;
+}
+query_element ::= EVAL primary_expression. {
+ efsi->flags = efsi->default_flags;
+}
+
+expression ::= assignment_expression.
+expression ::= expression COMMA assignment_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_COMMA, 2);
+}
+
+assignment_expression ::= conditional_expression.
+assignment_expression ::= lefthand_side_expression ASSIGN assignment_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_ASSIGN, 2);
+}
+assignment_expression ::= lefthand_side_expression STAR_ASSIGN assignment_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_STAR_ASSIGN, 2);
+}
+assignment_expression ::= lefthand_side_expression SLASH_ASSIGN assignment_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SLASH_ASSIGN, 2);
+}
+assignment_expression ::= lefthand_side_expression MOD_ASSIGN assignment_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MOD_ASSIGN, 2);
+}
+assignment_expression ::= lefthand_side_expression PLUS_ASSIGN assignment_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PLUS_ASSIGN, 2);
+}
+assignment_expression ::= lefthand_side_expression MINUS_ASSIGN assignment_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MINUS_ASSIGN, 2);
+}
+assignment_expression ::= lefthand_side_expression SHIFTL_ASSIGN assignment_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTL_ASSIGN, 2);
+}
+assignment_expression ::= lefthand_side_expression SHIFTR_ASSIGN assignment_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTR_ASSIGN, 2);
+}
+assignment_expression ::= lefthand_side_expression SHIFTRR_ASSIGN assignment_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTRR_ASSIGN, 2);
+}
+assignment_expression ::= lefthand_side_expression AND_ASSIGN assignment_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND_ASSIGN, 2);
+}
+assignment_expression ::= lefthand_side_expression XOR_ASSIGN assignment_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_XOR_ASSIGN, 2);
+}
+assignment_expression ::= lefthand_side_expression OR_ASSIGN assignment_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_OR_ASSIGN, 2);
+}
+
+conditional_expression ::= logical_or_expression.
+conditional_expression ::= logical_or_expression QUESTION(A) assignment_expression COLON(B) assignment_expression. {
+ grn_expr *e = (grn_expr *)efsi->e;
+ e->codes[A].nargs = B - A;
+ e->codes[B].nargs = e->codes_curr - B - 1;
+}
+
+logical_or_expression ::= logical_and_expression.
+logical_or_expression ::= logical_or_expression LOGICAL_OR logical_and_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_OR, 2);
+}
+
+logical_and_expression ::= bitwise_or_expression.
+logical_and_expression ::= logical_and_expression LOGICAL_AND bitwise_or_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND, 2);
+}
+logical_and_expression ::= logical_and_expression LOGICAL_AND_NOT bitwise_or_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND_NOT, 2);
+}
+
+bitwise_or_expression ::= bitwise_xor_expression.
+bitwise_or_expression ::= bitwise_or_expression BITWISE_OR bitwise_xor_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_OR, 2);
+}
+
+bitwise_xor_expression ::= bitwise_and_expression.
+bitwise_xor_expression ::= bitwise_xor_expression BITWISE_XOR bitwise_and_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_XOR, 2);
+}
+
+bitwise_and_expression ::= equality_expression.
+bitwise_and_expression ::= bitwise_and_expression BITWISE_AND equality_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_AND, 2);
+}
+
+equality_expression ::= relational_expression.
+equality_expression ::= equality_expression EQUAL relational_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_EQUAL, 2);
+}
+equality_expression ::= equality_expression NOT_EQUAL relational_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NOT_EQUAL, 2);
+}
+
+relational_expression ::= shift_expression.
+relational_expression ::= relational_expression LESS shift_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_LESS, 2);
+}
+relational_expression ::= relational_expression GREATER shift_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_GREATER, 2);
+}
+relational_expression ::= relational_expression LESS_EQUAL shift_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_LESS_EQUAL, 2);
+}
+relational_expression ::= relational_expression GREATER_EQUAL shift_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_GREATER_EQUAL, 2);
+}
+relational_expression ::= relational_expression IN shift_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_IN, 2);
+}
+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. {
+ {
+ 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);
+}
+relational_expression ::= relational_expression SIMILAR shift_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SIMILAR, 2);
+}
+relational_expression ::= relational_expression TERM_EXTRACT shift_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_TERM_EXTRACT, 2);
+}
+relational_expression ::= relational_expression LCP shift_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_LCP, 2);
+}
+relational_expression ::= relational_expression PREFIX shift_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PREFIX, 2);
+}
+relational_expression ::= relational_expression SUFFIX shift_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SUFFIX, 2);
+}
+relational_expression ::= relational_expression REGEXP shift_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_REGEXP, 2);
+}
+
+shift_expression ::= additive_expression.
+shift_expression ::= shift_expression SHIFTL additive_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTL, 2);
+}
+shift_expression ::= shift_expression SHIFTR additive_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTR, 2);
+}
+shift_expression ::= shift_expression SHIFTRR additive_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTRR, 2);
+}
+
+additive_expression ::= multiplicative_expression.
+additive_expression ::= additive_expression PLUS multiplicative_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PLUS, 2);
+}
+additive_expression ::= additive_expression MINUS multiplicative_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MINUS, 2);
+}
+
+multiplicative_expression ::= unary_expression.
+multiplicative_expression ::= multiplicative_expression STAR unary_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_STAR, 2);
+}
+multiplicative_expression ::= multiplicative_expression SLASH unary_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SLASH, 2);
+}
+multiplicative_expression ::= multiplicative_expression MOD unary_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MOD, 2);
+}
+
+unary_expression ::= postfix_expression.
+unary_expression ::= DELETE unary_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DELETE, 1);
+}
+unary_expression ::= INCR unary_expression. {
+ grn_ctx *ctx = efsi->ctx;
+ grn_expr *e = (grn_expr *)(efsi->e);
+ grn_expr_dfi *dfi_;
+ unsigned int const_p;
+
+ dfi_ = grn_expr_dfi_pop(e);
+ const_p = CONSTP(dfi_->code->value);
+ 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>",
+ (int)(efsi->str_end - efsi->str), efsi->str);
+ } else {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_INCR, 1);
+ }
+}
+unary_expression ::= DECR unary_expression. {
+ grn_ctx *ctx = efsi->ctx;
+ grn_expr *e = (grn_expr *)(efsi->e);
+ grn_expr_dfi *dfi_;
+ unsigned int const_p;
+
+ dfi_ = grn_expr_dfi_pop(e);
+ const_p = CONSTP(dfi_->code->value);
+ 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>",
+ (int)(efsi->str_end - efsi->str), efsi->str);
+ } else {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DECR, 1);
+ }
+}
+unary_expression ::= PLUS unary_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PLUS, 1);
+}
+unary_expression ::= MINUS unary_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MINUS, 1);
+}
+unary_expression ::= NOT unary_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NOT, 1);
+}
+unary_expression ::= BITWISE_NOT unary_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_NOT, 1);
+}
+unary_expression ::= ADJUST unary_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_ADJUST, 1);
+}
+unary_expression ::= EXACT unary_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_EXACT, 1);
+}
+unary_expression ::= PARTIAL unary_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PARTIAL, 1);
+}
+unary_expression ::= UNSPLIT unary_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_UNSPLIT, 1);
+}
+
+postfix_expression ::= lefthand_side_expression.
+postfix_expression ::= lefthand_side_expression INCR. {
+ grn_ctx *ctx = efsi->ctx;
+ grn_expr *e = (grn_expr *)(efsi->e);
+ grn_expr_dfi *dfi_;
+ unsigned int const_p;
+
+ dfi_ = grn_expr_dfi_pop(e);
+ const_p = CONSTP(dfi_->code->value);
+ 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>",
+ (int)(efsi->str_end - efsi->str), efsi->str);
+ } else {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_INCR_POST, 1);
+ }
+}
+postfix_expression ::= lefthand_side_expression DECR. {
+ grn_ctx *ctx = efsi->ctx;
+ grn_expr *e = (grn_expr *)(efsi->e);
+ grn_expr_dfi *dfi_;
+ unsigned int const_p;
+
+ dfi_ = grn_expr_dfi_pop(e);
+ const_p = CONSTP(dfi_->code->value);
+ 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>",
+ (int)(efsi->str_end - efsi->str), efsi->str);
+ } else {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DECR_POST, 1);
+ }
+}
+
+lefthand_side_expression ::= call_expression.
+lefthand_side_expression ::= member_expression.
+
+call_expression ::= member_expression arguments(A). {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_CALL, A);
+}
+
+member_expression ::= primary_expression.
+member_expression ::= member_expression member_expression_part.
+
+primary_expression ::= object_literal.
+primary_expression ::= PARENL expression PARENR.
+primary_expression ::= IDENTIFIER.
+primary_expression ::= array_literal.
+primary_expression ::= DECIMAL.
+primary_expression ::= HEX_INTEGER.
+primary_expression ::= STRING.
+primary_expression ::= BOOLEAN.
+primary_expression ::= NULL.
+
+array_literal ::= BRACKETL elision BRACKETR.
+array_literal ::= BRACKETL element_list elision BRACKETR.
+array_literal ::= BRACKETL element_list BRACKETR.
+
+elision ::= COMMA.
+elision ::= elision COMMA.
+
+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. {
+ 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;
+
+ 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. {
+ 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);
+}
+member_expression_part ::= DOT IDENTIFIER.
+
+arguments(A) ::= PARENL argument_list(B) PARENR. { A = B; }
+argument_list(A) ::= . { A = 0; }
+argument_list(A) ::= assignment_expression. { A = 1; }
+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(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. {
+ 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 (NEW_N_STACKED_COLUMNS == 1) {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_COMMA, 2);
+ }
+ N_STACKED_COLUMNS = 1;
+ }
+}
+
+output_column(N_STACKED_COLUMNS) ::= STAR. {
+ grn_ctx *ctx = efsi->ctx;
+ grn_obj *expr = efsi->e;
+ 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;
+
+ 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);
+
+ 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_OBJ_FIN(ctx, &columns_buffer);
+
+ N_STACKED_COLUMNS = n_columns;
+ } else {
+ /* TODO: report error */
+ N_STACKED_COLUMNS = 0;
+ }
+}
+output_column(N_STACKED_COLUMNS) ::= NONEXISTENT_COLUMN. {
+ N_STACKED_COLUMNS = 0;
+}
+output_column(N_STACKED_COLUMNS) ::= assignment_expression. {
+ N_STACKED_COLUMNS = 1;
+}
+
+adjuster ::= .
+adjuster ::= adjust_expression.
+adjuster ::= adjuster PLUS adjust_expression. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PLUS, 2);
+}
+
+adjust_expression ::= adjust_match_expression.
+adjust_expression ::= adjust_match_expression STAR DECIMAL. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_STAR, 2);
+}
+
+adjust_match_expression ::= IDENTIFIER MATCH STRING. {
+ grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MATCH, 2);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/grn_error.h b/storage/mroonga/vendor/groonga/lib/grn_error.h
new file mode 100644
index 00000000..6917de83
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_error.h
@@ -0,0 +1,34 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+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
diff --git a/storage/mroonga/vendor/groonga/lib/grn_expr.h b/storage/mroonga/vendor/groonga/lib/grn_expr.h
new file mode 100644
index 00000000..e270e185
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_expr.h
@@ -0,0 +1,86 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn_db.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SCAN_ACCESSOR (0x01)
+#define SCAN_PUSH (0x02)
+#define SCAN_POP (0x04)
+#define SCAN_PRE_CONST (0x08)
+
+typedef enum {
+ SCAN_START = 0,
+ SCAN_VAR,
+ SCAN_COL1,
+ SCAN_COL2,
+ SCAN_CONST
+} scan_stat;
+
+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,
+ uint32_t sid, int32_t weight,
+ grn_obj *scorer,
+ grn_obj *scorer_args_expr,
+ uint32_t scorer_args_expr_offset);
+scan_info **grn_scan_info_put_logical_op(grn_ctx *ctx, scan_info **sis, int *ip,
+ grn_operator op, int start);
+int grn_scan_info_get_flags(scan_info *si);
+void grn_scan_info_set_flags(scan_info *si, int flags);
+grn_operator grn_scan_info_get_logical_op(scan_info *si);
+void grn_scan_info_set_logical_op(scan_info *si, grn_operator logical_op);
+grn_operator grn_scan_info_get_op(scan_info *si);
+void grn_scan_info_set_op(scan_info *si, grn_operator op);
+void grn_scan_info_set_end(scan_info *si, uint32_t end);
+void grn_scan_info_set_query(scan_info *si, grn_obj *query);
+int grn_scan_info_get_max_interval(scan_info *si);
+void grn_scan_info_set_max_interval(scan_info *si, int max_interval);
+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,
+ grn_obj *buffer,
+ grn_expr_code *code,
+ const char *indent);
+void grn_p_expr_code(grn_ctx *ctx, grn_expr_code *code);
+
+grn_obj *grn_expr_alloc_const(grn_ctx *ctx, grn_obj *expr);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_expr_code.h b/storage/mroonga/vendor/groonga/lib/grn_expr_code.h
new file mode 100644
index 00000000..48c907d5
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_expr_code.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-1335 USA
+*/
+
+#pragma once
+
+#include "grn_db.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+unsigned int grn_expr_code_n_used_codes(grn_ctx *ctx,
+ grn_expr_code *start,
+ grn_expr_code *target);
+
+#ifdef __cplusplus
+}
+#endif
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 00000000..1f2a1f4e
--- /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-1335 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 00000000..538e88af
--- /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-1335 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
new file mode 100644
index 00000000..9597336a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_geo.h
@@ -0,0 +1,200 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include "grn_ii.h"
+#include "grn_db.h"
+
+#if defined(WIN32) || defined(__sun)
+# define _USE_MATH_DEFINES
+# ifndef MAX
+# define MAX(a, b) ((a) > (b) ? (a) : (b))
+# endif
+
+# ifndef MIN
+# define MIN(a, b) ((a) < (b) ? (a) : (b))
+# endif
+#endif /* WIN32 or __sun */
+#include <math.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GRN_GEO_RESOLUTION 3600000
+#define GRN_GEO_RADIUS 6357303
+#define GRN_GEO_BES_C1 6334834
+#define GRN_GEO_BES_C2 6377397
+#define GRN_GEO_BES_C3 0.006674
+#define GRN_GEO_GRS_C1 6335439
+#define GRN_GEO_GRS_C2 6378137
+#define GRN_GEO_GRS_C3 0.006694
+#define GRN_GEO_INT2RAD(x) ((M_PI / (GRN_GEO_RESOLUTION * 180)) * (x))
+#define GRN_GEO_RAD2INT(x) ((int)(((GRN_GEO_RESOLUTION * 180) / M_PI) * (x)))
+
+#define GRN_GEO_MAX_LATITUDE 324000000 /* 90 * 60 * 60 * 1000 */
+#define GRN_GEO_MAX_LONGITUDE (648000000 - 1) /* 180 * 60 * 60 * 1000 - 1 */
+#define GRN_GEO_MIN_LATITUDE -GRN_GEO_MAX_LATITUDE
+#define GRN_GEO_MIN_LONGITUDE -GRN_GEO_MAX_LONGITUDE
+
+#define GRN_GEO_POINT_VALUE_RAW(obj) (grn_geo_point *)GRN_BULK_HEAD(obj)
+#define GRN_GEO_POINT_VALUE_RADIUS(obj,_latitude,_longitude) do {\
+ grn_geo_point *_val = (grn_geo_point *)GRN_BULK_HEAD(obj);\
+ _latitude = GRN_GEO_INT2RAD(_val->latitude);\
+ _longitude = GRN_GEO_INT2RAD(_val->longitude);\
+} while (0)
+
+#define GRN_GEO_KEY_MAX_BITS 64
+
+typedef enum {
+ GRN_GEO_APPROXIMATE_RECTANGLE,
+ GRN_GEO_APPROXIMATE_SPHERE,
+ GRN_GEO_APPROXIMATE_ELLIPSOID
+} grn_geo_approximate_type;
+
+typedef enum {
+ GRN_GEO_CURSOR_ENTRY_STATUS_NONE = 0,
+ GRN_GEO_CURSOR_ENTRY_STATUS_TOP_INCLUDED = 1 << 0,
+ GRN_GEO_CURSOR_ENTRY_STATUS_BOTTOM_INCLUDED = 1 << 1,
+ GRN_GEO_CURSOR_ENTRY_STATUS_LEFT_INCLUDED = 1 << 2,
+ GRN_GEO_CURSOR_ENTRY_STATUS_RIGHT_INCLUDED = 1 << 3,
+ GRN_GEO_CURSOR_ENTRY_STATUS_LATITUDE_INNER = 1 << 4,
+ GRN_GEO_CURSOR_ENTRY_STATUS_LONGITUDE_INNER = 1 << 5
+} grn_geo_cursor_entry_status_flag;
+
+typedef enum {
+ GRN_GEO_AREA_NORTH_EAST,
+ GRN_GEO_AREA_NORTH_WEST,
+ GRN_GEO_AREA_SOUTH_WEST,
+ GRN_GEO_AREA_SOUTH_EAST,
+ GRN_GEO_AREA_LAST
+} grn_geo_area_type;
+
+#define GRN_GEO_N_AREAS GRN_GEO_AREA_LAST
+
+typedef struct {
+ uint8_t key[sizeof(grn_geo_point)];
+ int target_bit;
+ int status_flags;
+} grn_geo_cursor_entry;
+
+typedef struct {
+ grn_geo_point top_left;
+ grn_geo_point bottom_right;
+ uint8_t top_left_key[sizeof(grn_geo_point)];
+ uint8_t bottom_right_key[sizeof(grn_geo_point)];
+ int current_entry;
+ grn_geo_cursor_entry entries[GRN_GEO_KEY_MAX_BITS];
+} grn_geo_cursor_area;
+
+typedef struct {
+ grn_db_obj obj;
+ grn_obj *pat;
+ grn_obj *index;
+ grn_geo_point top_left;
+ grn_geo_point bottom_right;
+ grn_geo_point current;
+ grn_table_cursor *pat_cursor;
+ grn_ii_cursor *ii_cursor;
+ int offset;
+ int rest;
+ int minimum_reduce_bit;
+ grn_geo_area_type current_area;
+ grn_geo_cursor_area areas[GRN_GEO_N_AREAS];
+} grn_geo_cursor_in_rectangle;
+
+grn_rc grn_geo_cursor_close(grn_ctx *ctx, grn_obj *geo_cursor);
+
+
+grn_rc grn_geo_resolve_approximate_type(grn_ctx *ctx, grn_obj *type_name,
+ grn_geo_approximate_type *type);
+
+/**
+ * grn_geo_select_in_circle:
+ * @index: the index column for TokyoGeoPoint or WGS84GeoPpoint type.
+ * @center_point: the center point of the target circle. (ShortText, Text,
+ * LongText, TokyoGeoPoint or WGS84GeoPoint)
+ * @distance: the radius of the target circle (Int32,
+ * UInt32, Int64, UInt64 or Float) or the point
+ * on the circumference of the target circle. (ShortText, Text, LongText,
+ * TokyoGeoPoint or WGS84GeoPoint)
+ * @approximate_type: the approximate type to compute
+ * distance.
+ * @res: the table to store found record IDs. It must be
+ * GRN_TABLE_HASH_KEY type table.
+ * @op: the operator for matched records.
+ *
+ * It selects records that are in the circle specified by
+ * @center_point and @distance from @center_point. Records
+ * are searched by @index. Found records are added to @res
+ * table with @op operation.
+ **/
+grn_rc grn_geo_select_in_circle(grn_ctx *ctx,
+ grn_obj *index,
+ grn_obj *center_point,
+ grn_obj *distance,
+ grn_geo_approximate_type approximate_type,
+ grn_obj *res,
+ grn_operator op);
+
+grn_rc grn_selector_geo_in_circle(grn_ctx *ctx, grn_obj *table, grn_obj *index,
+ int nargs, grn_obj **args,
+ grn_obj *res, grn_operator op);
+grn_rc grn_selector_geo_in_rectangle(grn_ctx *ctx,
+ grn_obj *table, grn_obj *index,
+ int nargs, grn_obj **args,
+ grn_obj *res, grn_operator op);
+
+GRN_API grn_bool grn_geo_in_circle(grn_ctx *ctx, grn_obj *point, grn_obj *center,
+ grn_obj *radius_or_point,
+ grn_geo_approximate_type approximate_type);
+GRN_API grn_bool grn_geo_in_rectangle(grn_ctx *ctx, grn_obj *point,
+ grn_obj *top_left, grn_obj *bottom_right);
+grn_bool grn_geo_in_rectangle_raw(grn_ctx *ctx, grn_geo_point *point,
+ grn_geo_point *top_left,
+ grn_geo_point *bottom_right);
+double grn_geo_distance(grn_ctx *ctx, grn_obj *point1, grn_obj *point2,
+ grn_geo_approximate_type type);
+GRN_API double grn_geo_distance_rectangle(grn_ctx *ctx, grn_obj *point1,
+ grn_obj *point2);
+GRN_API double grn_geo_distance_sphere(grn_ctx *ctx, grn_obj *point1,
+ grn_obj *point2);
+GRN_API double grn_geo_distance_ellipsoid(grn_ctx *ctx, grn_obj *point1,
+ grn_obj *point2);
+double grn_geo_distance_rectangle_raw(grn_ctx *ctx,
+ grn_geo_point *point1,
+ grn_geo_point *point2);
+double grn_geo_distance_sphere_raw(grn_ctx *ctx,
+ grn_geo_point *point1,
+ grn_geo_point *point2);
+double grn_geo_distance_ellipsoid_raw(grn_ctx *ctx,
+ grn_geo_point *point1,
+ grn_geo_point *point2,
+ int c1, int c2, double c3);
+double grn_geo_distance_ellipsoid_raw_tokyo(grn_ctx *ctx,
+ grn_geo_point *point1,
+ grn_geo_point *point2);
+double grn_geo_distance_ellipsoid_raw_wgs84(grn_ctx *ctx,
+ grn_geo_point *point1,
+ grn_geo_point *point2);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_hash.h b/storage/mroonga/vendor/groonga/lib/grn_hash.h
new file mode 100644
index 00000000..4038909b
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_hash.h
@@ -0,0 +1,378 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include "grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**** grn_tiny_array ****/
+
+/*
+ * grn_tiny_array_init() accepts a logical OR of the following flags.
+ * Note that other flags, such as (1 << 30), will be ignored.
+ *
+ * - GRN_TINY_ARRAY_CLEAR specifies to initialize a new block with zeros.
+ * It is valid only iff specified with GRN_TINY_ARRAY_USE_MALLOC.
+ * - GRN_TINY_ARRAY_THREADSAFE specifies to create a critical section when
+ * allocating memory.
+ * - GRN_TINY_ARRAY_USE_MALLOC specifies to use GRN_MALLOC/CALLOC/FREE instead
+ * of GRN_CTX_ALLOC/FREE.
+ */
+#define GRN_TINY_ARRAY_CLEAR (1 << 0)
+#define GRN_TINY_ARRAY_THREADSAFE (1 << 1)
+#define GRN_TINY_ARRAY_USE_MALLOC (1 << 2)
+
+/*
+ * - GRN_TINY_ARRAY_FACTOR is the global parameter of grn_tiny_array.
+ * - GRN_TINY_ARRAY_GET_OFFSET() returns the offset of a specified block.
+ * - GRN_TINY_ARRAY_BASE_BLOCK_SIZE is the number of elements in the first
+ * block.
+ * - GRN_TINY_ARRAY_GET_BLOCK_SIZE() returns the number of elements in a
+ * specified block.
+ * - GRN_TINY_ARRAY_NUM_BLOCKS is the maximum number of blocks.
+ */
+#define GRN_TINY_ARRAY_FACTOR 0
+#define GRN_TINY_ARRAY_GET_OFFSET(block_id) \
+ (1 << ((block_id) << GRN_TINY_ARRAY_FACTOR))
+#define GRN_TINY_ARRAY_BASE_BLOCK_SIZE \
+ (GRN_TINY_ARRAY_GET_OFFSET(1) - GRN_TINY_ARRAY_GET_OFFSET(0))
+#define GRN_TINY_ARRAY_GET_BLOCK_SIZE(block_id) \
+ (GRN_TINY_ARRAY_BASE_BLOCK_SIZE * GRN_TINY_ARRAY_GET_OFFSET(block_id))
+#define GRN_TINY_ARRAY_NUM_BLOCKS (32 >> GRN_TINY_ARRAY_FACTOR)
+
+/*
+ * grn_tiny_array uses several blocks to emulate an array.
+ * The k-th block, blocks[k - 1], consists of 2^(k-1) elements.
+ */
+typedef struct _grn_tiny_array grn_tiny_array;
+
+struct _grn_tiny_array {
+ grn_ctx *ctx;
+ grn_id max;
+ uint16_t element_size;
+ uint16_t flags;
+ void *blocks[GRN_TINY_ARRAY_NUM_BLOCKS];
+ grn_critical_section lock;
+};
+
+#define GRN_TINY_ARRAY_EACH(array, head, tail, key, value, block) do { \
+ int _block_id; \
+ const grn_id _head = (head); \
+ const grn_id _tail = (tail); \
+ for (_block_id = 0, (key) = (_head); \
+ _block_id < GRN_TINY_ARRAY_NUM_BLOCKS && (key) <= (_tail); \
+ _block_id++) { \
+ int _id = GRN_TINY_ARRAY_GET_BLOCK_SIZE(_block_id); \
+ (value) = (array)->blocks[_block_id]; \
+ if (value) { \
+ while (_id-- && (key) <= (_tail)) { \
+ { \
+ block \
+ } \
+ (key)++; \
+ (value) = (void *)((byte *)(value) + (array)->element_size); \
+ } \
+ } else { \
+ (key) += _id; \
+ } \
+ } \
+} while (0)
+
+GRN_API void grn_tiny_array_init(grn_ctx *ctx, grn_tiny_array *array,
+ uint16_t element_size, uint16_t flags);
+GRN_API void grn_tiny_array_fin(grn_tiny_array *array);
+GRN_API void *grn_tiny_array_at(grn_tiny_array *array, grn_id id);
+GRN_API grn_id grn_tiny_array_id(grn_tiny_array *array,
+ const void *element_address);
+
+/**** grn_tiny_bitmap ****/
+
+typedef struct _grn_tiny_bitmap grn_tiny_bitmap;
+
+struct _grn_tiny_bitmap {
+ grn_ctx *ctx;
+ void *blocks[GRN_TINY_ARRAY_NUM_BLOCKS];
+};
+
+/**** grn_array ****/
+
+#define GRN_ARRAY_TINY (0x01<<6)
+
+/*
+ * grn_array uses grn_io or grn_tiny_array to represent an array.
+ *
+ * To create a grn_tiny_array-based grn_array, specify the GRN_ARRAY_TINY flag
+ * to grn_array_create(). Note that a grn_tiny_array-based grn_array is not
+ * backed by a file.
+ */
+struct _grn_array {
+ grn_db_obj obj;
+ grn_ctx *ctx;
+ uint32_t value_size;
+ int32_t n_keys;
+ grn_table_sort_key *keys;
+ uint32_t *n_garbages;
+ uint32_t *n_entries;
+
+ /* For grn_io_array. */
+ grn_io *io;
+ struct grn_array_header *header;
+ uint32_t *lock;
+
+ /* For grn_tiny_array. */
+ uint32_t n_garbages_buf;
+ uint32_t n_entries_buf;
+ grn_id garbages;
+ grn_tiny_array array;
+ grn_tiny_bitmap bitmap;
+};
+
+struct _grn_array_cursor {
+ grn_db_obj obj;
+ grn_array *array;
+ grn_ctx *ctx;
+ grn_id curr_rec;
+ grn_id tail;
+ unsigned int rest;
+ int dir;
+};
+
+/*
+ * 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,
+ grn_table_sort_key *keys, int n_keys);
+
+/* grn_table_queue */
+
+typedef struct _grn_table_queue grn_table_queue;
+
+struct _grn_table_queue {
+ grn_mutex mutex;
+ grn_cond cond;
+ grn_id head;
+ grn_id tail;
+ grn_id cap;
+ grn_bool unblock_requested;
+};
+
+GRN_API void grn_array_queue_lock_clear(grn_ctx *ctx, grn_array *array);
+GRN_API void grn_array_clear_curr_rec(grn_ctx *ctx, grn_array *array);
+GRN_API grn_table_queue *grn_array_queue(grn_ctx *ctx, grn_array *array);
+GRN_API uint32_t grn_table_queue_size(grn_table_queue *queue);
+GRN_API void grn_table_queue_head_increment(grn_table_queue *queue);
+GRN_API void grn_table_queue_tail_increment(grn_table_queue *queue);
+GRN_API grn_id grn_table_queue_head(grn_table_queue *queue);
+GRN_API grn_id grn_table_queue_tail(grn_table_queue *queue);
+
+/**** grn_hash ****/
+
+#define GRN_HASH_MAX_KEY_SIZE_NORMAL GRN_TABLE_MAX_KEY_SIZE
+#define GRN_HASH_MAX_KEY_SIZE_LARGE (0xffff)
+
+#define GRN_HASH_IS_LARGE_KEY(hash)\
+ ((hash)->key_size > GRN_HASH_MAX_KEY_SIZE_NORMAL)
+
+typedef struct _grn_hash_header_common grn_hash_header_common;
+typedef struct _grn_hash_header_normal grn_hash_header_normal;
+typedef struct _grn_hash_header_large grn_hash_header_large;
+
+struct _grn_hash {
+ grn_db_obj obj;
+ grn_ctx *ctx;
+ uint32_t key_size;
+ grn_encoding encoding;
+ uint32_t value_size;
+ uint32_t entry_size;
+ uint32_t *n_garbages;
+ uint32_t *n_entries;
+ uint32_t *max_offset;
+ grn_obj *tokenizer;
+ grn_obj *normalizer;
+ grn_obj token_filters;
+
+ /* For grn_io_hash. */
+ grn_io *io;
+ union {
+ grn_hash_header_common *common;
+ grn_hash_header_normal *normal;
+ grn_hash_header_large *large;
+ } header;
+ uint32_t *lock;
+ // uint32_t nref;
+ // unsigned int max_n_subrecs;
+ // unsigned int record_size;
+ // unsigned int subrec_size;
+ // grn_rec_unit record_unit;
+ // grn_rec_unit subrec_unit;
+ // uint8_t arrayp;
+ // grn_recordh *curr_rec;
+ // grn_set_cursor *cursor;
+ // int limit;
+ // void *userdata;
+ // grn_id subrec_id;
+
+ /* For grn_tiny_hash. */
+ uint32_t max_offset_;
+ uint32_t n_garbages_;
+ uint32_t n_entries_;
+ grn_id *index;
+ grn_id garbages;
+ grn_tiny_array a;
+ grn_tiny_bitmap bitmap;
+};
+
+#define GRN_HASH_HEADER_COMMON_FIELDS\
+ uint32_t flags;\
+ grn_encoding encoding;\
+ uint32_t key_size;\
+ uint32_t value_size;\
+ grn_id tokenizer;\
+ uint32_t curr_rec;\
+ uint32_t curr_key_normal;\
+ uint32_t idx_offset;\
+ uint32_t entry_size;\
+ uint32_t max_offset;\
+ uint32_t n_entries;\
+ uint32_t n_garbages;\
+ uint32_t lock;\
+ grn_id normalizer;\
+ uint32_t truncated;\
+ uint64_t curr_key_large;\
+ uint32_t reserved[12]
+
+struct _grn_hash_header_common {
+ GRN_HASH_HEADER_COMMON_FIELDS;
+};
+
+struct _grn_hash_header_normal {
+ GRN_HASH_HEADER_COMMON_FIELDS;
+ grn_id garbages[GRN_HASH_MAX_KEY_SIZE_NORMAL];
+ grn_table_queue queue;
+};
+
+struct _grn_hash_header_large {
+ GRN_HASH_HEADER_COMMON_FIELDS;
+ grn_id garbages[GRN_HASH_MAX_KEY_SIZE_LARGE];
+ grn_table_queue queue;
+};
+
+struct _grn_hash_cursor {
+ grn_db_obj obj;
+ grn_hash *hash;
+ grn_ctx *ctx;
+ grn_id curr_rec;
+ grn_id tail;
+ unsigned int rest;
+ int dir;
+};
+
+/* deprecated */
+
+#define GRN_TABLE_SORT_BY_KEY 0
+#define GRN_TABLE_SORT_BY_ID (1L<<1)
+#define GRN_TABLE_SORT_BY_VALUE (1L<<2)
+#define GRN_TABLE_SORT_RES_ID 0
+#define GRN_TABLE_SORT_RES_KEY (1L<<3)
+#define GRN_TABLE_SORT_AS_BIN 0
+#define GRN_TABLE_SORT_AS_NUMBER (1L<<4)
+#define GRN_TABLE_SORT_AS_SIGNED 0
+#define GRN_TABLE_SORT_AS_UNSIGNED (1L<<5)
+#define GRN_TABLE_SORT_AS_INT32 0
+#define GRN_TABLE_SORT_AS_INT64 (1L<<6)
+#define GRN_TABLE_SORT_NO_PROC 0
+#define GRN_TABLE_SORT_WITH_PROC (1L<<7)
+
+typedef struct _grn_table_sort_optarg grn_table_sort_optarg;
+
+struct _grn_table_sort_optarg {
+ grn_table_sort_flags flags;
+ int (*compar)(grn_ctx *ctx,
+ grn_obj *table1, void *target1, unsigned int target1_size,
+ grn_obj *table2, void *target2, unsigned int target2_size,
+ void *compare_arg);
+ void *compar_arg;
+ grn_obj *proc;
+ int offset;
+};
+
+GRN_API int grn_hash_sort(grn_ctx *ctx, grn_hash *hash, int limit,
+ grn_array *result, grn_table_sort_optarg *optarg);
+
+grn_rc grn_hash_lock(grn_ctx *ctx, grn_hash *hash, int timeout);
+grn_rc grn_hash_unlock(grn_ctx *ctx, grn_hash *hash);
+grn_rc grn_hash_clear_lock(grn_ctx *ctx, grn_hash *hash);
+
+#define GRN_HASH_SIZE(hash) (*((hash)->n_entries))
+
+/* private */
+typedef enum {
+ grn_rec_document = 0,
+ grn_rec_section,
+ grn_rec_position,
+ grn_rec_userdef,
+ grn_rec_none
+} grn_rec_unit;
+
+GRN_API grn_rc grn_hash_truncate(grn_ctx *ctx, grn_hash *hash);
+
+int grn_rec_unit_size(grn_rec_unit unit, int rec_size);
+
+const char * _grn_hash_key(grn_ctx *ctx, grn_hash *hash, grn_id id, uint32_t *key_size);
+
+int grn_hash_get_key_value(grn_ctx *ctx, grn_hash *hash, grn_id id,
+ void *keybuf, int bufsize, void *valuebuf);
+
+int _grn_hash_get_key_value(grn_ctx *ctx, grn_hash *hash, grn_id id,
+ void **key, void **value);
+
+grn_id grn_hash_next(grn_ctx *ctx, grn_hash *hash, grn_id id);
+
+/* only valid for hash tables, GRN_OBJ_KEY_VAR_SIZE && GRN_HASH_TINY */
+const char *_grn_hash_strkey_by_val(void *v, uint16_t *size);
+
+const char *grn_hash_get_value_(grn_ctx *ctx, grn_hash *hash, grn_id id, uint32_t *size);
+
+grn_rc grn_hash_remove(grn_ctx *ctx, const char *path);
+grn_rc grn_array_remove(grn_ctx *ctx, const char *path);
+
+grn_id grn_hash_at(grn_ctx *ctx, grn_hash *hash, grn_id id);
+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
diff --git a/storage/mroonga/vendor/groonga/lib/grn_ii.h b/storage/mroonga/vendor/groonga/lib/grn_ii.h
new file mode 100644
index 00000000..0598c9e7
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_ii.h
@@ -0,0 +1,192 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+/* "ii" is for inverted index */
+
+#include "grn.h"
+#include "grn_hash.h"
+#include "grn_io.h"
+#include "grn_store.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _grn_ii {
+ grn_db_obj obj;
+ 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
+#define GRN_II_W_CHUNK 22
+#define GRN_II_W_LEAST_CHUNK (GRN_II_W_TOTAL_CHUNK - 32)
+#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;
+ uint32_t flags;
+ uint32_t amax;
+ uint32_t smax;
+ uint32_t param1;
+ uint32_t param2;
+ uint32_t pnext;
+ uint32_t bgqhead;
+ uint32_t bgqtail;
+ uint32_t bgqbody[GRN_II_BGQSIZE];
+ uint32_t reserved[288];
+ 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];
+ uint8_t chunks[GRN_II_MAX_CHUNK >> 3];
+};
+
+struct _grn_ii_pos {
+ struct _grn_ii_pos *next;
+ uint32_t pos;
+};
+
+struct _grn_ii_updspec {
+ uint32_t rid;
+ uint32_t sid;
+ int32_t weight;
+ int32_t tf; /* number of postings successfully stored to index */
+ int32_t atf; /* actual number of postings */
+ int32_t offset;
+ struct _grn_ii_pos *pos;
+ struct _grn_ii_pos *tail;
+ /* grn_vgram_vnode *vnodes; */
+};
+
+typedef struct _grn_ii_updspec grn_ii_updspec;
+
+void grn_ii_init_from_env(void);
+
+GRN_API grn_ii *grn_ii_create(grn_ctx *ctx, const char *path, grn_obj *lexicon,
+ uint32_t flags);
+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,
+ grn_hash *h);
+grn_ii_updspec *grn_ii_updspec_open(grn_ctx *ctx, uint32_t rid, uint32_t sid);
+grn_rc grn_ii_updspec_close(grn_ctx *ctx, grn_ii_updspec *u);
+grn_rc grn_ii_updspec_add(grn_ctx *ctx, grn_ii_updspec *u, int pos, int32_t weight);
+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);
+
+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);
+
+uint32_t grn_ii_max_section(grn_ii *ii);
+
+const char *grn_ii_path(grn_ii *ii);
+grn_obj *grn_ii_lexicon(grn_ii *ii);
+
+/*
+grn_rc grn_ii_upd(grn_ctx *ctx, grn_ii *ii, grn_id rid, grn_vgram *vgram,
+ const char *oldvalue, unsigned int oldvalue_len,
+ const char *newvalue, unsigned int newvalue_len);
+grn_rc grn_ii_update(grn_ctx *ctx, grn_ii *ii, grn_id rid, grn_vgram *vgram,
+ unsigned int section,
+ grn_values *oldvalues, grn_values *newvalues);
+*/
+
+typedef struct _grn_select_optarg grn_select_optarg;
+
+struct _grn_select_optarg {
+ grn_operator mode;
+ int similarity_threshold;
+ int max_interval;
+ int *weight_vector;
+ int vector_size;
+ int (*func)(grn_ctx *, grn_hash *, const void *, int, void *);
+ void *func_arg;
+ int max_size;
+ 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,
+ unsigned int section, grn_obj *oldvalue,
+ grn_obj *newvalue, grn_obj *posting);
+grn_rc grn_ii_term_extract(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 grn_ii_similar_search(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_len,
+ grn_hash *s, grn_operator op, grn_select_optarg *optarg);
+GRN_API grn_rc 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);
+grn_rc grn_ii_sel(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_len,
+ grn_hash *s, grn_operator op, grn_search_optarg *optarg);
+
+void grn_ii_resolve_sel_and(grn_ctx *ctx, grn_hash *s, grn_operator op);
+
+grn_rc grn_ii_at(grn_ctx *ctx, grn_ii *ii, grn_id id, grn_hash *s, grn_operator op);
+
+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
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 00000000..b9142d5c
--- /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-1335 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
new file mode 100644
index 00000000..bc5ecf7f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_io.h
@@ -0,0 +1,487 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include "grn_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef WIN32
+# define GRN_IO_FILE_CREATE_MODE (GENERIC_READ | GENERIC_WRITE)
+#else /* WIN32 */
+# define GRN_IO_FILE_CREATE_MODE 0644
+#endif /* WIN32 */
+
+typedef enum {
+ grn_io_rdonly,
+ grn_io_wronly,
+ grn_io_rdwr
+} grn_io_rw_mode;
+
+typedef enum {
+ grn_io_auto,
+ grn_io_manual
+} grn_io_mode;
+
+/**** grn_io ****/
+
+typedef struct _grn_io grn_io;
+
+typedef struct {
+ grn_io *io;
+ grn_ctx *ctx;
+ uint8_t mode;
+ uint8_t tiny_p;
+ uint32_t pseg;
+ uint32_t segment;
+ uint32_t offset;
+ uint32_t size;
+ uint32_t nseg;
+ off_t pos;
+ void *addr;
+ uint32_t diff;
+ int32_t cached;
+#ifdef WIN32
+ HANDLE fmo;
+#endif /* WIN32 */
+ void *uncompressed_value;
+} grn_io_win;
+
+typedef struct {
+ void *map;
+ uint32_t nref;
+ uint32_t count;
+#ifdef WIN32
+ HANDLE fmo;
+#endif /* WIN32 */
+} grn_io_mapinfo;
+
+typedef struct _grn_io_array_info grn_io_array_info;
+
+struct _grn_io_header {
+ char idstr[16];
+ uint32_t type;
+ uint32_t version;
+ uint32_t flags;
+ uint32_t header_size;
+ uint32_t segment_size;
+ uint32_t max_segment;
+ uint32_t n_arrays;
+ uint32_t lock;
+ uint64_t curr_size;
+ uint32_t segment_tail;
+ uint32_t last_modified;
+};
+
+struct _grn_io {
+ char path[PATH_MAX];
+ struct _grn_io_header *header;
+ byte *user_header;
+ grn_io_mapinfo *maps;
+ uint32_t base;
+ uint32_t base_seg;
+ grn_io_mode mode;
+ struct _grn_io_fileinfo *fis;
+ grn_io_array_info *ainfo;
+ uint32_t max_map_seg;
+ uint32_t nmaps;
+ uint32_t nref;
+ uint32_t count;
+ uint8_t flags;
+ uint32_t *lock;
+};
+
+GRN_API 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,
+ unsigned int flags);
+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);
+
+void *grn_io_win_map(grn_io *io, grn_ctx *ctx, grn_io_win *iw, uint32_t segment,
+ uint32_t offset, uint32_t size, grn_io_rw_mode mode);
+grn_rc grn_io_win_unmap(grn_io_win *iw);
+
+typedef struct _grn_io_ja_einfo grn_io_ja_einfo;
+typedef struct _grn_io_ja_ehead grn_io_ja_ehead;
+
+struct _grn_io_ja_einfo {
+ uint32_t pos;
+ uint32_t size;
+};
+
+struct _grn_io_ja_ehead {
+ uint32_t size;
+ uint32_t key;
+};
+
+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_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);
+
+grn_rc grn_io_write_ja_ehead(grn_io *io, grn_ctx *ctx, uint32_t key,
+ uint32_t segment, uint32_t offset, uint32_t value_len);
+
+#define GRN_TABLE_ADD (0x01<<6)
+#define GRN_TABLE_ADDED (0x01<<7)
+
+#define GRN_IO_MAX_RETRY (0x10000)
+#define GRN_IO_MAX_REF (0x80000000)
+
+#define GRN_IO_EXPIRE_GTICK (0x01)
+#define GRN_IO_EXPIRE_SEGMENT (0x02)
+#define GRN_IO_TEMPORARY (0x04)
+
+void grn_io_seg_map_(grn_ctx *ctx, grn_io *io, uint32_t segno, grn_io_mapinfo *info);
+
+/* arguments must be validated by caller;
+ * io mustn't be NULL;
+ * segno must be in valid range;
+ * addr must be set NULL;
+ */
+#define GRN_IO_SEG_REF(io,segno,addr) do {\
+ grn_io_mapinfo *info = &(io)->maps[segno];\
+ uint32_t nref, retry, *pnref = &info->nref;\
+ if (io->flags & GRN_IO_EXPIRE_SEGMENT) {\
+ if (io->flags & GRN_IO_EXPIRE_GTICK) {\
+ for (retry = 0; !info->map || info->count != grn_gtick; retry++) {\
+ GRN_ATOMIC_ADD_EX(pnref, 1, nref);\
+ 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);\
+ break;\
+ }\
+ GRN_FUTEX_WAIT(pnref);\
+ } else {\
+ info->count = grn_gtick;\
+ if (!info->map) {\
+ grn_io_seg_map_(ctx, io, segno, info);\
+ if (!info->map) {\
+ GRN_LOG(ctx, GRN_LOG_CRIT,\
+ "mmap failed! in GRN_IO_SEG_REF(%p, %u): %s",\
+ io, segno, grn_current_error_message());\
+ }\
+ }\
+ GRN_ATOMIC_ADD_EX(pnref, -1, nref);\
+ GRN_FUTEX_WAKE(pnref);\
+ break;\
+ }\
+ }\
+ } else {\
+ for (retry = 0;; retry++) {\
+ GRN_ATOMIC_ADD_EX(pnref, 1, nref);\
+ 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);\
+ *pnref = 0; /* force reset */ \
+ break;\
+ }\
+ GRN_FUTEX_WAIT(pnref);\
+ continue;\
+ }\
+ if (nref >= 0x40000000) {\
+ 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);\
+ break;\
+ }\
+ GRN_FUTEX_WAIT(pnref);\
+ continue;\
+ } else {\
+ grn_io_seg_map_(ctx, io, segno, info);\
+ if (!info->map) {\
+ GRN_ATOMIC_ADD_EX(pnref, -1, nref);\
+ GRN_LOG(ctx, GRN_LOG_CRIT,\
+ "mmap failed!!! in GRN_IO_SEG_REF(%p, %u, %u): %s",\
+ io, segno, nref, grn_current_error_message());\
+ }\
+ \
+ GRN_FUTEX_WAKE(pnref);\
+ }\
+ }\
+ break;\
+ }\
+ info->count = grn_gtick;\
+ }\
+ } else {\
+ for (retry = 0; !info->map; retry++) {\
+ GRN_ATOMIC_ADD_EX(pnref, 1, nref);\
+ 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);\
+ break;\
+ }\
+ GRN_FUTEX_WAIT(pnref);\
+ } else {\
+ if (!info->map) {\
+ grn_io_seg_map_(ctx, io, segno, info);\
+ if (!info->map) {\
+ GRN_LOG(ctx, GRN_LOG_CRIT,\
+ "mmap failed!!!! in GRN_IO_SEG_REF(%p, %u): %s",\
+ io, segno, grn_current_error_message());\
+ }\
+ }\
+ GRN_ATOMIC_ADD_EX(pnref, -1, nref);\
+ GRN_FUTEX_WAKE(pnref);\
+ break;\
+ }\
+ }\
+ info->count = grn_gtick;\
+ }\
+ addr = info->map;\
+} while (0)
+
+#define GRN_IO_SEG_UNREF(io,segno) do {\
+ if (GRN_IO_EXPIRE_SEGMENT ==\
+ (io->flags & (GRN_IO_EXPIRE_GTICK|GRN_IO_EXPIRE_SEGMENT))) {\
+ uint32_t nref, *pnref = &(io)->maps[segno].nref;\
+ GRN_ATOMIC_ADD_EX(pnref, -1, nref);\
+ }\
+} while (0)
+
+uint32_t grn_io_base_seg(grn_io *io);
+const char *grn_io_path(grn_io *io);
+
+typedef struct _grn_io_array_spec grn_io_array_spec;
+
+struct _grn_io_array_spec {
+ uint32_t w_of_element;
+ uint32_t max_n_segments;
+};
+
+struct _grn_io_array_info {
+ uint32_t w_of_elm_in_a_segment;
+ uint32_t elm_mask_in_a_segment;
+ uint32_t max_n_segments;
+ uint32_t element_size;
+ uint32_t *segments;
+ void **addrs;
+};
+
+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);
+
+void *grn_io_array_at(grn_ctx *ctx, grn_io *io, uint32_t array, off_t offset, int *flags);
+
+void grn_io_segment_alloc(grn_ctx *ctx, grn_io *io, grn_io_array_info *ai,
+ uint32_t lseg, int *flags, void **p);
+
+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];\
+ uint32_t lseg = (offset) >> ainfo->w_of_elm_in_a_segment;\
+ void **p_ = &ainfo->addrs[lseg];\
+ if (!*p_) {\
+ grn_io_segment_alloc(ctx, (io), ainfo, lseg, (flags), p_);\
+ if (!*p_) { (res) = NULL; break; }\
+ }\
+ *((byte **)(&(res))) = (((byte *)*p_) + \
+ (((offset) & ainfo->elm_mask_in_a_segment) * ainfo->element_size));\
+} while (0)
+
+#define GRN_IO_ARRAY_BIT_AT(io,array,offset,res) do {\
+ uint8_t *ptr_;\
+ int flags_ = 0;\
+ GRN_IO_ARRAY_AT((io), (array), ((offset) >> 3) + 1, &flags_, ptr_);\
+ res = ptr_ ? ((*ptr_ >> ((offset) & 7)) & 1) : 0;\
+} while (0)
+
+#define GRN_IO_ARRAY_BIT_ON(io,array,offset) do {\
+ uint8_t *ptr_;\
+ int flags_ = GRN_TABLE_ADD;\
+ GRN_IO_ARRAY_AT((io), (array), ((offset) >> 3) + 1, &flags_, ptr_);\
+ if (ptr_) { *ptr_ |= (1 << ((offset) & 7)); }\
+} while (0)
+
+#define GRN_IO_ARRAY_BIT_OFF(io,array,offset) do {\
+ uint8_t *ptr_;\
+ int flags_ = GRN_TABLE_ADD;\
+ GRN_IO_ARRAY_AT((io), (array), ((offset) >> 3) + 1, &flags_, ptr_);\
+ if (ptr_) { *ptr_ &= ~(1 << ((offset) & 7)); }\
+} while (0)
+
+#define GRN_IO_ARRAY_BIT_FLIP(io,array,offset) do {\
+ uint8_t *ptr_;\
+ int flags_ = GRN_TABLE_ADD;\
+ GRN_IO_ARRAY_AT((io), (array), ((offset) >> 3) + 1, &flags_, ptr_);\
+ if (ptr_) { *ptr_ ^= (1 << ((offset) & 7)); }\
+} while (0)
+
+void *grn_io_anon_map(grn_ctx *ctx, grn_io_mapinfo *mi, size_t length);
+void grn_io_anon_unmap(grn_ctx *ctx, grn_io_mapinfo *mi, size_t length);
+uint32_t grn_io_detect_type(grn_ctx *ctx, const char *path);
+grn_rc grn_io_set_type(grn_io *io, uint32_t type);
+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);
+
+grn_rc grn_io_flush(grn_ctx *ctx, grn_io *io);
+
+/* encode/decode */
+
+#define GRN_B_ENC(v,p) do {\
+ uint8_t *_p = (uint8_t *)p; \
+ uint32_t _v = v; \
+ if (_v < 0x8f) { \
+ *_p++ = _v; \
+ } else if (_v < 0x408f) { \
+ _v -= 0x8f; \
+ *_p++ = 0xc0 + (_v >> 8); \
+ *_p++ = _v & 0xff; \
+ } else if (_v < 0x20408f) { \
+ _v -= 0x408f; \
+ *_p++ = 0xa0 + (_v >> 16); \
+ *_p++ = (_v >> 8) & 0xff; \
+ *_p++ = _v & 0xff; \
+ } else if (_v < 0x1020408f) { \
+ _v -= 0x20408f; \
+ *_p++ = 0x90 + (_v >> 24); \
+ *_p++ = (_v >> 16) & 0xff; \
+ *_p++ = (_v >> 8) & 0xff; \
+ *_p++ = _v & 0xff; \
+ } else { \
+ *_p++ = 0x8f; \
+ grn_memcpy(_p, &_v, sizeof(uint32_t));\
+ _p += sizeof(uint32_t); \
+ } \
+ p = _p; \
+} while (0)
+
+#define GRN_B_ENC_SIZE(v) \
+ ((v) < 0x8f ? 1 : ((v) < 0x408f ? 2 : ((v) < 0x20408f ? 3 : ((v) < 0x1020408f ? 4 : 5))))
+
+#define GRN_B_DEC(v,p) do { \
+ uint8_t *_p = (uint8_t *)p; \
+ uint32_t _v = *_p++; \
+ switch (_v >> 4) { \
+ case 0x08 : \
+ if (_v == 0x8f) { \
+ grn_memcpy(&_v, _p, sizeof(uint32_t));\
+ _p += sizeof(uint32_t); \
+ } \
+ break; \
+ case 0x09 : \
+ _v = (_v - 0x90) * 0x100 + *_p++; \
+ _v = _v * 0x100 + *_p++; \
+ _v = _v * 0x100 + *_p++ + 0x20408f; \
+ break; \
+ case 0x0a : \
+ case 0x0b : \
+ _v = (_v - 0xa0) * 0x100 + *_p++; \
+ _v = _v * 0x100 + *_p++ + 0x408f; \
+ break; \
+ case 0x0c : \
+ case 0x0d : \
+ case 0x0e : \
+ case 0x0f : \
+ _v = (_v - 0xc0) * 0x100 + *_p++ + 0x8f; \
+ break; \
+ } \
+ v = _v; \
+ p = _p; \
+} while (0)
+
+#define GRN_B_SKIP(p) do { \
+ uint8_t *_p = (uint8_t *)p; \
+ uint32_t _v = *_p++; \
+ switch (_v >> 4) { \
+ case 0x08 : \
+ if (_v == 0x8f) { \
+ _p += sizeof(uint32_t); \
+ } \
+ break; \
+ case 0x09 : \
+ _p += 3; \
+ break; \
+ case 0x0a : \
+ case 0x0b : \
+ _p += 2; \
+ break; \
+ case 0x0c : \
+ case 0x0d : \
+ case 0x0e : \
+ case 0x0f : \
+ _p += 1; \
+ break; \
+ } \
+ p = _p; \
+} while (0)
+
+#define GRN_B_COPY(p2,p1) do { \
+ uint32_t size = 0, _v = *p1++; \
+ *p2++ = _v; \
+ switch (_v >> 4) { \
+ case 0x08 : \
+ size = (_v == 0x8f) ? 4 : 0; \
+ break; \
+ case 0x09 : \
+ size = 3; \
+ break; \
+ case 0x0a : \
+ case 0x0b : \
+ size = 2; \
+ break; \
+ case 0x0c : \
+ case 0x0d : \
+ case 0x0e : \
+ case 0x0f : \
+ size = 1; \
+ break; \
+ } \
+ while (size--) { *p2++ = *p1++; } \
+} while (0)
+
+#ifdef __cplusplus
+}
+#endif
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 00000000..a3b909b2
--- /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-1335 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
new file mode 100644
index 00000000..58d745cf
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_logger.h
@@ -0,0 +1,35 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_logger_init(void);
+void grn_logger_fin(grn_ctx *ctx);
+
+void grn_query_logger_init(void);
+void grn_query_logger_fin(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_mrb.h b/storage/mroonga/vendor/groonga/lib/grn_mrb.h
new file mode 100644
index 00000000..d1e20a66
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_mrb.h
@@ -0,0 +1,42 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include "grn_ctx.h"
+
+#ifdef GRN_WITH_MRUBY
+# include <mruby.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_init_from_env(void);
+
+#ifdef GRN_WITH_MRUBY
+GRN_API mrb_value grn_mrb_load(grn_ctx *ctx, const char *path);
+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
diff --git a/storage/mroonga/vendor/groonga/lib/grn_msgpack.h b/storage/mroonga/vendor/groonga/lib/grn_msgpack.h
new file mode 100644
index 00000000..3452d588
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_msgpack.h
@@ -0,0 +1,46 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#ifdef GRN_WITH_MESSAGE_PACK
+# include <msgpack.h>
+
+# if MSGPACK_VERSION_MAJOR < 1
+typedef unsigned int msgpack_size_t;
+
+# define msgpack_pack_str(packer, size) msgpack_pack_raw(packer, size)
+# define msgpack_pack_str_body(packer, value, size) \
+ msgpack_pack_raw_body(packer, value, size)
+
+# define MSGPACK_OBJECT_STR MSGPACK_OBJECT_RAW
+# define MSGPACK_OBJECT_FLOAT MSGPACK_OBJECT_DOUBLE
+
+# define MSGPACK_OBJECT_STR_PTR(object) (object)->via.raw.ptr
+# define MSGPACK_OBJECT_STR_SIZE(object) (object)->via.raw.size
+
+# define MSGPACK_OBJECT_FLOAT_VALUE(object) (object)->via.dec
+# else /* MSGPACK_VERSION_MAJOR < 1 */
+typedef size_t msgpack_size_t;
+
+# define MSGPACK_OBJECT_STR_PTR(object) (object)->via.str.ptr
+# define MSGPACK_OBJECT_STR_SIZE(object) (object)->via.str.size
+
+# define MSGPACK_OBJECT_FLOAT_VALUE(object) (object)->via.f64
+# endif /* MSGPACK_VERSION_MAJOR < 1 */
+#endif /* GRN_WITH_MESSAGE_PACK */
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 00000000..33119d55
--- /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-1335 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
new file mode 100644
index 00000000..2ff50047
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_normalizer.h
@@ -0,0 +1,42 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include "grn_ctx.h"
+#include "grn_db.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GRN_NORMALIZER_AUTO_NAME "NormalizerAuto"
+
+grn_rc grn_normalizer_init(void);
+grn_rc grn_normalizer_fin(void);
+
+grn_rc grn_normalizer_normalize(grn_ctx *ctx,
+ grn_obj *normalizer,
+ grn_obj *string);
+
+grn_rc grn_db_init_builtin_normalizers(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
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 00000000..48eb503b
--- /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-1335 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
new file mode 100644
index 00000000..14364107
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_output.h
@@ -0,0 +1,127 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include "grn_ctx.h"
+#include "grn_store.h"
+#include "grn_ctx_impl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GRN_API void grn_output_array_open(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
+ const char *name, int nelements);
+GRN_API void grn_output_array_close(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type);
+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,
+ const char *value);
+GRN_API void grn_output_str(grn_ctx *ctx, grn_obj *outbuf,
+ grn_content_type output_type,
+ const char *value, size_t value_len);
+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,
+ grn_obj *table,
+ grn_obj_format *format);
+GRN_API void grn_output_table_records(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj *table,
+ grn_obj_format *format);
+
+grn_rc grn_output_format_set_columns(grn_ctx *ctx, grn_obj_format *format,
+ grn_obj *table,
+ const char *columns, int columns_len);
+
+#define GRN_OUTPUT_ARRAY_OPEN(name,nelements) \
+ (grn_ctx_output_array_open(ctx, name, nelements))
+#define GRN_OUTPUT_ARRAY_CLOSE() \
+ (grn_ctx_output_array_close(ctx))
+#define GRN_OUTPUT_MAP_OPEN(name,nelements) \
+ (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)\
+ (grn_ctx_output_cstr(ctx, value))
+#define GRN_OUTPUT_STR(value,value_len)\
+ (grn_ctx_output_str(ctx, value, value_len))
+#define GRN_OUTPUT_BOOL(value)\
+ (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)\
+ (grn_ctx_output_table_records(ctx, table, format))
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_pat.h b/storage/mroonga/vendor/groonga/lib/grn_pat.h
new file mode 100644
index 00000000..1a7e3cfb
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_pat.h
@@ -0,0 +1,129 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include "grn_db.h"
+#include "grn_hash.h"
+
+#ifdef __cplusplus
+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;
+ grn_io *io;
+ struct grn_pat_header *header;
+ grn_encoding encoding;
+ uint32_t key_size;
+ uint32_t value_size;
+ grn_obj *tokenizer;
+ grn_obj *normalizer;
+ 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; /* 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 {
+ uint32_t flags;
+ grn_encoding encoding;
+ uint32_t key_size;
+ uint32_t value_size;
+ grn_id tokenizer;
+ uint32_t n_entries;
+ uint32_t curr_rec;
+ int32_t curr_key;
+ int32_t curr_del;
+ int32_t curr_del2;
+ int32_t curr_del3;
+ uint32_t n_garbages;
+ grn_id normalizer;
+ 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];
+};
+
+struct _grn_pat_cursor_entry {
+ grn_id id;
+ uint16_t check;
+};
+
+typedef struct _grn_pat_cursor_entry grn_pat_cursor_entry;
+
+struct _grn_pat_cursor {
+ grn_db_obj obj;
+ grn_id curr_rec; /* ID of the latest record */
+ grn_pat *pat;
+ grn_ctx *ctx;
+ 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];
+};
+
+GRN_API grn_id grn_pat_curr_id(grn_ctx *ctx, grn_pat *pat);
+
+/* private */
+GRN_API grn_rc grn_pat_truncate(grn_ctx *ctx, grn_pat *pat);
+const char *_grn_pat_key(grn_ctx *ctx, grn_pat *pat, grn_id id, uint32_t *key_size);
+grn_id grn_pat_next(grn_ctx *ctx, grn_pat *pat, grn_id id);
+const char *grn_pat_get_value_(grn_ctx *ctx, grn_pat *pat, grn_id id, uint32_t *size);
+GRN_API grn_id grn_pat_at(grn_ctx *ctx, grn_pat *pat, grn_id id);
+void grn_pat_check(grn_ctx *ctx, grn_pat *pat);
+void grn_pat_inspect_nodes(grn_ctx *ctx, grn_pat *pat, grn_obj *buf);
+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
diff --git a/storage/mroonga/vendor/groonga/lib/grn_plugin.h b/storage/mroonga/vendor/groonga/lib/grn_plugin.h
new file mode 100644
index 00000000..0bed139c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_plugin.h
@@ -0,0 +1,62 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include "grn_ctx.h"
+#include "grn_store.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef WIN32
+typedef HINSTANCE grn_dl;
+typedef FARPROC grn_dl_symbol;
+
+#else
+typedef void * grn_dl;
+typedef void * grn_dl_symbol;
+#endif
+
+typedef struct _grn_plugin grn_plugin;
+
+struct _grn_plugin {
+ char path[PATH_MAX];
+ grn_dl dl;
+ grn_plugin_func init_func;
+ grn_plugin_func register_func;
+ grn_plugin_func unregister_func;
+ grn_plugin_func fin_func;
+ int refcount;
+};
+
+void grn_plugin_init_from_env(void);
+grn_rc grn_plugins_init(void);
+grn_rc grn_plugins_fin(void);
+grn_id grn_plugin_open(grn_ctx *ctx, const char *filename);
+grn_rc grn_plugin_close(grn_ctx *ctx, grn_id id);
+grn_id grn_plugin_reference(grn_ctx *ctx, const char *filename);
+const char *grn_plugin_path(grn_ctx *ctx, grn_id id);
+char *grn_plugin_find_path(grn_ctx *ctx, const char *name);
+void grn_plugin_ensure_registered(grn_ctx *ctx, grn_obj *proc);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_proc.h b/storage/mroonga/vendor/groonga/lib/grn_proc.h
new file mode 100644
index 00000000..267ef01b
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_proc.h
@@ -0,0 +1,152 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+
+#ifdef __cplusplus
+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_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
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 00000000..2b5fdc9c
--- /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-1335 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 00000000..bb76caf7
--- /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-1335 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
new file mode 100644
index 00000000..ddb4031a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_request_canceler.h
@@ -0,0 +1,28 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+
+grn_bool grn_request_canceler_init(void);
+void grn_request_canceler_fin(void);
+
+#ifdef __cplusplus
+}
+#endif
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 00000000..4a45751c
--- /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-1335 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
new file mode 100644
index 00000000..5ca6e8d5
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_rset.h
@@ -0,0 +1,114 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ double score;
+ int n_subrecs;
+ int subrecs[1];
+} grn_rset_recinfo;
+
+typedef struct {
+ grn_id rid;
+ uint32_t sid;
+ uint32_t pos;
+} grn_rset_posinfo;
+
+#define GRN_RSET_UTIL_BIT (0x80000000)
+
+#define GRN_RSET_N_SUBRECS_SIZE (sizeof(int))
+#define GRN_RSET_MAX_SIZE (sizeof(int64_t))
+#define GRN_RSET_MIN_SIZE (sizeof(int64_t))
+#define GRN_RSET_SUM_SIZE (sizeof(int64_t))
+#define GRN_RSET_AVG_SIZE (sizeof(double))
+
+#define GRN_RSET_SCORE_SIZE (sizeof(double))
+
+#define GRN_RSET_N_SUBRECS(ri) ((ri)->n_subrecs & ~GRN_RSET_UTIL_BIT)
+
+#define GRN_RSET_SUBREC_SIZE(subrec_size) \
+ (GRN_RSET_SCORE_SIZE + subrec_size)
+#define GRN_RSET_SUBRECS_CMP(a,b,dir) (((a) - (b))*(dir))
+#define GRN_RSET_SUBRECS_NTH(subrecs,size,n) \
+ ((double *)((byte *)subrecs + n * GRN_RSET_SUBREC_SIZE(size)))
+#define GRN_RSET_SUBRECS_COPY(subrecs,size,n,src) \
+ (grn_memcpy(GRN_RSET_SUBRECS_NTH(subrecs, size, n), src, GRN_RSET_SUBREC_SIZE(size)))
+#define GRN_RSET_SUBRECS_SIZE(subrec_size,n) \
+ (GRN_RSET_SUBREC_SIZE(subrec_size) * n)
+
+uint32_t grn_rset_recinfo_calc_values_size(grn_ctx *ctx,
+ grn_table_group_flags flags);
+void grn_rset_recinfo_update_calc_values(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table,
+ grn_obj *value);
+
+int64_t *grn_rset_recinfo_get_max_(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table);
+int64_t grn_rset_recinfo_get_max(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table);
+void grn_rset_recinfo_set_max(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table,
+ int64_t max);
+
+int64_t *grn_rset_recinfo_get_min_(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table);
+int64_t grn_rset_recinfo_get_min(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table);
+void grn_rset_recinfo_set_min(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table,
+ int64_t min);
+
+int64_t *grn_rset_recinfo_get_sum_(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table);
+int64_t grn_rset_recinfo_get_sum(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table);
+void grn_rset_recinfo_set_sum(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table,
+ int64_t sum);
+
+double *grn_rset_recinfo_get_avg_(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table);
+double grn_rset_recinfo_get_avg(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table);
+void grn_rset_recinfo_set_avg(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table,
+ double avg);
+
+#ifdef __cplusplus
+}
+#endif
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 00000000..8ea8597b
--- /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-1335 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
new file mode 100644
index 00000000..04e8bfd5
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_scorer.h
@@ -0,0 +1,49 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn_ctx.h"
+#include "grn_db.h"
+
+#include <groonga/scorer.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _grn_scorer_matched_record {
+ grn_obj *table;
+ grn_obj *lexicon;
+ grn_id id;
+ grn_obj terms;
+ grn_obj term_weights;
+ uint32_t total_term_weights;
+ uint64_t n_documents;
+ uint32_t n_occurrences;
+ uint64_t n_candidates;
+ uint32_t n_tokens;
+ int weight;
+ grn_obj *args_expr;
+ unsigned int args_expr_offset;
+};
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_scorers.h b/storage/mroonga/vendor/groonga/lib/grn_scorers.h
new file mode 100644
index 00000000..1f136a9c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_scorers.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-1335 USA
+*/
+
+#pragma once
+
+#include "grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+grn_rc grn_db_init_builtin_scorers(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_snip.h b/storage/mroonga/vendor/groonga/lib/grn_snip.h
new file mode 100644
index 00000000..3989a17d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_snip.h
@@ -0,0 +1,125 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include "grn_str.h"
+#include "grn_db.h"
+
+#define ASIZE 256U
+#define MAX_SNIP_TAG_COUNT 512U
+#define MAX_SNIP_COND_COUNT 32U
+#define MAX_SNIP_RESULT_COUNT 16U
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define SNIPCOND_NONSTOP 0
+#define SNIPCOND_STOP 1
+#define SNIPCOND_ACROSS 2
+
+#define GRN_QUERY_SCAN_ALLOCCONDS 0x0002
+
+typedef struct _snip_cond
+{
+ /* initial parameters */
+ const char *opentag;
+ const char *closetag;
+ size_t opentag_len;
+ size_t closetag_len;
+ grn_obj *keyword;
+
+ /* Tuned BM pre */
+ size_t bmBc[ASIZE];
+ size_t shift;
+
+ /* Tuned BM temporal result */
+ size_t found;
+ size_t last_found;
+ size_t last_offset;
+ size_t start_offset;
+ size_t end_offset;
+ size_t found_alpha_head;
+
+ /* search result */
+ int count;
+
+ /* stop flag */
+ int_least8_t stopflag;
+} snip_cond;
+
+typedef struct
+{
+ size_t start_offset;
+ size_t end_offset;
+ snip_cond *cond;
+} _snip_tag_result;
+
+typedef struct
+{
+ size_t start_offset;
+ size_t end_offset;
+ unsigned int first_tag_result_idx;
+ unsigned int last_tag_result_idx;
+ unsigned int tag_count;
+} _snip_result;
+
+typedef struct _grn_snip
+{
+ grn_db_obj obj;
+ grn_encoding encoding;
+ int flags;
+ size_t width;
+ unsigned int max_results;
+ const char *defaultopentag;
+ const char *defaultclosetag;
+ size_t defaultopentag_len;
+ size_t defaultclosetag_len;
+
+ grn_snip_mapping *mapping;
+
+ snip_cond cond[MAX_SNIP_COND_COUNT];
+ unsigned int cond_len;
+
+ unsigned int tag_count;
+ unsigned int snip_count;
+
+ const char *string;
+ grn_obj *nstr;
+
+ _snip_result snip_result[MAX_SNIP_RESULT_COUNT];
+ _snip_tag_result tag_result[MAX_SNIP_TAG_COUNT];
+
+ size_t max_tagged_len;
+
+ grn_obj *normalizer;
+} grn_snip;
+
+grn_rc grn_snip_close(grn_ctx *ctx, grn_snip *snip);
+grn_rc grn_snip_cond_init(grn_ctx *ctx, snip_cond *sc, const char *keyword, unsigned int keyword_len,
+ grn_encoding enc, grn_obj *normalizer, int flags);
+void grn_snip_cond_reinit(snip_cond *cond);
+grn_rc grn_snip_cond_close(grn_ctx *ctx, snip_cond *cond);
+void grn_bm_tunedbm(grn_ctx *ctx, snip_cond *cond, grn_obj *string, int flags);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_store.h b/storage/mroonga/vendor/groonga/lib/grn_store.h
new file mode 100644
index 00000000..8de6fd66
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_store.h
@@ -0,0 +1,216 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include "grn_ctx.h"
+#include "grn_hash.h"
+#include "grn_io.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**** fixed sized elements ****/
+
+typedef struct _grn_ra grn_ra;
+
+struct _grn_ra {
+ grn_db_obj obj;
+ grn_io *io;
+ int element_width;
+ int element_mask;
+ struct grn_ra_header *header;
+};
+
+struct grn_ra_header {
+ uint32_t element_size;
+ uint32_t nrecords; /* nrecords is not maintained by default */
+ uint32_t reserved[10];
+};
+
+grn_ra *grn_ra_create(grn_ctx *ctx, const char *path, unsigned int element_size);
+grn_ra *grn_ra_open(grn_ctx *ctx, const char *path);
+grn_rc grn_ra_info(grn_ctx *ctx, grn_ra *ra, unsigned int *element_size);
+grn_rc grn_ra_close(grn_ctx *ctx, grn_ra *ra);
+grn_rc grn_ra_remove(grn_ctx *ctx, const char *path);
+void *grn_ra_ref(grn_ctx *ctx, grn_ra *ra, grn_id id);
+grn_rc grn_ra_unref(grn_ctx *ctx, grn_ra *ra, grn_id id);
+
+typedef struct _grn_ra_cache grn_ra_cache;
+
+struct _grn_ra_cache {
+ void *p;
+ int32_t seg;
+};
+
+#define GRN_RA_CACHE_INIT(ra,c) do {\
+ (c)->p = NULL; (c)->seg = -1;\
+} while (0)
+
+#define GRN_RA_CACHE_FIN(ra,c) do {\
+ if ((c)->seg != -1) { GRN_IO_SEG_UNREF((ra)->io, (c)->seg); }\
+} while (0);
+
+void *grn_ra_ref_cache(grn_ctx *ctx, grn_ra *ra, grn_id id, grn_ra_cache *cache);
+
+/**** variable sized elements ****/
+
+typedef struct _grn_ja grn_ja;
+
+struct _grn_ja {
+ grn_db_obj obj;
+ grn_io *io;
+ struct grn_ja_header *header;
+};
+
+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,
+ void *value, uint32_t value_len, int flags, uint64_t *cas);
+int grn_ja_at(grn_ctx *ctx, grn_ja *ja, grn_id id, void *valbuf, int buf_size);
+
+GRN_API void *grn_ja_ref(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_io_win *iw,
+ uint32_t *value_len);
+grn_obj *grn_ja_get_value(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_obj *value);
+
+GRN_API grn_rc grn_ja_unref(grn_ctx *ctx, grn_io_win *iw);
+int grn_ja_defrag(grn_ctx *ctx, grn_ja *ja, int threshold);
+
+GRN_API grn_rc grn_ja_putv(grn_ctx *ctx, grn_ja *ja, grn_id id,
+ grn_obj *vector, int flags);
+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;
+ struct _grn_vgram_vnode *cdr;
+ grn_id tid;
+ grn_id vid;
+ int freq;
+ int len;
+} grn_vgram_vnode;
+
+typedef struct _grn_vgram grn_vgram;
+struct _grn_vgram {
+ void *vgram;
+};
+
+struct _grn_vgram_buf {
+ size_t len;
+ grn_id *tvs;
+ grn_id *tvp;
+ grn_id *tve;
+ grn_vgram_vnode *vps;
+ grn_vgram_vnode *vpp;
+ grn_vgram_vnode *vpe;
+};
+
+grn_vgram *grn_vgram_create(const char *path);
+grn_vgram *grn_vgram_open(const char *path);
+grn_rc grn_vgram_close(grn_vgram *vgram);
+grn_rc grn_vgram_update(grn_vgram *vgram, grn_id rid, grn_vgram_buf *b, grn_hash *terms);
+
+grn_vgram_buf *grn_vgram_buf_open(size_t len);
+grn_rc grn_vgram_buf_add(grn_vgram_buf *b, grn_id tid);
+grn_rc grn_vgram_buf_close(grn_vgram_buf *b);
+
+*/
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_str.h b/storage/mroonga/vendor/groonga/lib/grn_str.h
new file mode 100644
index 00000000..9efd28e3
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_str.h
@@ -0,0 +1,116 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include <groonga/nfkc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ GETOPT_OP_NONE = 0,
+ GETOPT_OP_ON,
+ GETOPT_OP_OFF,
+ GETOPT_OP_UPDATE
+} grn_str_getopt_op;
+
+typedef struct {
+ const char opt; /* ends opt == 0 && longopt == NULL */
+ const char *longopt;
+ const char **arg; /* if NULL, no arg are required */
+ int flag;
+ grn_str_getopt_op op;
+} grn_str_getopt_opt;
+
+GRN_API size_t grn_str_len(grn_ctx *ctx, const char *str, grn_encoding encoding, const char **last);
+
+#define GRN_STR_BLANK 0x80
+#define GRN_STR_ISBLANK(c) (c & 0x80)
+#define GRN_STR_CTYPE(c) (c & 0x7f)
+
+GRN_API int grn_isspace(const char *s, grn_encoding encoding);
+int8_t grn_atoi8(const char *nptr, const char *end, const char **rest);
+uint8_t grn_atoui8(const char *nptr, const char *end, const char **rest);
+int16_t grn_atoi16(const char *nptr, const char *end, const char **rest);
+uint16_t grn_atoui16(const char *nptr, const char *end, const char **rest);
+GRN_API int grn_atoi(const char *nptr, const char *end, const char **rest);
+GRN_API unsigned int grn_atoui(const char *nptr, const char *end, const char **rest);
+unsigned int grn_htoui(const char *nptr, const char *end, const char **rest);
+GRN_API int64_t grn_atoll(const char *nptr, const char *end, const char **rest);
+GRN_API uint64_t grn_atoull(const char *nptr, const char *end, const char **rest);
+grn_rc grn_itoa(int i, char *p, char *end, char **rest);
+grn_rc grn_lltoa(int64_t i, char *p, char *end, char **rest);
+grn_rc grn_ulltoa(uint64_t i, char *p, char *end, char **rest);
+GRN_API grn_rc grn_aton(grn_ctx *ctx, const char *p, const char *end, const char **rest, grn_obj *res);
+
+GRN_API void grn_itoh(unsigned int i, char *p, unsigned int len);
+int grn_str_tok(const char *str, size_t str_len, char delim, const char **tokbuf, int buf_size, const char **rest);
+GRN_API int grn_str_getopt(int argc, char * const argv[], const grn_str_getopt_opt *opts, int *flags);
+
+extern int grn_str_margin_size;
+
+char *grn_itob(grn_id id, char *p);
+grn_id grn_btoi(char *b);
+
+grn_rc grn_substring(grn_ctx *ctx, char **str, char **str_end, int start, int end, grn_encoding encoding);
+
+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_SET_CURR(buf,p) do {\
+ if (GRN_BULK_OUTP(buf)) {\
+ (buf)->u.b.curr = (char *)(p);\
+ } else {\
+ (buf)->header.flags = (char *)(p) - GRN_BULK_HEAD(buf);\
+ }\
+} while (0)
+
+grn_rc grn_text_ulltoa(grn_ctx *ctx, grn_obj *buf, unsigned long long int i);
+
+GRN_API const char *grn_text_cgidec(grn_ctx *ctx, grn_obj *buf,
+ const char *p, const char *e,
+ const char *delimiters);
+
+#define GRN_TOK_VOID (0x00)
+#define GRN_TOK_SYMBOL (0x01)
+#define GRN_TOK_STRING (0x02)
+#define GRN_TOK_QUOTE (0x03)
+
+GRN_API const char *grn_text_unesc_tok(grn_ctx *ctx, grn_obj *buf,
+ const char *p, const char *e,
+ char *tok_type);
+
+GRN_API void grn_str_url_path_normalize(grn_ctx *ctx,
+ const char *path, size_t path_len,
+ char *buf, size_t buf_len);
+
+#define GRN_OBJ_FORMAT_XML_ELEMENT_MASK (0x01<<1)
+#define GRN_OBJ_FORMAT_XML_ELEMENT_RESULTSET (0x00<<1)
+#define GRN_OBJ_FORMAT_XML_ELEMENT_NAVIGATIONENTRY (0x01<<1)
+
+#include <stdio.h>
+GRN_API grn_rc grn_text_fgets(grn_ctx *ctx, grn_obj *buf, FILE *fp);
+
+grn_bool grn_bulk_is_zero(grn_ctx *ctx, grn_obj *obj);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_string.h b/storage/mroonga/vendor/groonga/lib/grn_string.h
new file mode 100644
index 00000000..39e76c96
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_string.h
@@ -0,0 +1,51 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include "grn_ctx.h"
+#include "grn_db.h"
+#include "grn_str.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ grn_obj_header header;
+ const char *original;
+ unsigned int original_length_in_bytes;
+ char *normalized;
+ unsigned int normalized_length_in_bytes;
+ unsigned int n_characters;
+ short *checks;
+ unsigned char *ctypes;
+ grn_encoding encoding;
+ int flags;
+} grn_string;
+
+grn_obj *grn_string_open_(grn_ctx *ctx, const char *str, unsigned int str_len,
+ grn_obj *normalizer, int flags, grn_encoding encoding);
+grn_rc grn_string_close(grn_ctx *ctx, grn_obj *string);
+grn_rc grn_string_inspect(grn_ctx *ctx, grn_obj *buffer, grn_obj *string);
+
+#ifdef __cplusplus
+}
+#endif
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 00000000..b34f6687
--- /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-1335 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
new file mode 100644
index 00000000..a89f4c68
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_token_cursor.h
@@ -0,0 +1,81 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn_ctx.h"
+#include "grn_db.h"
+
+#include <groonga/tokenizer.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GRN_TOKENIZER_BEGIN_MARK_UTF8 "\xEF\xBF\xAF"
+#define GRN_TOKENIZER_BEGIN_MARK_UTF8_LEN 3
+#define GRN_TOKENIZER_END_MARK_UTF8 "\xEF\xBF\xB0"
+#define GRN_TOKENIZER_END_MARK_UTF8_LEN 3
+
+typedef enum {
+ GRN_TOKEN_CURSOR_DOING = 0,
+ GRN_TOKEN_CURSOR_DONE,
+ GRN_TOKEN_CURSOR_DONE_SKIP,
+ GRN_TOKEN_CURSOR_NOT_FOUND
+} grn_token_cursor_status;
+
+struct _grn_token {
+ grn_obj data;
+ grn_token_status status;
+};
+
+typedef struct {
+ grn_obj *table;
+ const unsigned char *orig;
+ const unsigned char *curr;
+ uint32_t orig_blen;
+ uint32_t curr_size;
+ int32_t pos;
+ grn_tokenize_mode mode;
+ grn_token_cursor_status status;
+ grn_bool force_prefix;
+ grn_obj_flags table_flags;
+ grn_encoding encoding;
+ grn_obj *tokenizer;
+ grn_proc_ctx pctx;
+ struct {
+ grn_obj *objects;
+ void **data;
+ } token_filter;
+ uint32_t variant;
+ grn_obj *nstr;
+} grn_token_cursor;
+
+#define GRN_TOKEN_CURSOR_ENABLE_TOKENIZED_DELIMITER (0x01L<<0)
+
+GRN_API grn_token_cursor *grn_token_cursor_open(grn_ctx *ctx, grn_obj *table,
+ const char *str, size_t str_len,
+ grn_tokenize_mode mode,
+ unsigned int flags);
+
+GRN_API grn_id grn_token_cursor_next(grn_ctx *ctx, grn_token_cursor *token_cursor);
+GRN_API grn_rc grn_token_cursor_close(grn_ctx *ctx, grn_token_cursor *token_cursor);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_tokenizers.h b/storage/mroonga/vendor/groonga/lib/grn_tokenizers.h
new file mode 100644
index 00000000..81ac2ab6
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_tokenizers.h
@@ -0,0 +1,38 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern grn_obj *grn_tokenizer_uvector;
+
+grn_rc grn_tokenizers_init(void);
+grn_rc grn_tokenizers_fin(void);
+
+grn_rc grn_db_init_mecab_tokenizer(grn_ctx *ctx);
+void grn_db_fin_mecab_tokenizer(grn_ctx *ctx);
+grn_rc grn_db_init_builtin_tokenizers(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
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 00000000..83f4dca8
--- /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-1335 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
new file mode 100644
index 00000000..5b888fd5
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_util.h
@@ -0,0 +1,49 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "grn.h"
+#include "grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GRN_API grn_rc grn_normalize_offset_and_limit(grn_ctx *ctx, int size, int *offset, int *limit);
+
+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
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 00000000..c5894241
--- /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-1335 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 00000000..c44e65a1
--- /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-1335 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 00000000..aee18aec
--- /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-1335 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
new file mode 100644
index 00000000..3fb372ee
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/hash.c
@@ -0,0 +1,3720 @@
+/* -*- 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-1335 USA
+*/
+#include "grn_hash.h"
+#include "grn_output.h"
+#include <string.h>
+#include <limits.h>
+
+#include "grn_store.h"
+#include "grn_normalizer.h"
+
+/* grn_tiny_array */
+
+/* Requirements: id != GRN_ID_NIL. */
+inline static int
+grn_tiny_array_get_block_id(grn_id id)
+{
+ int most_significant_one_bit_offset;
+ GRN_BIT_SCAN_REV(id, most_significant_one_bit_offset);
+ return most_significant_one_bit_offset >> GRN_TINY_ARRAY_FACTOR;
+}
+
+/* Requirements: id != GRN_ID_NIL. */
+inline static void *
+grn_tiny_array_get(grn_tiny_array *array, grn_id id) {
+ const int block_id = grn_tiny_array_get_block_id(id);
+ uint8_t * const block = (uint8_t *)array->blocks[block_id];
+ if (block) {
+ const size_t offset = GRN_TINY_ARRAY_GET_OFFSET(block_id);
+ return block + (id - offset) * array->element_size;
+ }
+ return NULL;
+}
+
+/* Requirements: id != GRN_ID_NIL. */
+inline static void *
+grn_tiny_array_put(grn_tiny_array *array, grn_id id) {
+ const int block_id = grn_tiny_array_get_block_id(id);
+ void ** const block = &array->blocks[block_id];
+ const size_t offset = GRN_TINY_ARRAY_GET_OFFSET(block_id);
+ if (!*block) {
+ grn_ctx * const ctx = array->ctx;
+ if (array->flags & GRN_TINY_ARRAY_THREADSAFE) {
+ CRITICAL_SECTION_ENTER(array->lock);
+ }
+ if (!*block) {
+ const size_t block_size =
+ GRN_TINY_ARRAY_GET_BLOCK_SIZE(block_id) * array->element_size;
+ if (array->flags & GRN_TINY_ARRAY_USE_MALLOC) {
+ if (array->flags & GRN_TINY_ARRAY_CLEAR) {
+ *block = GRN_CALLOC(block_size);
+ } else {
+ *block = GRN_MALLOC(block_size);
+ }
+ } else {
+ *block = GRN_CTX_ALLOC(ctx, block_size);
+ }
+ }
+ if (array->flags & GRN_TINY_ARRAY_THREADSAFE) {
+ CRITICAL_SECTION_LEAVE(array->lock);
+ }
+ if (!*block) {
+ return NULL;
+ }
+ }
+ if (id > array->max) {
+ array->max = id;
+ }
+ return (uint8_t *)*block + (id - offset) * array->element_size;
+}
+
+inline static void *
+grn_tiny_array_at_inline(grn_tiny_array *array, grn_id id)
+{
+ return id ? grn_tiny_array_put(array, id) : NULL;
+}
+
+void
+grn_tiny_array_init(grn_ctx *ctx, grn_tiny_array *array,
+ uint16_t element_size, uint16_t flags)
+{
+ array->ctx = ctx;
+ array->max = 0;
+ array->element_size = element_size;
+ array->flags = flags;
+ memset(array->blocks, 0, sizeof(array->blocks));
+ if (flags & GRN_TINY_ARRAY_THREADSAFE) {
+ CRITICAL_SECTION_INIT(array->lock);
+ }
+}
+
+void
+grn_tiny_array_fin(grn_tiny_array *array)
+{
+ int block_id;
+ grn_ctx * const ctx = array->ctx;
+ for (block_id = 0; block_id < GRN_TINY_ARRAY_NUM_BLOCKS; block_id++) {
+ if (array->blocks[block_id]) {
+ if (array->flags & GRN_TINY_ARRAY_USE_MALLOC) {
+ GRN_FREE(array->blocks[block_id]);
+ } else {
+ GRN_CTX_FREE(ctx, array->blocks[block_id]);
+ }
+ array->blocks[block_id] = NULL;
+ }
+ }
+}
+
+void *
+grn_tiny_array_at(grn_tiny_array *array, grn_id id)
+{
+ return grn_tiny_array_at_inline(array, id);
+}
+
+grn_id
+grn_tiny_array_id(grn_tiny_array *array, const void *element_address)
+{
+ const uint8_t * const ptr = (const uint8_t *)element_address;
+ uint32_t block_id, offset = 1;
+ for (block_id = 0; block_id < GRN_TINY_ARRAY_NUM_BLOCKS; block_id++) {
+ const uint32_t block_size = GRN_TINY_ARRAY_GET_BLOCK_SIZE(block_id);
+ const uint8_t * const block = (const uint8_t *)array->blocks[block_id];
+ if (block) {
+ if (block <= ptr && ptr < (block + block_size * array->element_size)) {
+ return offset + ((ptr - block) / array->element_size);
+ }
+ }
+ offset += block_size;
+ }
+ return GRN_ID_NIL;
+}
+
+/* grn_tiny_bitmap */
+
+static void
+grn_tiny_bitmap_init(grn_ctx *ctx, grn_tiny_bitmap *bitmap)
+{
+ bitmap->ctx = ctx;
+ memset(bitmap->blocks, 0, sizeof(bitmap->blocks));
+}
+
+static void
+grn_tiny_bitmap_fin(grn_tiny_bitmap *bitmap)
+{
+ int block_id;
+ grn_ctx * const ctx = bitmap->ctx;
+ for (block_id = 0; block_id < GRN_TINY_ARRAY_NUM_BLOCKS; block_id++) {
+ if (bitmap->blocks[block_id]) {
+ GRN_CTX_FREE(ctx, bitmap->blocks[block_id]);
+ bitmap->blocks[block_id] = NULL;
+ }
+ }
+}
+
+/* Requirements: bit_id != GRN_ID_NIL. */
+inline static uint8_t *
+grn_tiny_bitmap_get_byte(grn_tiny_bitmap *bitmap, grn_id bit_id) {
+ const uint32_t byte_id = (bit_id >> 3) + 1;
+ const int block_id = grn_tiny_array_get_block_id(byte_id);
+ uint8_t * const block = (uint8_t *)bitmap->blocks[block_id];
+ if (block) {
+ const size_t offset = GRN_TINY_ARRAY_GET_OFFSET(block_id);
+ return block + byte_id - offset;
+ }
+ return NULL;
+}
+
+/* Requirements: bit_id != GRN_ID_NIL. */
+inline static uint8_t *
+grn_tiny_bitmap_put_byte(grn_tiny_bitmap *bitmap, grn_id bit_id) {
+ const uint32_t byte_id = (bit_id >> 3) + 1;
+ const int block_id = grn_tiny_array_get_block_id(byte_id);
+ void ** const block = &bitmap->blocks[block_id];
+ const size_t offset = GRN_TINY_ARRAY_GET_OFFSET(block_id);
+ if (!*block) {
+ grn_ctx * const ctx = bitmap->ctx;
+ *block = GRN_CTX_ALLOC(ctx, GRN_TINY_ARRAY_GET_BLOCK_SIZE(block_id));
+ if (!*block) {
+ return NULL;
+ }
+ }
+ return (uint8_t *)*block + byte_id - offset;
+}
+
+/* Requirements: bit_id != GRN_ID_NIL. */
+/* Return value: 1/0 on success, -1 on failure. */
+/* Note: A bitmap is extended if needed. */
+inline static int
+grn_tiny_bitmap_put(grn_tiny_bitmap *bitmap, grn_id bit_id)
+{
+ uint8_t * const ptr = grn_tiny_bitmap_put_byte(bitmap, bit_id);
+ return ptr ? ((*ptr >> (bit_id & 7)) & 1) : -1;
+}
+
+/* Requirements: bit_id != GRN_ID_NIL. */
+inline static uint8_t *
+grn_tiny_bitmap_get_and_set(grn_tiny_bitmap *bitmap, grn_id bit_id,
+ grn_bool bit)
+{
+ uint8_t * const ptr = grn_tiny_bitmap_get_byte(bitmap, bit_id);
+ if (ptr) {
+ /* This branch will be removed because the given `bit' is constant. */
+ if (bit) {
+ *ptr |= 1 << (bit_id & 7);
+ } else {
+ *ptr &= ~(1 << (bit_id & 7));
+ }
+ }
+ return ptr;
+}
+
+/* Requirements: bit_id != GRN_ID_NIL. */
+/* Note: A bitmap is extended if needed. */
+inline static uint8_t *
+grn_tiny_bitmap_put_and_set(grn_tiny_bitmap *bitmap, grn_id bit_id,
+ grn_bool bit)
+{
+ uint8_t * const ptr = grn_tiny_bitmap_put_byte(bitmap, bit_id);
+ if (ptr) {
+ /* This branch will be removed because the given `bit' is constant. */
+ if (bit) {
+ *ptr |= 1 << (bit_id & 7);
+ } else {
+ *ptr &= ~(1 << (bit_id & 7));
+ }
+ }
+ return ptr;
+}
+
+/* grn_io_array */
+
+#define GRN_ARRAY_MAX (GRN_ID_MAX - 8)
+
+inline static void *
+grn_io_array_at_inline(grn_ctx *ctx, grn_io *io, uint32_t segment_id,
+ uint64_t offset, int flags)
+{
+ void *ptr;
+ GRN_IO_ARRAY_AT(io, segment_id, offset, &flags, ptr);
+ return ptr;
+}
+
+/*
+ * grn_io_array_bit_at() returns 1/0 on success, -1 on failure.
+ */
+inline static int
+grn_io_array_bit_at(grn_ctx *ctx, grn_io *io,
+ uint32_t segment_id, uint32_t offset)
+{
+ uint8_t * const ptr = (uint8_t *)grn_io_array_at_inline(
+ ctx, io, segment_id, (offset >> 3) + 1, 0);
+ return ptr ? ((*ptr >> (offset & 7)) & 1) : -1;
+}
+
+/*
+ * The following functions, grn_io_array_bit_*(), return a non-NULL pointer on
+ * success, a NULL pointer on failure.
+ */
+inline static void *
+grn_io_array_bit_on(grn_ctx *ctx, grn_io *io,
+ uint32_t segment_id, uint32_t offset)
+{
+ uint8_t * const ptr = (uint8_t *)grn_io_array_at_inline(
+ ctx, io, segment_id, (offset >> 3) + 1, GRN_TABLE_ADD);
+ if (ptr) {
+ *ptr |= 1 << (offset & 7);
+ }
+ return ptr;
+}
+
+inline static void *
+grn_io_array_bit_off(grn_ctx *ctx, grn_io *io,
+ uint32_t segment_id, uint32_t offset)
+{
+ uint8_t * const ptr = (uint8_t *)grn_io_array_at_inline(
+ ctx, io, segment_id, (offset >> 3) + 1, GRN_TABLE_ADD);
+ if (ptr) {
+ *ptr &= ~(1 << (offset & 7));
+ }
+ return ptr;
+}
+
+/* grn_table_queue */
+
+static void
+grn_table_queue_lock_init(grn_ctx *ctx, grn_table_queue *queue)
+{
+ MUTEX_INIT_SHARED(queue->mutex);
+ COND_INIT_SHARED(queue->cond);
+}
+
+static void
+grn_table_queue_init(grn_ctx *ctx, grn_table_queue *queue)
+{
+ queue->head = 0;
+ queue->tail = 0;
+ queue->cap = GRN_ARRAY_MAX;
+ queue->unblock_requested = GRN_FALSE;
+ grn_table_queue_lock_init(ctx, queue);
+}
+
+uint32_t
+grn_table_queue_size(grn_table_queue *queue)
+{
+ return (queue->head < queue->tail)
+ ? 2 * queue->cap + queue->head - queue->tail
+ : queue->head - queue->tail;
+}
+
+void
+grn_table_queue_head_increment(grn_table_queue *queue)
+{
+ if (queue->head == 2 * queue->cap) {
+ queue->head = 1;
+ } else {
+ queue->head++;
+ }
+}
+
+void
+grn_table_queue_tail_increment(grn_table_queue *queue)
+{
+ if (queue->tail == 2 * queue->cap) {
+ queue->tail = 1;
+ } else {
+ queue->tail++;
+ }
+}
+
+grn_id
+grn_table_queue_head(grn_table_queue *queue)
+{
+ return queue->head > queue->cap
+ ? queue->head - queue->cap
+ : queue->head;
+}
+
+grn_id
+grn_table_queue_tail(grn_table_queue *queue)
+{
+ return queue->tail > queue->cap
+ ? queue->tail - queue->cap
+ : queue->tail;
+}
+
+/* grn_array */
+
+#define GRN_ARRAY_SEGMENT_SIZE 0x400000
+
+/* Header of grn_io-based grn_array. */
+struct grn_array_header {
+ uint32_t flags;
+ uint32_t curr_rec;
+ uint32_t value_size;
+ uint32_t n_entries;
+ uint32_t n_garbages;
+ grn_id garbages;
+ uint32_t lock;
+ uint32_t truncated;
+ uint32_t reserved[8];
+ grn_table_queue queue;
+};
+
+/*
+ * A grn_io-based grn_array consists of the following 2 segments.
+ * GRN_ARRAY_VALUE_SEGMENT: stores values.
+ * GRN_ARRAY_BITMAP_SEGMENT: stores whether entries are valid or not.
+ */
+enum {
+ GRN_ARRAY_VALUE_SEGMENT = 0,
+ GRN_ARRAY_BITMAP_SEGMENT = 1
+};
+
+inline static grn_bool
+grn_array_is_io_array(grn_array *array)
+{
+ return array->io != NULL;
+}
+
+inline static void *
+grn_array_io_entry_at(grn_ctx *ctx, grn_array *array, grn_id id, int flags)
+{
+ return grn_io_array_at_inline(ctx, array->io, GRN_ARRAY_VALUE_SEGMENT, id, flags);
+}
+
+inline static void *
+grn_array_entry_at(grn_ctx *ctx, grn_array *array, grn_id id, int flags)
+{
+ if (grn_array_is_io_array(array)) {
+ return grn_array_io_entry_at(ctx, array, id, flags);
+ } else {
+ return grn_tiny_array_at_inline(&array->array, id);
+ }
+}
+
+/* grn_array_bitmap_at() returns 1/0 on success, -1 on failure. */
+inline static int
+grn_array_bitmap_at(grn_ctx *ctx, grn_array *array, grn_id id)
+{
+ if (grn_array_is_io_array(array)) {
+ return grn_io_array_bit_at(ctx, array->io, GRN_ARRAY_BITMAP_SEGMENT, id);
+ } else {
+ return grn_tiny_bitmap_put(&array->bitmap, id);
+ }
+}
+
+static grn_rc
+grn_array_init_tiny_array(grn_ctx *ctx, grn_array *array, const char *path,
+ uint32_t value_size, uint32_t flags)
+{
+ if (path) {
+ ERR(GRN_INVALID_ARGUMENT, "failed to create tiny array");
+ return ctx->rc;
+ }
+ array->obj.header.flags = flags;
+ array->ctx = ctx;
+ array->value_size = value_size;
+ array->n_keys = 0;
+ array->keys = NULL;
+ array->n_garbages = &array->n_garbages_buf;
+ array->n_entries = &array->n_entries_buf;
+ 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);
+ return GRN_SUCCESS;
+}
+
+static grn_io *
+grn_array_create_io_array(grn_ctx *ctx, const char *path, uint32_t value_size)
+{
+ uint32_t w_of_element = 0;
+ grn_io_array_spec array_spec[2];
+
+ while ((1U << w_of_element) < value_size) {
+ w_of_element++;
+ }
+
+ array_spec[GRN_ARRAY_VALUE_SEGMENT].w_of_element = w_of_element;
+ array_spec[GRN_ARRAY_VALUE_SEGMENT].max_n_segments =
+ 1U << (30 - (22 - w_of_element));
+ array_spec[GRN_ARRAY_BITMAP_SEGMENT].w_of_element = 0;
+ array_spec[GRN_ARRAY_BITMAP_SEGMENT].max_n_segments = 1U << (30 - (22 + 3));
+ return grn_io_create_with_array(ctx, path, sizeof(struct grn_array_header),
+ GRN_ARRAY_SEGMENT_SIZE, grn_io_auto,
+ 2, array_spec);
+}
+
+static grn_rc
+grn_array_init_io_array(grn_ctx *ctx, grn_array *array, const char *path,
+ uint32_t value_size, uint32_t flags)
+{
+ grn_io *io;
+ struct grn_array_header *header;
+
+ io = grn_array_create_io_array(ctx, path, value_size);
+ if (!io) {
+ return ctx->rc;
+ }
+ grn_io_set_type(io, GRN_TABLE_NO_KEY);
+
+ header = grn_io_header(io);
+ header->flags = flags;
+ header->curr_rec = 0;
+ header->lock = 0;
+ header->value_size = value_size;
+ 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;
+ array->value_size = value_size;
+ array->n_keys = 0;
+ array->keys = NULL;
+ array->n_garbages = &header->n_garbages;
+ array->n_entries = &header->n_entries;
+ array->io = io;
+ array->header = header;
+ array->lock = &header->lock;
+ return GRN_SUCCESS;
+}
+
+void
+grn_array_queue_lock_clear(grn_ctx *ctx, grn_array *array)
+{
+ struct grn_array_header *header;
+ header = grn_io_header(array->io);
+ grn_table_queue_lock_init(ctx, &header->queue);
+}
+
+grn_table_queue *
+grn_array_queue(grn_ctx *ctx, grn_array *array)
+{
+ if (grn_array_is_io_array(array)) {
+ struct grn_array_header *header;
+ header = grn_io_header(array->io);
+ return &header->queue;
+ } else {
+ return NULL;
+ }
+}
+
+static grn_rc
+grn_array_init(grn_ctx *ctx, grn_array *array,
+ const char *path, uint32_t value_size, uint32_t flags)
+{
+ if (flags & GRN_ARRAY_TINY) {
+ return grn_array_init_tiny_array(ctx, array, path, value_size, flags);
+ } else {
+ return grn_array_init_io_array(ctx, array, path, value_size, flags);
+ }
+}
+
+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_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)) {
+ return array;
+ }
+ GRN_FREE(array);
+ }
+ }
+ return NULL;
+}
+
+grn_array *
+grn_array_open(grn_ctx *ctx, const char *path)
+{
+ if (ctx) {
+ grn_io * const io = grn_io_open(ctx, path, grn_io_auto);
+ if (io) {
+ struct grn_array_header * const header = grn_io_header(io);
+ 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)) {
+ GRN_DB_OBJ_SET_TYPE(array, GRN_TABLE_NO_KEY);
+ array->obj.header.flags = header->flags;
+ array->ctx = ctx;
+ array->value_size = header->value_size;
+ array->n_keys = 0;
+ array->keys = NULL;
+ array->n_garbages = &header->n_garbages;
+ array->n_entries = &header->n_entries;
+ array->io = io;
+ array->header = header;
+ array->lock = &header->lock;
+ return array;
+ } else {
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "invalid array flags. (%x)", header->flags);
+ }
+ GRN_FREE(array);
+ }
+ } else {
+ ERR(GRN_INVALID_FORMAT,
+ "[table][array] file type must be %#04x: <%#04x>",
+ GRN_TABLE_NO_KEY, io_type);
+ }
+ grn_io_close(ctx, io);
+ }
+ }
+ 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)
+{
+ grn_rc rc = GRN_SUCCESS;
+ if (!ctx || !array) { return GRN_INVALID_ARGUMENT; }
+ if (array->keys) { GRN_FREE(array->keys); }
+ if (grn_array_is_io_array(array)) {
+ rc = grn_io_close(ctx, array->io);
+ } else {
+ GRN_ASSERT(ctx == array->ctx);
+ grn_tiny_array_fin(&array->array);
+ grn_tiny_bitmap_fin(&array->bitmap);
+ }
+ GRN_FREE(array);
+ return rc;
+}
+
+grn_rc
+grn_array_remove(grn_ctx *ctx, const char *path)
+{
+ if (!ctx || !path) { return GRN_INVALID_ARGUMENT; }
+ 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;
+ 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) {
+ path = GRN_STRDUP(io_path);
+ if (!path) {
+ ERR(GRN_NO_MEMORY_AVAILABLE, "cannot duplicate path: <%s>", io_path);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ }
+ value_size = array->value_size;
+ 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;
+ if (path) {
+ rc = grn_io_remove(ctx, path);
+ }
+ }
+ }
+ if (!rc) {
+ rc = grn_array_init(ctx, array, path, value_size, flags);
+ }
+ if (path) { GRN_FREE(path); }
+ return rc;
+}
+
+inline static grn_id
+grn_array_get_max_id(grn_array *array)
+{
+ return grn_array_is_io_array(array) ? array->header->curr_rec : array->array.max;
+}
+
+inline static void *
+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
+ * when there are garbages in the array.
+ */
+ if (grn_array_bitmap_at(ctx, array, id) != 1) {
+ return NULL;
+ }
+ } else if (id == 0 || id > grn_array_get_max_id(array)) {
+ return NULL;
+ }
+ return grn_array_entry_at(ctx, array, id, 0);
+}
+
+int
+grn_array_get_value(grn_ctx *ctx, grn_array *array, grn_id id, void *valuebuf)
+{
+ void * const value = grn_array_get_value_inline(ctx, array, id);
+ if (value) {
+ if (valuebuf) {
+ grn_memcpy(valuebuf, value, array->value_size);
+ }
+ return array->value_size;
+ }
+ return 0;
+}
+
+void *
+_grn_array_get_value(grn_ctx *ctx, grn_array *array, grn_id id)
+{
+ return grn_array_get_value_inline(ctx, array, id);
+}
+
+inline static grn_rc
+grn_array_set_value_inline(grn_ctx *ctx, grn_array *array, grn_id id,
+ const void *value, int flags)
+{
+ void *entry;
+ entry = grn_array_entry_at(ctx, array, id, 0);
+ if (!entry) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+
+ switch ((flags & GRN_OBJ_SET_MASK)) {
+ case GRN_OBJ_SET :
+ grn_memcpy(entry, value, array->value_size);
+ return GRN_SUCCESS;
+ case GRN_OBJ_INCR :
+ switch (array->value_size) {
+ case sizeof(int32_t) :
+ *((int32_t *)entry) += *((int32_t *)value);
+ return GRN_SUCCESS;
+ case sizeof(int64_t) :
+ *((int64_t *)entry) += *((int64_t *)value);
+ return GRN_SUCCESS;
+ default :
+ return GRN_INVALID_ARGUMENT;
+ }
+ break;
+ case GRN_OBJ_DECR :
+ switch (array->value_size) {
+ case sizeof(int32_t) :
+ *((int32_t *)entry) -= *((int32_t *)value);
+ return GRN_SUCCESS;
+ case sizeof(int64_t) :
+ *((int64_t *)entry) -= *((int64_t *)value);
+ return GRN_SUCCESS;
+ default :
+ return GRN_INVALID_ARGUMENT;
+ }
+ break;
+ default :
+ /* todo : support other types. */
+ return GRN_INVALID_ARGUMENT;
+ }
+}
+
+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
+ * when there are garbages in the array.
+ */
+ if (grn_array_bitmap_at(ctx, array, id) != 1) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ } else if (id == 0 || id > grn_array_get_max_id(array)) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ return grn_array_set_value_inline(ctx, array, id, value, flags);
+}
+
+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;
+ }
+
+ {
+ rc = GRN_SUCCESS;
+ /* lock */
+ if (grn_array_is_io_array(array)) {
+ if (array->value_size >= sizeof(grn_id)) {
+ struct grn_array_header * const header = array->header;
+ void * const entry = grn_array_io_entry_at(ctx, array, id, 0);
+ if (!entry) {
+ rc = GRN_INVALID_ARGUMENT;
+ } else {
+ *((grn_id *)entry) = header->garbages;
+ header->garbages = id;
+ }
+ }
+ if (!rc) {
+ (*array->n_entries)--;
+ (*array->n_garbages)++;
+ /*
+ * The following grn_io_array_bit_off() fails iff a problem has
+ * occurred after the above grn_array_bitmap_at(). That is to say,
+ * an unexpected case.
+ */
+ grn_io_array_bit_off(ctx, array->io, GRN_ARRAY_BITMAP_SEGMENT, id);
+ }
+ } else {
+ if (array->value_size >= sizeof(grn_id)) {
+ void * const entry = grn_tiny_array_get(&array->array, id);
+ if (!entry) {
+ rc = GRN_INVALID_ARGUMENT;
+ } else {
+ *((grn_id *)entry) = array->garbages;
+ array->garbages = id;
+ }
+ }
+ if (!rc) {
+ (*array->n_entries)--;
+ (*array->n_garbages)++;
+ /*
+ * The following grn_io_array_bit_off() fails iff a problem has
+ * occurred after the above grn_array_bitmap_at(). That is to say,
+ * an unexpected case.
+ */
+ grn_tiny_bitmap_get_and_set(&array->bitmap, id, 0);
+ }
+ }
+ /* unlock */
+ return rc;
+ }
+}
+
+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
+ * when there are garbages in the array.
+ */
+ if (grn_array_bitmap_at(ctx, array, id) != 1) {
+ return GRN_ID_NIL;
+ }
+ } else if (id > grn_array_get_max_id(array)) {
+ return GRN_ID_NIL;
+ }
+ return id;
+}
+
+grn_rc
+grn_array_copy_sort_key(grn_ctx *ctx, grn_array *array,
+ grn_table_sort_key *keys, int n_keys)
+{
+ array->keys = (grn_table_sort_key *)GRN_MALLOCN(grn_table_sort_key, n_keys);
+ if (!array->keys) {
+ return ctx->rc;
+ }
+ grn_memcpy(array->keys, keys, sizeof(grn_table_sort_key) * n_keys);
+ array->n_keys = n_keys;
+ return GRN_SUCCESS;
+}
+
+void
+grn_array_cursor_close(grn_ctx *ctx, grn_array_cursor *cursor)
+{
+ GRN_ASSERT(cursor->ctx == ctx);
+ GRN_FREE(cursor);
+}
+
+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_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; }
+
+ GRN_DB_OBJ_SET_TYPE(cursor, GRN_CURSOR_TABLE_NO_KEY);
+ cursor->array = array;
+ cursor->ctx = ctx;
+ cursor->obj.header.flags = flags;
+ cursor->obj.header.domain = GRN_ID_NIL;
+
+ if (flags & GRN_CURSOR_DESCENDING) {
+ cursor->dir = -1;
+ if (max) {
+ cursor->curr_rec = max;
+ if (!(flags & GRN_CURSOR_LT)) { cursor->curr_rec++; }
+ } else {
+ cursor->curr_rec = grn_array_get_max_id(array) + 1;
+ }
+ if (min) {
+ cursor->tail = min;
+ if ((flags & GRN_CURSOR_GT)) { cursor->tail++; }
+ } else {
+ cursor->tail = GRN_ID_NIL + 1;
+ }
+ if (cursor->curr_rec < cursor->tail) { cursor->tail = cursor->curr_rec; }
+ } else {
+ cursor->dir = 1;
+ if (min) {
+ cursor->curr_rec = min;
+ if (!(flags & GRN_CURSOR_GT)) { cursor->curr_rec--; }
+ } else {
+ cursor->curr_rec = GRN_ID_NIL;
+ }
+ if (max) {
+ cursor->tail = max;
+ if ((flags & GRN_CURSOR_LT)) { cursor->tail--; }
+ } else {
+ cursor->tail = grn_array_get_max_id(array);
+ }
+ if (cursor->tail < cursor->curr_rec) { cursor->tail = cursor->curr_rec; }
+ }
+
+ if (*array->n_garbages) {
+ while (offset && cursor->curr_rec != cursor->tail) {
+ cursor->curr_rec += cursor->dir;
+ if (grn_array_bitmap_at(ctx, cursor->array, cursor->curr_rec) == 1) {
+ offset--;
+ }
+ }
+ } else {
+ cursor->curr_rec += cursor->dir * offset;
+ }
+ cursor->rest = (limit < 0) ? GRN_ARRAY_MAX : limit;
+ return cursor;
+}
+
+grn_id
+grn_array_cursor_next(grn_ctx *ctx, grn_array_cursor *cursor)
+{
+ if (cursor && cursor->rest) {
+ while (cursor->curr_rec != cursor->tail) {
+ cursor->curr_rec += cursor->dir;
+ if (*cursor->array->n_garbages) {
+ if (grn_array_bitmap_at(ctx, cursor->array, cursor->curr_rec) != 1) {
+ continue;
+ }
+ }
+ cursor->rest--;
+ return cursor->curr_rec;
+ }
+ }
+ return GRN_ID_NIL;
+}
+
+grn_id
+grn_array_next(grn_ctx *ctx, grn_array *array, grn_id id)
+{
+ 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) {
+ return id;
+ }
+ }
+ return GRN_ID_NIL;
+}
+
+int
+grn_array_cursor_get_value(grn_ctx *ctx, grn_array_cursor *cursor, void **value)
+{
+ if (cursor && value) {
+ void * const entry = grn_array_entry_at(ctx, cursor->array, cursor->curr_rec, 0);
+ if (entry) {
+ *value = entry;
+ return cursor->array->value_size;
+ }
+ }
+ return 0;
+}
+
+grn_rc
+grn_array_cursor_set_value(grn_ctx *ctx, grn_array_cursor *cursor,
+ const void *value, int flags)
+{
+ return grn_array_set_value_inline(ctx, cursor->array, cursor->curr_rec,
+ value, flags);
+}
+
+grn_rc
+grn_array_cursor_delete(grn_ctx *ctx, grn_array_cursor *cursor,
+ grn_table_delete_optarg *optarg)
+{
+ return grn_array_delete_by_id(ctx, cursor->array, cursor->curr_rec, optarg);
+}
+
+inline static grn_id
+grn_array_add_to_tiny_array(grn_ctx *ctx, grn_array *array, void **value)
+{
+ grn_id id = array->garbages;
+ void *entry;
+ if (id) {
+ /* These operations fail iff the array is broken. */
+ entry = grn_tiny_array_get(&array->array, id);
+ if (!entry) {
+ return GRN_ID_NIL;
+ }
+ array->garbages = *(grn_id *)entry;
+ memset(entry, 0, array->value_size);
+ (*array->n_garbages)--;
+ if (!grn_tiny_bitmap_get_and_set(&array->bitmap, id, 1)) {
+ /* Actually, it is difficult to recover from this error. */
+ *(grn_id *)entry = array->garbages;
+ array->garbages = id;
+ (*array->n_garbages)++;
+ return GRN_ID_NIL;
+ }
+ } else {
+ id = array->array.max + 1;
+ if (!grn_tiny_bitmap_put_and_set(&array->bitmap, id, 1)) {
+ return GRN_ID_NIL;
+ }
+ entry = grn_tiny_array_put(&array->array, id);
+ if (!entry) {
+ grn_tiny_bitmap_get_and_set(&array->bitmap, id, 0);
+ return GRN_ID_NIL;
+ }
+ array->array.max = id;
+ }
+ (*array->n_entries)++;
+ if (value) { *value = entry; }
+ return id;
+}
+
+inline static grn_id
+grn_array_add_to_io_array(grn_ctx *ctx, grn_array *array, void **value)
+{
+ 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);
+ if (!entry) {
+ return GRN_ID_NIL;
+ }
+ header->garbages = *(grn_id *)entry;
+ memset(entry, 0, header->value_size);
+ (*array->n_garbages)--;
+ if (!grn_io_array_bit_on(ctx, array->io, GRN_ARRAY_BITMAP_SEGMENT, id)) {
+ /* Actually, it is difficult to recover from this error. */
+ *(grn_id *)entry = array->garbages;
+ array->garbages = id;
+ (*array->n_garbages)++;
+ return GRN_ID_NIL;
+ }
+ } else {
+ if (header->curr_rec >= GRN_ARRAY_MAX) { return GRN_ID_NIL; }
+ id = header->curr_rec + 1;
+ if (!grn_io_array_bit_on(ctx, array->io, GRN_ARRAY_BITMAP_SEGMENT, id)) {
+ return GRN_ID_NIL;
+ }
+ entry = grn_array_io_entry_at(ctx, array, id, GRN_TABLE_ADD);
+ if (!entry) {
+ grn_io_array_bit_off(ctx, array->io, GRN_ARRAY_BITMAP_SEGMENT, id);
+ return GRN_ID_NIL;
+ }
+ header->curr_rec = id;
+ }
+ (*array->n_entries)++;
+ if (value) { *value = entry; }
+ return id;
+}
+
+void
+grn_array_clear_curr_rec(grn_ctx *ctx, grn_array *array)
+{
+ struct grn_array_header * const header = array->header;
+ header->curr_rec = GRN_ID_NIL;
+}
+
+grn_id
+grn_array_add(grn_ctx *ctx, grn_array *array, void **value)
+{
+ if (ctx && array) {
+ if (grn_array_is_io_array(array)) {
+ return grn_array_add_to_io_array(ctx, array, value);
+ } else {
+ return grn_array_add_to_tiny_array(ctx, array, value);
+ }
+ }
+ return GRN_ID_NIL;
+}
+
+grn_id
+grn_array_push(grn_ctx *ctx, grn_array *array,
+ void (*func)(grn_ctx *, grn_array *, grn_id, void *),
+ void *func_arg)
+{
+ grn_id id = GRN_ID_NIL;
+ 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);
+ }
+ id = grn_array_add(ctx, array, NULL);
+ if (func) {
+ func(ctx, array, id, func_arg);
+ }
+ 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);
+ } else {
+ ERR(GRN_OPERATION_NOT_SUPPORTED, "only persistent arrays support push");
+ }
+ return id;
+}
+
+grn_id
+grn_array_pull(grn_ctx *ctx, grn_array *array, grn_bool blockp,
+ void (*func)(grn_ctx *, grn_array *, grn_id, void *),
+ void *func_arg)
+{
+ grn_id id = GRN_ID_NIL;
+ grn_table_queue *queue = grn_array_queue(ctx, array);
+ if (queue) {
+ MUTEX_LOCK(queue->mutex);
+ queue->unblock_requested = GRN_FALSE;
+ while (grn_table_queue_size(queue) == 0) {
+ if (!blockp || queue->unblock_requested) {
+ MUTEX_UNLOCK(queue->mutex);
+ GRN_OUTPUT_BOOL(0);
+ return id;
+ }
+ COND_WAIT(queue->cond, queue->mutex);
+ }
+ grn_table_queue_tail_increment(queue);
+ id = grn_table_queue_tail(queue);
+ if (func) {
+ func(ctx, array, id, func_arg);
+ }
+ MUTEX_UNLOCK(queue->mutex);
+ } else {
+ ERR(GRN_OPERATION_NOT_SUPPORTED, "only persistent arrays support pull");
+ }
+ return id;
+}
+
+void
+grn_array_unblock(grn_ctx *ctx, grn_array *array)
+{
+ grn_table_queue *queue = grn_array_queue(ctx, array);
+ if (!queue) {
+ return;
+ }
+
+ queue->unblock_requested = GRN_TRUE;
+ COND_BROADCAST(queue->cond);
+}
+
+/* grn_hash : hash table */
+
+#define GRN_HASH_MAX_SEGMENT 0x400
+#define GRN_HASH_HEADER_SIZE_NORMAL 0x9000
+#define GRN_HASH_HEADER_SIZE_LARGE\
+ (GRN_HASH_HEADER_SIZE_NORMAL +\
+ (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 {
+ uint8_t key[4];
+ uint8_t value[1];
+} grn_plain_hash_entry;
+
+typedef struct {
+ uint32_t hash_value;
+ uint8_t key_and_value[1];
+} grn_rich_hash_entry;
+
+typedef struct {
+ uint32_t hash_value;
+ uint16_t flag;
+ uint16_t key_size;
+ union {
+ uint8_t buf[sizeof(uint32_t)];
+ uint32_t offset;
+ } key;
+ uint8_t value[1];
+} 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;
+ uint16_t flag;
+ uint16_t key_size;
+ union {
+ uint8_t buf[sizeof(void *)];
+ void *ptr;
+ } key;
+ uint8_t value[1];
+} grn_tiny_hash_entry;
+
+/*
+ * hash_value is valid even if the entry is grn_plain_hash_entry. In this case,
+ * its hash_value equals its key.
+ * flag, key_size and key.buf are valid if the entry has a variable length key.
+ */
+typedef struct {
+ uint32_t hash_value;
+ uint16_t flag;
+ uint16_t key_size;
+} grn_hash_entry_header;
+
+typedef union {
+ uint32_t hash_value;
+ grn_hash_entry_header header;
+ grn_plain_hash_entry plain_entry;
+ grn_rich_hash_entry rich_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;
+
+typedef struct {
+ uint32_t key;
+ uint8_t dummy[1];
+} entry;
+
+typedef struct {
+ uint32_t key;
+ uint16_t flag;
+ uint16_t size;
+ uint32_t str;
+ uint8_t dummy[1];
+} entry_str;
+
+typedef struct {
+ uint32_t key;
+ uint16_t flag;
+ uint16_t size;
+ char *str;
+ uint8_t dummy[1];
+} entry_astr;
+
+enum {
+ GRN_HASH_KEY_SEGMENT = 0,
+ GRN_HASH_ENTRY_SEGMENT = 1,
+ GRN_HASH_INDEX_SEGMENT = 2,
+ 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)
+{
+ return hash->io != NULL;
+}
+
+inline static void *
+grn_io_hash_entry_at(grn_ctx *ctx, grn_hash *hash, grn_id id, int flags)
+{
+ return grn_io_array_at_inline(ctx, hash->io, GRN_HASH_ENTRY_SEGMENT, id, flags);
+}
+
+/* todo : error handling */
+inline static void *
+grn_hash_entry_at(grn_ctx *ctx, grn_hash *hash, grn_id id, int flags)
+{
+ if (grn_hash_is_io_hash(hash)) {
+ return grn_io_hash_entry_at(ctx, hash, id, flags);
+ } else {
+ return grn_tiny_array_at_inline(&hash->a, id);
+ }
+}
+
+inline static grn_bool
+grn_hash_bitmap_at(grn_ctx *ctx, grn_hash *hash, grn_id id)
+{
+ if (grn_hash_is_io_hash(hash)) {
+ return grn_io_array_bit_at(ctx, hash->io, GRN_HASH_BITMAP_SEGMENT, id) == 1;
+ } else {
+ return grn_tiny_bitmap_put(&hash->bitmap, id) == 1;
+ }
+}
+
+inline static grn_id *
+grn_io_hash_idx_at(grn_ctx *ctx, grn_hash *hash, grn_id id)
+{
+ return grn_io_array_at_inline(ctx, hash->io, GRN_HASH_INDEX_SEGMENT,
+ id, GRN_TABLE_ADD);
+}
+
+inline static grn_id *
+grn_hash_idx_at(grn_ctx *ctx, grn_hash *hash, grn_id id)
+{
+ if (grn_hash_is_io_hash(hash)) {
+ id = (id & *hash->max_offset) + hash->header.common->idx_offset;
+ return grn_io_hash_idx_at(ctx, hash, id);
+ } else {
+ return hash->index + (id & *hash->max_offset);
+ }
+}
+
+inline static void *
+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);
+}
+
+#define HASH_IMMEDIATE 1
+
+#define MAX_INDEX_SIZE ((GRN_HASH_MAX_SEGMENT * (IDX_MASK_IN_A_SEGMENT + 1)) >> 1)
+
+inline static uint16_t
+grn_hash_entry_get_key_size(grn_hash *hash, grn_hash_entry *entry)
+{
+ if (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) {
+ return entry->header.key_size;
+ } else {
+ return hash->key_size;
+ }
+}
+
+inline static char *
+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 (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 {
+ 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) {
+ return (char *)entry->tiny_entry.key.buf;
+ } else {
+ return entry->tiny_entry.key.ptr;
+ }
+ }
+ } else {
+ if (hash->key_size == sizeof(uint32_t)) {
+ return (char *)entry->plain_entry.key;
+ } else {
+ return (char *)entry->rich_entry.key_and_value;
+ }
+ }
+}
+
+inline static void *
+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)) {
+ 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;
+ }
+ } else {
+ if (hash->key_size == sizeof(uint32_t)) {
+ return entry->plain_entry.value;
+ } else {
+ return entry->rich_entry.key_and_value + hash->key_size;
+ }
+ }
+}
+
+inline static grn_rc
+grn_io_hash_entry_put_key(grn_ctx *ctx, grn_hash *hash,
+ grn_hash_entry *entry,
+ const void *key, unsigned int key_size)
+{
+ 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 {
+ 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) {
+ 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 = 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;
+ }
+ }
+
+ {
+ void * const key_ptr = grn_io_hash_key_at(ctx, hash, key_offset);
+ if (!key_ptr) {
+ 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);
+ }
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+grn_hash_entry_put_key(grn_ctx *ctx, grn_hash *hash,
+ grn_hash_entry *entry, uint32_t hash_value,
+ const void *key, unsigned int key_size)
+{
+ if (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) {
+ if (grn_hash_is_io_hash(hash)) {
+ 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, entry, key, key_size);
+ if (rc) {
+ return rc;
+ }
+ 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;
+ }
+ } else {
+ if (key_size <= sizeof(entry->tiny_entry.key.buf)) {
+ grn_memcpy(entry->tiny_entry.key.buf, key, key_size);
+ entry->tiny_entry.flag = HASH_IMMEDIATE;
+ } else {
+ grn_ctx * const ctx = hash->ctx;
+ entry->tiny_entry.key.ptr = GRN_CTX_ALLOC(ctx, key_size);
+ if (!entry->tiny_entry.key.ptr) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ grn_memcpy(entry->tiny_entry.key.ptr, key, key_size);
+ entry->tiny_entry.flag = 0;
+ }
+ entry->tiny_entry.hash_value = hash_value;
+ entry->tiny_entry.key_size = key_size;
+ }
+ } else {
+ if (hash->key_size == sizeof(uint32_t)) {
+ *(uint32_t *)entry->plain_entry.key = hash_value;
+ } else {
+ entry->rich_entry.hash_value = hash_value;
+ grn_memcpy(entry->rich_entry.key_and_value, key, key_size);
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+/*
+ * grn_hash_entry_compare_key() returns GRN_TRUE if the entry key equals the
+ * specified key, or GRN_FALSE otherwise.
+ */
+inline static grn_bool
+grn_hash_entry_compare_key(grn_ctx *ctx, grn_hash *hash,
+ grn_hash_entry *entry, uint32_t hash_value,
+ const void *key, unsigned int key_size)
+{
+ if (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) {
+ if (entry->hash_value != hash_value ||
+ entry->header.key_size != key_size) {
+ return GRN_FALSE;
+ }
+ if (grn_hash_is_io_hash(hash)) {
+ 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 {
+ 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) {
+ return !memcmp(key, entry->tiny_entry.key.buf, key_size);
+ } else {
+ return !memcmp(key, entry->tiny_entry.key.ptr, key_size);
+ }
+ }
+ } else {
+ if (entry->hash_value != hash_value) {
+ return GRN_FALSE;
+ }
+ if (key_size == sizeof(uint32_t)) {
+ return GRN_TRUE;
+ } else {
+ return !memcmp(key, entry->rich_entry.key_and_value, key_size);
+ }
+ }
+}
+
+inline static char *
+get_key(grn_ctx *ctx, grn_hash *hash, entry_str *n)
+{
+ return grn_hash_entry_get_key(ctx, hash, (grn_hash_entry *)n);
+}
+
+inline static void *
+get_value(grn_ctx *ctx, grn_hash *hash, entry_str *n)
+{
+ return grn_hash_entry_get_value(ctx, hash, (grn_hash_entry *)n);
+}
+
+inline static int
+match_key(grn_ctx *ctx, grn_hash *hash, entry_str *ee, uint32_t h,
+ const char *key, unsigned int len)
+{
+ return grn_hash_entry_compare_key(ctx, hash, (grn_hash_entry *)ee,
+ h, key, len);
+}
+
+#define GARBAGE (0xffffffff)
+
+inline static uint32_t
+grn_io_hash_calculate_entry_size(uint32_t key_size, uint32_t value_size,
+ uint32_t flags)
+{
+ if (flags & GRN_OBJ_KEY_VAR_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;
+ } else {
+ return (uintptr_t)((grn_rich_hash_entry *)0)->key_and_value
+ + key_size + 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 flags)
+{
+ uint32_t w_of_element = 0;
+ grn_io_array_spec array_spec[4];
+
+ while ((1U << w_of_element) < entry_size) {
+ w_of_element++;
+ }
+
+ array_spec[GRN_HASH_KEY_SEGMENT].w_of_element = 0;
+ 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));
+ array_spec[GRN_HASH_INDEX_SEGMENT].w_of_element = 2;
+ array_spec[GRN_HASH_INDEX_SEGMENT].max_n_segments = 1U << (30 - (22 - 2));
+ array_spec[GRN_HASH_BITMAP_SEGMENT].w_of_element = 0;
+ array_spec[GRN_HASH_BITMAP_SEGMENT].max_n_segments = 1U << (30 - (22 + 3));
+ return grn_io_create_with_array(ctx, path, header_size,
+ GRN_HASH_SEGMENT_SIZE,
+ grn_io_auto, 4, array_spec);
+}
+
+static grn_rc
+grn_io_hash_init(grn_ctx *ctx, grn_hash *hash, const char *path,
+ uint32_t key_size, uint32_t value_size, uint32_t flags,
+ grn_encoding encoding, uint32_t init_size)
+{
+ grn_io *io;
+ grn_hash_header_common *header;
+ uint32_t header_size, entry_size, max_offset;
+
+ if (key_size <= GRN_HASH_MAX_KEY_SIZE_NORMAL) {
+ header_size = GRN_HASH_HEADER_SIZE_NORMAL;
+ } else {
+ header_size = GRN_HASH_HEADER_SIZE_LARGE;
+ }
+ 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, flags);
+ if (!io) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ grn_io_set_type(io, GRN_TABLE_HASH_KEY);
+
+ max_offset = IDX_MASK_IN_A_SEGMENT + 1;
+ while (max_offset < init_size * 2) {
+ max_offset *= 2;
+ }
+ max_offset--;
+
+ if (encoding == GRN_ENC_DEFAULT) {
+ encoding = ctx->encoding;
+ }
+
+ hash->key_size = key_size;
+
+ header = grn_io_header(io);
+ header->flags = flags;
+ header->encoding = encoding;
+ header->key_size = key_size;
+ header->curr_rec = 0;
+ header->curr_key_normal = 0;
+ header->curr_key_large = 0;
+ header->lock = 0;
+ header->idx_offset = 0;
+ header->value_size = value_size;
+ header->entry_size = entry_size;
+ header->max_offset = max_offset;
+ header->n_entries = 0;
+ header->n_garbages = 0;
+ header->tokenizer = GRN_ID_NIL;
+ if (header->flags & GRN_OBJ_KEY_NORMALIZE) {
+ header->flags &= ~GRN_OBJ_KEY_NORMALIZE;
+ hash->normalizer = grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1);
+ header->normalizer = grn_obj_id(ctx, hash->normalizer);
+ } else {
+ 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;
+ if (GRN_HASH_IS_LARGE_KEY(hash)) {
+ queue = &(((grn_hash_header_large *)(header))->queue);
+ } else {
+ queue = &(((grn_hash_header_normal *)(header))->queue);
+ }
+ grn_table_queue_init(ctx, queue);
+ }
+
+ hash->obj.header.flags = (header->flags & GRN_OBJ_FLAGS_MASK);
+ hash->ctx = ctx;
+ hash->encoding = encoding;
+ hash->value_size = value_size;
+ hash->entry_size = entry_size;
+ hash->n_garbages = &header->n_garbages;
+ hash->n_entries = &header->n_entries;
+ hash->max_offset = &header->max_offset;
+ hash->io = io;
+ hash->header.common = header;
+ hash->lock = &header->lock;
+ hash->tokenizer = NULL;
+ return GRN_SUCCESS;
+}
+
+#define INITIAL_INDEX_SIZE 256U
+
+static uint32_t
+grn_tiny_hash_calculate_entry_size(uint32_t key_size, uint32_t value_size,
+ uint32_t flags)
+{
+ uint32_t entry_size;
+ if (flags & GRN_OBJ_KEY_VAR_SIZE) {
+ entry_size = (uintptr_t)((grn_tiny_hash_entry *)0)->value + value_size;
+ } else {
+ if (key_size == sizeof(uint32_t)) {
+ entry_size = (uintptr_t)((grn_plain_hash_entry *)0)->value + value_size;
+ } else {
+ entry_size = (uintptr_t)((grn_rich_hash_entry *)0)->key_and_value
+ + key_size + value_size;
+ }
+ }
+ if (entry_size != sizeof(uint32_t)) {
+ entry_size += sizeof(uintptr_t) - 1;
+ entry_size &= ~(sizeof(uintptr_t) - 1);
+ }
+ return entry_size;
+}
+
+static grn_rc
+grn_tiny_hash_init(grn_ctx *ctx, grn_hash *hash, const char *path,
+ uint32_t key_size, uint32_t value_size, uint32_t flags,
+ grn_encoding encoding)
+{
+ uint32_t entry_size;
+
+ if (path) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ hash->index = GRN_CTX_ALLOC(ctx, INITIAL_INDEX_SIZE * sizeof(grn_id));
+ if (!hash->index) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+
+ entry_size = grn_tiny_hash_calculate_entry_size(key_size, value_size, flags);
+ hash->obj.header.flags = flags;
+ hash->ctx = ctx;
+ hash->key_size = key_size;
+ hash->encoding = encoding;
+ hash->value_size = value_size;
+ hash->entry_size = entry_size;
+ hash->n_garbages = &hash->n_garbages_;
+ hash->n_entries = &hash->n_entries_;
+ 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;
+ hash->tokenizer = NULL;
+ hash->normalizer = NULL;
+ GRN_PTR_INIT(&(hash->token_filters), GRN_OBJ_VECTOR, GRN_ID_NIL);
+ grn_tiny_array_init(ctx, &hash->a, entry_size, GRN_TINY_ARRAY_CLEAR);
+ grn_tiny_bitmap_init(ctx, &hash->bitmap);
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_hash_init(grn_ctx *ctx, grn_hash *hash, const char *path,
+ uint32_t key_size, uint32_t value_size, uint32_t flags)
+{
+ if (flags & GRN_HASH_TINY) {
+ return grn_tiny_hash_init(ctx, hash, path, key_size, value_size,
+ flags, ctx->encoding);
+ } else {
+ return grn_io_hash_init(ctx, hash, path, key_size, value_size,
+ flags, ctx->encoding, 0);
+ }
+}
+
+grn_hash *
+grn_hash_create(grn_ctx *ctx, const char *path, uint32_t key_size, uint32_t value_size,
+ uint32_t flags)
+{
+ grn_hash *hash;
+ if (!ctx) {
+ return NULL;
+ }
+ if (key_size > GRN_HASH_MAX_KEY_SIZE_LARGE) {
+ return NULL;
+ }
+ hash = (grn_hash *)GRN_CALLOC(sizeof(grn_hash));
+ if (!hash) {
+ return NULL;
+ }
+ GRN_DB_OBJ_SET_TYPE(hash, GRN_TABLE_HASH_KEY);
+ if (grn_hash_init(ctx, hash, path, key_size, value_size, flags)) {
+ GRN_FREE(hash);
+ return NULL;
+ }
+ return hash;
+}
+
+grn_hash *
+grn_hash_open(grn_ctx *ctx, const char *path)
+{
+ if (ctx) {
+ grn_io * const io = grn_io_open(ctx, path, grn_io_auto);
+ if (io) {
+ grn_hash_header_common * const header = grn_io_header(io);
+ 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)) {
+ GRN_DB_OBJ_SET_TYPE(hash, GRN_TABLE_HASH_KEY);
+ hash->ctx = ctx;
+ hash->key_size = header->key_size;
+ hash->encoding = header->encoding;
+ hash->value_size = header->value_size;
+ hash->entry_size = header->entry_size;
+ hash->n_garbages = &header->n_garbages;
+ hash->n_entries = &header->n_entries;
+ hash->max_offset = &header->max_offset;
+ hash->io = io;
+ hash->header.common = header;
+ hash->lock = &header->lock;
+ hash->tokenizer = grn_ctx_at(ctx, header->tokenizer);
+ if (header->flags & GRN_OBJ_KEY_NORMALIZE) {
+ header->flags &= ~GRN_OBJ_KEY_NORMALIZE;
+ hash->normalizer = grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1);
+ header->normalizer = grn_obj_id(ctx, hash->normalizer);
+ } else {
+ hash->normalizer = grn_ctx_at(ctx, header->normalizer);
+ }
+ GRN_PTR_INIT(&(hash->token_filters), GRN_OBJ_VECTOR, GRN_ID_NIL);
+ hash->obj.header.flags = header->flags;
+ return hash;
+ } else {
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
+ "invalid hash flag. (%x)", header->flags);
+ }
+ GRN_FREE(hash);
+ }
+ } else {
+ ERR(GRN_INVALID_FORMAT,
+ "[table][hash] file type must be %#04x: <%#04x>",
+ GRN_TABLE_HASH_KEY, io_type);
+ }
+ grn_io_close(ctx, io);
+ }
+ }
+ 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)
+{
+ if (!hash->index) {
+ return GRN_INVALID_ARGUMENT;
+ }
+
+ GRN_OBJ_FIN(ctx, &(hash->token_filters));
+
+ if (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) {
+ uint32_t num_remaining_entries = *hash->n_entries;
+ grn_id *hash_ptr;
+ for (hash_ptr = hash->index; num_remaining_entries; hash_ptr++) {
+ const grn_id id = *hash_ptr;
+ if (id && id != GARBAGE) {
+ grn_tiny_hash_entry * const entry =
+ (grn_tiny_hash_entry *)grn_tiny_array_get(&hash->a, id);
+ GRN_ASSERT(entry);
+ num_remaining_entries--;
+ if (entry && !(entry->flag & HASH_IMMEDIATE)) {
+ GRN_CTX_FREE(ctx, entry->key.ptr);
+ }
+ }
+ }
+ }
+ grn_tiny_array_fin(&hash->a);
+ grn_tiny_bitmap_fin(&hash->bitmap);
+ GRN_CTX_FREE(ctx, hash->index);
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_hash_close(grn_ctx *ctx, grn_hash *hash)
+{
+ grn_rc rc;
+ if (!ctx || !hash) { return GRN_INVALID_ARGUMENT; }
+ if (grn_hash_is_io_hash(hash)) {
+ rc = grn_io_close(ctx, hash->io);
+ GRN_OBJ_FIN(ctx, &(hash->token_filters));
+ } else {
+ GRN_ASSERT(ctx == hash->ctx);
+ rc = grn_tiny_hash_fin(ctx, hash);
+ }
+ GRN_FREE(hash);
+ return rc;
+}
+
+grn_rc
+grn_hash_remove(grn_ctx *ctx, const char *path)
+{
+ if (!ctx || !path) { return GRN_INVALID_ARGUMENT; }
+ return grn_io_remove(ctx, path);
+}
+
+grn_rc
+grn_hash_truncate(grn_ctx *ctx, grn_hash *hash)
+{
+ 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);
+ if (io_path && *io_path) {
+ path = GRN_STRDUP(io_path);
+ if (!path) {
+ ERR(GRN_NO_MEMORY_AVAILABLE, "cannot duplicate path: <%s>", io_path);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ }
+ key_size = hash->key_size;
+ value_size = hash->value_size;
+ 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;
+ if (path) {
+ 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);
+ }
+ if (path) {
+ GRN_FREE(path);
+ }
+ return rc;
+}
+
+inline static uint32_t
+grn_hash_calculate_hash_value(const void *ptr, uint32_t size)
+{
+ uint32_t i;
+ uint32_t hash_value = 0;
+ for (i = 0; i < size; i++) {
+ hash_value = (hash_value * 1021) + ((const uint8_t *)ptr)[i];
+ }
+ return hash_value;
+}
+
+inline static uint32_t
+grn_hash_calculate_step(uint32_t hash_value)
+{
+ return (hash_value >> 2) | 0x1010101;
+}
+
+static grn_rc
+grn_hash_reset(grn_ctx *ctx, grn_hash *hash, uint32_t expected_n_entries)
+{
+ grn_id *new_index = NULL;
+ uint32_t new_index_size = INITIAL_INDEX_SIZE;
+ grn_id *src_ptr = NULL, *dest_ptr = NULL;
+ uint32_t src_offset = 0, dest_offset = 0;
+ const uint32_t n_entries = *hash->n_entries;
+ const uint32_t max_offset = *hash->max_offset;
+
+ if (!expected_n_entries) {
+ expected_n_entries = n_entries * 2;
+ }
+ if (expected_n_entries > INT_MAX) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ while (new_index_size <= expected_n_entries) {
+ new_index_size *= 2;
+ }
+
+ if (grn_hash_is_io_hash(hash)) {
+ uint32_t i;
+ src_offset = hash->header.common->idx_offset;
+ dest_offset = MAX_INDEX_SIZE - src_offset;
+ for (i = 0; i < new_index_size; i += (IDX_MASK_IN_A_SEGMENT + 1)) {
+ /*
+ * The following grn_io_hash_idx_at() allocates memory for a new segment
+ * and returns a pointer to the new segment. It's actually bad manners
+ * but faster than calling grn_io_hash_idx_at() for each element.
+ */
+ dest_ptr = grn_io_hash_idx_at(ctx, hash, i + dest_offset);
+ if (!dest_ptr) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ memset(dest_ptr, 0, GRN_HASH_SEGMENT_SIZE);
+ }
+ } else {
+ GRN_ASSERT(ctx == hash->ctx);
+ new_index = GRN_CTX_ALLOC(ctx, new_index_size * sizeof(grn_id));
+ if (!new_index) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ src_ptr = hash->index;
+ }
+
+ {
+ uint32_t src_pos, count;
+ const uint32_t new_max_offset = new_index_size - 1;
+ for (count = 0, src_pos = 0; count < n_entries && src_pos <= max_offset;
+ src_pos++, src_ptr++) {
+ uint32_t i, step;
+ grn_id entry_id;
+ grn_hash_entry *entry;
+ if (grn_hash_is_io_hash(hash) && !(src_pos & IDX_MASK_IN_A_SEGMENT)) {
+ src_ptr = grn_io_hash_idx_at(ctx, hash, src_pos + src_offset);
+ if (!src_ptr) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ entry_id = *src_ptr;
+ if (!entry_id || (entry_id == GARBAGE)) {
+ continue;
+ }
+ entry = grn_hash_entry_at(ctx, hash, entry_id, GRN_TABLE_ADD);
+ if (!entry) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ step = grn_hash_calculate_step(entry->hash_value);
+ for (i = entry->hash_value; ; i += step) {
+ i &= new_max_offset;
+ if (grn_hash_is_io_hash(hash)) {
+ dest_ptr = grn_io_hash_idx_at(ctx, hash, i + dest_offset);
+ if (!dest_ptr) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ } else {
+ dest_ptr = new_index + i;
+ }
+ if (!*dest_ptr) {
+ break;
+ }
+ }
+ *dest_ptr = entry_id;
+ count++;
+ }
+ *hash->max_offset = new_max_offset;
+ *hash->n_garbages = 0;
+ }
+
+ if (grn_hash_is_io_hash(hash)) {
+ hash->header.common->idx_offset = dest_offset;
+ } else {
+ grn_id * const old_index = hash->index;
+ hash->index = new_index;
+ GRN_CTX_FREE(ctx, old_index);
+ }
+
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_hash_lock(grn_ctx *ctx, grn_hash *hash, int timeout)
+{
+ static int _ncalls = 0, _ncolls = 0;
+ uint32_t count;
+ _ncalls++;
+ for (count = 0;; count++) {
+ uint32_t lock;
+ GRN_ATOMIC_ADD_EX(hash->lock, 1, lock);
+ if (lock) {
+ GRN_ATOMIC_ADD_EX(hash->lock, -1, lock);
+ if (!timeout || (timeout > 0 && timeout == count)) { break; }
+ if (!(++_ncolls % 1000000) && (_ncolls > _ncalls)) {
+ if (_ncolls < 0 || _ncalls < 0) {
+ _ncolls = 0; _ncalls = 0;
+ } else {
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "hash(%p) collisions(%d/%d)", hash, _ncolls, _ncalls);
+ }
+ }
+ grn_nanosleep(GRN_LOCK_WAIT_TIME_NANOSECOND);
+ continue;
+ }
+ return GRN_SUCCESS;
+ }
+ ERR(GRN_RESOURCE_DEADLOCK_AVOIDED, "grn_hash_lock");
+ return ctx->rc;
+}
+
+grn_rc
+grn_hash_unlock(grn_ctx *ctx, grn_hash *hash)
+{
+ uint32_t lock;
+ GRN_ATOMIC_ADD_EX(hash->lock, -1, lock);
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_hash_clear_lock(grn_ctx *ctx, grn_hash *hash)
+{
+ *hash->lock = 0;
+ 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)
+{
+ grn_id entry_id;
+ grn_hash_entry *entry;
+ grn_hash_header_common * const header = hash->header.common;
+ grn_id *garbages;
+
+ if (GRN_HASH_IS_LARGE_KEY(hash)) {
+ garbages = hash->header.large->garbages;
+ } else {
+ garbages = hash->header.normal->garbages;
+ }
+
+ entry_id = garbages[key_size - 1];
+ if (entry_id) {
+ entry = grn_io_hash_entry_at(ctx, hash, entry_id, GRN_TABLE_ADD);
+ if (!entry) {
+ return GRN_ID_NIL;
+ }
+ 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. */
+ 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);
+ }
+ } else {
+ entry_id = header->curr_rec + 1;
+ entry = grn_hash_entry_at(ctx, hash, entry_id, GRN_TABLE_ADD);
+ if (!entry) {
+ return GRN_ID_NIL;
+ }
+ header->curr_rec = entry_id;
+ }
+
+ if (!grn_io_array_bit_on(ctx, hash->io, GRN_HASH_BITMAP_SEGMENT, entry_id)) {
+ /* TODO: error handling. */
+ }
+
+ if (grn_hash_entry_put_key(ctx, hash, entry, hash_value, key, key_size)) {
+ grn_hash_delete_by_id(ctx, hash, entry_id, NULL);
+ return GRN_ID_NIL;
+ }
+
+ if (value) {
+ *value = grn_hash_entry_get_value(ctx, hash, entry);
+ }
+ return entry_id;
+}
+
+inline static grn_id
+grn_tiny_hash_add(grn_ctx *ctx, grn_hash *hash, uint32_t hash_value,
+ const void *key, unsigned int key_size, void **value)
+{
+ grn_id entry_id;
+ grn_hash_entry *entry;
+ if (hash->garbages) {
+ entry_id = hash->garbages;
+ entry = (grn_hash_entry *)grn_tiny_array_get(&hash->a, entry_id);
+ hash->garbages = *(grn_id *)entry;
+ memset(entry, 0, hash->entry_size);
+ } else {
+ entry_id = hash->a.max + 1;
+ entry = (grn_hash_entry *)grn_tiny_array_put(&hash->a, entry_id);
+ if (!entry) {
+ return GRN_ID_NIL;
+ }
+ }
+
+ if (!grn_tiny_bitmap_put_and_set(&hash->bitmap, entry_id, 1)) {
+ /* TODO: error handling. */
+ }
+
+ if (grn_hash_entry_put_key(ctx, hash, entry, hash_value, key, key_size)) {
+ /* TODO: error handling. */
+ }
+
+ if (value) {
+ *value = grn_hash_entry_get_value(ctx, hash, entry);
+ }
+ return entry_id;
+}
+
+grn_id
+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;
+ }
+ if (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) {
+ if (key_size > hash->key_size) {
+ ERR(GRN_INVALID_ARGUMENT, "too long key");
+ return GRN_ID_NIL;
+ }
+ hash_value = grn_hash_calculate_hash_value(key, key_size);
+ } else {
+ if (key_size != hash->key_size) {
+ ERR(GRN_INVALID_ARGUMENT, "key size unmatch");
+ return GRN_ID_NIL;
+ }
+ if (key_size == sizeof(uint32_t)) {
+ hash_value = *((uint32_t *)key);
+ } else {
+ hash_value = grn_hash_calculate_hash_value(key, key_size);
+ }
+ }
+
+ {
+ uint32_t i;
+ const uint32_t step = grn_hash_calculate_step(hash_value);
+ grn_id id, *index, *garbage_index = NULL;
+ grn_hash_entry *entry;
+
+ /* 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);
+ }
+
+ for (i = hash_value; ; i += step) {
+ index = grn_hash_idx_at(ctx, hash, i);
+ if (!index) {
+ return GRN_ID_NIL;
+ }
+ id = *index;
+ if (!id) {
+ break;
+ }
+ if (id == GARBAGE) {
+ if (!garbage_index) {
+ garbage_index = index;
+ }
+ continue;
+ }
+
+ entry = grn_hash_entry_at(ctx, hash, id, GRN_TABLE_ADD);
+ if (!entry) {
+ return GRN_ID_NIL;
+ }
+ if (grn_hash_entry_compare_key(ctx, hash, entry, hash_value,
+ key, key_size)) {
+ if (value) {
+ *value = grn_hash_entry_get_value(ctx, hash, entry);
+ }
+ if (added) {
+ *added = 0;
+ }
+ return id;
+ }
+ }
+
+ if (grn_hash_is_io_hash(hash)) {
+ id = grn_io_hash_add(ctx, hash, hash_value, key, key_size, value);
+ } else {
+ id = grn_tiny_hash_add(ctx, hash, hash_value, key, key_size, value);
+ }
+ if (!id) {
+ return GRN_ID_NIL;
+ }
+ if (garbage_index) {
+ (*hash->n_garbages)--;
+ index = garbage_index;
+ }
+ *index = id;
+ (*hash->n_entries)++;
+ /* unlock */
+
+ if (added) {
+ *added = 1;
+ }
+ return id;
+ }
+}
+
+grn_id
+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;
+ }
+ hash_value = grn_hash_calculate_hash_value(key, key_size);
+ } else {
+ if (key_size != hash->key_size) {
+ return GRN_ID_NIL;
+ }
+ if (key_size == sizeof(uint32_t)) {
+ hash_value = *((uint32_t *)key);
+ } else {
+ hash_value = grn_hash_calculate_hash_value(key, key_size);
+ }
+ }
+
+ {
+ uint32_t i;
+ const uint32_t step = grn_hash_calculate_step(hash_value);
+ for (i = hash_value; ; i += step) {
+ grn_id id;
+ grn_id * const index = grn_hash_idx_at(ctx, hash, i);
+ if (!index) {
+ return GRN_ID_NIL;
+ }
+ id = *index;
+ if (!id) {
+ return GRN_ID_NIL;
+ }
+ if (id != GARBAGE) {
+ grn_hash_entry * const entry = grn_hash_entry_at(ctx, hash, id, 0);
+ if (entry) {
+ if (grn_hash_entry_compare_key(ctx, hash, entry, hash_value,
+ key, key_size)) {
+ if (value) {
+ *value = grn_hash_entry_get_value(ctx, hash, entry);
+ }
+ return id;
+ }
+ }
+ }
+ }
+ }
+}
+
+inline static grn_hash_entry *
+grn_hash_get_entry(grn_ctx *ctx, grn_hash *hash, grn_id id)
+{
+ if (!grn_hash_bitmap_at(ctx, hash, id)) {
+ return NULL;
+ }
+ return grn_hash_entry_at(ctx, hash, id, 0);
+}
+
+const char *
+_grn_hash_key(grn_ctx *ctx, grn_hash *hash, grn_id id, uint32_t *key_size)
+{
+ grn_hash_entry * const entry = grn_hash_get_entry(ctx, hash, id);
+ if (!entry) {
+ *key_size = 0;
+ return NULL;
+ }
+ *key_size = grn_hash_entry_get_key_size(hash, entry);
+ return grn_hash_entry_get_key(ctx, hash, entry);
+}
+
+int
+grn_hash_get_key(grn_ctx *ctx, grn_hash *hash, grn_id id, void *keybuf, int bufsize)
+{
+ int key_size;
+ 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);
+ if (bufsize >= key_size) {
+ grn_memcpy(keybuf, grn_hash_entry_get_key(ctx, hash, entry), key_size);
+ }
+ return key_size;
+}
+
+int
+grn_hash_get_key2(grn_ctx *ctx, grn_hash *hash, grn_id id, grn_obj *bulk)
+{
+ int key_size;
+ char *key;
+ 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);
+ if (bulk->header.impl_flags & GRN_OBJ_REFER) {
+ bulk->u.b.head = key;
+ bulk->u.b.curr = key + key_size;
+ } else {
+ grn_bulk_write(ctx, bulk, key, key_size);
+ }
+ return key_size;
+}
+
+int
+grn_hash_get_value(grn_ctx *ctx, grn_hash *hash, grn_id id, void *valuebuf)
+{
+ void *value;
+ 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(ctx, hash, entry);
+ if (!value) {
+ return 0;
+ }
+ if (valuebuf) {
+ grn_memcpy(valuebuf, value, hash->value_size);
+ }
+ return hash->value_size;
+}
+
+const char *
+grn_hash_get_value_(grn_ctx *ctx, grn_hash *hash, grn_id id, uint32_t *size)
+{
+ const void *value;
+ 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(ctx, hash, entry);
+ if (!value) {
+ return NULL;
+ }
+ if (size) {
+ *size = hash->value_size;
+ }
+ return (const char *)value;
+}
+
+int
+grn_hash_get_key_value(grn_ctx *ctx, grn_hash *hash, grn_id id,
+ void *keybuf, int bufsize, void *valuebuf)
+{
+ void *value;
+ int key_size;
+ 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);
+ if (bufsize >= key_size) {
+ grn_memcpy(keybuf, grn_hash_entry_get_key(ctx, hash, entry), key_size);
+ }
+ value = grn_hash_entry_get_value(ctx, hash, entry);
+ if (!value) {
+ return 0;
+ }
+ if (valuebuf) {
+ grn_memcpy(valuebuf, value, hash->value_size);
+ }
+ return key_size;
+}
+
+int
+_grn_hash_get_key_value(grn_ctx *ctx, grn_hash *hash, grn_id id,
+ void **key, void **value)
+{
+ int key_size;
+ 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(ctx, hash, entry);
+ return *value ? key_size : 0;
+}
+
+grn_rc
+grn_hash_set_value(grn_ctx *ctx, grn_hash *hash, grn_id id,
+ const void *value, int flags)
+{
+ 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;
+ }
+ entry = grn_hash_get_entry(ctx, hash, id);
+ if (!entry) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ entry_value = grn_hash_entry_get_value(ctx, hash, entry);
+ if (!entry_value) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+
+ switch (flags & GRN_OBJ_SET_MASK) {
+ case GRN_OBJ_SET :
+ grn_memcpy(entry_value, value, hash->value_size);
+ return GRN_SUCCESS;
+ case GRN_OBJ_INCR :
+ switch (hash->value_size) {
+ case sizeof(int32_t) :
+ *((int32_t *)entry_value) += *((int32_t *)value);
+ return GRN_SUCCESS;
+ case sizeof(int64_t) :
+ *((int64_t *)entry_value) += *((int64_t *)value);
+ return GRN_SUCCESS;
+ default :
+ return GRN_INVALID_ARGUMENT;
+ }
+ break;
+ case GRN_OBJ_DECR :
+ switch (hash->value_size) {
+ case sizeof(int32_t) :
+ *((int32_t *)entry_value) -= *((int32_t *)value);
+ return GRN_SUCCESS;
+ case sizeof(int64_t) :
+ *((int64_t *)entry_value) -= *((int64_t *)value);
+ return GRN_SUCCESS;
+ default :
+ return GRN_INVALID_ARGUMENT;
+ }
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "flags = %d", flags);
+ return ctx->rc;
+ }
+}
+
+#define DELETE_IT do {\
+ *ep = GARBAGE;\
+ if (grn_hash_is_io_hash(hash)) {\
+ uint32_t size = key_size - 1;\
+ grn_id *garbages;\
+ if (GRN_HASH_IS_LARGE_KEY(hash)) {\
+ garbages = hash->header.large->garbages;\
+ } else {\
+ garbages = hash->header.normal->garbages;\
+ }\
+ ee->key = garbages[size];\
+ garbages[size] = e;\
+ grn_io_array_bit_off(ctx, hash->io, GRN_HASH_BITMAP_SEGMENT, e);\
+ } else {\
+ ee->key = hash->garbages;\
+ hash->garbages = e;\
+ if ((hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) && !(ee->flag & HASH_IMMEDIATE)) {\
+ grn_ctx *ctx = hash->ctx;\
+ GRN_CTX_FREE(ctx, ((entry_astr *)ee)->str);\
+ }\
+ grn_tiny_bitmap_get_and_set(&hash->bitmap, e, 0);\
+ }\
+ (*hash->n_entries)--;\
+ (*hash->n_garbages)++;\
+ rc = GRN_SUCCESS;\
+} while (0)
+
+grn_rc
+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;
+ 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) {
+ grn_id e, *ep;
+ uint32_t i, key_size, h = ee->key, s = grn_hash_calculate_step(h);
+ key_size = (hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) ? ee->size : hash->key_size;
+ for (i = h; ; i += s) {
+ if (!(ep = grn_hash_idx_at(ctx, hash, i))) { return GRN_NO_MEMORY_AVAILABLE; }
+ if (!(e = *ep)) { break; }
+ if (e == id) {
+ DELETE_IT;
+ break;
+ }
+ }
+ }
+ /* unlock */
+ return rc;
+}
+
+grn_rc
+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_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);
+ } else {
+ if (key_size != hash->key_size) { return GRN_INVALID_ARGUMENT; }
+ if (key_size == sizeof(uint32_t)) {
+ h = *((uint32_t *)key);
+ } else {
+ h = grn_hash_calculate_hash_value(key, key_size);
+ }
+ }
+ s = grn_hash_calculate_step(h);
+ {
+ grn_id e, *ep;
+ /* lock */
+ m = *hash->max_offset;
+ for (i = h; ; i += s) {
+ if (!(ep = grn_hash_idx_at(ctx, hash, i))) { return GRN_NO_MEMORY_AVAILABLE; }
+ if (!(e = *ep)) { break; }
+ if (e == GARBAGE) { continue; }
+ {
+ entry_str * const ee = grn_hash_entry_at(ctx, hash, e, 0);
+ if (ee && match_key(ctx, hash, ee, h, key, key_size)) {
+ DELETE_IT;
+ break;
+ }
+ }
+ }
+ /* unlock */
+ return rc;
+ }
+}
+
+/* only valid for hash tables, GRN_OBJ_KEY_VAR_SIZE && GRN_HASH_TINY */
+const char *
+_grn_hash_strkey_by_val(void *v, uint16_t *size)
+{
+ entry_astr *n = (entry_astr *)((uintptr_t)v -
+ (uintptr_t)&((entry_astr *)0)->dummy);
+ *size = n->size;
+ return (n->flag & HASH_IMMEDIATE) ? (char *)&n->str : n->str;
+}
+
+void
+grn_hash_cursor_close(grn_ctx *ctx, grn_hash_cursor *c)
+{
+ GRN_ASSERT(c->ctx == ctx);
+ GRN_FREE(c);
+}
+
+#define HASH_CURR_MAX(hash) \
+ ((grn_hash_is_io_hash(hash)) ? (hash)->header.common->curr_rec : (hash)->a.max)
+
+grn_hash_cursor *
+grn_hash_cursor_open(grn_ctx *ctx, grn_hash *hash,
+ const void *min, uint32_t min_size,
+ const void *max, uint32_t max_size,
+ int offset, int limit, int flags)
+{
+ 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;
+ c->ctx = ctx;
+ c->obj.header.flags = flags;
+ c->obj.header.domain = GRN_ID_NIL;
+ if (flags & GRN_CURSOR_DESCENDING) {
+ c->dir = -1;
+ if (max) {
+ if (!(c->curr_rec = grn_hash_get(ctx, hash, max, max_size, NULL))) {
+ c->tail = GRN_ID_NIL;
+ goto exit;
+ }
+ if (!(flags & GRN_CURSOR_LT)) { c->curr_rec++; }
+ } else {
+ c->curr_rec = HASH_CURR_MAX(hash) + 1;
+ }
+ if (min) {
+ if (!(c->tail = grn_hash_get(ctx, hash, min, min_size, NULL))) {
+ c->curr_rec = GRN_ID_NIL;
+ goto exit;
+ }
+ if ((flags & GRN_CURSOR_GT)) { c->tail++; }
+ } else {
+ c->tail = GRN_ID_NIL + 1;
+ }
+ if (c->curr_rec < c->tail) { c->tail = c->curr_rec; }
+ } else {
+ c->dir = 1;
+ if (min) {
+ if (!(c->curr_rec = grn_hash_get(ctx, hash, min, min_size, NULL))) {
+ c->tail = GRN_ID_NIL;
+ goto exit;
+ }
+ if (!(flags & GRN_CURSOR_GT)) { c->curr_rec--; }
+ } else {
+ c->curr_rec = GRN_ID_NIL;
+ }
+ if (max) {
+ if (!(c->tail = grn_hash_get(ctx, hash, max, max_size, NULL))) {
+ c->curr_rec = GRN_ID_NIL;
+ goto exit;
+ }
+ if ((flags & GRN_CURSOR_LT)) { c->tail--; }
+ } else {
+ c->tail = HASH_CURR_MAX(hash);
+ }
+ if (c->tail < c->curr_rec) { c->tail = c->curr_rec; }
+ }
+ if (*hash->n_entries != HASH_CURR_MAX(hash)) {
+ while (offset && c->curr_rec != c->tail) {
+ c->curr_rec += c->dir;
+ if (grn_hash_bitmap_at(ctx, c->hash, c->curr_rec)) { offset--; }
+ }
+ } else {
+ c->curr_rec += c->dir * offset;
+ }
+exit :
+ c->rest = (limit < 0) ? GRN_ARRAY_MAX : limit;
+ return c;
+}
+
+grn_id
+grn_hash_cursor_next(grn_ctx *ctx, grn_hash_cursor *c)
+{
+ if (c && c->rest) {
+ while (c->curr_rec != c->tail) {
+ c->curr_rec += c->dir;
+ if (*c->hash->n_entries != HASH_CURR_MAX(c->hash)) {
+ if (!grn_hash_bitmap_at(ctx, c->hash, c->curr_rec)) { continue; }
+ }
+ c->rest--;
+ return c->curr_rec;
+ }
+ }
+ return GRN_ID_NIL;
+}
+
+grn_id
+grn_hash_next(grn_ctx *ctx, grn_hash *hash, grn_id id)
+{
+ grn_id max = HASH_CURR_MAX(hash);
+ while (++id <= max) {
+ if (grn_hash_bitmap_at(ctx, hash, id)) { return id; }
+ }
+ return GRN_ID_NIL;
+}
+
+grn_id
+grn_hash_at(grn_ctx *ctx, grn_hash *hash, grn_id id)
+{
+ return grn_hash_bitmap_at(ctx, hash, id) ? id : GRN_ID_NIL;
+}
+
+int
+grn_hash_cursor_get_key(grn_ctx *ctx, grn_hash_cursor *c, void **key)
+{
+ int key_size;
+ entry_str *ee;
+ if (!c) { return 0; }
+ ee = grn_hash_entry_at(ctx, c->hash, c->curr_rec, 0);
+ if (!ee) { return 0; }
+ key_size = (c->hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) ? ee->size : c->hash->key_size;
+ *key = get_key(ctx, c->hash, ee);
+ return key_size;
+}
+
+int
+grn_hash_cursor_get_value(grn_ctx *ctx, grn_hash_cursor *c, void **value)
+{
+ void *v;
+ entry_str *ee;
+ if (!c) { return 0; }
+ ee = grn_hash_entry_at(ctx, c->hash, c->curr_rec, 0);
+ if (ee && (v = get_value(ctx, c->hash, ee))) {
+ *value = v;
+ return c->hash->value_size;
+ }
+ return 0;
+}
+
+int
+grn_hash_cursor_get_key_value(grn_ctx *ctx, grn_hash_cursor *c,
+ void **key, uint32_t *key_size, void **value)
+{
+ entry_str *ee;
+ if (!c) { return GRN_INVALID_ARGUMENT; }
+ ee = grn_hash_entry_at(ctx, c->hash, c->curr_rec, 0);
+ if (!ee) { return GRN_INVALID_ARGUMENT; }
+ if (key_size) {
+ *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(ctx, c->hash, ee); }
+ return c->hash->value_size;
+}
+
+grn_rc
+grn_hash_cursor_set_value(grn_ctx *ctx, grn_hash_cursor *c,
+ const void *value, int flags)
+{
+ if (!c) { return GRN_INVALID_ARGUMENT; }
+ return grn_hash_set_value(ctx, c->hash, c->curr_rec, value, flags);
+}
+
+grn_rc
+grn_hash_cursor_delete(grn_ctx *ctx, grn_hash_cursor *c,
+ grn_table_delete_optarg *optarg)
+{
+ if (!c) { return GRN_INVALID_ARGUMENT; }
+ return grn_hash_delete_by_id(ctx, c->hash, c->curr_rec, optarg);
+}
+
+/* sort */
+
+#define PREPARE_VAL(e,ep,es) do {\
+ if ((arg->flags & GRN_TABLE_SORT_BY_VALUE)) {\
+ 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))));\
+ es = ((hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE)\
+ ? ((entry_str *)(e))->size : hash->key_size); \
+ }\
+ ep += arg->offset;\
+ es -= arg->offset;\
+} while (0)
+
+#define COMPARE_VAL_(ap,as,bp,bs)\
+ (arg->compar\
+ ? arg->compar(ctx,\
+ (grn_obj *)hash, (void *)(ap), as,\
+ (grn_obj *)hash, (void *)(bp), bs, arg->compar_arg)\
+ : ((arg->flags & GRN_TABLE_SORT_AS_NUMBER)\
+ ? ((arg->flags & GRN_TABLE_SORT_AS_UNSIGNED)\
+ ? ((arg->flags & GRN_TABLE_SORT_AS_INT64)\
+ ? *((uint64_t *)(ap)) > *((uint64_t *)(bp))\
+ : *((uint32_t *)(ap)) > *((uint32_t *)(bp)))\
+ : ((arg->flags & GRN_TABLE_SORT_AS_INT64)\
+ ? *((int64_t *)(ap)) > *((int64_t *)(bp))\
+ : *((int32_t *)(ap)) > *((int32_t *)(bp))))\
+ : grn_str_greater(ap, as, bp, bs)))
+
+#define COMPARE_VAL(ap,as,bp,bs)\
+ ((dir) ? COMPARE_VAL_((bp),(bs),(ap),(as)) : COMPARE_VAL_((ap),(as),(bp),(bs)))
+
+inline static entry **
+pack(grn_ctx *ctx, grn_hash *hash, entry **res, grn_table_sort_optarg *arg, int dir)
+{
+ uint32_t n;
+ uint32_t cs, es;
+ const uint8_t *cp, *ep;
+ entry **head, **tail, *e, *c;
+ grn_id id, m = HASH_CURR_MAX(hash);
+ for (id = m >> 1;;id = (id == m) ? 1 : id + 1) {
+ if (grn_hash_bitmap_at(ctx, hash, id)) { break; }
+ }
+ c = grn_hash_entry_at(ctx, hash, id, 0);
+ if (!c) { return NULL; }
+ PREPARE_VAL(c, cp, cs);
+ head = res;
+ n = *hash->n_entries - 1;
+ tail = res + n;
+ while (n--) {
+ do {
+ id = (id == m) ? 1 : id + 1;
+ } while (!grn_hash_bitmap_at(ctx, hash, id));
+ e = grn_hash_entry_at(ctx, hash, id, 0);
+ if (!e) { return NULL; }
+ PREPARE_VAL(e, ep, es);
+ if (COMPARE_VAL(cp, cs, ep, es)) {
+ *head++ = e;
+ } else {
+ *tail-- = e;
+ }
+ }
+ *head = c;
+ return *hash->n_entries > 2 ? head : NULL;
+}
+
+inline static void
+swap(entry **a, entry **b)
+{
+ entry *c_ = *a;
+ *a = *b;
+ *b = c_;
+}
+
+#define SWAP(a,ap,as,b,bp,bs) do {\
+ const uint8_t *cp_ = ap;\
+ uint32_t cs_ = as;\
+ ap = bp; bp = cp_;\
+ as = bs; bs = cs_;\
+ swap(a,b);\
+} while (0)
+
+inline static entry **
+part(grn_ctx *ctx, entry **b, entry **e, grn_table_sort_optarg *arg, grn_hash *hash, int dir)
+{
+ entry **c;
+ const uint8_t *bp, *cp, *ep;
+ uint32_t bs, cs, es;
+ intptr_t d = e - b;
+ PREPARE_VAL(*b, bp, bs);
+ PREPARE_VAL(*e, ep, es);
+ if (COMPARE_VAL(bp, bs, ep, es)) {
+ SWAP(b, bp, bs, e, ep, es);
+ }
+ if (d < 2) { return NULL; }
+ c = b + (d >> 1);
+ PREPARE_VAL(*c, cp, cs);
+ if (COMPARE_VAL(bp, bs, cp, cs)) {
+ SWAP(b, bp, bs, c, cp, cs);
+ } else {
+ if (COMPARE_VAL(cp, cs, ep, es)) {
+ SWAP(c, cp, cs, e, ep, es);
+ }
+ }
+ if (d < 3) { return NULL; }
+ b++;
+ swap(b, c);
+ c = b;
+ PREPARE_VAL(*c, cp, cs);
+ for (;;) {
+ do {
+ b++;
+ PREPARE_VAL(*b, bp, bs);
+ } while (COMPARE_VAL(cp, cs, bp, bs));
+ do {
+ e--;
+ PREPARE_VAL(*e, ep, es);
+ } while (COMPARE_VAL(ep, es, cp, cs));
+ if (b >= e) { break; }
+ SWAP(b, bp, bs, e, ep, es);
+ }
+ SWAP(c, cp, cs, e, ep, es);
+ return e;
+}
+
+static void
+_sort(grn_ctx *ctx, entry **head, entry **tail, int limit,
+ grn_table_sort_optarg *arg, grn_hash *hash, int dir)
+{
+ entry **c;
+ if (head < tail && (c = part(ctx, head, tail, arg, hash, dir))) {
+ intptr_t rest = limit - 1 - (c - head);
+ _sort(ctx, head, c - 1, limit, arg, hash, dir);
+ if (rest > 0) { _sort(ctx, c + 1, tail, (int)rest, arg, hash, dir); }
+ }
+}
+
+static void
+sort(grn_ctx *ctx,
+ grn_hash *hash, entry **res, int limit, grn_table_sort_optarg *arg, int dir)
+{
+ entry **c = pack(ctx, hash, res, arg, dir);
+ if (c) {
+ intptr_t rest = limit - 1 - (c - res);
+ _sort(ctx, res, c - 1, limit, arg, hash, dir);
+ if (rest > 0 ) {
+ _sort(ctx, c + 1, res + *hash->n_entries - 1, (int)rest, arg, hash, dir);
+ }
+ }
+}
+
+typedef struct {
+ grn_id id;
+ int32_t v;
+} val32;
+
+#define PREPARE_VAL32(id,e,ep) do {\
+ (ep)->id = id;\
+ (ep)->v = (arg->flags & GRN_TABLE_SORT_BY_ID)\
+ ? (int32_t) id\
+ : (*((int32_t *)((byte *)((arg->flags & GRN_TABLE_SORT_BY_VALUE)\
+ ? get_value(ctx, hash, (e))\
+ : get_key(ctx, hash, (e))) + arg->offset)));\
+} while (0)
+
+#define COMPARE_VAL32_(ap,bp) \
+ (arg->compar\
+ ? arg->compar(ctx,\
+ (grn_obj *)hash, (void *)&(ap)->v, sizeof(uint32_t),\
+ (grn_obj *)hash, (void *)&(bp)->v, sizeof(uint32_t),\
+ arg->compar_arg)\
+ : ((arg->flags & GRN_TABLE_SORT_AS_NUMBER)\
+ ? ((arg->flags & GRN_TABLE_SORT_AS_UNSIGNED)\
+ ? *((uint32_t *)&(ap)->v) > *((uint32_t *)&(bp)->v)\
+ : *((int32_t *)&(ap)->v) > *((int32_t *)&(bp)->v))\
+ : memcmp(&(ap)->v, &(bp)->v, sizeof(uint32_t)) > 0))
+
+#define COMPARE_VAL32(ap,bp)\
+ ((dir) ? COMPARE_VAL32_((bp),(ap)) : COMPARE_VAL32_((ap),(bp)))
+
+inline static val32 *
+pack_val32(grn_ctx *ctx, grn_hash *hash, val32 *res, grn_table_sort_optarg *arg, int dir)
+{
+ uint32_t n;
+ entry_str *e, *c;
+ val32 *head, *tail, cr, er;
+ grn_id id, m = HASH_CURR_MAX(hash);
+ for (id = m >> 1;;id = (id == m) ? 1 : id + 1) {
+ if (grn_hash_bitmap_at(ctx, hash, id)) { break; }
+ }
+ c = grn_hash_entry_at(ctx, hash, id, 0);
+ if (!c) { return NULL; }
+ PREPARE_VAL32(id, c, &cr);
+ head = res;
+ n = *hash->n_entries - 1;
+ tail = res + n;
+ while (n--) {
+ do {
+ id = (id == m) ? 1 : id + 1;
+ } while (!grn_hash_bitmap_at(ctx, hash, id));
+ e = grn_hash_entry_at(ctx, hash, id, 0);
+ if (!e) { return NULL; }
+ PREPARE_VAL32(id, e, &er);
+ if (COMPARE_VAL32(&cr, &er)) {
+ *head++ = er;
+ } else {
+ *tail-- = er;
+ }
+ }
+ *head = cr;
+ return *hash->n_entries > 2 ? head : NULL;
+}
+
+#define SWAP_VAL32(ap,bp) do {\
+ val32 cr_ = *ap;\
+ *ap = *bp;\
+ *bp = cr_;\
+} while (0)
+
+inline static val32 *
+part_val32(grn_ctx *ctx,
+ val32 *b, val32 *e, grn_table_sort_optarg *arg, grn_hash *hash, int dir)
+{
+ val32 *c;
+ intptr_t d = e - b;
+ if (COMPARE_VAL32(b, e)) { SWAP_VAL32(b, e); }
+ if (d < 2) { return NULL; }
+ c = b + (d >> 1);
+ if (COMPARE_VAL32(b, c)) {
+ SWAP_VAL32(b, c);
+ } else {
+ if (COMPARE_VAL32(c, e)) { SWAP_VAL32(c, e); }
+ }
+ if (d < 3) { return NULL; }
+ b++;
+ SWAP_VAL32(b, c);
+ c = b;
+ for (;;) {
+ do { b++; } while (COMPARE_VAL32(c, b));
+ do { e--; } while (COMPARE_VAL32(e, c));
+ if (b >= e) { break; }
+ SWAP_VAL32(b, e);
+ }
+ SWAP_VAL32(c, e);
+ return e;
+}
+
+static void
+_sort_val32(grn_ctx *ctx, val32 *head, val32 *tail, int limit,
+ grn_table_sort_optarg *arg, grn_hash *hash, int dir)
+{
+ val32 *c;
+ if (head < tail && (c = part_val32(ctx, head, tail, arg, hash, dir))) {
+ intptr_t rest = limit - 1 - (c - head);
+ _sort_val32(ctx, head, c - 1, limit, arg, hash, dir);
+ if (rest > 0) { _sort_val32(ctx, c + 1, tail, (int)rest, arg, hash, dir); }
+ }
+}
+
+static void
+sort_val32(grn_ctx *ctx,
+ grn_hash *hash, val32 *res, int limit, grn_table_sort_optarg *arg, int dir)
+{
+ val32 *c = pack_val32(ctx, hash, res, arg, dir);
+ if (c) {
+ intptr_t rest = limit - 1 - (c - res);
+ _sort_val32(ctx, res, c - 1, limit, arg, hash, dir);
+ if (rest > 0 ) {
+ _sort_val32(ctx, c + 1, res + *hash->n_entries - 1, (int)rest, arg, hash, dir);
+ }
+ }
+}
+
+inline static grn_id
+entry2id(grn_ctx *ctx, grn_hash *hash, entry *e)
+{
+ entry *e2;
+ grn_id id, *ep;
+ uint32_t i, h = e->key, s = grn_hash_calculate_step(h);
+ for (i = h; ; i += s) {
+ if (!(ep = grn_hash_idx_at(ctx, hash, i))) { return GRN_ID_NIL; }
+ if (!(id = *ep)) { break; }
+ if (id != GARBAGE) {
+ e2 = grn_hash_entry_at(ctx, hash, id, 0);
+ if (!e2) { return GRN_ID_NIL; }
+ if (e2 == e) { break; }
+ }
+ }
+ return id;
+}
+
+int
+grn_hash_sort(grn_ctx *ctx, grn_hash *hash,
+ int limit, grn_array *result, grn_table_sort_optarg *optarg)
+{
+ 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;
+ }
+ if (limit < 0) {
+ limit += *hash->n_entries + 1;
+ if (limit < 0) {
+ GRN_LOG(ctx, GRN_LOG_ALERT, "limit is too small in grn_hash_sort !");
+ return 0;
+ }
+ }
+ if (limit > *hash->n_entries) { limit = *hash->n_entries; }
+ /* hash->limit = limit; */
+ if (optarg) {
+ int dir = (optarg->flags & GRN_TABLE_SORT_DESC);
+ if ((optarg->flags & GRN_TABLE_SORT_BY_ID) ||
+ (optarg->flags & GRN_TABLE_SORT_BY_VALUE)
+ ? ((hash->value_size - optarg->offset) == sizeof(uint32_t))
+ : (!(hash->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE)
+ && hash->key_size == sizeof(uint32_t))) {
+ if (sizeof(entry *) != sizeof(val32)) {
+ GRN_FREE(res);
+ if (!(res = GRN_MALLOC(sizeof(val32) * *hash->n_entries))) {
+ GRN_LOG(ctx, GRN_LOG_ALERT, "allocation of entries failed on grn_hash_sort !");
+ return 0;
+ }
+ }
+ sort_val32(ctx, hash, (val32 *)res, limit, optarg, dir);
+ {
+ int i;
+ grn_id *v;
+ val32 *rp = (val32 *)res;
+ for (i = 0; i < limit; i++, rp++) {
+ if (!grn_array_add(ctx, result, (void **)&v)) { break; }
+ if (!(*v = rp->id)) { break; }
+ }
+ GRN_FREE(res);
+ return i;
+ }
+ } else {
+ sort(ctx, hash, res, limit, optarg, dir);
+ }
+ } else {
+ grn_table_sort_optarg opt = {0, NULL, NULL, NULL, 0};
+ sort(ctx, hash, res, limit, &opt, 0);
+ }
+ {
+ int i;
+ grn_id *v;
+ entry **rp = res;
+ for (i = 0; i < limit; i++, rp++) {
+ if (!grn_array_add(ctx, result, (void **)&v)) { break; }
+ if (!(*v = entry2id(ctx, hash, *rp))) { break; }
+ }
+ GRN_FREE(res);
+ return i;
+ }
+}
+
+void
+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", 26);
+ GRN_OUTPUT_CSTR("flags");
+ grn_itoh(h->flags, buf, 8);
+ GRN_OUTPUT_STR(buf, 8);
+ GRN_OUTPUT_CSTR("key_size");
+ GRN_OUTPUT_INT64(hash->key_size);
+ GRN_OUTPUT_CSTR("value_size");
+ GRN_OUTPUT_INT64(hash->value_size);
+ GRN_OUTPUT_CSTR("tokenizer");
+ GRN_OUTPUT_INT64(h->tokenizer);
+ GRN_OUTPUT_CSTR("normalizer");
+ GRN_OUTPUT_INT64(h->normalizer);
+ GRN_OUTPUT_CSTR("curr_rec");
+ GRN_OUTPUT_INT64(h->curr_rec);
+ 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");
+ GRN_OUTPUT_INT64(hash->entry_size);
+ GRN_OUTPUT_CSTR("max_offset");
+ GRN_OUTPUT_INT64(*hash->max_offset);
+ GRN_OUTPUT_CSTR("n_entries");
+ GRN_OUTPUT_INT64(*hash->n_entries);
+ GRN_OUTPUT_CSTR("n_garbages");
+ GRN_OUTPUT_INT64(*hash->n_garbages);
+ GRN_OUTPUT_CSTR("lock");
+ GRN_OUTPUT_INT64(h->lock);
+ GRN_OUTPUT_MAP_CLOSE();
+ GRN_OUTPUT_ARRAY_CLOSE();
+}
+
+/* rhash : grn_hash with subrecs */
+
+#ifdef USE_GRN_INDEX2
+
+static uint32_t default_flags = GRN_HASH_TINY;
+
+grn_rc
+grn_rhash_init(grn_ctx *ctx, grn_hash *hash, grn_rec_unit record_unit, int record_size,
+ grn_rec_unit subrec_unit, int subrec_size, unsigned int max_n_subrecs)
+{
+ grn_rc rc;
+ record_size = grn_rec_unit_size(record_unit, record_size);
+ subrec_size = grn_rec_unit_size(subrec_unit, subrec_size);
+ if (record_unit != grn_rec_userdef && subrec_unit != grn_rec_userdef) {
+ subrec_size -= record_size;
+ }
+ if (!hash) { return GRN_INVALID_ARGUMENT; }
+ if (record_size < 0) { return GRN_INVALID_ARGUMENT; }
+ if ((default_flags & GRN_HASH_TINY)) {
+ rc = grn_tiny_hash_init(ctx, hash, NULL, record_size,
+ max_n_subrecs * (GRN_RSET_SCORE_SIZE + subrec_size),
+ default_flags, GRN_ENC_NONE);
+ } else {
+ rc = grn_io_hash_init(ctx, hash, NULL, record_size,
+ max_n_subrecs * (GRN_RSET_SCORE_SIZE + subrec_size),
+ default_flags, GRN_ENC_NONE, 0);
+ }
+ if (rc) { return rc; }
+ hash->record_unit = record_unit;
+ hash->subrec_unit = subrec_unit;
+ hash->subrec_size = subrec_size;
+ hash->max_n_subrecs = max_n_subrecs;
+ return rc;
+}
+
+grn_rc
+grn_rhash_fin(grn_ctx *ctx, grn_hash *hash)
+{
+ grn_rc rc;
+ if (grn_hash_is_io_hash(hash)) {
+ rc = grn_io_close(ctx, hash->io);
+ } else {
+ GRN_ASSERT(ctx == hash->ctx);
+ rc = grn_tiny_hash_fin(ctx, hash);
+ }
+ return rc;
+}
+
+inline static void
+subrecs_push(byte *subrecs, int size, int n_subrecs, int score, void *body, int dir)
+{
+ byte *v;
+ int *c2;
+ int n = n_subrecs - 1, n2;
+ while (n) {
+ n2 = (n - 1) >> 1;
+ c2 = GRN_RSET_SUBRECS_NTH(subrecs,size,n2);
+ if (GRN_RSET_SUBRECS_CMP(score, *c2, dir) > 0) { break; }
+ GRN_RSET_SUBRECS_COPY(subrecs,size,n,c2);
+ n = n2;
+ }
+ v = subrecs + n * (size + GRN_RSET_SCORE_SIZE);
+ *((int *)v) = score;
+ grn_memcpy(v + GRN_RSET_SCORE_SIZE, body, size);
+}
+
+inline static void
+subrecs_replace_min(byte *subrecs, int size, int n_subrecs, int score, void *body, int dir)
+{
+ byte *v;
+ int n = 0, n1, n2, *c1, *c2;
+ for (;;) {
+ n1 = n * 2 + 1;
+ n2 = n1 + 1;
+ c1 = n1 < n_subrecs ? GRN_RSET_SUBRECS_NTH(subrecs,size,n1) : NULL;
+ c2 = n2 < n_subrecs ? GRN_RSET_SUBRECS_NTH(subrecs,size,n2) : NULL;
+ if (c1 && GRN_RSET_SUBRECS_CMP(score, *c1, dir) > 0) {
+ if (c2 &&
+ GRN_RSET_SUBRECS_CMP(score, *c2, dir) > 0 &&
+ GRN_RSET_SUBRECS_CMP(*c1, *c2, dir) > 0) {
+ GRN_RSET_SUBRECS_COPY(subrecs,size,n,c2);
+ n = n2;
+ } else {
+ GRN_RSET_SUBRECS_COPY(subrecs,size,n,c1);
+ n = n1;
+ }
+ } else {
+ if (c2 && GRN_RSET_SUBRECS_CMP(score, *c2, dir) > 0) {
+ GRN_RSET_SUBRECS_COPY(subrecs,size,n,c2);
+ n = n2;
+ } else {
+ break;
+ }
+ }
+ }
+ v = subrecs + n * (size + GRN_RSET_SCORE_SIZE);
+ grn_memcpy(v, &score, GRN_RSET_SCORE_SIZE);
+ grn_memcpy(v + GRN_RSET_SCORE_SIZE, body, size);
+}
+
+void
+grn_rhash_add_subrec(grn_hash *s, grn_rset_recinfo *ri, int score, void *body, int dir)
+{
+ int limit = s->max_n_subrecs;
+ ri->score += score;
+ ri->n_subrecs += 1;
+ if (limit) {
+ int ssize = s->subrec_size;
+ int n_subrecs = GRN_RSET_N_SUBRECS(ri);
+ if (limit < n_subrecs) {
+ if (GRN_RSET_SUBRECS_CMP(score, *ri->subrecs, dir) > 0) {
+ subrecs_replace_min(ri->subrecs, ssize, limit, score, body, dir);
+ }
+ } else {
+ subrecs_push(ri->subrecs, ssize, n_subrecs, score, body, dir);
+ }
+ }
+}
+
+grn_hash *
+grn_rhash_group(grn_hash *s, int limit, grn_group_optarg *optarg)
+{
+ grn_ctx *ctx = s->ctx;
+ grn_hash *g, h;
+ grn_rset_recinfo *ri;
+ grn_rec_unit unit;
+ grn_hash_cursor *c;
+ grn_id rh;
+ byte *key, *ekey, *gkey = NULL;
+ int funcp, dir;
+ unsigned int rsize;
+ if (!s || !s->index) { return NULL; }
+ if (optarg) {
+ unit = grn_rec_userdef;
+ rsize = optarg->key_size;
+ funcp = optarg->func ? 1 : 0;
+ dir = (optarg->mode == grn_sort_ascending) ? -1 : 1;
+ } else {
+ unit = grn_rec_document;
+ rsize = grn_rec_unit_size(unit, sizeof(grn_id));
+ funcp = 0;
+ dir = 1;
+ }
+ if (funcp) {
+ gkey = GRN_MALLOC(rsize ? rsize : 8192);
+ if (!gkey) {
+ GRN_LOG(ctx, GRN_LOG_ALERT, "allocation for gkey failed !");
+ return NULL;
+ }
+ } else {
+ if (s->key_size <= rsize) { return NULL; }
+ }
+ if (!(c = grn_hash_cursor_open(s->ctx, s, NULL, 0, NULL, -1, 0))) {
+ GRN_LOG(ctx, GRN_LOG_ALERT, "grn_hash_cursor_open on grn_hash_group failed !");
+ if (gkey) { GRN_FREE(gkey); }
+ return NULL;
+ }
+ grn_memcpy(&h, s, sizeof(grn_hash));
+ g = s;
+ s = &h;
+ if (grn_rhash_init(ctx, g, unit, rsize, s->record_unit, s->key_size, limit)) {
+ GRN_LOG(ctx, GRN_LOG_ALERT, "grn_rhash_init in grn_hash_group failed !");
+ grn_hash_cursor_close(s->ctx, c);
+ if (gkey) { GRN_FREE(gkey); }
+ return NULL;
+ }
+ while ((rh = grn_hash_cursor_next(ctx, c))) {
+ grn_hash_cursor_get_key_value(ctx, c, (void **)&key, NULL, (void **)&ri);
+ if (funcp) {
+ if (optarg->func((grn_records *)s,
+ (grn_recordh *)(intptr_t)rh, gkey, optarg->func_arg)) { continue; }
+ ekey = key;
+ } else {
+ gkey = key;
+ ekey = key + rsize;
+ }
+ {
+ grn_rset_recinfo *gri;
+ if (grn_hash_add(ctx, g, gkey, rsize, (void **)&gri, NULL)) {
+ grn_rhash_add_subrec(g, gri, ri->score, ekey, dir);
+ }
+ }
+ }
+ grn_hash_cursor_close(s->ctx, c);
+ grn_rhash_fin(s->ctx, s);
+ if (funcp) { GRN_FREE(gkey); }
+ return g;
+}
+
+grn_rc
+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;
+ grn_rset_recinfo *ri;
+ int *p, unit_size = GRN_RSET_SCORE_SIZE + s->subrec_size;
+ if (!s || !rh || index < 0) { return GRN_INVALID_ARGUMENT; }
+ if ((unsigned int)index >= s->max_n_subrecs) { return GRN_INVALID_ARGUMENT; }
+ {
+ entry_str *ee;
+ if (!grn_hash_bitmap_at(ctx, s, rh)) { return GRN_INVALID_ARGUMENT; }
+ 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(ctx, s, ee);
+ if (!pi || !ri) { return GRN_INVALID_ARGUMENT; }
+ }
+ if (index >= ri->n_subrecs) { return GRN_INVALID_ARGUMENT; }
+ p = (int *)(ri->subrecs + index * unit_size);
+ if (score) { *score = p[0]; }
+ if (subrec) { *subrec = &p[1]; }
+ switch (s->record_unit) {
+ case grn_rec_document :
+ if (rid) { *rid = pi->rid; }
+ if (section) { *section = (s->subrec_unit != grn_rec_userdef) ? p[1] : 0; }
+ if (pos) { *pos = (s->subrec_unit == grn_rec_position) ? p[2] : 0; }
+ break;
+ case grn_rec_section :
+ if (rid) { *rid = pi->rid; }
+ if (section) { *section = pi->sid; }
+ if (pos) { *pos = (s->subrec_unit == grn_rec_position) ? p[1] : 0; }
+ break;
+ default :
+ pi = (grn_rset_posinfo *)&p[1];
+ switch (s->subrec_unit) {
+ case grn_rec_document :
+ if (rid) { *rid = pi->rid; }
+ if (section) { *section = 0; }
+ if (pos) { *pos = 0; }
+ break;
+ case grn_rec_section :
+ if (rid) { *rid = pi->rid; }
+ if (section) { *section = pi->sid; }
+ if (pos) { *pos = 0; }
+ break;
+ case grn_rec_position :
+ if (rid) { *rid = pi->rid; }
+ if (section) { *section = pi->sid; }
+ if (pos) { *pos = pi->pos; }
+ break;
+ default :
+ if (rid) { *rid = 0; }
+ if (section) { *section = 0; }
+ if (pos) { *pos = 0; }
+ break;
+ }
+ break;
+ }
+ 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
new file mode 100644
index 00000000..91751f94
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/icudump.c
@@ -0,0 +1,298 @@
+/* -*- c-basic-offset: 2 -*- */
+/* Copyright(C) 2010 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-1335 USA
+*/
+#include <stdio.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <string.h>
+#include <unicode/utf.h>
+#include <unicode/uchar.h>
+#include <unicode/unorm.h>
+#include <unicode/ustring.h>
+
+#define MAX_UNICODE 0x110000
+#define BUF_SIZE 0x100
+
+static int
+ucs2utf(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);
+}
+
+void
+blockcode(void)
+{
+ UChar32 ch;
+ unsigned char *p, src[7];
+ UBlockCode code, lc = -1;
+ for (ch = 1; ch < MAX_UNICODE; ch++) {
+ if (!U_IS_UNICODE_CHAR(ch)) { continue; }
+ code = ublock_getCode(ch);
+ if (code != lc) {
+ ucs2utf(ch, src);
+ for (p = src; *p; p++) {
+ printf("%x:", *p);
+ }
+ printf("\t%04x\t%d\n", ch, code);
+ }
+ lc = code;
+ }
+}
+
+int
+normalize(const char *str, char *res, UNormalizationMode mode)
+{
+ UErrorCode rc;
+ int32_t ulen, nlen;
+ UChar ubuf[BUF_SIZE], nbuf[BUF_SIZE];
+ rc = U_ZERO_ERROR;
+ u_strFromUTF8(ubuf, BUF_SIZE, &ulen, str, -1, &rc);
+ if (rc != U_ZERO_ERROR /*&& rc != U_STRING_NOT_TERMINATED_WARNING*/) {
+ return -1;
+ }
+ rc = U_ZERO_ERROR;
+ nlen = unorm_normalize(ubuf, ulen, mode, 0, nbuf, BUF_SIZE, &rc);
+ if (rc != U_ZERO_ERROR /*&& rc != U_STRING_NOT_TERMINATED_WARNING*/) {
+ return -1;
+ }
+ rc = U_ZERO_ERROR;
+ u_strToUTF8(res, BUF_SIZE, NULL, nbuf, nlen, &rc);
+ if (rc != U_ZERO_ERROR /*&& rc != U_BUFFER_OVERFLOW_ERROR*/) {
+ return -1;
+ }
+ return 0;
+}
+
+void
+dump(UNormalizationMode mode)
+{
+ UChar32 ch;
+ char str[7], norm[BUF_SIZE];
+ for (ch = 1; ch < MAX_UNICODE; ch++) {
+ if (!U_IS_UNICODE_CHAR(ch)) { continue; }
+ ucs2utf(ch, (unsigned char *)str);
+ if (normalize(str, norm, mode)) {
+ printf("ch=%04x error occure\n", ch);
+ continue;
+ }
+ if (strcmp(norm, str)) {
+ printf("%04x\t%s\t%s\n", ch, str, norm);
+ }
+ }
+}
+
+void
+ccdump(void)
+{
+ UChar32 ch;
+ char str[7], nfd[BUF_SIZE], nfc[BUF_SIZE];
+ for (ch = 1; ch < MAX_UNICODE; ch++) {
+ if (!U_IS_UNICODE_CHAR(ch)) { continue; }
+ ucs2utf(ch, (unsigned char *)str);
+ if (normalize(str, nfd, UNORM_NFD)) {
+ printf("ch=%04x error occure\n", ch);
+ continue;
+ }
+ if (normalize(str, nfc, UNORM_NFC)) {
+ printf("ch=%04x error occure\n", ch);
+ continue;
+ }
+ if (strcmp(nfd, nfc)) {
+ printf("%04x\t%s\t%s\n", ch, nfd, nfc);
+ }
+ }
+}
+
+enum {
+ ctype_null = 0,
+ ctype_alpha,
+ ctype_digit,
+ ctype_symbol,
+ ctype_hiragana,
+ ctype_katakana,
+ ctype_kanji,
+ ctype_others
+};
+
+static const char *ctypes[] = {
+ "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
+gcdump(void)
+{
+ UChar32 ch;
+ unsigned char *p, src[7];
+ int ctype, lc = -1;
+ for (ch = 1; ch < MAX_UNICODE; ch++) {
+ UCharCategory cat;
+ UBlockCode code;
+ if (!U_IS_UNICODE_CHAR(ch)) { continue; }
+ code = ublock_getCode(ch);
+ switch (code) {
+ case UBLOCK_CJK_RADICALS_SUPPLEMENT: /* cjk radicals */
+ case UBLOCK_KANGXI_RADICALS: /* kanji radicals */
+ case UBLOCK_BOPOMOFO: /* bopomofo letter */
+ case UBLOCK_HANGUL_COMPATIBILITY_JAMO: /* hangul letter */
+ case UBLOCK_KANBUN: /* kaeri ten used in kanbun ex. re-ten */
+ case UBLOCK_BOPOMOFO_EXTENDED: /* bopomofo extended letter */
+ case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A: /* cjk letter */
+ case UBLOCK_CJK_UNIFIED_IDEOGRAPHS: /* cjk letter */
+ case UBLOCK_YI_SYLLABLES: /* Yi syllables */
+ case UBLOCK_YI_RADICALS: /* Yi radicals */
+ case UBLOCK_HANGUL_SYLLABLES: /* hangul syllables */
+ case UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS: /* cjk letter */
+ case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B: /* cjk letter */
+ case UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT: /* cjk letter */
+ case UBLOCK_CJK_STROKES: /* kakijun*/
+ ctype = ctype_kanji;
+ break;
+ case UBLOCK_CJK_SYMBOLS_AND_PUNCTUATION: /* symbols ex. JIS mark */
+ case UBLOCK_ENCLOSED_CJK_LETTERS_AND_MONTHS: /* ex. (kabu) */
+ case UBLOCK_CJK_COMPATIBILITY: /* symbols ex. ton doll */
+ case UBLOCK_CJK_COMPATIBILITY_FORMS: /* symbols ex. tategaki kagi-kakko */
+ ctype = ctype_symbol;
+ break;
+ case UBLOCK_HIRAGANA:
+ ctype = ctype_hiragana;
+ break;
+ case UBLOCK_KATAKANA:
+ case UBLOCK_KATAKANA_PHONETIC_EXTENSIONS:
+ ctype = ctype_katakana;
+ break;
+ default:
+ cat = u_charType(ch);
+ switch (cat) {
+ case U_UPPERCASE_LETTER:
+ case U_LOWERCASE_LETTER:
+ case U_TITLECASE_LETTER:
+ case U_MODIFIER_LETTER:
+ case U_OTHER_LETTER:
+ ctype = ctype_alpha;
+ break;
+ case U_DECIMAL_DIGIT_NUMBER:
+ case U_LETTER_NUMBER:
+ case U_OTHER_NUMBER:
+ ctype = ctype_digit;
+ break;
+ case U_DASH_PUNCTUATION:
+ case U_START_PUNCTUATION:
+ case U_END_PUNCTUATION:
+ case U_CONNECTOR_PUNCTUATION:
+ case U_OTHER_PUNCTUATION:
+ case U_MATH_SYMBOL:
+ case U_CURRENCY_SYMBOL:
+ case U_MODIFIER_SYMBOL:
+ case U_OTHER_SYMBOL:
+ ctype = ctype_symbol;
+ break;
+ default:
+ ctype = ctype_others;
+ break;
+ }
+ break;
+ }
+ if (ctype != lc) {
+ ucs2utf(ch, src);
+ for (p = src; *p; p++) {
+ printf("%x:", *p);
+ }
+ printf("\t%04x\t%s\n", ch, ctypes[ctype]);
+ }
+ lc = ctype;
+ }
+}
+
+struct option options[] = {
+ {"bc", 0, NULL, 'b'},
+ {"nfd", 0, NULL, 'd'},
+ {"nfkd", 0, NULL, 'D'},
+ {"nfc", 0, NULL, 'c'},
+ {"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, "bdDcCogv", options, NULL)) {
+ case 'b' :
+ blockcode();
+ break;
+ case 'd' :
+ dump(UNORM_NFD);
+ break;
+ case 'D' :
+ dump(UNORM_NFKD);
+ break;
+ case 'c' :
+ dump(UNORM_NFC);
+ break;
+ case 'C' :
+ dump(UNORM_NFKC);
+ break;
+ case 'o' :
+ ccdump();
+ break;
+ case 'g' :
+ gcdump();
+ break;
+ case 'v' :
+ printf("%s\n", U_UNICODE_VERSION);
+ break;
+ default :
+ 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 00000000..96eae9f9
--- /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-1335 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
new file mode 100644
index 00000000..2abd0747
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ii.c
@@ -0,0 +1,12816 @@
+/* -*- 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-1335 USA
+*/
+#include "grn.h"
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#ifdef WIN32
+# include <io.h>
+# include <share.h>
+#endif /* WIN32 */
+
+#include "grn_ii.h"
+#include "grn_ctx_impl.h"
+#include "grn_token_cursor.h"
+#include "grn_pat.h"
+#include "grn_db.h"
+#include "grn_output.h"
+#include "grn_scorer.h"
+#include "grn_util.h"
+
+#ifdef GRN_WITH_ONIGMO
+# define GRN_II_SELECT_ENABLE_SEQUENTIAL_SEARCH
+#endif
+
+#ifdef GRN_II_SELECT_ENABLE_SEQUENTIAL_SEARCH
+# include "grn_string.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)
+#define W_ARRAY_ELEMENT 3
+#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 S_GARBAGE (1<<12)
+
+#define CHUNK_SPLIT 0x80000000
+#define CHUNK_SPLIT_THRESHOLD 0x60000
+
+#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))
+
+#ifndef S_IRUSR
+# define S_IRUSR 0400
+#endif /* S_IRUSR */
+#ifndef S_IWUSR
+# define S_IWUSR 0200
+#endif /* S_IWUSR */
+
+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)
+{
+ {
+ char grn_ii_cursor_set_min_enable_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_II_CURSOR_SET_MIN_ENABLE",
+ grn_ii_cursor_set_min_enable_env,
+ GRN_ENV_BUFFER_SIZE);
+ 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;
+ }
+ }
+
+ {
+ char grn_ii_select_too_many_index_match_ratio_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_II_SELECT_TOO_MANY_INDEX_MATCH_RATIO",
+ grn_ii_select_too_many_index_match_ratio_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_ii_select_too_many_index_match_ratio_env[0]) {
+ grn_ii_select_too_many_index_match_ratio =
+ 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 */
+
+inline static uint32_t
+segment_get(grn_ctx *ctx, grn_ii *ii)
+{
+ uint32_t pseg;
+ if (ii->header->bgqtail == ((ii->header->bgqhead + 1) & (GRN_II_BGQSIZE - 1))) {
+ pseg = ii->header->bgqbody[ii->header->bgqtail];
+ ii->header->bgqtail = (ii->header->bgqtail + 1) & (GRN_II_BGQSIZE - 1);
+ } else {
+ pseg = ii->header->pnext;
+#ifndef CUT_OFF_COMPATIBILITY
+ if (!pseg) {
+ int i;
+ uint32_t pmax = 0;
+ 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]) != GRN_II_PSEG_NOT_ASSIGNED) {
+ if (pseg > pmax) { pmax = pseg; }
+ used[pseg] = 1;
+ }
+ }
+ 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 < ii->seg->header->max_segment) {
+ ii->header->pnext++;
+ }
+ }
+ return pseg;
+}
+
+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 < ii->seg->header->max_segment) {
+ void *p = NULL;
+ GRN_IO_SEG_REF(ii->seg, seg, p);
+ if (!p) { return GRN_NO_MEMORY_AVAILABLE; }
+ memset(p, 0, S_SEGMENT);
+ GRN_IO_SEG_UNREF(ii->seg, seg);
+ *pseg = seg;
+ return GRN_SUCCESS;
+ } else {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+}
+
+inline static grn_rc
+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] != 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] == 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 < ii->seg->header->max_segment) {
+ ii->header->binfo[lseg] = pseg;
+ if (lseg >= ii->header->bmax) { ii->header->bmax = lseg + 1; }
+ return GRN_SUCCESS;
+ } else {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+}
+
+static grn_rc
+buffer_segment_reserve(grn_ctx *ctx, grn_ii *ii,
+ uint32_t *lseg0, uint32_t *pseg0,
+ uint32_t *lseg1, uint32_t *pseg1)
+{
+ uint32_t i = 0;
+ for (;; i++) {
+ 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) {
+ 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)) == 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(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]) != 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 == ii->seg->header->max_segment) {
+ GRN_FREE(used);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ if (!used[pseg]) { break; }
+ }
+ *pseg0 = pseg++;
+ for (;; pseg++) {
+ 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 ctx->rc;
+}
+
+#define BGQENQUE(lseg) do {\
+ 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);\
+ }\
+} while (0)
+
+inline static void
+buffer_segment_update(grn_ii *ii, uint32_t lseg, uint32_t pseg)
+{
+ BGQENQUE(lseg);
+ // smb_wmb();
+ ii->header->binfo[lseg] = pseg;
+ if (lseg >= ii->header->bmax) { ii->header->bmax = lseg + 1; }
+}
+
+inline static void
+buffer_segment_clear(grn_ii *ii, uint32_t lseg)
+{
+ BGQENQUE(lseg);
+ // smb_wmb();
+ ii->header->binfo[lseg] = GRN_II_PSEG_NOT_ASSIGNED;
+}
+
+/* chunk */
+
+#define HEADER_CHUNK_AT(ii,offset) \
+ ((((ii)->header->chunks[((offset) >> 3)]) >> ((offset) & 7)) & 1)
+
+#define HEADER_CHUNK_ON(ii,offset) \
+ (((ii)->header->chunks[((offset) >> 3)]) |= (1 << ((offset) & 7)))
+
+#define HEADER_CHUNK_OFF(ii,offset) \
+ (((ii)->header->chunks[((offset) >> 3)]) &= ~(1 << ((offset) & 7)))
+
+#define N_GARBAGES_TH 1
+
+#define N_GARBAGES ((S_GARBAGE - (sizeof(uint32_t) * 4))/(sizeof(uint32_t)))
+
+typedef struct {
+ uint32_t head;
+ uint32_t tail;
+ uint32_t nrecs;
+ uint32_t next;
+ uint32_t recs[N_GARBAGES];
+} grn_ii_ginfo;
+
+#define WIN_MAP(chunk,ctx,iw,seg,pos,size,mode)\
+ 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)
+/*
+static int new_histogram[32];
+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;
+ GRN_BIT_SCAN_REV(es, m);
+ m++;
+ new_histogram[m]++;
+ }
+ */
+ if (size > S_CHUNK) {
+ int i, j;
+ uint32_t n = (size + S_CHUNK - 1) >> GRN_II_W_CHUNK;
+ for (i = 0, j = -1; i < n_chunks; i++) {
+ if (HEADER_CHUNK_AT(ii, i)) {
+ j = i;
+ } else {
+ if (i == j + n) {
+ j++;
+ *res = j << GRN_II_N_CHUNK_VARIATION;
+ for (; j <= i; j++) { HEADER_CHUNK_ON(ii, j); }
+ return GRN_SUCCESS;
+ }
+ }
+ }
+ {
+ 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;
+ if (size > (1 << GRN_II_W_LEAST_CHUNK)) {
+ int es = size - 1;
+ GRN_BIT_SCAN_REV(es, m);
+ m++;
+ } else {
+ m = GRN_II_W_LEAST_CHUNK;
+ }
+ aligned_size = 1 << (m - GRN_II_W_LEAST_CHUNK);
+ if (ii->header->ngarbages[m - GRN_II_W_LEAST_CHUNK] > N_GARBAGES_TH) {
+ grn_ii_ginfo *ginfo;
+ uint32_t *gseg;
+ grn_io_win iw, iw_;
+ iw_.addr = NULL;
+ gseg = &ii->header->garbages[m - GRN_II_W_LEAST_CHUNK];
+ 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_); }
+ {
+ 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 != 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--;
+ ii->header->ngarbages[m - GRN_II_W_LEAST_CHUNK]--;
+ if (!ginfo->nrecs) {
+ HEADER_CHUNK_OFF(ii, *gseg);
+ *gseg = ginfo->next;
+ }
+ if (iw_.addr) { grn_io_win_unmap(&iw_); }
+ grn_io_win_unmap(&iw);
+ return GRN_SUCCESS;
+ }
+ if (iw_.addr) { grn_io_win_unmap(&iw_); }
+ iw_ = iw;
+ gseg = &ginfo->next;
+ }
+ if (iw_.addr) { grn_io_win_unmap(&iw_); }
+ }
+ vp = &ii->header->free_chunks[m - GRN_II_W_LEAST_CHUNK];
+ if (*vp == GRN_II_PSEG_NOT_ASSIGNED) {
+ int i = 0;
+ while (HEADER_CHUNK_AT(ii, i)) {
+ 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;
+ }
+ *res = *vp;
+ *vp += 1 << (m - GRN_II_W_LEAST_CHUNK);
+ if (!(*vp & ((1 << GRN_II_N_CHUNK_VARIATION) - 1))) {
+ *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)
+{
+ /*
+ if (size) {
+ int m, es = size - 1;
+ GRN_BIT_SCAN_REV(es, m);
+ m++;
+ free_histogram[m]++;
+ }
+ */
+ grn_io_win iw, iw_;
+ grn_ii_ginfo *ginfo= 0;
+ uint32_t seg, m, *gseg;
+ seg = offset >> GRN_II_N_CHUNK_VARIATION;
+ if (size > S_CHUNK) {
+ int n = (size + S_CHUNK - 1) >> GRN_II_W_CHUNK;
+ for (; n--; seg++) { HEADER_CHUNK_OFF(ii, seg); }
+ return GRN_SUCCESS;
+ }
+ if (size > (1 << GRN_II_W_LEAST_CHUNK)) {
+ int es = size - 1;
+ GRN_BIT_SCAN_REV(es, m);
+ m++;
+ } else {
+ m = GRN_II_W_LEAST_CHUNK;
+ }
+ gseg = &ii->header->garbages[m - GRN_II_W_LEAST_CHUNK];
+ iw_.addr = NULL;
+ 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;
+ }
+ if (ginfo->nrecs < N_GARBAGES) { break; }
+ if (iw_.addr) { grn_io_win_unmap(&iw_); }
+ iw_ = iw;
+ gseg = &ginfo->next;
+ }
+ 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_); }
+ return rc;
+ }
+ ginfo = WIN_MAP(ii->chunk, ctx, &iw, *gseg, 0, S_GARBAGE, grn_io_rdwr);
+ /*
+ uint32_t i = 0;
+ while (HEADER_CHUNK_AT(ii, i)) {
+ if (++i >= ii->chunk->header->max_segment) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ HEADER_CHUNK_ON(ii, i);
+ *gseg = i;
+ GRN_IO_SEG_MAP2(ii->chunk, *gseg, ginfo);
+ */
+ if (!ginfo) {
+ if (iw_.addr) { grn_io_win_unmap(&iw_); }
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ ginfo->head = 0;
+ ginfo->tail = 0;
+ ginfo->nrecs = 0;
+ ginfo->next = GRN_II_PSEG_NOT_ASSIGNED;
+ }
+ if (iw_.addr) { grn_io_win_unmap(&iw_); }
+ ginfo->recs[ginfo->head] = offset;
+ if (++ginfo->head == N_GARBAGES) { ginfo->head = 0; }
+ ginfo->nrecs++;
+ grn_io_win_unmap(&iw);
+ ii->header->ngarbages[m - GRN_II_W_LEAST_CHUNK]++;
+ return GRN_SUCCESS;
+}
+
+#define UNIT_SIZE 0x80
+#define UNIT_MASK (UNIT_SIZE - 1)
+
+/* <generated> */
+static uint8_t *
+pack_1(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ v = *p++ << 7;
+ v += *p++ << 6;
+ v += *p++ << 5;
+ v += *p++ << 4;
+ v += *p++ << 3;
+ v += *p++ << 2;
+ v += *p++ << 1;
+ *rp++ = v + *p++;
+ return rp;
+}
+static uint8_t *
+unpack_1(uint32_t *p, uint8_t *dp)
+{
+ *p++ = (*dp >> 7);
+ *p++ = ((*dp >> 6) & 0x1);
+ *p++ = ((*dp >> 5) & 0x1);
+ *p++ = ((*dp >> 4) & 0x1);
+ *p++ = ((*dp >> 3) & 0x1);
+ *p++ = ((*dp >> 2) & 0x1);
+ *p++ = ((*dp >> 1) & 0x1);
+ *p++ = (*dp++ & 0x1);
+ return dp;
+}
+static uint8_t *
+pack_2(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ v = *p++ << 6;
+ v += *p++ << 4;
+ v += *p++ << 2;
+ *rp++ = v + *p++;
+ v = *p++ << 6;
+ v += *p++ << 4;
+ v += *p++ << 2;
+ *rp++ = v + *p++;
+ return rp;
+}
+static uint8_t *
+unpack_2(uint32_t *p, uint8_t *dp)
+{
+ *p++ = (*dp >> 6);
+ *p++ = ((*dp >> 4) & 0x3);
+ *p++ = ((*dp >> 2) & 0x3);
+ *p++ = (*dp++ & 0x3);
+ *p++ = (*dp >> 6);
+ *p++ = ((*dp >> 4) & 0x3);
+ *p++ = ((*dp >> 2) & 0x3);
+ *p++ = (*dp++ & 0x3);
+ return dp;
+}
+static uint8_t *
+pack_3(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ v = *p++ << 5;
+ v += *p++ << 2;
+ *rp++ = v + (*p >> 1); v = *p++ << 7;
+ v += *p++ << 4;
+ v += *p++ << 1;
+ *rp++ = v + (*p >> 2); v = *p++ << 6;
+ v += *p++ << 3;
+ *rp++ = v + *p++;
+ return rp;
+}
+static uint8_t *
+unpack_3(uint32_t *p, uint8_t *dp)
+{
+ uint32_t v;
+ *p++ = (*dp >> 5);
+ *p++ = ((*dp >> 2) & 0x7);
+ v = ((*dp++ << 1) & 0x7); *p++ = v + (*dp >> 7);
+ *p++ = ((*dp >> 4) & 0x7);
+ *p++ = ((*dp >> 1) & 0x7);
+ v = ((*dp++ << 2) & 0x7); *p++ = v + (*dp >> 6);
+ *p++ = ((*dp >> 3) & 0x7);
+ *p++ = (*dp++ & 0x7);
+ return dp;
+}
+static uint8_t *
+pack_4(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ v = *p++ << 4;
+ *rp++ = v + *p++;
+ v = *p++ << 4;
+ *rp++ = v + *p++;
+ v = *p++ << 4;
+ *rp++ = v + *p++;
+ v = *p++ << 4;
+ *rp++ = v + *p++;
+ return rp;
+}
+static uint8_t *
+unpack_4(uint32_t *p, uint8_t *dp)
+{
+ *p++ = (*dp >> 4);
+ *p++ = (*dp++ & 0xf);
+ *p++ = (*dp >> 4);
+ *p++ = (*dp++ & 0xf);
+ *p++ = (*dp >> 4);
+ *p++ = (*dp++ & 0xf);
+ *p++ = (*dp >> 4);
+ *p++ = (*dp++ & 0xf);
+ return dp;
+}
+static uint8_t *
+pack_5(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ v = *p++ << 3;
+ *rp++ = v + (*p >> 2); v = *p++ << 6;
+ v += *p++ << 1;
+ *rp++ = v + (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 1); v = *p++ << 7;
+ v += *p++ << 2;
+ *rp++ = v + (*p >> 3); v = *p++ << 5;
+ *rp++ = v + *p++;
+ return rp;
+}
+static uint8_t *
+unpack_5(uint32_t *p, uint8_t *dp)
+{
+ uint32_t v;
+ *p++ = (*dp >> 3);
+ v = ((*dp++ << 2) & 0x1f); *p++ = v + (*dp >> 6);
+ *p++ = ((*dp >> 1) & 0x1f);
+ v = ((*dp++ << 4) & 0x1f); *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 1) & 0x1f); *p++ = v + (*dp >> 7);
+ *p++ = ((*dp >> 2) & 0x1f);
+ v = ((*dp++ << 3) & 0x1f); *p++ = v + (*dp >> 5);
+ *p++ = (*dp++ & 0x1f);
+ return dp;
+}
+static uint8_t *
+pack_6(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ v = *p++ << 2;
+ *rp++ = v + (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 2); v = *p++ << 6;
+ *rp++ = v + *p++;
+ v = *p++ << 2;
+ *rp++ = v + (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 2); v = *p++ << 6;
+ *rp++ = v + *p++;
+ return rp;
+}
+static uint8_t *
+unpack_6(uint32_t *p, uint8_t *dp)
+{
+ uint32_t v;
+ *p++ = (*dp >> 2);
+ v = ((*dp++ << 4) & 0x3f); *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 2) & 0x3f); *p++ = v + (*dp >> 6);
+ *p++ = (*dp++ & 0x3f);
+ *p++ = (*dp >> 2);
+ v = ((*dp++ << 4) & 0x3f); *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 2) & 0x3f); *p++ = v + (*dp >> 6);
+ *p++ = (*dp++ & 0x3f);
+ return dp;
+}
+static uint8_t *
+pack_7(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ v = *p++ << 1;
+ *rp++ = v + (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 5); v = *p++ << 3;
+ *rp++ = v + (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 3); v = *p++ << 5;
+ *rp++ = v + (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 1); v = *p++ << 7;
+ *rp++ = v + *p++;
+ return rp;
+}
+static uint8_t *
+unpack_7(uint32_t *p, uint8_t *dp)
+{
+ uint32_t v;
+ *p++ = (*dp >> 1);
+ v = ((*dp++ << 6) & 0x7f); *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 5) & 0x7f); *p++ = v + (*dp >> 3);
+ v = ((*dp++ << 4) & 0x7f); *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 3) & 0x7f); *p++ = v + (*dp >> 5);
+ v = ((*dp++ << 2) & 0x7f); *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 1) & 0x7f); *p++ = v + (*dp >> 7);
+ *p++ = (*dp++ & 0x7f);
+ return dp;
+}
+static uint8_t *
+pack_8(uint32_t *p, uint8_t *rp)
+{
+ *rp++ = *p++;
+ *rp++ = *p++;
+ *rp++ = *p++;
+ *rp++ = *p++;
+ *rp++ = *p++;
+ *rp++ = *p++;
+ *rp++ = *p++;
+ *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+unpack_8(uint32_t *p, uint8_t *dp)
+{
+ *p++ = *dp++;
+ *p++ = *dp++;
+ *p++ = *dp++;
+ *p++ = *dp++;
+ *p++ = *dp++;
+ *p++ = *dp++;
+ *p++ = *dp++;
+ *p++ = *dp++;
+ return dp;
+}
+static uint8_t *
+pack_9(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ *rp++ = (*p >> 1); v = *p++ << 7;
+ *rp++ = v + (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 3); v = *p++ << 5;
+ *rp++ = v + (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 5); v = *p++ << 3;
+ *rp++ = v + (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 7); v = *p++ << 1;
+ *rp++ = v + (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+unpack_9(uint32_t *p, uint8_t *dp)
+{
+ uint32_t v;
+ v = *dp++ << 1; *p++ = v + (*dp >> 7);
+ v = ((*dp++ << 2) & 0x1ff); *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 3) & 0x1ff); *p++ = v + (*dp >> 5);
+ v = ((*dp++ << 4) & 0x1ff); *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 5) & 0x1ff); *p++ = v + (*dp >> 3);
+ v = ((*dp++ << 6) & 0x1ff); *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 7) & 0x1ff); *p++ = v + (*dp >> 1);
+ v = ((*dp++ << 8) & 0x1ff); *p++ = v + *dp++;
+ return dp;
+}
+static uint8_t *
+pack_10(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+unpack_10(uint32_t *p, uint8_t *dp)
+{
+ uint32_t v;
+ v = *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 4) & 0x3ff); *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 6) & 0x3ff); *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 8) & 0x3ff); *p++ = v + *dp++;
+ v = *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 4) & 0x3ff); *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 6) & 0x3ff); *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 8) & 0x3ff); *p++ = v + *dp++;
+ return dp;
+}
+static uint8_t *
+pack_11(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ *rp++ = (*p >> 3); v = *p++ << 5;
+ *rp++ = v + (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 9); *rp++ = (*p >> 1); v = *p++ << 7;
+ *rp++ = v + (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 7); v = *p++ << 1;
+ *rp++ = v + (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 5); v = *p++ << 3;
+ *rp++ = v + (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+unpack_11(uint32_t *p, uint8_t *dp)
+{
+ uint32_t v;
+ v = *dp++ << 3; *p++ = v + (*dp >> 5);
+ v = ((*dp++ << 6) & 0x7ff); *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 9) & 0x7ff); v += *dp++ << 1; *p++ = v + (*dp >> 7);
+ v = ((*dp++ << 4) & 0x7ff); *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 7) & 0x7ff); *p++ = v + (*dp >> 1);
+ v = ((*dp++ << 10) & 0x7ff); v += *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 5) & 0x7ff); *p++ = v + (*dp >> 3);
+ v = ((*dp++ << 8) & 0x7ff); *p++ = v + *dp++;
+ return dp;
+}
+static uint8_t *
+pack_12(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+unpack_12(uint32_t *p, uint8_t *dp)
+{
+ uint32_t v;
+ v = *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 8) & 0xfff); *p++ = v + *dp++;
+ v = *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 8) & 0xfff); *p++ = v + *dp++;
+ v = *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 8) & 0xfff); *p++ = v + *dp++;
+ v = *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 8) & 0xfff); *p++ = v + *dp++;
+ return dp;
+}
+static uint8_t *
+pack_13(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ *rp++ = (*p >> 5); v = *p++ << 3;
+ *rp++ = v + (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 7); v = *p++ << 1;
+ *rp++ = v + (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 9); *rp++ = (*p >> 1); v = *p++ << 7;
+ *rp++ = v + (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 11); *rp++ = (*p >> 3); v = *p++ << 5;
+ *rp++ = v + (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+unpack_13(uint32_t *p, uint8_t *dp)
+{
+ uint32_t v;
+ v = *dp++ << 5; *p++ = v + (*dp >> 3);
+ v = ((*dp++ << 10) & 0x1fff); v += *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 7) & 0x1fff); *p++ = v + (*dp >> 1);
+ v = ((*dp++ << 12) & 0x1fff); v += *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 9) & 0x1fff); v += *dp++ << 1; *p++ = v + (*dp >> 7);
+ v = ((*dp++ << 6) & 0x1fff); *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 11) & 0x1fff); v += *dp++ << 3; *p++ = v + (*dp >> 5);
+ v = ((*dp++ << 8) & 0x1fff); *p++ = v + *dp++;
+ return dp;
+}
+static uint8_t *
+pack_14(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ *rp++ = (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+unpack_14(uint32_t *p, uint8_t *dp)
+{
+ uint32_t v;
+ v = *dp++ << 6; *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 12) & 0x3fff); v += *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 10) & 0x3fff); v += *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 8) & 0x3fff); *p++ = v + *dp++;
+ v = *dp++ << 6; *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 12) & 0x3fff); v += *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 10) & 0x3fff); v += *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 8) & 0x3fff); *p++ = v + *dp++;
+ return dp;
+}
+static uint8_t *
+pack_15(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ *rp++ = (*p >> 7); v = *p++ << 1;
+ *rp++ = v + (*p >> 14); *rp++ = (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 13); *rp++ = (*p >> 5); v = *p++ << 3;
+ *rp++ = v + (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 11); *rp++ = (*p >> 3); v = *p++ << 5;
+ *rp++ = v + (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 9); *rp++ = (*p >> 1); v = *p++ << 7;
+ *rp++ = v + (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+unpack_15(uint32_t *p, uint8_t *dp)
+{
+ uint32_t v;
+ v = *dp++ << 7; *p++ = v + (*dp >> 1);
+ v = ((*dp++ << 14) & 0x7fff); v += *dp++ << 6; *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 13) & 0x7fff); v += *dp++ << 5; *p++ = v + (*dp >> 3);
+ v = ((*dp++ << 12) & 0x7fff); v += *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 11) & 0x7fff); v += *dp++ << 3; *p++ = v + (*dp >> 5);
+ v = ((*dp++ << 10) & 0x7fff); v += *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 9) & 0x7fff); v += *dp++ << 1; *p++ = v + (*dp >> 7);
+ v = ((*dp++ << 8) & 0x7fff); *p++ = v + *dp++;
+ return dp;
+}
+static uint8_t *
+pack_16(uint32_t *p, uint8_t *rp)
+{
+ *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+unpack_16(uint32_t *p, uint8_t *dp)
+{
+ uint32_t v;
+ v = *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 8; *p++ = v + *dp++;
+ return dp;
+}
+static uint8_t *
+pack_17(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ *rp++ = (*p >> 9); *rp++ = (*p >> 1); v = *p++ << 7;
+ *rp++ = v + (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 11); *rp++ = (*p >> 3); v = *p++ << 5;
+ *rp++ = v + (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 13); *rp++ = (*p >> 5); v = *p++ << 3;
+ *rp++ = v + (*p >> 14); *rp++ = (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 15); *rp++ = (*p >> 7); v = *p++ << 1;
+ *rp++ = v + (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+unpack_17(uint32_t *p, uint8_t *dp)
+{
+ uint32_t v;
+ v = *dp++ << 9; v += *dp++ << 1; *p++ = v + (*dp >> 7);
+ v = ((*dp++ << 10) & 0x1ffff); v += *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 11) & 0x1ffff); v += *dp++ << 3; *p++ = v + (*dp >> 5);
+ v = ((*dp++ << 12) & 0x1ffff); v += *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 13) & 0x1ffff); v += *dp++ << 5; *p++ = v + (*dp >> 3);
+ v = ((*dp++ << 14) & 0x1ffff); v += *dp++ << 6; *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 15) & 0x1ffff); v += *dp++ << 7; *p++ = v + (*dp >> 1);
+ v = ((*dp++ << 16) & 0x1ffff); v += *dp++ << 8; *p++ = v + *dp++;
+ return dp;
+}
+static uint8_t *
+pack_18(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ *rp++ = (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 14); *rp++ = (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 14); *rp++ = (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+unpack_18(uint32_t *p, uint8_t *dp)
+{
+ uint32_t v;
+ v = *dp++ << 10; v += *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 12) & 0x3ffff); v += *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 14) & 0x3ffff); v += *dp++ << 6; *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 16) & 0x3ffff); v += *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 10; v += *dp++ << 2; *p++ = v + (*dp >> 6);
+ v = ((*dp++ << 12) & 0x3ffff); v += *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 14) & 0x3ffff); v += *dp++ << 6; *p++ = v + (*dp >> 2);
+ v = ((*dp++ << 16) & 0x3ffff); v += *dp++ << 8; *p++ = v + *dp++;
+ return dp;
+}
+static uint8_t *
+pack_19(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ *rp++ = (*p >> 11); *rp++ = (*p >> 3); v = *p++ << 5;
+ *rp++ = v + (*p >> 14); *rp++ = (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 17); *rp++ = (*p >> 9); *rp++ = (*p >> 1); v = *p++ << 7;
+ *rp++ = v + (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 15); *rp++ = (*p >> 7); v = *p++ << 1;
+ *rp++ = v + (*p >> 18); *rp++ = (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 13); *rp++ = (*p >> 5); v = *p++ << 3;
+ *rp++ = v + (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+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++ << 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++ << 13) & 0x7ffff); v += *dp++ << 5; *p++ = v + (*dp >> 3);
+ v = ((*dp++ << 16) & 0x7ffff); v += *dp++ << 8; *p++ = v + *dp++;
+ return dp;
+}
+static uint8_t *
+pack_20(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+unpack_20(uint32_t *p, uint8_t *dp)
+{
+ uint32_t v;
+ v = *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 16) & 0xfffff); v += *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 16) & 0xfffff); v += *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 16) & 0xfffff); v += *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 16) & 0xfffff); v += *dp++ << 8; *p++ = v + *dp++;
+ return dp;
+}
+static uint8_t *
+pack_21(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ *rp++ = (*p >> 13); *rp++ = (*p >> 5); v = *p++ << 3;
+ *rp++ = v + (*p >> 18); *rp++ = (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 15); *rp++ = (*p >> 7); v = *p++ << 1;
+ *rp++ = v + (*p >> 20); *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 17); *rp++ = (*p >> 9); *rp++ = (*p >> 1); v = *p++ << 7;
+ *rp++ = v + (*p >> 14); *rp++ = (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 19); *rp++ = (*p >> 11); *rp++ = (*p >> 3); v = *p++ << 5;
+ *rp++ = v + (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+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++ << 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++ << 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++ << 16) & 0x1fffff); v += *dp++ << 8; *p++ = v + *dp++;
+ return dp;
+}
+static uint8_t *
+pack_22(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ *rp++ = (*p >> 14); *rp++ = (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 20); *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 18); *rp++ = (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 14); *rp++ = (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 20); *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 18); *rp++ = (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+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++ << 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++ << 16) & 0x3fffff); v += *dp++ << 8; *p++ = v + *dp++;
+ return dp;
+}
+static uint8_t *
+pack_23(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ *rp++ = (*p >> 15); *rp++ = (*p >> 7); v = *p++ << 1;
+ *rp++ = v + (*p >> 22); *rp++ = (*p >> 14); *rp++ = (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 21); *rp++ = (*p >> 13); *rp++ = (*p >> 5); v = *p++ << 3;
+ *rp++ = v + (*p >> 20); *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 19); *rp++ = (*p >> 11); *rp++ = (*p >> 3); v = *p++ << 5;
+ *rp++ = v + (*p >> 18); *rp++ = (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 17); *rp++ = (*p >> 9); *rp++ = (*p >> 1); v = *p++ << 7;
+ *rp++ = v + (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+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++ << 16) & 0x7fffff); v += *dp++ << 8; *p++ = v + *dp++;
+ return dp;
+}
+static uint8_t *
+pack_24(uint32_t *p, uint8_t *rp)
+{
+ *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+unpack_24(uint32_t *p, uint8_t *dp)
+{
+ uint32_t v;
+ v = *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ return dp;
+}
+static uint8_t *
+pack_25(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ *rp++ = (*p >> 17); *rp++ = (*p >> 9); *rp++ = (*p >> 1); v = *p++ << 7;
+ *rp++ = v + (*p >> 18); *rp++ = (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 19); *rp++ = (*p >> 11); *rp++ = (*p >> 3); v = *p++ << 5;
+ *rp++ = v + (*p >> 20); *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 21); *rp++ = (*p >> 13); *rp++ = (*p >> 5); v = *p++ << 3;
+ *rp++ = v + (*p >> 22); *rp++ = (*p >> 14); *rp++ = (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 23); *rp++ = (*p >> 15); *rp++ = (*p >> 7); v = *p++ << 1;
+ *rp++ = v + (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+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++;
+ return dp;
+}
+static uint8_t *
+pack_26(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ *rp++ = (*p >> 18); *rp++ = (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 20); *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 22); *rp++ = (*p >> 14); *rp++ = (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 18); *rp++ = (*p >> 10); *rp++ = (*p >> 2); v = *p++ << 6;
+ *rp++ = v + (*p >> 20); *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 22); *rp++ = (*p >> 14); *rp++ = (*p >> 6); v = *p++ << 2;
+ *rp++ = v + (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+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++ << 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++;
+ return dp;
+}
+static uint8_t *
+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 >> 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 >> 21); *rp++ = (*p >> 13); *rp++ = (*p >> 5); v = *p++ << 3;
+ *rp++ = v + (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+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++;
+ return dp;
+}
+static uint8_t *
+pack_28(uint32_t *p, uint8_t *rp)
+{
+ uint8_t v;
+ *rp++ = (*p >> 20); *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 20); *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 20); *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 20); *rp++ = (*p >> 12); *rp++ = (*p >> 4); v = *p++ << 4;
+ *rp++ = v + (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+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++ << 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++ << 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++ << 20; v += *dp++ << 12; v += *dp++ << 4; *p++ = v + (*dp >> 4);
+ v = ((*dp++ << 24) & 0xfffffff); v += *dp++ << 16; v += *dp++ << 8;
+ *p++ = v + *dp++;
+ return dp;
+}
+static uint8_t *
+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 >> 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 >> 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 >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+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++;
+ return dp;
+}
+static uint8_t *
+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 >> 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++;
+ return rp;
+}
+static uint8_t *
+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++ << 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++;
+ return dp;
+}
+static uint8_t *
+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++;
+ return rp;
+}
+static uint8_t *
+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++;
+ return dp;
+}
+static uint8_t *
+pack_32(uint32_t *p, uint8_t *rp)
+{
+ *rp++ = (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ *rp++ = (*p >> 24); *rp++ = (*p >> 16); *rp++ = (*p >> 8); *rp++ = *p++;
+ return rp;
+}
+static uint8_t *
+unpack_32(uint32_t *p, uint8_t *dp)
+{
+ uint32_t v;
+ v = *dp++ << 24; v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 24; v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 24; v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 24; v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 24; v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 24; v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 24; v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ v = *dp++ << 24; v += *dp++ << 16; v += *dp++ << 8; *p++ = v + *dp++;
+ return dp;
+}
+/* </generated> */
+
+static uint8_t *
+pack_(uint32_t *p, uint32_t i, int w, uint8_t *rp)
+{
+ while (i >= 8) {
+ switch (w) {
+ case 0 : break;
+ case 1 : rp = pack_1(p, rp); break;
+ case 2 : rp = pack_2(p, rp); break;
+ case 3 : rp = pack_3(p, rp); break;
+ case 4 : rp = pack_4(p, rp); break;
+ case 5 : rp = pack_5(p, rp); break;
+ case 6 : rp = pack_6(p, rp); break;
+ case 7 : rp = pack_7(p, rp); break;
+ case 8 : rp = pack_8(p, rp); break;
+ case 9 : rp = pack_9(p, rp); break;
+ case 10 : rp = pack_10(p, rp); break;
+ case 11 : rp = pack_11(p, rp); break;
+ case 12 : rp = pack_12(p, rp); break;
+ case 13 : rp = pack_13(p, rp); break;
+ case 14 : rp = pack_14(p, rp); break;
+ case 15 : rp = pack_15(p, rp); break;
+ case 16 : rp = pack_16(p, rp); break;
+ case 17 : rp = pack_17(p, rp); break;
+ case 18 : rp = pack_18(p, rp); break;
+ case 19 : rp = pack_19(p, rp); break;
+ case 20 : rp = pack_20(p, rp); break;
+ case 21 : rp = pack_21(p, rp); break;
+ case 22 : rp = pack_22(p, rp); break;
+ case 23 : rp = pack_23(p, rp); break;
+ case 24 : rp = pack_24(p, rp); break;
+ case 25 : rp = pack_25(p, rp); break;
+ case 26 : rp = pack_26(p, rp); break;
+ case 27 : rp = pack_27(p, rp); break;
+ case 28 : rp = pack_28(p, rp); break;
+ case 29 : rp = pack_29(p, rp); break;
+ case 30 : rp = pack_30(p, rp); break;
+ case 31 : rp = pack_31(p, rp); break;
+ case 32 : rp = pack_32(p, rp); break;
+ }
+ p += 8;
+ i -= 8;
+ }
+ {
+ int b;
+ uint8_t v;
+ uint32_t *pe = p + i;
+ for (b = 8 - w, v = 0; p < pe;) {
+ if (b > 0) {
+ v += *p++ << b;
+ b -= w;
+ } else if (b < 0) {
+ *rp++ = v + (*p >> -b);
+ b += 8;
+ v = 0;
+ } else {
+ *rp++ = v + *p++;
+ b = 8 - w;
+ v = 0;
+ }
+ }
+ if (b + w != 8) { *rp++ = v; }
+ return rp;
+ }
+}
+
+static uint8_t *
+pack(uint32_t *p, uint32_t i, uint8_t *freq, uint8_t *rp)
+{
+ int32_t k, w;
+ uint8_t ebuf[UNIT_SIZE], *ep = ebuf;
+ uint32_t s, *pe = p + i, r, th = i - (i >> 3);
+ for (w = 0, s = 0; w <= 32; w++) {
+ if ((s += freq[w]) >= th) { break; }
+ }
+ if (i == s) {
+ *rp++ = w;
+ return pack_(p, i, w, rp);
+ }
+ r = 1 << w;
+ *rp++ = w + 0x80;
+ *rp++ = i - s;
+ if (r >= UNIT_SIZE) {
+ uint32_t first, *last = &first;
+ for (k = 0; p < pe; p++, k++) {
+ if (*p >= r) {
+ GRN_B_ENC(*p - r, ep);
+ *last = k;
+ last = p;
+ }
+ }
+ *last = 0;
+ *rp++ = (uint8_t) first;
+ } else {
+ for (k = 0; p < pe; p++, k++) {
+ if (*p >= r) {
+ *ep++ = k;
+ GRN_B_ENC(*p - r, ep);
+ *p = 0;
+ }
+ }
+ }
+ rp = pack_(p - i, i, w, rp);
+ grn_memcpy(rp, ebuf, ep - ebuf);
+ return rp + (ep - ebuf);
+}
+
+int
+grn_p_enc(grn_ctx *ctx, uint32_t *data, uint32_t data_size, uint8_t **res)
+{
+ uint8_t *rp, freq[33];
+ uint32_t j, *dp, *dpe, d, w, buf[UNIT_SIZE];
+ *res = rp = GRN_MALLOC(data_size * sizeof(uint32_t) * 2);
+ GRN_B_ENC(data_size, rp);
+ memset(freq, 0, 33);
+ for (j = 0, dp = data, dpe = dp + data_size; dp < dpe; j++, dp++) {
+ if (j == UNIT_SIZE) {
+ rp = pack(buf, j, freq, rp);
+ memset(freq, 0, 33);
+ j = 0;
+ }
+ if ((d = buf[j] = *dp)) {
+ GRN_BIT_SCAN_REV(d, w);
+ freq[w + 1]++;
+ } else {
+ freq[0]++;
+ }
+ }
+ if (j) { rp = pack(buf, j, freq, rp); }
+ return rp - *res;
+}
+
+#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;
+ uint32_t data_size;
+ uint32_t flags;
+} datavec;
+
+static grn_rc
+datavec_reset(grn_ctx *ctx, datavec *dv, uint32_t dvlen,
+ size_t unitsize, size_t totalsize)
+{
+ int i;
+ 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)))) {
+ 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;
+ }
+ for (i = 1; i < dvlen; i++) {
+ dv[i].data = dv[i - 1].data + unitsize;
+ }
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+datavec_init(grn_ctx *ctx, datavec *dv, uint32_t dvlen,
+ size_t unitsize, size_t totalsize)
+{
+ int i;
+ if (!totalsize) {
+ memset(dv, 0, sizeof(datavec) * (dvlen + 1));
+ return GRN_SUCCESS;
+ }
+ if (!(dv[0].data = GRN_MALLOC(totalsize * sizeof(uint32_t)))) {
+ 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++) {
+ dv[i].data = dv[i - 1].data + unitsize;
+ }
+ return GRN_SUCCESS;
+}
+
+static void
+datavec_fin(grn_ctx *ctx, datavec *dv)
+{
+ if (dv[0].data) { GRN_FREE(dv[0].data); }
+}
+
+size_t
+grn_p_encv(grn_ctx *ctx, datavec *dv, uint32_t dvlen, uint8_t *res)
+{
+ uint8_t *rp = res, freq[33];
+ uint32_t pgap, usep, l, df, data_size, *dp, *dpe;
+ if (!dvlen || !(df = dv[0].data_size)) { return 0; }
+ for (usep = 0, data_size = 0, l = 0; l < dvlen; l++) {
+ uint32_t dl = dv[l].data_size;
+ if (dl < df || ((dl > df) && (l != dvlen - 1))) {
+ /* invalid argument */
+ return 0;
+ }
+ usep += (dv[l].flags & USE_P_ENC) << l;
+ data_size += dl;
+ }
+ pgap = data_size - df * dvlen;
+ if (!usep) {
+ GRN_B_ENC((df << 1) + 1, rp);
+ for (l = 0; l < dvlen; l++) {
+ for (dp = dv[l].data, dpe = dp + dv[l].data_size; dp < dpe; dp++) {
+ GRN_B_ENC(*dp, rp);
+ }
+ }
+ } else {
+ uint32_t buf[UNIT_SIZE];
+ GRN_B_ENC((usep << 1), rp);
+ GRN_B_ENC(df, rp);
+ if (dv[dvlen - 1].flags & ODD) {
+ GRN_B_ENC(pgap, rp);
+ } else {
+ GRN_ASSERT(!pgap);
+ }
+ for (l = 0; l < dvlen; l++) {
+ dp = dv[l].data;
+ dpe = dp + dv[l].data_size;
+ if ((dv[l].flags & USE_P_ENC)) {
+ uint32_t j = 0, d;
+ memset(freq, 0, 33);
+ while (dp < dpe) {
+ if (j == UNIT_SIZE) {
+ rp = pack(buf, j, freq, rp);
+ memset(freq, 0, 33);
+ j = 0;
+ }
+ if ((d = buf[j++] = *dp++)) {
+ uint32_t w;
+ GRN_BIT_SCAN_REV(d, w);
+ freq[w + 1]++;
+ } else {
+ freq[0]++;
+ }
+ }
+ if (j) { rp = pack(buf, j, freq, rp); }
+ } else {
+ while (dp < dpe) { GRN_B_ENC(*dp++, rp); }
+ }
+ }
+ }
+ return rp - res;
+}
+
+#define GRN_B_DEC_CHECK(v,p,pe) do { \
+ uint8_t *_p = (uint8_t *)p; \
+ uint32_t _v; \
+ if (_p >= pe) { return 0; } \
+ _v = *_p++; \
+ switch (_v >> 4) { \
+ case 0x08 : \
+ if (_v == 0x8f) { \
+ if (_p + sizeof(uint32_t) > pe) { return 0; } \
+ grn_memcpy(&_v, _p, sizeof(uint32_t)); \
+ _p += sizeof(uint32_t); \
+ } \
+ break; \
+ case 0x09 : \
+ if (_p + 3 > pe) { return 0; } \
+ _v = (_v - 0x90) * 0x100 + *_p++; \
+ _v = _v * 0x100 + *_p++; \
+ _v = _v * 0x100 + *_p++ + 0x20408f; \
+ break; \
+ case 0x0a : \
+ case 0x0b : \
+ if (_p + 2 > pe) { return 0; } \
+ _v = (_v - 0xa0) * 0x100 + *_p++; \
+ _v = _v * 0x100 + *_p++ + 0x408f; \
+ break; \
+ case 0x0c : \
+ case 0x0d : \
+ case 0x0e : \
+ case 0x0f : \
+ if (_p + 1 > pe) { return 0; } \
+ _v = (_v - 0xc0) * 0x100 + *_p++ + 0x8f; \
+ break; \
+ } \
+ v = _v; \
+ p = _p; \
+} while (0)
+
+static uint8_t *
+unpack(uint8_t *dp, uint8_t *dpe, int i, uint32_t *rp)
+{
+ uint8_t ne = 0, k = 0, w = *dp++;
+ uint32_t m, *p = rp;
+ if (w & 0x80) {
+ ne = *dp++;
+ w -= 0x80;
+ m = (1 << w) - 1;
+ if (m >= UNIT_MASK) { k = *dp++; }
+ } else {
+ m = (1 << w) - 1;
+ }
+ if (w) {
+ while (i >= 8) {
+ if (dp + w > dpe) { return NULL; }
+ switch (w) {
+ case 1 : dp = unpack_1(p, dp); break;
+ case 2 : dp = unpack_2(p, dp); break;
+ case 3 : dp = unpack_3(p, dp); break;
+ case 4 : dp = unpack_4(p, dp); break;
+ case 5 : dp = unpack_5(p, dp); break;
+ case 6 : dp = unpack_6(p, dp); break;
+ case 7 : dp = unpack_7(p, dp); break;
+ case 8 : dp = unpack_8(p, dp); break;
+ case 9 : dp = unpack_9(p, dp); break;
+ case 10 : dp = unpack_10(p, dp); break;
+ case 11 : dp = unpack_11(p, dp); break;
+ case 12 : dp = unpack_12(p, dp); break;
+ case 13 : dp = unpack_13(p, dp); break;
+ case 14 : dp = unpack_14(p, dp); break;
+ case 15 : dp = unpack_15(p, dp); break;
+ case 16 : dp = unpack_16(p, dp); break;
+ case 17 : dp = unpack_17(p, dp); break;
+ case 18 : dp = unpack_18(p, dp); break;
+ case 19 : dp = unpack_19(p, dp); break;
+ case 20 : dp = unpack_20(p, dp); break;
+ case 21 : dp = unpack_21(p, dp); break;
+ case 22 : dp = unpack_22(p, dp); break;
+ case 23 : dp = unpack_23(p, dp); break;
+ case 24 : dp = unpack_24(p, dp); break;
+ case 25 : dp = unpack_25(p, dp); break;
+ case 26 : dp = unpack_26(p, dp); break;
+ case 27 : dp = unpack_27(p, dp); break;
+ case 28 : dp = unpack_28(p, dp); break;
+ case 29 : dp = unpack_29(p, dp); break;
+ case 30 : dp = unpack_30(p, dp); break;
+ case 31 : dp = unpack_31(p, dp); break;
+ case 32 : dp = unpack_32(p, dp); break;
+ }
+ i -= 8;
+ p += 8;
+ }
+ {
+ int b;
+ uint32_t v, *pe;
+ for (b = 8 - w, v = 0, pe = p + i; p < pe && dp < dpe;) {
+ if (b > 0) {
+ *p++ = v + ((*dp >> b) & m);
+ b -= w;
+ v = 0;
+ } else if (b < 0) {
+ v += (*dp++ << -b) & m;
+ b += 8;
+ } else {
+ *p++ = v + (*dp++ & m);
+ b = 8 - w;
+ v = 0;
+ }
+ }
+ if (b + w != 8) { dp++; }
+ }
+ } else {
+ memset(p, 0, sizeof(uint32_t) * i);
+ }
+ if (ne) {
+ if (m >= UNIT_MASK) {
+ uint32_t *pp;
+ while (ne--) {
+ pp = &rp[k];
+ k = *pp;
+ GRN_B_DEC_CHECK(*pp, dp, dpe);
+ *pp += (m + 1);
+ }
+ } else {
+ while (ne--) {
+ k = *dp++;
+ GRN_B_DEC_CHECK(rp[k], dp, dpe);
+ rp[k] += (m + 1);
+ }
+ }
+ }
+ return dp;
+}
+
+int
+grn_p_dec(grn_ctx *ctx, uint8_t *data, uint32_t data_size, uint32_t nreq, uint32_t **res)
+{
+ uint8_t *dp = data, *dpe = data + data_size;
+ uint32_t rest, orig_size, *rp, *rpe;
+ GRN_B_DEC(orig_size, dp);
+ if (!orig_size) {
+ if (!nreq || nreq > data_size) { nreq = data_size; }
+ if ((*res = rp = GRN_MALLOC(nreq * 4))) {
+ for (rpe = rp + nreq; dp < data + data_size && rp < rpe; rp++) {
+ GRN_B_DEC(*rp, dp);
+ }
+ }
+ return rp - *res;
+ } else {
+ if (!(*res = rp = GRN_MALLOC(orig_size * sizeof(uint32_t)))) {
+ return 0;
+ }
+ if (!nreq || nreq > orig_size) { nreq = orig_size; }
+ for (rest = nreq; rest >= UNIT_SIZE; rest -= UNIT_SIZE) {
+ if (!(dp = unpack(dp, dpe, UNIT_SIZE, rp))) { return 0; }
+ rp += UNIT_SIZE;
+ }
+ if (rest) { if (!(dp = unpack(dp, dpe, rest, rp))) { return 0; } }
+ GRN_ASSERT(data + data_size == dp);
+ return nreq;
+ }
+}
+
+int
+grn_p_decv(grn_ctx *ctx, uint8_t *data, uint32_t data_size, datavec *dv, uint32_t dvlen)
+{
+ size_t size;
+ uint32_t df, l, i, *rp, nreq;
+ uint8_t *dp = data, *dpe = data + data_size;
+ if (!data_size) {
+ dv[0].data_size = 0;
+ return 0;
+ }
+ for (nreq = 0; nreq < dvlen; nreq++) {
+ if (dv[nreq].flags & CUT_OFF) { break; }
+ }
+ if (!nreq) { return 0; }
+ GRN_B_DEC_CHECK(df, dp, dpe);
+ if ((df & 1)) {
+ df >>= 1;
+ size = nreq == dvlen ? data_size : df * nreq;
+ if (dv[dvlen].data < dv[0].data + size) {
+ if (dv[0].data) { GRN_FREE(dv[0].data); }
+ if (!(rp = GRN_MALLOC(size * sizeof(uint32_t)))) { return 0; }
+ dv[dvlen].data = rp + size;
+ } else {
+ rp = dv[0].data;
+ }
+ for (l = 0; l < dvlen; l++) {
+ if (dv[l].flags & CUT_OFF) { break; }
+ dv[l].data = rp;
+ if (l < dvlen - 1) {
+ for (i = 0; i < df; i++, rp++) { GRN_B_DEC_CHECK(*rp, dp, dpe); }
+ } else {
+ for (i = 0; dp < dpe; i++, rp++) { GRN_B_DEC_CHECK(*rp, dp, dpe); }
+ }
+ dv[l].data_size = i;
+ }
+ } else {
+ uint32_t n, rest, usep = df >> 1;
+ GRN_B_DEC_CHECK(df, dp, dpe);
+ if (dv[dvlen -1].flags & ODD) {
+ GRN_B_DEC_CHECK(rest, dp, dpe);
+ } else {
+ rest = 0;
+ }
+ size = df * nreq + (nreq == dvlen ? rest : 0);
+ if (dv[dvlen].data < dv[0].data + size) {
+ if (dv[0].data) { GRN_FREE(dv[0].data); }
+ if (!(rp = GRN_MALLOC(size * sizeof(uint32_t)))) { return 0; }
+ dv[dvlen].data = rp + size;
+ } else {
+ rp = dv[0].data;
+ }
+ for (l = 0; l < dvlen; l++) {
+ if (dv[l].flags & CUT_OFF) { break; }
+ dv[l].data = rp;
+ dv[l].data_size = n = (l < dvlen - 1) ? df : df + rest;
+ if (usep & (1 << l)) {
+ for (; n >= UNIT_SIZE; n -= UNIT_SIZE) {
+ if (!(dp = unpack(dp, dpe, UNIT_SIZE, rp))) { return 0; }
+ rp += UNIT_SIZE;
+ }
+ if (n) {
+ if (!(dp = unpack(dp, dpe, n, rp))) { return 0; }
+ rp += n;
+ }
+ dv[l].flags |= USE_P_ENC;
+ } else {
+ for (; n; n--, rp++) {
+ GRN_B_DEC_CHECK(*rp, dp, dpe);
+ }
+ }
+ }
+ GRN_ASSERT(dp == dpe);
+ if (dp != dpe) {
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "data_size=%d, %" GRN_FMT_LLD,
+ data_size, (long long int)(dpe - dp));
+ }
+ }
+ return rp - dv[0].data;
+}
+
+int
+grn_b_enc(grn_ctx *ctx, uint32_t *data, uint32_t data_size, uint8_t **res)
+{
+ uint8_t *rp;
+ uint32_t *dp, i;
+ *res = rp = GRN_MALLOC(data_size * sizeof(uint32_t) * 2);
+ GRN_B_ENC(data_size, rp);
+ for (i = data_size, dp = data; i; i--, dp++) {
+ GRN_B_ENC(*dp, rp);
+ }
+ return rp - *res;
+}
+
+int
+grn_b_dec(grn_ctx *ctx, uint8_t *data, uint32_t data_size, uint32_t **res)
+{
+ uint32_t i, *rp, orig_size;
+ uint8_t *dp = data;
+ GRN_B_DEC(orig_size, dp);
+ *res = rp = GRN_MALLOC(orig_size * sizeof(uint32_t));
+ for (i = orig_size; i; i--, rp++) {
+ GRN_B_DEC(*rp, dp);
+ }
+ return orig_size;
+}
+
+/* buffer */
+
+typedef struct {
+ uint32_t tid;
+ uint32_t size_in_chunk;
+ uint32_t pos_in_chunk;
+ uint16_t size_in_buffer;
+ uint16_t pos_in_buffer;
+} buffer_term;
+
+typedef struct {
+ uint16_t step;
+ uint16_t jump;
+} buffer_rec;
+
+typedef struct {
+ uint32_t chunk;
+ uint32_t chunk_size;
+ uint32_t buffer_free;
+ uint16_t nterms;
+ uint16_t nterms_void;
+} buffer_header;
+
+struct grn_ii_buffer {
+ buffer_header header;
+ buffer_term terms[(S_SEGMENT - sizeof(buffer_header))/sizeof(buffer_term)];
+};
+
+typedef struct grn_ii_buffer buffer;
+
+inline static uint32_t
+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 != GRN_II_PSEG_NOT_ASSIGNED) {
+ GRN_IO_SEG_REF(ii->seg, pseg, p);
+ if (!p) { return GRN_II_PSEG_NOT_ASSIGNED; }
+ if (b) { *b = (buffer *)p; }
+ if (bt) { *bt = (buffer_term *)(p + LPOS(pos)); }
+ }
+ return pseg;
+}
+
+inline static grn_rc
+buffer_close(grn_ctx *ctx, grn_ii *ii, uint32_t pseg)
+{
+ if (pseg >= ii->seg->header->max_segment) {
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "invalid pseg buffer_close(%d)", pseg);
+ return GRN_INVALID_ARGUMENT;
+ }
+ GRN_IO_SEG_UNREF(ii->seg, pseg);
+ return GRN_SUCCESS;
+}
+
+typedef struct {
+ uint32_t rid;
+ uint32_t sid;
+} docid;
+
+#define BUFFER_REC_DEL(r) ((r)->jump = 1)
+#define BUFFER_REC_DELETED(r) ((r)->jump == 1)
+
+#define BUFFER_REC_AT(b,pos) ((buffer_rec *)(b) + (pos))
+#define BUFFER_REC_POS(b,rec) ((uint16_t)((rec) - (buffer_rec *)(b)))
+
+inline static void
+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);
+ 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);
+ for (pos = bt->pos_in_buffer; pos; pos = r->step) {
+ r = BUFFER_REC_AT(b, pos);
+ 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);
+ }
+}
+
+inline static grn_rc
+check_jump(grn_ctx *ctx, grn_ii *ii, buffer *b, buffer_rec *r, int j)
+{
+ uint16_t i = BUFFER_REC_POS(b, r);
+ uint8_t *p;
+ buffer_rec *r2;
+ docid id, id2;
+ if (!j) { return GRN_SUCCESS; }
+ 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);
+ } else {
+ id.sid = 1;
+ }
+ if (j == 1) {
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "deleting! %d(%d:%d)", i, id.rid, id.sid);
+ return GRN_SUCCESS;
+ }
+ r2 = BUFFER_REC_AT(b, j);
+ 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);
+ } else {
+ 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);
+ 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);
+ return GRN_FILE_CORRUPT;
+ }
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+set_jump_r(grn_ctx *ctx, grn_ii *ii, buffer *b, buffer_rec *from, int to)
+{
+ int i, j, max_jump = 100;
+ buffer_rec *r, *r2;
+ for (r = from, j = to; j > 1 && max_jump--; r = BUFFER_REC_AT(b, r->step)) {
+ r2 = BUFFER_REC_AT(b, j);
+ if (r == r2) { break; }
+ if (BUFFER_REC_DELETED(r2)) { break; }
+ if (j == (i = r->jump)) { break; }
+ if (j == r->step) { break; }
+ if (check_jump(ctx, ii, b, r, j)) {
+ ERR(GRN_FILE_CORRUPT, "check_jump failed");
+ return ctx->rc;
+ }
+ r->jump = j;
+ j = i;
+ if (!r->step) { return GRN_FILE_CORRUPT; }
+ }
+ return GRN_SUCCESS;
+}
+
+#define GET_NUM_BITS(x,n) do {\
+ n = x;\
+ n = (n & 0x55555555) + ((n >> 1) & 0x55555555);\
+ n = (n & 0x33333333) + ((n >> 2) & 0x33333333);\
+ n = (n & 0x0F0F0F0F) + ((n >> 4) & 0x0F0F0F0F);\
+ n = (n & 0x00FF00FF) + ((n >> 8) & 0x00FF00FF);\
+ n = (n & 0x0000FFFF) + ((n >>16) & 0x0000FFFF);\
+} while (0)
+
+inline static grn_rc
+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;
+ 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(GRN_NEXT_ADDR(rnew), bs, size - sizeof(buffer_rec));
+ for (;;) {
+ if (!*lastp) {
+ rnew->step = 0;
+ rnew->jump = 0;
+ // smb_wmb();
+ *lastp = pos;
+ if (bt->size_in_buffer++ > 1) {
+ buffer_rec *rhead = BUFFER_REC_AT(b, bt->pos_in_buffer);
+ rhead->jump = pos;
+ if (!(bt->size_in_buffer & 1)) {
+ int n;
+ buffer_rec *r = BUFFER_REC_AT(b, rhead->step), *r2;
+ GET_NUM_BITS(bt->size_in_buffer, n);
+ while (n-- && (r->jump > 1)) {
+ r2 = BUFFER_REC_AT(b, r->jump);
+ if (BUFFER_REC_DELETED(r2)) { break; }
+ r = r2;
+ }
+ if (r != rnew) { set_jump_r(ctx, ii, b, r, last); }
+ }
+ }
+ break;
+ }
+ r_curr = BUFFER_REC_AT(b, *lastp);
+ 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 (id_curr.rid < id_post.rid ||
+ (id_curr.rid == id_post.rid && id_curr.sid < id_post.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;
+ lastp = &bt->pos_in_buffer;
+ continue;
+ }
+ id_post.rid = id_curr.rid;
+ id_post.sid = id_curr.sid;
+ if (u->rid < id_curr.rid || (u->rid == id_curr.rid && u->sid <= id_curr.sid)) {
+ uint16_t step = *lastp, jump = r_curr->jump;
+ if (u->rid == id_curr.rid) {
+ if (u->sid == 0) {
+ while (id_curr.rid == u->rid) {
+ BUFFER_REC_DEL(r_curr);
+ if (!(step = r_curr->step)) { break; }
+ r_curr = BUFFER_REC_AT(b, step);
+ 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;
+ }
+ }
+ } else if (u->sid == id_curr.sid) {
+ BUFFER_REC_DEL(r_curr);
+ step = r_curr->step;
+ }
+ }
+ rnew->step = step;
+ rnew->jump = check_jump(ctx, ii, b, rnew, jump) ? 0 : jump;
+ // smb_wmb();
+ *lastp = pos;
+ break;
+ }
+
+ if (reset) {
+ r_start = r_curr;
+ id_start.rid = id_curr.rid;
+ id_start.sid = id_curr.sid;
+ if (!(delta0 = u->rid - id_start.rid)) { delta0 = u->sid - id_start.sid; }
+ nhops = 0;
+ vhops = 1;
+ vdelta = delta0 >> 1;
+ } else {
+ 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;
+ }
+ if (nhops > vhops) {
+ set_jump_r(ctx, ii, b, r_start, *lastp);
+ } else {
+ nhops++;
+ }
+ }
+
+ last = *lastp;
+ lastp = &r_curr->step;
+ reset = 0;
+ {
+ uint16_t posj = r_curr->jump;
+ if (posj > 1) {
+ buffer_rec *rj = BUFFER_REC_AT(b, posj);
+ if (!BUFFER_REC_DELETED(rj)) {
+ docid idj;
+ 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);
+ } else {
+ idj.sid = 1;
+ }
+ if (idj.rid < u->rid || (idj.rid == u->rid && idj.sid < u->sid)) {
+ last = posj;
+ lastp = &rj->step;
+ } else {
+ reset = 1;
+ }
+ }
+ }
+ }
+ }
+ return ctx->rc;
+}
+
+/* array */
+
+inline static uint32_t *
+array_at(grn_ctx *ctx, grn_ii *ii, uint32_t id)
+{
+ byte *p = NULL;
+ uint32_t seg, pseg;
+ if (id > GRN_ID_MAX) { return NULL; }
+ seg = id >> W_ARRAY;
+ 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);
+}
+
+inline static uint32_t *
+array_get(grn_ctx *ctx, grn_ii *ii, uint32_t id)
+{
+ byte *p = NULL;
+ uint16_t seg;
+ uint32_t pseg;
+ if (id > GRN_ID_MAX) { return NULL; }
+ seg = id >> W_ARRAY;
+ 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; }
+ }
+ 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);
+}
+
+inline static void
+array_unref(grn_ii *ii, uint32_t id)
+{
+ GRN_IO_SEG_UNREF(ii->seg, ii->header->ainfo[id >> W_ARRAY]);
+}
+
+/* updspec */
+
+grn_ii_updspec *
+grn_ii_updspec_open(grn_ctx *ctx, uint32_t rid, uint32_t sid)
+{
+ grn_ii_updspec *u;
+ if (!(u = GRN_MALLOC(sizeof(grn_ii_updspec)))) { return NULL; }
+ u->rid = rid;
+ u->sid = sid;
+ u->weight = 0;
+ u->tf = 0;
+ u->atf = 0;
+ u->pos = NULL;
+ u->tail = NULL;
+ // u->vnodes = NULL;
+ return u;
+}
+
+#define GRN_II_MAX_TF 0x1ffff
+
+grn_rc
+grn_ii_updspec_add(grn_ctx *ctx, grn_ii_updspec *u, int pos, int32_t weight)
+{
+ struct _grn_ii_pos *p;
+ u->atf++;
+ if (u->tf >= GRN_II_MAX_TF) { return GRN_SUCCESS; }
+ if (!(p = GRN_MALLOC(sizeof(struct _grn_ii_pos)))) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ u->weight += weight;
+ p->pos = pos;
+ p->next = NULL;
+ if (u->tail) {
+ u->tail->next = p;
+ } else {
+ u->pos = p;
+ }
+ u->tail = p;
+ u->tf++;
+ return GRN_SUCCESS;
+}
+
+int
+grn_ii_updspec_cmp(grn_ii_updspec *a, grn_ii_updspec *b)
+{
+ struct _grn_ii_pos *pa, *pb;
+ if (a->rid != b->rid) { return a->rid - b->rid; }
+ if (a->sid != b->sid) { return a->sid - b->sid; }
+ if (a->weight != b->weight) { return a->weight - b->weight; }
+ if (a->tf != b->tf) { return a->tf - b->tf; }
+ for (pa = a->pos, pb = b->pos; pa && pb; pa = pa->next, pb = pb->next) {
+ if (pa->pos != pb->pos) { return pa->pos - pb->pos; }
+ }
+ if (pa) { return 1; }
+ if (pb) { return -1; }
+ return 0;
+}
+
+grn_rc
+grn_ii_updspec_close(grn_ctx *ctx, grn_ii_updspec *u)
+{
+ struct _grn_ii_pos *p = u->pos, *q;
+ while (p) {
+ q = p->next;
+ GRN_FREE(p);
+ p = q;
+ }
+ GRN_FREE(u);
+ return GRN_SUCCESS;
+}
+
+inline static uint8_t *
+encode_rec(grn_ctx *ctx, grn_ii *ii, grn_ii_updspec *u, unsigned int *size, int deletep)
+{
+ uint8_t *br, *p;
+ struct _grn_ii_pos *pp;
+ uint32_t lpos, tf, weight;
+ if (deletep) {
+ tf = 0;
+ weight = 0;
+ } else {
+ tf = u->tf;
+ weight = u->weight;
+ }
+ if (!(br = GRN_MALLOC((tf + 4) * 5))) {
+ return NULL;
+ }
+ p = br;
+ GRN_B_ENC(u->rid, p);
+ if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) {
+ GRN_B_ENC(u->sid, p);
+ } else {
+ u->sid = 1;
+ }
+ GRN_B_ENC(tf, p);
+ if ((ii->header->flags & GRN_OBJ_WITH_WEIGHT)) { GRN_B_ENC(weight, p); }
+ if ((ii->header->flags & GRN_OBJ_WITH_POSITION)) {
+ for (lpos = 0, pp = u->pos; pp && tf--; lpos = pp->pos, pp = pp->next) {
+ GRN_B_ENC(pp->pos - lpos, p);
+ }
+ }
+ while (((intptr_t)p & 0x03)) { *p++ = 0; }
+ *size = (unsigned int) ((p - br) + sizeof(buffer_rec));
+ return br;
+}
+
+typedef struct {
+ grn_ii *ii;
+ grn_hash *h;
+} lexicon_deletable_arg;
+
+#ifdef CASCADE_DELETE_LEXICON
+static int
+lexicon_deletable(grn_ctx *ctx, grn_obj *lexicon, grn_id tid, void *arg)
+{
+ uint32_t *a;
+ grn_hash *h = ((lexicon_deletable_arg *)arg)->h;
+ grn_ii *ii = ((lexicon_deletable_arg *)arg)->ii;
+ if (!h) { return 0; }
+ if ((a = array_at(ctx, ii, tid))) {
+ if (a[0]) {
+ array_unref(ii, tid);
+ return 0;
+ }
+ array_unref(ii, tid);
+ }
+ {
+ grn_ii_updspec **u;
+ if (!grn_hash_get(ctx, h, &tid, sizeof(grn_id), (void **) &u)) {
+ return (ERRP(ctx, GRN_ERROR)) ? 0 : 1;
+ }
+ if (!(*u)->tf || !(*u)->sid) { return 1; }
+ return 0;
+ }
+}
+#endif /* CASCADE_DELETE_LEXICON */
+
+inline static void
+lexicon_delete(grn_ctx *ctx, grn_ii *ii, uint32_t tid, grn_hash *h)
+{
+#ifdef CASCADE_DELETE_LEXICON
+ lexicon_deletable_arg arg = {ii, h};
+ grn_table_delete_optarg optarg = {0, lexicon_deletable, &arg};
+ _grn_table_delete_by_id(ctx, ii->lexicon, tid, &optarg);
+#endif /* CASCADE_DELETE_LEXICON */
+}
+
+typedef struct {
+ grn_id rid;
+ uint32_t sid;
+ uint32_t tf;
+ uint32_t weight;
+ uint32_t flags;
+} docinfo;
+
+#define GETNEXTC() do {\
+ if (sdf) {\
+ uint32_t dgap = *srp++;\
+ cid.rid += dgap;\
+ if (dgap) { cid.sid = 0; }\
+ snp += cid.tf;\
+ cid.tf = 1 + *stp++;\
+ if ((ii->header->flags & GRN_OBJ_WITH_WEIGHT)) { cid.weight = *sop++; }\
+ if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) {\
+ cid.sid += 1 + *ssp++;\
+ } else {\
+ cid.sid = 1;\
+ }\
+ sdf--;\
+ } else {\
+ cid.rid = 0;\
+ }\
+} while (0)
+
+#define PUTNEXT_(id) do {\
+ uint32_t dgap = id.rid - lid.rid;\
+ uint32_t sgap = (dgap ? id.sid : id.sid - lid.sid) - 1;\
+ *ridp++ = dgap;\
+ if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) {\
+ *sidp++ = sgap;\
+ }\
+ *tfp++ = id.tf - 1;\
+ if ((ii->header->flags & GRN_OBJ_WITH_WEIGHT)) { *weightp++ = id.weight; }\
+ lid.rid = id.rid;\
+ lid.sid = id.sid;\
+} while (0)
+
+#define PUTNEXTC() do {\
+ if (cid.rid) {\
+ if (cid.tf) {\
+ if (lid.rid > cid.rid || (lid.rid == cid.rid && lid.sid >= cid.sid)) {\
+ 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);\
+ if ((ii->header->flags & GRN_OBJ_WITH_POSITION)) {\
+ uint32_t i;\
+ for (i = 0; i < cid.tf; i++) {\
+ *posp++ = snp[i];\
+ spos += snp[i];\
+ }\
+ }\
+ } else {\
+ DEFINE_NAME(ii);\
+ CRIT(GRN_FILE_CORRUPT,\
+ "[ii][broken] invalid posting in chunk: <%.*s>: (%d,%d)",\
+ name_size, name, bt->tid, cid.rid);\
+ break;\
+ }\
+ }\
+ GETNEXTC();\
+} while (0)
+
+#define GETNEXTB() do {\
+ if (nextb) {\
+ uint32_t lrid = bid.rid, lsid = bid.sid;\
+ buffer_rec *br = BUFFER_REC_AT(sb, nextb);\
+ 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);\
+ } else {\
+ bid.sid = 1;\
+ }\
+ if (lrid > bid.rid || (lrid == bid.rid && lsid >= bid.sid)) {\
+ 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;\
+ } else {\
+ bid.rid = 0;\
+ }\
+} while (0)
+
+#define PUTNEXTB() do {\
+ if (bid.rid && bid.sid) {\
+ GRN_B_DEC(bid.tf, sbp);\
+ if (bid.tf > 0) {\
+ if (lid.rid > bid.rid || (lid.rid == bid.rid && lid.sid >= bid.sid)) {\
+ 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);\
+ }\
+ PUTNEXT_(bid);\
+ if ((ii->header->flags & GRN_OBJ_WITH_POSITION)) {\
+ while (bid.tf--) { GRN_B_DEC(*posp, sbp); spos += *posp++; }\
+ }\
+ }\
+ }\
+ GETNEXTB();\
+} while (0)
+
+#define MERGE_BC(cond) do {\
+ if (bid.rid) {\
+ 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();\
+ }\
+ }\
+ }\
+ } else {\
+ PUTNEXTB();\
+ if (ctx->rc != GRN_SUCCESS) { break; }\
+ }\
+ } else {\
+ if (cid.rid) {\
+ PUTNEXTC();\
+ if (ctx->rc != GRN_SUCCESS) { break; }\
+ } else {\
+ break;\
+ }\
+ }\
+} while (cond)
+
+typedef struct {
+ uint32_t segno;
+ uint32_t size;
+ uint32_t dgap;
+} chunk_info;
+
+static grn_rc
+chunk_flush(grn_ctx *ctx, grn_ii *ii, chunk_info *cinfo, uint8_t *enc, uint32_t encsize)
+{
+ uint8_t *dc;
+ uint32_t dcn;
+ grn_io_win dw;
+ if (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);
+ cinfo->segno = dcn;
+ cinfo->size = encsize;
+ } else {
+ chunk_free(ctx, ii, dcn, 0, encsize);
+ {
+ 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 ctx->rc;
+}
+
+static grn_rc
+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_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;
+ uint8_t *sbp = *sbpp;
+ datavec rdv[MAX_N_ELEMENTS + 1];
+ size_t bufsize = S_SEGMENT * ii->n_elements;
+ datavec_init(ctx, rdv, ii->n_elements, 0, 0);
+ if ((ii->header->flags & GRN_OBJ_WITH_POSITION)) {
+ rdv[ii->n_elements - 1].flags = ODD;
+ }
+ bufsize += grn_p_decv(ctx, scp, cinfo->size, rdv, ii->n_elements);
+ // (df in chunk list) = a[1] - sdf;
+ {
+ int j = 0;
+ sdf = rdv[j].data_size;
+ srp = rdv[j++].data;
+ if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) { ssp = rdv[j++].data; }
+ stp = rdv[j++].data;
+ if ((ii->header->flags & GRN_OBJ_WITH_WEIGHT)) { sop = rdv[j++].data; }
+ snn = rdv[j].data_size;
+ snp = rdv[j].data;
+ }
+ datavec_reset(ctx, dv, ii->n_elements, sdf + S_SEGMENT, bufsize);
+ if (ctx->rc == GRN_SUCCESS) {
+ {
+ int j = 0;
+ ridp = dv[j++].data;
+ if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) { sidp = dv[j++].data; }
+ tfp = dv[j++].data;
+ if ((ii->header->flags & GRN_OBJ_WITH_WEIGHT)) { weightp = dv[j++].data; }
+ posp = dv[j].data;
+ }
+ GETNEXTC();
+ MERGE_BC(bid.rid <= rid || cid.rid);
+ 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 {
+ 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;
+ uint32_t np = posp - dv[ii->n_elements - 1].data;
+ uint32_t f_s = (ndf < 3) ? 0 : USE_P_ENC;
+ uint32_t f_d = ((ndf < 16) || (ndf <= (lid.rid >> 8))) ? 0 : USE_P_ENC;
+ dv[j].data_size = ndf; dv[j++].flags = f_d;
+ if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) {
+ dv[j].data_size = ndf; dv[j++].flags = f_s;
+ }
+ dv[j].data_size = ndf; dv[j++].flags = f_s;
+ if ((ii->header->flags & GRN_OBJ_WITH_WEIGHT)) {
+ dv[j].data_size = ndf; dv[j++].flags = f_s;
+ }
+ if ((ii->header->flags & GRN_OBJ_WITH_POSITION)) {
+ uint32_t f_p = ((np < 32) || (np <= (spos >> 13))) ? 0 : USE_P_ENC;
+ dv[j].data_size = np; dv[j].flags = f_p|ODD;
+ }
+ if ((enc = GRN_MALLOC((ndf * 4 + np) * 2))) {
+ encsize = grn_p_encv(ctx, dv, ii->n_elements, enc);
+ chunk_flush(ctx, ii, cinfo, enc, encsize);
+ if (ctx->rc == GRN_SUCCESS) {
+ chunk_free(ctx, ii, segno, 0, size);
+ }
+ GRN_FREE(enc);
+ } else {
+ 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 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;
+ uint8_t *sbp = NULL, *dcp = dc;
+ datavec dv[MAX_N_ELEMENTS + 1];
+ datavec rdv[MAX_N_ELEMENTS + 1];
+ uint16_t n = db->header.nterms, nterms_void = 0;
+ size_t unitsize = (S_SEGMENT + sb->header.chunk_size / sb->header.nterms) * 2;
+ // size_t unitsize = (S_SEGMENT + sb->header.chunk_size) * 2 + (1<<24);
+ size_t totalsize = unitsize * ii->n_elements;
+ //todo : realloc
+ 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)) {
+ rdv[ii->n_elements - 1].flags = ODD;
+ }
+ for (bt = db->terms; n; n--, bt++) {
+ uint16_t nextb;
+ uint64_t spos = 0;
+ int32_t balance = 0;
+ uint32_t *ridp, *sidp = NULL, *tfp, *weightp = NULL, *posp, nchunks = 0;
+ uint32_t nvchunks = 0;
+ chunk_info *cinfo = NULL;
+ grn_id crid = GRN_ID_NIL;
+ docinfo cid = {0, 0, 0, 0, 0}, lid = {0, 0, 0, 0, 0}, bid = {0, 0};
+ uint32_t sdf = 0, snn = 0, ndf;
+ uint32_t *srp = NULL, *ssp = NULL, *stp = NULL, *sop = NULL, *snp = NULL;
+ if (!bt->tid) {
+ nterms_void++;
+ continue;
+ }
+ if (!bt->pos_in_buffer) {
+ GRN_ASSERT(!bt->size_in_buffer);
+ if (bt->size_in_chunk) {
+ grn_memcpy(dcp, sc + bt->pos_in_chunk, bt->size_in_chunk);
+ bt->pos_in_chunk = (uint32_t)(dcp - dc);
+ dcp += bt->size_in_chunk;
+ }
+ continue;
+ }
+ nextb = bt->pos_in_buffer;
+ GETNEXTB();
+ if (sc && bt->size_in_chunk) {
+ uint8_t *scp = sc + bt->pos_in_chunk;
+ uint8_t *sce = scp + bt->size_in_chunk;
+ size_t size = S_SEGMENT * ii->n_elements;
+ if ((bt->tid & CHUNK_SPLIT)) {
+ int i;
+ GRN_B_DEC(nchunks, scp);
+ if (!(cinfo = GRN_MALLOCN(chunk_info, nchunks + 1))) {
+ datavec_fin(ctx, dv);
+ datavec_fin(ctx, rdv);
+ {
+ 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);
+ GRN_B_DEC(cinfo[i].size, scp);
+ GRN_B_DEC(cinfo[i].dgap, scp);
+ crid += cinfo[i].dgap;
+ if (bid.rid <= crid) {
+ 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);
+ {
+ 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) {
+ nvchunks++;
+ } else {
+ crid -= cinfo[i].dgap;
+ cinfo[i + 1].dgap += cinfo[i].dgap;
+ }
+ }
+ }
+ if (sce > scp) {
+ size += grn_p_decv(ctx, scp, sce - scp, rdv, ii->n_elements);
+ {
+ int j = 0;
+ sdf = rdv[j].data_size;
+ srp = rdv[j++].data;
+ if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) { ssp = rdv[j++].data; }
+ stp = rdv[j++].data;
+ if ((ii->header->flags & GRN_OBJ_WITH_WEIGHT)) { sop = rdv[j++].data; }
+ snn = rdv[j].data_size;
+ snp = rdv[j].data;
+ }
+ 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);
+ {
+ 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;
+ }
+ }
+ }
+ {
+ int j = 0;
+ ridp = dv[j++].data;
+ if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) { sidp = dv[j++].data; }
+ tfp = dv[j++].data;
+ if ((ii->header->flags & GRN_OBJ_WITH_WEIGHT)) { weightp = dv[j++].data; }
+ posp = dv[j].data;
+ }
+ 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;
+ /*
+ {
+ grn_obj buf;
+ uint32_t rid, sid, tf, i, pos, *pp;
+ GRN_TEXT_INIT(&buf, 0);
+ rid = 0;
+ pp = dv[3].data;
+ for (i = 0; i < ndf; i++) {
+ GRN_BULK_REWIND(&buf);
+ rid += dv[0].data[i];
+ if (dv[0].data[i]) { sid = 0; }
+ sid += dv[1].data[i] + 1;
+ tf = dv[2].data[i] + 1;
+ pos = 0;
+ grn_text_itoa(ctx, &buf, rid);
+ GRN_TEXT_PUTC(ctx, &buf, ':');
+ grn_text_itoa(ctx, &buf, sid);
+ GRN_TEXT_PUTC(ctx, &buf, ':');
+ grn_text_itoa(ctx, &buf, tf);
+ GRN_TEXT_PUTC(ctx, &buf, ':');
+ while (tf--) {
+ pos += *pp++;
+ grn_text_itoa(ctx, &buf, pos);
+ if (tf) { GRN_TEXT_PUTC(ctx, &buf, ','); }
+ }
+ GRN_TEXT_PUTC(ctx, &buf, '\0');
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "Posting:%s", GRN_TEXT_VALUE(&buf));
+ }
+ GRN_OBJ_FIN(ctx, &buf);
+ }
+ */
+ {
+ grn_id tid = bt->tid & GRN_ID_MAX;
+ uint32_t *a = array_at(ctx, ii, tid);
+ if (!a) {
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "array_entry not found tid=%d", tid);
+ memset(bt, 0, sizeof(buffer_term));
+ nterms_void++;
+ } else {
+ if (!ndf && !nvchunks) {
+ a[0] = 0;
+ a[1] = 0;
+ lexicon_delete(ctx, ii, tid, h);
+ memset(bt, 0, sizeof(buffer_term));
+ nterms_void++;
+ } else if ((ii->header->flags & GRN_OBJ_WITH_SECTION)
+ && !nvchunks && ndf == 1 && lid.rid < 0x100000 &&
+ lid.sid < 0x800 && lid.tf == 1 && lid.weight == 0) {
+ a[0] = (lid.rid << 12) + (lid.sid << 1) + 1;
+ a[1] = (ii->header->flags & GRN_OBJ_WITH_POSITION) ? posp[-1] : 0;
+ memset(bt, 0, sizeof(buffer_term));
+ nterms_void++;
+ } else if (!(ii->header->flags & GRN_OBJ_WITH_SECTION)
+ && !nvchunks && ndf == 1 && lid.tf == 1 && lid.weight == 0) {
+ a[0] = (lid.rid << 1) + 1;
+ a[1] = (ii->header->flags & GRN_OBJ_WITH_POSITION) ? posp[-1] : 0;
+ memset(bt, 0, sizeof(buffer_term));
+ nterms_void++;
+ } else {
+ int j = 0;
+ uint8_t *dcp0;
+ uint32_t encsize;
+ uint32_t f_s = (ndf < 3) ? 0 : USE_P_ENC;
+ uint32_t f_d = ((ndf < 16) || (ndf <= (lid.rid >> 8))) ? 0 : USE_P_ENC;
+ dv[j].data_size = ndf; dv[j++].flags = f_d;
+ if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) {
+ dv[j].data_size = ndf; dv[j++].flags = f_s;
+ }
+ dv[j].data_size = ndf; dv[j++].flags = f_s;
+ if ((ii->header->flags & GRN_OBJ_WITH_WEIGHT)) {
+ dv[j].data_size = ndf; dv[j++].flags = f_s;
+ }
+ if ((ii->header->flags & GRN_OBJ_WITH_POSITION)) {
+ uint32_t np = posp - dv[ii->n_elements - 1].data;
+ uint32_t f_p = ((np < 32) || (np <= (spos >> 13))) ? 0 : USE_P_ENC;
+ dv[j].data_size = np; dv[j].flags = f_p|ODD;
+ }
+ dcp0 = dcp;
+ a[1] = (bt->size_in_chunk ? a[1] : 0) + (ndf - sdf) + balance;
+ if (nvchunks) {
+ int i;
+ GRN_B_ENC(nvchunks, dcp);
+ for (i = 0; i < nchunks; i++) {
+ if (cinfo[i].size) {
+ GRN_B_ENC(cinfo[i].segno, dcp);
+ GRN_B_ENC(cinfo[i].size, dcp);
+ GRN_B_ENC(cinfo[i].dgap, dcp);
+ }
+ }
+ }
+ encsize = grn_p_encv(ctx, dv, ii->n_elements, dcp);
+
+ 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 &&
+ (cinfo || (cinfo = GRN_MALLOCN(chunk_info, nchunks + 1))) &&
+ !chunk_flush(ctx, ii, &cinfo[nchunks], dcp, encsize)) {
+ int i;
+ cinfo[nchunks].dgap = lid.rid - crid;
+ nvchunks++;
+ dcp = dcp0;
+ GRN_B_ENC(nvchunks, dcp);
+ for (i = 0; i <= nchunks; i++) {
+ if (cinfo[i].size) {
+ GRN_B_ENC(cinfo[i].segno, dcp);
+ GRN_B_ENC(cinfo[i].size, dcp);
+ GRN_B_ENC(cinfo[i].dgap, dcp);
+ }
+ }
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "split (%d) encsize=%d", tid, encsize);
+ bt->tid |= CHUNK_SPLIT;
+ } else {
+ dcp += encsize;
+ if (!nvchunks) {
+ bt->tid &= ~CHUNK_SPLIT;
+ }
+ }
+ bt->pos_in_chunk = (uint32_t)(dcp0 - dc);
+ bt->size_in_chunk = (uint32_t)(dcp - dcp0);
+ bt->size_in_buffer = 0;
+ bt->pos_in_buffer = 0;
+ }
+ array_unref(ii, tid);
+ }
+ }
+ if (cinfo) { GRN_FREE(cinfo); }
+ }
+ datavec_fin(ctx, rdv);
+ datavec_fin(ctx, dv);
+ db->header.chunk_size = (uint32_t)(dcp - dc);
+ db->header.buffer_free =
+ S_SEGMENT - sizeof(buffer_header) - db->header.nterms * sizeof(buffer_term);
+ db->header.nterms_void = nterms_void;
+ return ctx->rc;
+}
+
+static void
+fake_map(grn_ctx *ctx, grn_io *io, grn_io_win *iw, void *addr, uint32_t seg, uint32_t size)
+{
+ iw->ctx = ctx;
+ iw->diff = 0;
+ iw->io = io;
+ iw->mode = grn_io_wronly;
+ iw->segment = ((seg) >> GRN_II_N_CHUNK_VARIATION);
+ iw->offset = (((seg) & ((1 << GRN_II_N_CHUNK_VARIATION) - 1)) << GRN_II_W_LEAST_CHUNK);
+ iw->size = size;
+ iw->cached = 0;
+ iw->addr = addr;
+}
+
+static grn_rc
+buffer_flush(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h)
+{
+ 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] == 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 == 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) == 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;
+ 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 > 0) {
+ chunk_new(ctx, ii, &dcn, actual_chunk_size);
+ }
+ 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);
+ 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 != 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;
+ }
+ } else {
+ GRN_FREE(dc);
+ if (actual_chunk_size) {
+ chunk_free(ctx, ii, dcn, 0, actual_chunk_size);
+ }
+ 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 != GRN_II_PSEG_NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
+ }
+ } else {
+ GRN_FREE(dc);
+ if (scn != GRN_II_PSEG_NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
+ }
+ } else {
+ GRN_FREE(dc);
+ {
+ 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 {
+ 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 {
+ 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);
+ }
+ return ctx->rc;
+}
+
+void
+grn_ii_buffer_check(grn_ctx *ctx, grn_ii *ii, uint32_t seg)
+{
+ grn_io_win sw;
+ buffer *sb;
+ uint8_t *sc = NULL;
+ uint32_t pseg, scn, nterms_with_corrupt_chunk = 0, nterm_with_chunk = 0;
+ uint32_t ndeleted_terms_with_value = 0;
+ buffer_term *bt;
+ uint8_t *sbp = NULL;
+ datavec rdv[MAX_N_ELEMENTS + 1];
+ uint16_t n;
+ int nterms_void = 0;
+ int size_in_buffer = 0;
+ grn_obj buf;
+ size_t lower_bound;
+ int64_t nloops = 0, nviolations = 0;
+ 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 == GRN_II_PSEG_NOT_ASSIGNED) {
+ GRN_OUTPUT_BOOL(GRN_FALSE);
+ return;
+ }
+ lower_bound =
+ (sb->header.buffer_free + sizeof(buffer_term) * sb->header.nterms)
+ / sizeof(buffer_rec);
+ datavec_init(ctx, rdv, ii->n_elements, 0, 0);
+ if ((ii->header->flags & GRN_OBJ_WITH_POSITION)) {
+ rdv[ii->n_elements - 1].flags = ODD;
+ }
+ GRN_OUTPUT_MAP_OPEN("BUFFER", -1);
+ GRN_OUTPUT_CSTR("buffer id");
+ GRN_OUTPUT_INT64(seg);
+ 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))) {
+ GRN_OUTPUT_CSTR("chunk size");
+ GRN_OUTPUT_INT64(sb->header.chunk_size);
+ } else {
+ GRN_OUTPUT_CSTR("unmappable chunk size");
+ GRN_OUTPUT_INT64(sb->header.chunk_size);
+ }
+ }
+ GRN_OUTPUT_CSTR("buffer term");
+ GRN_OUTPUT_ARRAY_OPEN("TERMS", sb->header.nterms);
+
+ GRN_OBJ_INIT(&buf, GRN_BULK, 0, ii->lexicon->header.domain);
+ for (bt = sb->terms, n = sb->header.nterms; n; n--, bt++) {
+ grn_id tid, tid_;
+ char key[GRN_TABLE_MAX_KEY_SIZE];
+ int key_size;
+ uint16_t nextb;
+ uint32_t nchunks = 0;
+ chunk_info *cinfo = NULL;
+ grn_id crid = GRN_ID_NIL;
+ docinfo bid = {0, 0};
+ uint32_t sdf = 0, snn = 0;
+ uint32_t *srp = NULL, *ssp = NULL, *stp = NULL, *sop = NULL, *snp = NULL;
+ if (!bt->tid && !bt->pos_in_buffer && !bt->size_in_buffer) {
+ nterms_void++;
+ continue;
+ }
+ 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);
+ tid_ = grn_table_get(ctx, ii->lexicon, key, key_size);
+ GRN_TEXT_SET(ctx, &buf, key, key_size);
+ GRN_OUTPUT_OBJ(&buf, NULL);
+ GRN_OUTPUT_INT64(bt->tid);
+ GRN_OUTPUT_INT64(tid_);
+ nextb = bt->pos_in_buffer;
+ size_in_buffer += bt->size_in_buffer;
+ if (tid != tid_ && (bt->size_in_buffer || bt->size_in_chunk)) {
+ ndeleted_terms_with_value++;
+ }
+ GETNEXTB();
+ GRN_OUTPUT_INT64(bt->size_in_buffer);
+ GRN_OUTPUT_INT64(bt->size_in_chunk);
+ if (sc && bt->size_in_chunk) {
+ uint8_t *scp = sc + bt->pos_in_chunk;
+ uint8_t *sce = scp + bt->size_in_chunk;
+ size_t size = S_SEGMENT * ii->n_elements;
+ if ((bt->tid & CHUNK_SPLIT)) {
+ int i;
+ GRN_B_DEC(nchunks, scp);
+ if (!(cinfo = GRN_MALLOCN(chunk_info, nchunks + 1))) {
+ datavec_fin(ctx, rdv);
+ GRN_OBJ_FIN(ctx, &buf);
+ return;
+ }
+ for (i = 0; i < nchunks; i++) {
+ GRN_B_DEC(cinfo[i].segno, scp);
+ GRN_B_DEC(cinfo[i].size, scp);
+ GRN_B_DEC(cinfo[i].dgap, scp);
+ crid += cinfo[i].dgap;
+ }
+ }
+ if (sce > scp) {
+ size += grn_p_decv(ctx, scp, sce - scp, rdv, ii->n_elements);
+ {
+ int j = 0;
+ sdf = rdv[j].data_size;
+ GRN_OUTPUT_INT64(sdf);
+ srp = rdv[j++].data;
+ if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) { ssp = rdv[j++].data; }
+ if (sdf != rdv[j].data_size) {
+ nterms_with_corrupt_chunk++;
+ }
+ stp = rdv[j++].data;
+ if ((ii->header->flags & GRN_OBJ_WITH_WEIGHT)) { sop = rdv[j++].data; }
+ GRN_OUTPUT_INT64(rdv[j].data_size);
+ snn = rdv[j].data_size;
+ snp = rdv[j].data;
+ }
+ nterm_with_chunk++;
+ }
+ }
+ {
+ uint16_t pos;
+ grn_id rid, sid, rid_ = 0, sid_ = 0;
+ uint8_t *p;
+ buffer_rec *r;
+ for (pos = bt->pos_in_buffer; pos; pos = r->step) {
+ if (pos < lower_bound) {
+ nviolations++;
+ }
+ r = BUFFER_REC_AT(sb, pos);
+ 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;
+ }
+ if (rid < rid_ || (rid == rid_ && sid < sid_)) {
+ nloops++;
+ }
+ rid_ = rid;
+ sid_ = sid;
+ }
+ }
+ GRN_OUTPUT_ARRAY_CLOSE();
+ if (cinfo) { GRN_FREE(cinfo); }
+ }
+ GRN_OBJ_FIN(ctx, &buf);
+
+ GRN_OUTPUT_ARRAY_CLOSE();
+ GRN_OUTPUT_CSTR("buffer free");
+ GRN_OUTPUT_INT64(sb->header.buffer_free);
+ GRN_OUTPUT_CSTR("size in buffer");
+ GRN_OUTPUT_INT64(size_in_buffer);
+ GRN_OUTPUT_CSTR("nterms");
+ GRN_OUTPUT_INT64(sb->header.nterms);
+ if (nterms_void != sb->header.nterms_void) {
+ GRN_OUTPUT_CSTR("nterms void gap");
+ GRN_OUTPUT_INT64(nterms_void - sb->header.nterms_void);
+ }
+ GRN_OUTPUT_CSTR("nterms with chunk");
+ GRN_OUTPUT_INT64(nterm_with_chunk);
+ if (nterms_with_corrupt_chunk) {
+ GRN_OUTPUT_CSTR("nterms with corrupt chunk");
+ GRN_OUTPUT_INT64(nterms_with_corrupt_chunk);
+ }
+ if (ndeleted_terms_with_value) {
+ GRN_OUTPUT_CSTR("number of deleted terms with value");
+ GRN_OUTPUT_INT64(ndeleted_terms_with_value);
+ }
+ if (nloops) {
+ GRN_OUTPUT_CSTR("number of loops");
+ GRN_OUTPUT_INT64(nloops);
+ }
+ if (nviolations) {
+ GRN_OUTPUT_CSTR("number of violations");
+ GRN_OUTPUT_INT64(nviolations);
+ }
+ GRN_OUTPUT_MAP_CLOSE();
+ datavec_fin(ctx, rdv);
+ if (sc) { grn_io_win_unmap(&sw); }
+ buffer_close(ctx, ii, pseg);
+}
+
+typedef struct {
+ buffer_term *bt;
+ const char *key;
+ uint32_t key_size;
+} term_sort;
+
+static int
+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) {
+ r = memcmp(x->key, y->key, y->key_size);
+ return r ? r : x->key_size - y->key_size;
+ } else {
+ r = memcmp(x->key, y->key, x->key_size);
+ return r ? r : x->key_size - y->key_size;
+ }
+}
+
+static grn_rc
+term_split(grn_ctx *ctx, grn_obj *lexicon, buffer *sb, buffer *db0, buffer *db1)
+{
+ uint16_t i, n, *nt;
+ buffer_term *bt;
+ uint32_t s, th = (sb->header.chunk_size + sb->header.nterms) >> 1;
+ term_sort *ts = GRN_MALLOC(sb->header.nterms * sizeof(term_sort));
+ if (!ts) { return GRN_NO_MEMORY_AVAILABLE; }
+ for (i = 0, n = sb->header.nterms, bt = sb->terms; n; bt++, n--) {
+ if (bt->tid) {
+ grn_id tid = bt->tid & GRN_ID_MAX;
+ ts[i].key = _grn_table_key(ctx, lexicon, tid, &ts[i].key_size);
+ ts[i].bt = bt;
+ i++;
+ }
+ }
+ qsort(ts, i, sizeof(term_sort), term_compar);
+ memset(db0, 0, S_SEGMENT);
+ bt = db0->terms;
+ nt = &db0->header.nterms;
+ for (s = 0; n + 1 < i && s <= th; n++, bt++) {
+ grn_memcpy(bt, ts[n].bt, sizeof(buffer_term));
+ (*nt)++;
+ s += ts[n].bt->size_in_chunk + 1;
+ }
+ memset(db1, 0, S_SEGMENT);
+ bt = db1->terms;
+ nt = &db1->header.nterms;
+ for (; n < i; n++, bt++) {
+ grn_memcpy(bt, ts[n].bt, sizeof(buffer_term));
+ (*nt)++;
+ }
+ GRN_FREE(ts);
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "d0=%d d1=%d",
+ db0->header.nterms, db1->header.nterms);
+ return GRN_SUCCESS;
+}
+
+static void
+array_update(grn_ctx *ctx, grn_ii *ii, uint32_t dls, buffer *db)
+{
+ uint16_t n;
+ buffer_term *bt;
+ uint32_t *a, pos = SEG2POS(dls, sizeof(buffer_header));
+ for (n = db->header.nterms, bt = db->terms; n; n--, bt++) {
+ if (bt->tid) {
+ grn_id tid = bt->tid & GRN_ID_MAX;
+ if ((a = array_at(ctx, ii, tid))) {
+ a[0] = pos;
+ array_unref(ii, tid);
+ } else {
+ GRN_LOG(ctx, GRN_LOG_WARNING, "array_at failed (%d)", tid);
+ }
+ }
+ pos += sizeof(buffer_term) >> 2;
+ }
+}
+
+static grn_rc
+buffer_split(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h)
+{
+ grn_io_win sw, dw0, dw1;
+ buffer *sb, *db0 = NULL, *db1 = NULL;
+ uint8_t *sc = NULL, *dc0, *dc1;
+ 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 == 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);
+ if (db1) {
+ uint32_t actual_db0_chunk_size = 0;
+ uint32_t actual_db1_chunk_size = 0;
+ 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) == 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);
+ 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 > 0) {
+ chunk_new(ctx, ii, &dcn0, actual_db0_chunk_size);
+ }
+ 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);
+ 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 > 0) {
+ chunk_new(ctx, ii, &dcn1, actual_db1_chunk_size);
+ }
+ 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);
+ array_update(ctx, ii, dls1, db1);
+ 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 != 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;
+ }
+ } else {
+ if (actual_db1_chunk_size) {
+ chunk_free(ctx, ii, dcn1, 0, actual_db1_chunk_size);
+ }
+ if (actual_db0_chunk_size) {
+ chunk_free(ctx, ii, dcn0, 0, actual_db0_chunk_size);
+ }
+ GRN_FREE(dc1);
+ 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 != 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 != 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);
+ GRN_FREE(dc0);
+ 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 != GRN_II_PSEG_NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
+ }
+ } else {
+ GRN_FREE(dc1);
+ GRN_FREE(dc0);
+ if (scn != GRN_II_PSEG_NOT_ASSIGNED) { grn_io_win_unmap(&sw); }
+ }
+ } else {
+ GRN_FREE(dc1);
+ GRN_FREE(dc0);
+ {
+ 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);
+ {
+ 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 {
+ 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 {
+ 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 {
+ 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);
+ }
+ return ctx->rc;
+}
+
+#define SCALE_FACTOR 2048
+#define MAX_NTERMS 8192
+#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 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)
+{
+ uint32_t *a;
+
+ a = array_at(ctx, ii, tid);
+ if (!a) {
+ return;
+ }
+
+ 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 {
+ 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; }
+ }
+ }
+
+ 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);
+ }
+ } 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;
+ }
+ buffer_new_find_segment(ctx, ii, size, tid, h, b, lseg, pseg);
+ }
+ }
+ 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;
+ }
+ }
+ } 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 == GRN_II_PSEG_NOT_ASSIGNED) {
+ if (buffer_segment_new(ctx, ii, &lseg) ||
+ (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 = 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_DEBUG, "inconsistent buffer(%d)", lseg);
+ b->header.nterms_void = 0;
+ b->header.nterms++;
+ b->header.buffer_free -= size + sizeof(buffer_term);
+ } else {
+ b->header.nterms_void--;
+ b->header.buffer_free -= size;
+ }
+ } else {
+ offset = b->header.nterms++;
+ b->header.buffer_free -= size + sizeof(buffer_term);
+ }
+ *pos = SEG2POS(lseg, (sizeof(buffer_header) + sizeof(buffer_term) * offset));
+ *bt = &b->terms[offset];
+ *br = (buffer_rec *)(((byte *)&b->terms[b->header.nterms]) + b->header.buffer_free);
+ *bp = b;
+ return pseg;
+}
+
+/* ii */
+
+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_table_flags lflags;
+ grn_encoding encoding;
+ grn_obj *tokenizer;
+ /*
+ for (i = 0; i < 32; i++) {
+ new_histogram[i] = 0;
+ free_histogram[i] = 0;
+ }
+ */
+ if (grn_table_get_info(ctx, lexicon, &lflags, &encoding, &tokenizer,
+ NULL, NULL)) {
+ return NULL;
+ }
+ if (path && strlen(path) + 6 >= PATH_MAX) { return NULL; }
+
+ 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, max_n_chunks, grn_io_auto,
+ GRN_IO_EXPIRE_SEGMENT);
+ } else {
+ chunk = grn_io_create(ctx, NULL, 0, S_CHUNK, max_n_chunks, grn_io_auto, 0);
+ }
+ if (!chunk) {
+ grn_io_close(ctx, seg);
+ grn_io_remove(ctx, path);
+ return NULL;
+ }
+ 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] = 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] = GRN_II_PSEG_NOT_ASSIGNED;
+ header->garbages[i] = GRN_II_PSEG_NOT_ASSIGNED;
+ }
+ header->flags = flags;
+ ii->seg = seg;
+ ii->chunk = chunk;
+ ii->lexicon = lexicon;
+ ii->lflags = lflags;
+ ii->encoding = encoding;
+ ii->header = header;
+ ii->n_elements = 2;
+ if ((flags & GRN_OBJ_WITH_SECTION)) { ii->n_elements++; }
+ if ((flags & GRN_OBJ_WITH_WEIGHT)) { ii->n_elements++; }
+ if ((flags & GRN_OBJ_WITH_POSITION)) { ii->n_elements++; }
+ return ii;
+}
+
+grn_ii *
+grn_ii_create(grn_ctx *ctx, const char *path, grn_obj *lexicon, uint32_t flags)
+{
+ grn_ii *ii = NULL;
+ if (!(ii = GRN_MALLOCN(grn_ii, 1))) {
+ return NULL;
+ }
+ GRN_DB_OBJ_SET_TYPE(ii, GRN_COLUMN_INDEX);
+ if (!_grn_ii_create(ctx, ii, path, lexicon, flags)) {
+ GRN_FREE(ii);
+ return NULL;
+ }
+ return ii;
+}
+
+grn_rc
+grn_ii_remove(grn_ctx *ctx, const char *path)
+{
+ grn_rc rc;
+ char buffer[PATH_MAX];
+ if (!path || strlen(path) > PATH_MAX - 4) { return GRN_INVALID_ARGUMENT; }
+ if ((rc = grn_io_remove(ctx, path))) { goto exit; }
+ grn_snprintf(buffer, PATH_MAX, PATH_MAX,
+ "%-.256s.c", path);
+ rc = grn_io_remove(ctx, buffer);
+exit :
+ return rc;
+}
+
+grn_rc
+grn_ii_truncate(grn_ctx *ctx, grn_ii *ii)
+{
+ grn_rc rc;
+ const char *io_segpath, *io_chunkpath;
+ char *segpath, *chunkpath = NULL;
+ grn_obj *lexicon;
+ uint32_t flags;
+ if ((io_segpath = grn_io_path(ii->seg)) && *io_segpath != '\0') {
+ if (!(segpath = GRN_STRDUP(io_segpath))) {
+ ERR(GRN_NO_MEMORY_AVAILABLE, "cannot duplicate path: <%-.256s>", io_segpath);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ if ((io_chunkpath = grn_io_path(ii->chunk)) && *io_chunkpath != '\0') {
+ if (!(chunkpath = GRN_STRDUP(io_chunkpath))) {
+ ERR(GRN_NO_MEMORY_AVAILABLE, "cannot duplicate path: <%-.256s>", io_chunkpath);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ } else {
+ chunkpath = NULL;
+ }
+ } else {
+ segpath = NULL;
+ }
+ lexicon = ii->lexicon;
+ flags = ii->header->flags;
+ if ((rc = grn_io_close(ctx, ii->seg))) { goto exit; }
+ if ((rc = grn_io_close(ctx, ii->chunk))) { goto exit; }
+ ii->seg = NULL;
+ ii->chunk = NULL;
+ if (segpath && (rc = grn_io_remove(ctx, segpath))) { goto exit; }
+ if (chunkpath && (rc = grn_io_remove(ctx, chunkpath))) { goto exit; }
+ if (!_grn_ii_create(ctx, ii, segpath, lexicon, flags)) {
+ rc = GRN_UNKNOWN_ERROR;
+ }
+exit:
+ if (segpath) { GRN_FREE(segpath); }
+ if (chunkpath) { GRN_FREE(chunkpath); }
+ return rc;
+}
+
+grn_ii *
+grn_ii_open(grn_ctx *ctx, const char *path, grn_obj *lexicon)
+{
+ grn_io *seg, *chunk;
+ grn_ii *ii;
+ char path2[PATH_MAX];
+ struct grn_ii_header *header;
+ uint32_t io_type;
+ grn_table_flags lflags;
+ grn_encoding encoding;
+ grn_obj *tokenizer;
+ if (grn_table_get_info(ctx, lexicon, &lflags, &encoding, &tokenizer,
+ NULL, NULL)) {
+ return NULL;
+ }
+ if (strlen(path) + 6 >= PATH_MAX) { return NULL; }
+ grn_strcpy(path2, PATH_MAX, path);
+ grn_strcat(path2, PATH_MAX, ".c");
+ seg = grn_io_open(ctx, path, grn_io_auto);
+ if (!seg) { return NULL; }
+ chunk = grn_io_open(ctx, path2, grn_io_auto);
+ if (!chunk) {
+ grn_io_close(ctx, seg);
+ return NULL;
+ }
+ header = grn_io_header(seg);
+ 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_MALLOCN(grn_ii, 1))) {
+ grn_io_close(ctx, seg);
+ grn_io_close(ctx, chunk);
+ return NULL;
+ }
+ GRN_DB_OBJ_SET_TYPE(ii, GRN_COLUMN_INDEX);
+ ii->seg = seg;
+ ii->chunk = chunk;
+ ii->lexicon = lexicon;
+ ii->lflags = lflags;
+ ii->encoding = encoding;
+ ii->header = header;
+ ii->n_elements = 2;
+ if ((header->flags & GRN_OBJ_WITH_SECTION)) { ii->n_elements++; }
+ if ((header->flags & GRN_OBJ_WITH_WEIGHT)) { ii->n_elements++; }
+ if ((header->flags & GRN_OBJ_WITH_POSITION)) { ii->n_elements++; }
+ return ii;
+}
+
+grn_rc
+grn_ii_close(grn_ctx *ctx, grn_ii *ii)
+{
+ grn_rc rc;
+ 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_FREE(ii);
+ /*
+ {
+ int i;
+ for (i = 0; i < 32; i++) {
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "new[%d]=%d free[%d]=%d",
+ i, new_histogram[i],
+ i, free_histogram[i]);
+ }
+ }
+ */
+ return rc;
+}
+
+grn_rc
+grn_ii_info(grn_ctx *ctx, grn_ii *ii, uint64_t *seg_size, uint64_t *chunk_size)
+{
+ grn_rc rc;
+
+ if (seg_size) {
+ if ((rc = grn_io_size(ctx, ii->seg, seg_size))) {
+ return rc;
+ }
+ }
+
+ if (chunk_size) {
+ if ((rc = grn_io_size(ctx, ii->chunk, chunk_size))) {
+ return rc;
+ }
+ }
+
+ 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)
+{
+ /*
+ grn_io_expire(ctx, ii->seg, 128, 1000000);
+ */
+ grn_io_expire(ctx, ii->chunk, 0, 1000000);
+}
+
+grn_rc
+grn_ii_flush(grn_ctx *ctx, grn_ii *ii)
+{
+ grn_rc rc;
+
+ rc = grn_io_flush(ctx, ii->seg);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_io_flush(ctx, ii->chunk);
+ }
+
+ 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)
+{
+ buffer *b;
+ uint8_t *bs;
+ buffer_rec *br = NULL;
+ buffer_term *bt;
+ uint32_t pseg = 0, pos = 0, size, *a;
+ 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))) {
+ 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))) {
+ 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)) == 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) {
+ int bfb = b->header.buffer_free;
+ 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(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);
+ 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;
+ }
+ 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);
+ continue;
+ }
+ 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]);
+ {
+ 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",
+ 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);
+ /* todo: direct merge */
+ goto exit;
+ }
+ }
+ b->header.buffer_free -= size;
+ br = (buffer_rec *)(((byte *)&b->terms[b->header.nterms])
+ + b->header.buffer_free);
+ } else {
+ grn_ii_updspec u2;
+ uint32_t size2 = 0, v = a[0];
+ struct _grn_ii_pos pos2;
+ pos2.pos = a[1];
+ pos2.next = NULL;
+ u2.pos = &pos2;
+ if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) {
+ u2.rid = BIT31_12(v);
+ u2.sid = BIT11_01(v);
+ } else {
+ u2.rid = v >> 1;
+ u2.sid = 1;
+ }
+ u2.tf = 1;
+ u2.weight = 0;
+ if (u2.rid != u->rid || u2.sid != u->sid) {
+ uint8_t *bs2 = encode_rec(ctx, ii, &u2, &size2, 0);
+ if (!bs2) {
+ 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 == 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;
+ bt->size_in_chunk = 0;
+ bt->pos_in_chunk = 0;
+ bt->size_in_buffer = 0;
+ bt->pos_in_buffer = 0;
+ 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);
+ GRN_FREE(bs2);
+ }
+ }
+ }
+ break;
+ }
+ if (!br) {
+ if (u->tf == 1 && u->weight == 0) {
+ if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) {
+ if (u->rid < 0x100000 && u->sid < 0x800) {
+ a[0] = (u->rid << 12) + (u->sid << 1) + 1;
+ a[1] = u->pos->pos;
+ goto exit;
+ }
+ } else {
+ a[0] = (u->rid << 1) + 1;
+ a[1] = u->pos->pos;
+ goto exit;
+ }
+ }
+ pseg = buffer_new(ctx, ii, size, &pos, &bt, &br, &b, tid, h);
+ 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;
+ }
+ 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);
+ {
+ 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 ctx->rc;
+}
+
+grn_rc
+grn_ii_delete_one(grn_ctx *ctx, grn_ii *ii, grn_id tid, grn_ii_updspec *u, grn_hash *h)
+{
+ buffer *b;
+ uint8_t *bs = NULL;
+ buffer_rec *br;
+ buffer_term *bt;
+ uint32_t pseg, size, *a;
+ 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) {
+ if ((ii->header->flags & GRN_OBJ_WITH_SECTION)) {
+ uint32_t rid = BIT31_12(a[0]);
+ uint32_t sid = BIT11_01(a[0]);
+ if (u->rid == rid && (!u->sid || u->sid == sid)) {
+ a[0] = 0;
+ lexicon_delete(ctx, ii, tid, h);
+ }
+ } else {
+ uint32_t rid = a[0] >> 1;
+ if (u->rid == rid) {
+ a[0] = 0;
+ lexicon_delete(ctx, ii, tid, h);
+ }
+ }
+ goto exit;
+ }
+ if (!(bs = encode_rec(ctx, ii, u, &size, 1))) {
+ 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)) == 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]));
+ buffer_close(ctx, ii, pseg);
+ 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);
+ continue;
+ }
+ 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]));
+ if (b->header.buffer_free < size) {
+ 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;
+ }
+ }
+
+ b->header.buffer_free -= size;
+ br = (buffer_rec *)(((byte *)&b->terms[b->header.nterms]) + b->header.buffer_free);
+ 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 ctx->rc;
+}
+
+#define CHUNK_USED 1
+#define BUFFER_USED 2
+#define SOLE_DOC_USED 4
+#define SOLE_POS_USED 8
+
+struct _grn_ii_cursor {
+ grn_db_obj obj;
+ grn_ctx *ctx;
+ grn_ii *ii;
+ grn_id id;
+ grn_posting *post;
+
+ grn_id min; /* Minimum record ID */
+ grn_id max;
+ grn_posting pc;
+ grn_posting pb;
+
+ uint32_t cdf; /* Document frequency */
+ uint32_t *cdp;
+ 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;
+
+ int nelements;
+ uint32_t nchunks;
+ uint32_t curr_chunk;
+ chunk_info *cinfo;
+ grn_io_win iw;
+ uint8_t *cp;
+ uint8_t *cpe;
+ datavec rdv[MAX_N_ELEMENTS + 1];
+
+ struct grn_ii_buffer *buf;
+ uint16_t stat;
+ uint16_t nextb;
+ uint32_t buffer_pseg;
+ int flags;
+ uint32_t *ppseg;
+
+ int weight;
+
+ uint32_t prev_chunk_rid;
+};
+
+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 GRN_FALSE; }
+ }
+ return GRN_TRUE;
+ }
+ return GRN_FALSE;
+}
+
+static int
+chunk_is_reused(grn_ctx *ctx, grn_ii *ii, grn_ii_cursor *c, uint32_t offset, uint32_t size)
+{
+ if (*c->ppseg != c->buffer_pseg) {
+ uint32_t i, m, gseg;
+ if (size > S_CHUNK) { return 1; }
+ if (size > (1 << GRN_II_W_LEAST_CHUNK)) {
+ int es = size - 1;
+ GRN_BIT_SCAN_REV(es, m);
+ m++;
+ } else {
+ m = GRN_II_W_LEAST_CHUNK;
+ }
+ gseg = ii->header->garbages[m - GRN_II_W_LEAST_CHUNK];
+ 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);
+ if (!ginfo) { break; }
+ for (i = 0; i < ginfo->nrecs; i++) {
+ if (ginfo->recs[i] == offset) {
+ grn_io_win_unmap(&iw);
+ return 0;
+ }
+ }
+ gseg = ginfo->next;
+ grn_io_win_unmap(&iw);
+ }
+ return 1;
+ }
+ return 0;
+}
+
+#define GRN_II_CURSOR_CMP(c1,c2) \
+ (((c1)->post->rid > (c2)->post->rid) || \
+ (((c1)->post->rid == (c2)->post->rid) && \
+ (((c1)->post->sid > (c2)->post->sid) || \
+ (((c1)->post->sid == (c2)->post->sid) && \
+ ((c1)->post->pos > (c2)->post->pos)))))
+
+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 *c = NULL;
+ uint32_t pos, *a;
+ if (!(a = array_at(ctx, ii, tid))) { return NULL; }
+ for (;;) {
+ c = NULL;
+ if (!(pos = a[0])) { goto exit; }
+ if (!(c = GRN_MALLOC(sizeof(grn_ii_cursor)))) { goto exit; }
+ memset(c, 0, sizeof(grn_ii_cursor));
+ c->ctx = ctx;
+ c->ii = ii;
+ c->id = tid;
+ c->min = min;
+ 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)) {
+ c->pb.rid = BIT31_12(pos);
+ c->pb.sid = BIT11_01(pos);
+ } else {
+ c->pb.rid = pos >> 1;
+ c->pb.sid = 1;
+ }
+ c->pb.tf = 1;
+ c->pb.weight = 0;
+ c->pb.pos = a[1];
+ } else {
+ uint32_t chunk;
+ buffer_term *bt;
+ 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) != 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);
+ GRN_FREE(c);
+ c = NULL;
+ goto exit;
+ }
+ if (buffer_is_reused(ctx, ii, c)) {
+ grn_ii_cursor_close(ctx, c);
+ continue;
+ }
+ c->cpe = c->cp + bt->size_in_chunk;
+ if ((bt->tid & CHUNK_SPLIT)) {
+ int i;
+ grn_id crid;
+ GRN_B_DEC(c->nchunks, c->cp);
+ if (chunk_is_reused(ctx, ii, c, chunk, c->buf->header.chunk_size)) {
+ grn_ii_cursor_close(ctx, c);
+ continue;
+ }
+ if (!(c->cinfo = GRN_MALLOCN(chunk_info, c->nchunks))) {
+ buffer_close(ctx, ii, c->buffer_pseg);
+ grn_io_win_unmap(&c->iw);
+ GRN_FREE(c);
+ c = NULL;
+ goto exit;
+ }
+ for (i = 0, crid = GRN_ID_NIL; i < c->nchunks; i++) {
+ GRN_B_DEC(c->cinfo[i].segno, c->cp);
+ 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->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);
+ continue;
+ }
+ }
+ if ((ii->header->flags & GRN_OBJ_WITH_POSITION)) {
+ c->rdv[ii->n_elements - 1].flags = ODD;
+ }
+ }
+ c->nextb = bt->pos_in_buffer;
+ c->stat = CHUNK_USED|BUFFER_USED;
+ }
+ if (pos == a[0]) { break; }
+ grn_ii_cursor_close(ctx, c);
+ }
+exit :
+ array_unref(ii, tid);
+ return c;
+}
+
+static inline void
+grn_ii_cursor_set_min(grn_ctx *ctx, grn_ii_cursor *c, grn_id min)
+{
+ if (c->min >= min) {
+ return;
+ }
+
+ if (grn_ii_cursor_set_min_enable) {
+ grn_id old_min = c->min;
+ c->min = min;
+ 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;
+ } else {
+ rid -= c->cinfo[i].dgap;
+ break;
+ }
+ }
+ 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(%-.256s->%-.256s)",
+ c,
+ old_min, min,
+ old_chunk, c->curr_chunk,
+ old_chunk_used ? "true" : "false",
+ (c->stat & CHUNK_USED) ? "true" : "false");
+ }
+ }
+ }
+}
+
+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) {
+ 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_DEBUG, "posting(%d):%-.256s", 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) {
+ 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 = GRN_ID_NIL;
+ 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))) {
+ 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,
+ "[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 = GRN_ID_NIL;
+ 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;
+ }
+ if ((c->ii->header->flags & GRN_OBJ_WITH_POSITION)) {
+ c->cpp = c->rdv[j].data;
+ }
+ }
+ 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 = GRN_ID_NIL;
+ }
+ }
+ break;
+ }
+ }
+ if (c->stat & BUFFER_USED) {
+ for (;;) {
+ 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_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 = 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);
+ } else {
+ c->pb.sid = 1;
+ }
+ if (lrid > c->pb.rid || (lrid == c->pb.rid && lsid >= c->pb.sid)) {
+ 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 && !BUFFER_REC_DELETED(br)) {
+ buffer_rec *jump_br = BUFFER_REC_AT(c->buf, br->jump);
+ 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;
+ }
+ continue;
+ }
+ 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;
+ }
+ break;
+ }
+ }
+ if (c->pb.rid) {
+ if (c->pc.rid) {
+ if (c->pc.rid < c->pb.rid) {
+ c->stat = CHUNK_USED;
+ 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 (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 (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 (include_garbage || (c->pb.tf)) {
+ c->post = &c->pb;
+ break;
+ }
+ }
+ } else {
+ c->stat = CHUNK_USED;
+ }
+ }
+ }
+ } else {
+ c->stat = BUFFER_USED;
+ if (include_garbage || (c->pb.tf && c->pb.sid)) {
+ c->post = &c->pb;
+ break;
+ }
+ }
+ } else {
+ if (c->pc.rid) {
+ c->stat = CHUNK_USED;
+ if (include_garbage || (c->pc.tf && c->pc.sid)) {
+ 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;
+ if (c->post->rid < c->min) {
+ c->post = NULL;
+ return NULL;
+ }
+ }
+ }
+ return c->post;
+}
+
+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;
+ if ((c->ii->header->flags & GRN_OBJ_WITH_POSITION)) {
+ if (c->nelements == c->ii->n_elements) {
+ if (c->buf) {
+ if (c->post == &c->pc) {
+ if (c->pc.rest) {
+ c->pc.rest--;
+ c->pc.pos += *c->cpp++;
+ } else {
+ return NULL;
+ }
+ } else if (c->post == &c->pb) {
+ if (buffer_is_reused(ctx, c->ii, c)) {
+ 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--;
+ GRN_B_DEC(gap, c->bp);
+ c->pb.pos += gap;
+ } else {
+ return NULL;
+ }
+ } else {
+ return NULL;
+ }
+ } else {
+ if (c->stat & SOLE_POS_USED) {
+ return NULL;
+ } else {
+ c->stat |= SOLE_POS_USED;
+ }
+ }
+ }
+ } else {
+ if (c->stat & SOLE_POS_USED) {
+ return NULL;
+ } else {
+ c->stat |= SOLE_POS_USED;
+ }
+ }
+ return c->post;
+}
+
+grn_rc
+grn_ii_cursor_close(grn_ctx *ctx, grn_ii_cursor *c)
+{
+ if (!c) { return GRN_INVALID_ARGUMENT; }
+ datavec_fin(ctx, c->rdv);
+ if (c->cinfo) { GRN_FREE(c->cinfo); }
+ if (c->buf) { buffer_close(ctx, c->ii, c->buffer_pseg); }
+ if (c->cp) { grn_io_win_unmap(&c->iw); }
+ GRN_FREE(c);
+ return GRN_SUCCESS;
+}
+
+uint32_t
+grn_ii_get_chunksize(grn_ctx *ctx, grn_ii *ii, grn_id tid)
+{
+ uint32_t res, pos, *a;
+ a = array_at(ctx, ii, tid);
+ if (!a) { return 0; }
+ if ((pos = a[0])) {
+ if (pos & 1) {
+ res = 0;
+ } else {
+ buffer *buf;
+ uint32_t pseg;
+ buffer_term *bt;
+ if ((pseg = buffer_open(ctx, ii, pos, &bt, &buf)) == GRN_II_PSEG_NOT_ASSIGNED) {
+ res = 0;
+ } else {
+ res = bt->size_in_chunk;
+ buffer_close(ctx, ii, pseg);
+ }
+ }
+ } else {
+ res = 0;
+ }
+ array_unref(ii, tid);
+ return res;
+}
+
+uint32_t
+grn_ii_estimate_size(grn_ctx *ctx, grn_ii *ii, grn_id tid)
+{
+ uint32_t res, pos, *a;
+ a = array_at(ctx, ii, tid);
+ if (!a) { return 0; }
+ if ((pos = a[0])) {
+ if (pos & 1) {
+ res = 1;
+ } else {
+ buffer *buf;
+ uint32_t pseg;
+ buffer_term *bt;
+ 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;
+ buffer_close(ctx, ii, pseg);
+ }
+ }
+ } else {
+ res = 0;
+ }
+ array_unref(ii, tid);
+ return res;
+}
+
+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 *size_in_chunk, unsigned int *pos_in_chunk,
+ unsigned int *size_in_buffer, unsigned int *pos_in_buffer)
+{
+ buffer *b;
+ buffer_term *bt;
+ uint32_t pseg, *ap;
+ ERRCLR(NULL);
+ ap = array_at(ctx, ii, tid);
+ if (!ap) { return 0; }
+ a[0] = *ap;
+ 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)) == GRN_II_PSEG_NOT_ASSIGNED) { return 3; }
+ *chunk = b->header.chunk;
+ *chunk_size = b->header.chunk_size;
+ *buffer_free = b->header.buffer_free;
+ *nterms = b->header.nterms;
+ *bt_tid = bt->tid;
+ *size_in_chunk = bt->size_in_chunk;
+ *pos_in_chunk = bt->pos_in_chunk;
+ *size_in_buffer = bt->size_in_buffer;
+ *pos_in_buffer = bt->pos_in_buffer;
+ buffer_close(ctx, ii, pseg);
+ return 4;
+}
+
+const char *
+grn_ii_path(grn_ii *ii)
+{
+ return grn_io_path(ii->seg);
+}
+
+uint32_t
+grn_ii_max_section(grn_ii *ii)
+{
+ return ii->header->smax;
+}
+
+grn_obj *
+grn_ii_lexicon(grn_ii *ii)
+{
+ return ii->lexicon;
+}
+
+/* private classes */
+
+/* b-heap */
+
+typedef struct {
+ int n_entries;
+ int n_bins;
+ grn_ii_cursor **bins;
+} cursor_heap;
+
+static inline cursor_heap *
+cursor_heap_open(grn_ctx *ctx, int max)
+{
+ cursor_heap *h = GRN_MALLOC(sizeof(cursor_heap));
+ if (!h) { return NULL; }
+ h->bins = GRN_MALLOC(sizeof(grn_ii_cursor *) * max);
+ if (!h->bins) {
+ GRN_FREE(h);
+ return NULL;
+ }
+ h->n_entries = 0;
+ h->n_bins = max;
+ return h;
+}
+
+static inline grn_rc
+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;
+ if (h->n_entries >= h->n_bins) {
+ int max = h->n_bins * 2;
+ grn_ii_cursor **bins = GRN_REALLOC(h->bins, sizeof(grn_ii_cursor *) * max);
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "expanded cursor_heap to %d,%p", max, bins);
+ if (!bins) { return GRN_NO_MEMORY_AVAILABLE; }
+ h->n_bins = max;
+ h->bins = bins;
+ }
+ {
+ 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;
+ }
+ if (!grn_ii_cursor_next(ctx, c)) {
+ grn_ii_cursor_close(ctx, c);
+ return GRN_END_OF_DATA;
+ }
+ if (!grn_ii_cursor_next_pos(ctx, 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][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;
+ c2 = h->bins[n2];
+ if (GRN_II_CURSOR_CMP(c, c2)) { break; }
+ h->bins[n] = c2;
+ n = n2;
+ }
+ h->bins[n] = c;
+ }
+ return GRN_SUCCESS;
+}
+
+static inline grn_rc
+cursor_heap_push2(cursor_heap *h)
+{
+ grn_rc rc = GRN_SUCCESS;
+ return rc;
+}
+
+static inline grn_ii_cursor *
+cursor_heap_min(cursor_heap *h)
+{
+ return h->n_entries ? h->bins[0] : NULL;
+}
+
+static inline void
+cursor_heap_recalc_min(cursor_heap *h)
+{
+ int n = 0, n1, n2, m;
+ if ((m = h->n_entries) > 1) {
+ grn_ii_cursor *c = h->bins[0], *c1, *c2;
+ for (;;) {
+ n1 = n * 2 + 1;
+ n2 = n1 + 1;
+ c1 = n1 < m ? h->bins[n1] : NULL;
+ c2 = n2 < m ? h->bins[n2] : NULL;
+ if (c1 && GRN_II_CURSOR_CMP(c, c1)) {
+ if (c2 && GRN_II_CURSOR_CMP(c, c2) && GRN_II_CURSOR_CMP(c1, c2)) {
+ h->bins[n] = c2;
+ n = n2;
+ } else {
+ h->bins[n] = c1;
+ n = n1;
+ }
+ } else {
+ if (c2 && GRN_II_CURSOR_CMP(c, c2)) {
+ h->bins[n] = c2;
+ n = n2;
+ } else {
+ h->bins[n] = c;
+ break;
+ }
+ }
+ }
+ }
+}
+
+static inline void
+cursor_heap_pop(grn_ctx *ctx, cursor_heap *h, grn_id min)
+{
+ if (h->n_entries) {
+ grn_ii_cursor *c = h->bins[0];
+ grn_ii_cursor_set_min(ctx, c, min);
+ if (!grn_ii_cursor_next(ctx, c)) {
+ grn_ii_cursor_close(ctx, c);
+ h->bins[0] = h->bins[--h->n_entries];
+ } else if (!grn_ii_cursor_next_pos(ctx, 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];
+ }
+ if (h->n_entries > 1) { cursor_heap_recalc_min(h); }
+ }
+}
+
+static inline void
+cursor_heap_pop_pos(grn_ctx *ctx, cursor_heap *h)
+{
+ if (h->n_entries) {
+ grn_ii_cursor *c = h->bins[0];
+ if (!grn_ii_cursor_next_pos(ctx, c)) {
+ if (!grn_ii_cursor_next(ctx, c)) {
+ grn_ii_cursor_close(ctx, c);
+ h->bins[0] = h->bins[--h->n_entries];
+ } else if (!grn_ii_cursor_next_pos(ctx, 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][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];
+ }
+ }
+ if (h->n_entries > 1) { cursor_heap_recalc_min(h); }
+ }
+}
+
+static inline void
+cursor_heap_close(grn_ctx *ctx, cursor_heap *h)
+{
+ int i;
+ if (!h) { return; }
+ for (i = h->n_entries; i--;) { grn_ii_cursor_close(ctx, h->bins[i]); }
+ GRN_FREE(h->bins);
+ GRN_FREE(h);
+}
+
+/* update */
+#ifdef USE_VGRAM
+
+inline static grn_rc
+index_add(grn_ctx *ctx, grn_id rid, grn_obj *lexicon, grn_ii *ii, grn_vgram *vgram,
+ const char *value, size_t value_len)
+{
+ grn_hash *h;
+ unsigned int token_flags = 0;
+ grn_token_cursor *token_cursor;
+ grn_ii_updspec **u;
+ grn_id tid, *tp;
+ grn_rc r, rc = GRN_SUCCESS;
+ grn_vgram_buf *sbuf = NULL;
+ if (!rid) { return GRN_INVALID_ARGUMENT; }
+ if (!(token_cursor = grn_token_cursor_open(ctx, lexicon, value, value_len,
+ GRN_TOKEN_ADD, token_flags))) {
+ 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);
+ if (!h) {
+ GRN_LOG(ctx, GRN_LOG_ALERT, "grn_hash_create on index_add failed !");
+ grn_token_cursor_close(ctx, token_cursor);
+ if (sbuf) { grn_vgram_buf_close(sbuf); }
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ 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 (!*u) {
+ if (!(*u = grn_ii_updspec_open(ctx, rid, 1))) {
+ 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!");
+ goto exit;
+ }
+ if (sbuf) { grn_vgram_buf_add(sbuf, tid); }
+ }
+ }
+ grn_token_cursor_close(ctx, token_cursor);
+ // todo : support vgram
+ // if (sbuf) { grn_vgram_update(vgram, rid, sbuf, (grn_set *)h); }
+ GRN_HASH_EACH(ctx, h, id, &tp, NULL, &u, {
+ if ((r = grn_ii_update_one(ctx, ii, *tp, *u, h))) { rc = r; }
+ grn_ii_updspec_close(ctx, *u);
+ });
+ grn_hash_close(ctx, h);
+ if (sbuf) { grn_vgram_buf_close(sbuf); }
+ return rc;
+exit:
+ grn_hash_close(ctx, h);
+ grn_token_cursor_close(ctx, token_cursor);
+ if (sbuf) { grn_vgram_buf_close(sbuf); }
+ return GRN_NO_MEMORY_AVAILABLE;
+}
+
+inline static grn_rc
+index_del(grn_ctx *ctx, grn_id rid, grn_obj *lexicon, grn_ii *ii, grn_vgram *vgram,
+ const char *value, size_t value_len)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_hash *h;
+ unsigned int token_flags = 0;
+ grn_token_cursor *token_cursor;
+ grn_ii_updspec **u;
+ grn_id tid, *tp;
+ if (!rid) { return GRN_INVALID_ARGUMENT; }
+ if (!(token_cursor = grn_token_cursor_open(ctx, lexicon, value, value_len,
+ 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);
+ if (!h) {
+ GRN_LOG(ctx, GRN_LOG_ALERT, "grn_hash_create on index_del failed !");
+ grn_token_cursor_close(ctx, token_cursor);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ 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 (!*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_hash_close(ctx, h);
+ grn_token_cursor_close(ctx, token_cursor);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ }
+ }
+ grn_token_cursor_close(ctx, token_cursor);
+ GRN_HASH_EACH(ctx, h, id, &tp, NULL, &u, {
+ if (*tp) {
+ grn_rc r;
+ r = grn_ii_delete_one(ctx, ii, *tp, *u, NULL);
+ if (r) {
+ rc = r;
+ }
+ }
+ grn_ii_updspec_close(ctx, *u);
+ });
+ grn_hash_close(ctx, h);
+ return rc;
+}
+
+grn_rc
+grn_ii_upd(grn_ctx *ctx, grn_ii *ii, grn_id rid, grn_vgram *vgram,
+ const char *oldvalue, unsigned int oldvalue_len,
+ const char *newvalue, unsigned int newvalue_len)
+{
+ grn_rc rc;
+ grn_obj *lexicon = ii->lexicon;
+ if (!rid) { return GRN_INVALID_ARGUMENT; }
+ if (oldvalue && *oldvalue) {
+ if ((rc = index_del(ctx, rid, lexicon, ii, vgram, oldvalue, oldvalue_len))) {
+ GRN_LOG(ctx, GRN_LOG_ERROR, "index_del on grn_ii_upd failed !");
+ goto exit;
+ }
+ }
+ if (newvalue && *newvalue) {
+ rc = index_add(ctx, rid, lexicon, ii, vgram, newvalue, newvalue_len);
+ }
+exit :
+ return rc;
+}
+
+grn_rc
+grn_ii_update(grn_ctx *ctx, grn_ii *ii, grn_id rid, grn_vgram *vgram, unsigned int section,
+ grn_values *oldvalues, grn_values *newvalues)
+{
+ int j;
+ grn_value *v;
+ unsigned int token_flags = 0;
+ grn_token_cursor *token_cursor;
+ grn_rc rc = GRN_SUCCESS;
+ grn_hash *old, *new;
+ grn_id tid, *tp;
+ grn_ii_updspec **u, **un;
+ grn_obj *lexicon = ii->lexicon;
+ if (!lexicon || !ii || !rid) {
+ GRN_LOG(ctx, GRN_LOG_WARNING, "grn_ii_update: invalid argument");
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (newvalues) {
+ 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))) {
+ 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)) {
+ 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_token_cursor_close(ctx, token_cursor);
+ grn_hash_close(ctx, new);
+ rc = GRN_NO_MEMORY_AVAILABLE;
+ goto exit;
+ }
+ }
+ 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_token_cursor_close(ctx, token_cursor);
+ grn_hash_close(ctx, new);
+ rc = GRN_NO_MEMORY_AVAILABLE;
+ goto exit;
+ }
+ }
+ }
+ grn_token_cursor_close(ctx, token_cursor);
+ }
+ }
+ if (!GRN_HASH_SIZE(new)) {
+ grn_hash_close(ctx, new);
+ new = NULL;
+ }
+ } else {
+ new = NULL;
+ }
+ if (oldvalues) {
+ 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!");
+ 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))) {
+ 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)) {
+ 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_token_cursor_close(ctx, token_cursor);
+ if (new) { grn_hash_close(ctx, new); };
+ grn_hash_close(ctx, old);
+ rc = GRN_NO_MEMORY_AVAILABLE;
+ goto exit;
+ }
+ }
+ 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_token_cursor_close(ctx, token_cursor);
+ if (new) { grn_hash_close(ctx, new); };
+ grn_hash_close(ctx, old);
+ rc = GRN_NO_MEMORY_AVAILABLE;
+ goto exit;
+ }
+ }
+ }
+ grn_token_cursor_close(ctx, token_cursor);
+ }
+ }
+ } else {
+ old = NULL;
+ }
+ 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 (!grn_ii_updspec_cmp(*u, *un)) {
+ grn_ii_updspec_close(ctx, *un);
+ grn_hash_delete_by_id(ctx, new, eid, NULL);
+ }
+ } else {
+ grn_rc r;
+ r = grn_ii_delete_one(ctx, ii, *tp, *u, new);
+ if (r) {
+ rc = r;
+ }
+ }
+ grn_ii_updspec_close(ctx, *u);
+ });
+ grn_hash_close(ctx, old);
+ }
+ if (new) {
+ GRN_HASH_EACH(ctx, new, id, &tp, NULL, &u, {
+ grn_rc r;
+ if ((r = grn_ii_update_one(ctx, ii, *tp, *u, new))) { rc = r; }
+ grn_ii_updspec_close(ctx, *u);
+ });
+ grn_hash_close(ctx, new);
+ } else {
+ if (!section) {
+ /* todo: delete key when all sections deleted */
+ }
+ }
+exit :
+ return rc;
+}
+#endif /* USE_VGRAM */
+
+static grn_rc
+grn_vector2updspecs(grn_ctx *ctx, grn_ii *ii, grn_id rid, unsigned int section,
+ grn_obj *in, grn_obj *out, grn_tokenize_mode mode,
+ grn_obj *posting)
+{
+ int j;
+ grn_id tid;
+ grn_section *v;
+ grn_token_cursor *token_cursor;
+ grn_ii_updspec **u;
+ grn_hash *h = (grn_hash *)out;
+ grn_obj *lexicon = ii->lexicon;
+ if (in->u.v.body) {
+ const char *head = GRN_BULK_HEAD(in->u.v.body);
+ 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))) {
+ 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)) {
+ break;
+ }
+ if (!*u) {
+ if (!(*u = grn_ii_updspec_open(ctx, rid, section))) {
+ 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 ctx->rc;
+ }
+ }
+ if (grn_ii_updspec_add(ctx, *u, token_cursor->pos, v->weight)) {
+ 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 ctx->rc;
+ }
+ }
+ }
+ grn_token_cursor_close(ctx, token_cursor);
+ }
+ }
+ }
+ return ctx->rc;
+}
+
+static grn_rc
+grn_uvector2updspecs_data(grn_ctx *ctx, grn_ii *ii, grn_id rid,
+ unsigned int section, grn_obj *in, grn_obj *out,
+ grn_tokenize_mode mode, grn_obj *posting)
+{
+ int i, n;
+ grn_hash *h = (grn_hash *)out;
+ grn_obj *lexicon = ii->lexicon;
+ unsigned int element_size;
+
+ 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,
+ mode, token_flags);
+ if (!token_cursor) {
+ continue;
+ }
+
+ while (!token_cursor->status) {
+ 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)) {
+ break;
+ }
+ if (!*u) {
+ if (!(*u = grn_ii_updspec_open(ctx, rid, section))) {
+ GRN_LOG(ctx, GRN_LOG_ALERT,
+ "grn_ii_updspec_open on grn_uvector2updspecs_data failed!");
+ grn_token_cursor_close(ctx, token_cursor);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ 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);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ }
+
+ grn_token_cursor_close(ctx, token_cursor);
+ }
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_uvector2updspecs_id(grn_ctx *ctx, grn_ii *ii, grn_id rid,
+ unsigned int section, grn_obj *in, grn_obj *out)
+{
+ int i, n;
+ grn_ii_updspec **u;
+ grn_hash *h = (grn_hash *)out;
+
+ n = grn_vector_size(ctx, in);
+ for (i = 0; i < n; i++) {
+ grn_id id;
+ unsigned int weight;
+
+ id = grn_uvector_get_element(ctx, in, i, &weight);
+ if (!grn_hash_add(ctx, h, &id, 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!");
+ 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!");
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_uvector2updspecs(grn_ctx *ctx, grn_ii *ii, grn_id rid,
+ unsigned int section, grn_obj *in, grn_obj *out,
+ grn_tokenize_mode mode, grn_obj *posting)
+{
+ if (in->header.domain < GRN_N_RESERVED_TYPES) {
+ return grn_uvector2updspecs_data(ctx, ii, rid, section, in, out,
+ mode, posting);
+ } else {
+ return grn_uvector2updspecs_id(ctx, ii, rid, section, in, out);
+ }
+}
+
+grn_rc
+grn_ii_column_update(grn_ctx *ctx, grn_ii *ii, grn_id rid, unsigned int section,
+ grn_obj *oldvalue, grn_obj *newvalue, grn_obj *posting)
+{
+ grn_id *tp;
+ grn_bool do_grn_ii_updspec_cmp = GRN_TRUE;
+ grn_ii_updspec **u, **un;
+ 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));
+ post = &buf;
+ }
+ if (grn_io_lock(ctx, ii->seg, grn_lock_timeout)) { return ctx->rc; }
+ if (new) {
+ unsigned char type = (ii->obj.header.domain == new->header.domain)
+ ? GRN_UVECTOR
+ : new->header.type;
+ switch (type) {
+ case GRN_BULK :
+ {
+ if (grn_bulk_is_zero(ctx, new)) {
+ do_grn_ii_updspec_cmp = GRN_FALSE;
+ }
+ new_ = new;
+ GRN_OBJ_INIT(&newv, GRN_VECTOR, GRN_OBJ_DO_SHALLOW_COPY, GRN_DB_TEXT);
+ newv.u.v.body = new;
+ new = &newv;
+ grn_vector_delimit(ctx, new, 0, GRN_ID_NIL);
+ if (new_ != newvalue) { grn_obj_close(ctx, new_); }
+ }
+ /* fallthru */
+ case GRN_VECTOR :
+ new_ = new;
+ new = (grn_obj *)grn_hash_create(ctx, NULL, sizeof(grn_id),
+ sizeof(grn_ii_updspec *),
+ GRN_HASH_TINY);
+ if (!new) {
+ DEFINE_NAME(ii);
+ MERR("[ii][column][update][new][vector] failed to create a hash table: "
+ "<%.*s>: ",
+ name_size, name);
+ } else {
+ grn_vector2updspecs(ctx, ii, rid, section, new_, new,
+ GRN_TOKEN_ADD, post);
+ }
+ if (new_ != newvalue) { grn_obj_close(ctx, new_); }
+ if (ctx->rc != GRN_SUCCESS) { goto exit; }
+ break;
+ case GRN_UVECTOR :
+ new_ = new;
+ new = (grn_obj *)grn_hash_create(ctx, NULL, sizeof(grn_id),
+ sizeof(grn_ii_updspec *),
+ GRN_HASH_TINY);
+ if (!new) {
+ 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) {
+ 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);
+ 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);
+ 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 (ctx->rc != GRN_SUCCESS) { goto exit; }
+ break;
+ case GRN_TABLE_HASH_KEY :
+ break;
+ default :
+ {
+ DEFINE_NAME(ii);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[ii][column][update][new] invalid object: "
+ "<%.*s>: "
+ "<%-.256s>(%#x)",
+ name_size, name,
+ grn_obj_type_to_string(type),
+ type);
+ }
+ goto exit;
+ }
+ }
+ if (posting) {
+ grn_ii_updspec *u_;
+ uint32_t offset = 0;
+ grn_id tid_ = 0, gap, tid, *tpe;
+ grn_table_sort_optarg arg = {GRN_TABLE_SORT_ASC|
+ GRN_TABLE_SORT_AS_NUMBER|
+ GRN_TABLE_SORT_AS_UNSIGNED, NULL, NULL,0 };
+ grn_array *sorted = grn_array_create(ctx, NULL, sizeof(grn_id), 0);
+ grn_hash_sort(ctx, (grn_hash *)new, -1, sorted, &arg);
+ GRN_TEXT_PUT(ctx, posting, ((grn_hash *)new)->n_entries, sizeof(uint32_t));
+ GRN_ARRAY_EACH(ctx, sorted, 0, 0, id, &tp, {
+ grn_hash_get_key(ctx, (grn_hash *)new, *tp, &tid, sizeof(grn_id));
+ gap = tid - tid_;
+ GRN_TEXT_PUT(ctx, posting, &gap, sizeof(grn_id));
+ tid_ = tid;
+ });
+ GRN_ARRAY_EACH(ctx, sorted, 0, 0, id, &tp, {
+ grn_hash_get_value(ctx, (grn_hash *)new, *tp, &u_);
+ u_->offset = offset++;
+ GRN_TEXT_PUT(ctx, posting, &u_->tf, sizeof(int32_t));
+ });
+ 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_TEXT_PUT(ctx, posting, &(*u)->offset, sizeof(int32_t));
+ }
+ GRN_OBJ_FIN(ctx, post);
+ grn_array_close(ctx, sorted);
+ }
+
+ if (old) {
+ unsigned char type = (ii->obj.header.domain == old->header.domain)
+ ? GRN_UVECTOR
+ : old->header.type;
+ switch (type) {
+ case GRN_BULK :
+ {
+ // const char *str = GRN_BULK_HEAD(old);
+ // unsigned int str_len = GRN_BULK_VSIZE(old);
+ old_ = old;
+ GRN_OBJ_INIT(&oldv, GRN_VECTOR, GRN_OBJ_DO_SHALLOW_COPY, GRN_DB_TEXT);
+ oldv.u.v.body = old;
+ old = &oldv;
+ grn_vector_delimit(ctx, old, 0, GRN_ID_NIL);
+ if (old_ != oldvalue) { grn_obj_close(ctx, old_); }
+ }
+ /* fallthru */
+ case GRN_VECTOR :
+ old_ = old;
+ old = (grn_obj *)grn_hash_create(ctx, NULL, sizeof(grn_id),
+ sizeof(grn_ii_updspec *),
+ GRN_HASH_TINY);
+ if (!old) {
+ DEFINE_NAME(ii);
+ MERR("[ii][column][update][old][vector] failed to create a hash table: "
+ "<%.*s>: ",
+ name_size, name);
+ } else {
+ grn_vector2updspecs(ctx, ii, rid, section, old_, old,
+ GRN_TOKEN_DEL, NULL);
+ }
+ if (old_ != oldvalue) { grn_obj_close(ctx, old_); }
+ if (ctx->rc != GRN_SUCCESS) { goto exit; }
+ break;
+ case GRN_UVECTOR :
+ old_ = old;
+ old = (grn_obj *)grn_hash_create(ctx, NULL, sizeof(grn_id),
+ sizeof(grn_ii_updspec *),
+ GRN_HASH_TINY);
+ if (!old) {
+ 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) {
+ 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);
+ 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);
+ 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 (ctx->rc != GRN_SUCCESS) { goto exit; }
+ break;
+ case GRN_TABLE_HASH_KEY :
+ break;
+ default :
+ {
+ DEFINE_NAME(ii);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[ii][column][update][old] invalid object: "
+ "<%.*s>: "
+ "<%-.256s>(%#x)",
+ name_size, name,
+ grn_obj_type_to_string(type),
+ type);
+ }
+ goto exit;
+ }
+ }
+
+ if (old) {
+ grn_id eid;
+ 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 (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_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_ii_update_one(ctx, ii, *tp, *u, n);
+ grn_ii_updspec_close(ctx, *u);
+ if (ctx->rc != GRN_SUCCESS) {
+ break;
+ }
+ });
+ } else {
+ if (!section) {
+ /* todo: delete key when all sections deleted */
+ }
+ }
+exit :
+ grn_io_unlock(ii->seg);
+ if (old && old != oldvalue) { grn_obj_close(ctx, old); }
+ if (new && new != newvalue) { grn_obj_close(ctx, new); }
+ return ctx->rc;
+}
+
+/* token_info */
+
+typedef struct {
+ cursor_heap *cursors;
+ int offset;
+ int pos;
+ int size;
+ int ntoken;
+ 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,
+ const char *key, unsigned int key_size, token_info *ti)
+{
+ int s = 0;
+ grn_hash *h, *g;
+ uint32_t *offset2;
+ grn_hash_cursor *c;
+ grn_id *tp, *tq;
+ if ((h = grn_hash_create(ctx, NULL, sizeof(grn_id), 0, 0))) {
+ grn_table_search(ctx, lexicon, key, key_size,
+ GRN_OP_PREFIX, (grn_obj *)h, GRN_OP_OR);
+ if (GRN_HASH_SIZE(h)) {
+ if ((ti->cursors = cursor_heap_open(ctx, GRN_HASH_SIZE(h) + 256))) {
+ if ((c = grn_hash_cursor_open(ctx, h, NULL, 0, NULL, 0, 0, -1, 0))) {
+ uint32_t key2_size;
+ const char *key2;
+ while (grn_hash_cursor_next(ctx, c)) {
+ grn_hash_cursor_get_key(ctx, c, (void **) &tp);
+ key2 = _grn_table_key(ctx, lexicon, *tp, &key2_size);
+ if (!key2) { break; }
+ if ((lexicon->header.type != GRN_TABLE_PAT_KEY) ||
+ !(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, 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);
+ 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, 0, GRN_ID_NIL);
+ ti->ntoken++;
+ ti->size += s;
+ }
+ });
+ grn_hash_close(ctx, g);
+ }
+ }
+ }
+ grn_hash_cursor_close(ctx, c);
+ }
+ }
+ }
+ grn_hash_close(ctx, h);
+ }
+}
+
+inline static grn_rc
+token_info_close(grn_ctx *ctx, token_info *ti)
+{
+ cursor_heap_close(ctx, ti->cursors);
+ GRN_FREE(ti);
+ return GRN_SUCCESS;
+}
+
+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, grn_fuzzy_search_optarg *args, grn_id min)
+{
+ int s = 0;
+ grn_hash *h;
+ token_info *ti;
+ grn_id tid;
+ grn_id *tp;
+ if (!key) { return NULL; }
+ if (!(ti = GRN_MALLOC(sizeof(token_info)))) { return NULL; }
+ ti->cursors = NULL;
+ ti->size = 0;
+ ti->ntoken = 0;
+ ti->offset = offset;
+ switch (mode) {
+ case EX_BOTH :
+ token_info_expand_both(ctx, lexicon, ii, key, key_size, ti);
+ break;
+ case EX_NONE :
+ 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, 0, min);
+ ti->ntoken++;
+ ti->size = s;
+ }
+ break;
+ case EX_PREFIX :
+ if ((h = grn_hash_create(ctx, NULL, sizeof(grn_id), 0, 0))) {
+ grn_table_search(ctx, lexicon, key, key_size,
+ GRN_OP_PREFIX, (grn_obj *)h, GRN_OP_OR);
+ if (GRN_HASH_SIZE(h)) {
+ 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, 0, min);
+ ti->ntoken++;
+ ti->size += s;
+ }
+ });
+ }
+ }
+ grn_hash_close(ctx, h);
+ }
+ break;
+ case EX_SUFFIX :
+ if ((h = grn_hash_create(ctx, NULL, sizeof(grn_id), 0, 0))) {
+ grn_table_search(ctx, lexicon, key, key_size,
+ GRN_OP_SUFFIX, (grn_obj *)h, GRN_OP_OR);
+ if (GRN_HASH_SIZE(h)) {
+ if ((ti->cursors = cursor_heap_open(ctx, GRN_HASH_SIZE(h)))) {
+ 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, 0, min);
+ ti->ntoken++;
+ ti->size += s;
+ }
+ });
+ }
+ }
+ 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);
+ return NULL;
+ }
+ {
+ grn_ii_cursor *ic;
+ if (ti->cursors && (ic = cursor_heap_min(ti->cursors))) {
+ grn_posting *p = ic->post;
+ ti->pos = p->pos - ti->offset;
+ ti->p = p;
+ } else {
+ token_info_close(ctx, ti);
+ ti = NULL;
+ }
+ }
+ return ti;
+}
+
+static inline grn_rc
+token_info_skip(grn_ctx *ctx, token_info *ti, uint32_t rid, uint32_t sid)
+{
+ grn_ii_cursor *c;
+ grn_posting *p;
+ for (;;) {
+ if (!(c = cursor_heap_min(ti->cursors))) { return GRN_END_OF_DATA; }
+ p = c->post;
+ if (p->rid > rid || (p->rid == rid && p->sid >= sid)) { break; }
+ cursor_heap_pop(ctx, ti->cursors, rid);
+ }
+ ti->pos = p->pos - ti->offset;
+ ti->p = p;
+ return GRN_SUCCESS;
+}
+
+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_posting *p;
+ pos += ti->offset;
+ for (;;) {
+ if (!(c = cursor_heap_min(ti->cursors))) { return GRN_END_OF_DATA; }
+ p = c->post;
+ if (p->rid != rid || p->sid != sid || p->pos >= pos) { break; }
+ cursor_heap_pop_pos(ctx, ti->cursors);
+ }
+ ti->pos = p->pos - ti->offset;
+ ti->p = p;
+ return GRN_SUCCESS;
+}
+
+inline static int
+token_compare(const void *a, const void *b)
+{
+ const token_info *t1 = *((token_info **)a), *t2 = *((token_info **)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, grn_id min,
+ grn_operator mode)
+{
+ token_info *ti;
+ const char *key;
+ uint32_t size;
+ 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_TOKEN_GET,
+ token_flags);
+ *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, NULL, min))) {
+ tis[(*n)++] = ti;
+ rc = GRN_SUCCESS;
+ }
+ } else {
+ grn_id tid;
+ int ef;
+ switch (mode) {
+ case GRN_OP_PREFIX :
+ ef = EX_PREFIX;
+ break;
+ case GRN_OP_SUFFIX :
+ ef = EX_SUFFIX;
+ break;
+ case GRN_OP_PARTIAL :
+ ef = EX_BOTH;
+ break;
+ default :
+ ef = EX_NONE;
+ break;
+ }
+ tid = grn_token_cursor_next(ctx, token_cursor);
+ if (token_cursor->force_prefix) { ef |= EX_PREFIX; }
+ 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, 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, 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, NULL, GRN_ID_NIL);
+ ti = token_info_open(ctx, lexicon, ii, (char *)token_cursor->orig,
+ 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, NULL, min);
+ break;
+ case GRN_TOKEN_CURSOR_DONE_SKIP :
+ *only_skip_token = GRN_TRUE;
+ goto exit;
+ default :
+ goto exit;
+ }
+ 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; }
+ switch (token_cursor->status) {
+ case GRN_TOKEN_CURSOR_DONE_SKIP :
+ 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, 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, 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, NULL, min);
+ break;
+ }
+ if (!ti) {
+ goto exit;
+ }
+ tis[(*n)++] = ti;
+ }
+ rc = GRN_SUCCESS;
+ }
+exit :
+ grn_token_cursor_close(ctx, token_cursor);
+ 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)
+{
+ token_info **tie;
+ for (tie = tis + n; tis < tie; tis++) { (*tis)->offset = 0; }
+}
+
+/* select */
+
+inline static void
+res_add(grn_ctx *ctx, grn_hash *s, grn_rset_posinfo *pi, double score,
+ grn_operator op)
+{
+ grn_rset_recinfo *ri;
+ switch (op) {
+ case GRN_OP_OR :
+ if (grn_hash_add(ctx, s, pi, s->key_size, (void **)&ri, NULL)) {
+ if (s->obj.header.flags & GRN_OBJ_WITH_SUBREC) {
+ grn_table_add_subrec((grn_obj *)s, ri, score, pi, 1);
+ }
+ }
+ break;
+ case GRN_OP_AND :
+ if (grn_hash_get(ctx, s, pi, s->key_size, (void **)&ri)) {
+ if (s->obj.header.flags & GRN_OBJ_WITH_SUBREC) {
+ ri->n_subrecs |= GRN_RSET_UTIL_BIT;
+ grn_table_add_subrec((grn_obj *)s, ri, score, pi, 1);
+ }
+ }
+ break;
+ case GRN_OP_AND_NOT :
+ {
+ grn_id id;
+ if ((id = grn_hash_get(ctx, s, pi, s->key_size, (void **)&ri))) {
+ grn_hash_delete_by_id(ctx, s, id, NULL);
+ }
+ }
+ break;
+ case GRN_OP_ADJUST :
+ if (grn_hash_get(ctx, s, pi, s->key_size, (void **)&ri)) {
+ if (s->obj.header.flags & GRN_OBJ_WITH_SUBREC) {
+ ri->score += score;
+ }
+ }
+ break;
+ default :
+ break;
+ }
+}
+
+grn_rc
+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;
+}
+
+#ifdef USE_BHEAP
+
+/* todo */
+
+#else /* USE_BHEAP */
+
+struct _btr_node {
+ struct _btr_node *car;
+ struct _btr_node *cdr;
+ token_info *ti;
+};
+
+typedef struct _btr_node btr_node;
+
+typedef struct {
+ int n;
+ token_info *min;
+ token_info *max;
+ btr_node *root;
+ btr_node *nodes;
+} btr;
+
+inline static void
+bt_zap(btr *bt)
+{
+ bt->n = 0;
+ bt->min = NULL;
+ bt->max = NULL;
+ bt->root = NULL;
+}
+
+inline static btr *
+bt_open(grn_ctx *ctx, int size)
+{
+ btr *bt = GRN_MALLOC(sizeof(btr));
+ if (bt) {
+ bt_zap(bt);
+ if (!(bt->nodes = GRN_MALLOC(sizeof(btr_node) * size))) {
+ GRN_FREE(bt);
+ bt = NULL;
+ }
+ }
+ return bt;
+}
+
+inline static void
+bt_close(grn_ctx *ctx, btr *bt)
+{
+ if (!bt) { return; }
+ GRN_FREE(bt->nodes);
+ GRN_FREE(bt);
+}
+
+inline static void
+bt_push(btr *bt, token_info *ti)
+{
+ int pos = ti->pos, minp = 1, maxp = 1;
+ btr_node *node, *new, **last;
+ new = bt->nodes + bt->n++;
+ new->ti = ti;
+ new->car = NULL;
+ new->cdr = NULL;
+ for (last = &bt->root; (node = *last);) {
+ if (pos < node->ti->pos) {
+ last = &node->car;
+ maxp = 0;
+ } else {
+ last = &node->cdr;
+ minp = 0;
+ }
+ }
+ *last = new;
+ if (minp) { bt->min = ti; }
+ if (maxp) { bt->max = ti; }
+}
+
+inline static void
+bt_pop(btr *bt)
+{
+ btr_node *node, *min, *newmin, **last;
+ for (last = &bt->root; (min = *last) && min->car; last = &min->car) ;
+ if (min) {
+ int pos = min->ti->pos, minp = 1, maxp = 1;
+ *last = min->cdr;
+ min->cdr = NULL;
+ for (last = &bt->root; (node = *last);) {
+ if (pos < node->ti->pos) {
+ last = &node->car;
+ maxp = 0;
+ } else {
+ last = &node->cdr;
+ minp = 0;
+ }
+ }
+ *last = min;
+ if (maxp) { bt->max = min->ti; }
+ if (!minp) {
+ for (newmin = bt->root; newmin->car; newmin = newmin->car) ;
+ bt->min = newmin->ti;
+ }
+ }
+}
+
+#endif /* USE_BHEAP */
+
+typedef enum {
+ grn_wv_none = 0,
+ grn_wv_static,
+ grn_wv_dynamic,
+ grn_wv_constant
+} grn_wv_mode;
+
+inline static double
+get_weight(grn_ctx *ctx, grn_hash *s, grn_id rid, int sid,
+ grn_wv_mode wvm, grn_select_optarg *optarg)
+{
+ switch (wvm) {
+ case grn_wv_none :
+ return 1;
+ case grn_wv_static :
+ return sid <= optarg->vector_size ? optarg->weight_vector[sid - 1] : 0;
+ case grn_wv_dynamic :
+ /* todo : support hash with keys
+ if (s->keys) {
+ uint32_t key_size;
+ const char *key = _grn_table_key(ctx, s->keys, rid, &key_size);
+ // todo : change grn_select_optarg
+ return key ? optarg->func(s, key, key_size, sid, optarg->func_arg) : 0;
+ }
+ */
+ /* todo : cast */
+ return optarg->func(ctx, (void *)s, (void *)(intptr_t)rid, sid,
+ optarg->func_arg);
+ case grn_wv_constant :
+ return optarg->vector_size;
+ default :
+ return 1;
+ }
+}
+
+grn_rc
+grn_ii_similar_search(grn_ctx *ctx, grn_ii *ii,
+ const char *string, unsigned int string_len,
+ grn_hash *s, grn_operator op, grn_select_optarg *optarg)
+{
+ int *w1, limit;
+ grn_id tid, *tp, max_size;
+ grn_rc rc = GRN_SUCCESS;
+ grn_hash *h;
+ 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 (!(h = grn_hash_create(ctx, NULL, sizeof(grn_id), sizeof(int), 0))) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ if (!(token_cursor = grn_token_cursor_open(ctx, lexicon, string, string_len,
+ GRN_TOKEN_GET, token_flags))) {
+ grn_hash_close(ctx, h);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ if (!(max_size = optarg->max_size)) { max_size = 1048576; }
+ 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 (tid && 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->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);
+ if (!c) {
+ 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;
+ }
+ while (grn_hash_cursor_next(ctx, c)) {
+ uint32_t es;
+ grn_hash_cursor_get_key_value(ctx, c, (void **) &tp, NULL, (void **) &w1);
+ if ((es = grn_ii_estimate_size(ctx, ii, *tp))) {
+ *w1 += max_size / es;
+ } else {
+ grn_hash_cursor_delete(ctx, c, NULL);
+ }
+ }
+ grn_hash_cursor_close(ctx, c);
+ }
+ limit = optarg->similarity_threshold
+ ? (optarg->similarity_threshold > GRN_HASH_SIZE(h)
+ ? GRN_HASH_SIZE(h)
+ : optarg->similarity_threshold)
+ : (GRN_HASH_SIZE(h) >> 3) + 1;
+ if (GRN_HASH_SIZE(h)) {
+ grn_id j, id;
+ int w2, rep;
+ grn_ii_cursor *c;
+ 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,
+ NULL,
+ NULL,
+ 0
+ };
+ 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_hash_close(ctx, h);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ grn_hash_sort(ctx, h, limit, sorted, &arg);
+ /* todo support subrec
+ rep = (s->record_unit == grn_rec_position || s->subrec_unit == grn_rec_position);
+ */
+ rep = 0;
+ if (optarg->func) {
+ wvm = grn_wv_dynamic;
+ } else if (optarg->vector_size) {
+ wvm = optarg->weight_vector ? grn_wv_static : grn_wv_constant;
+ }
+ for (j = 1; j <= limit; j++) {
+ grn_array_get_value(ctx, sorted, j, &id);
+ _grn_hash_get_key_value(ctx, h, id, (void **) &tp, (void **) &w1);
+ if (!*tp || !(c = grn_ii_cursor_open(ctx, ii, *tp, GRN_ID_NIL, GRN_ID_MAX,
+ rep
+ ? ii->n_elements
+ : ii->n_elements - 1, 0))) {
+ GRN_LOG(ctx, GRN_LOG_ERROR, "cursor open failed (%d)", *tp);
+ continue;
+ }
+ if (rep) {
+ while (grn_ii_cursor_next(ctx, c)) {
+ 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);
+ }
+ }
+ }
+ } else {
+ 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);
+ }
+ }
+ }
+ grn_ii_cursor_close(ctx, c);
+ }
+ grn_array_close(ctx, sorted);
+ }
+ grn_hash_close(ctx, h);
+ grn_ii_resolve_sel_and(ctx, s, op);
+ // grn_hash_cursor_clear(r);
+ return rc;
+}
+
+#define TERM_EXTRACT_EACH_POST 0
+#define TERM_EXTRACT_EACH_TERM 1
+
+grn_rc
+grn_ii_term_extract(grn_ctx *ctx, grn_ii *ii, const char *string,
+ unsigned int string_len, grn_hash *s,
+ grn_operator op, grn_select_optarg *optarg)
+{
+ grn_rset_posinfo pi;
+ grn_id tid;
+ const char *p, *pe;
+ grn_obj *nstr;
+ const char *normalized;
+ unsigned int normalized_length_in_bytes;
+ grn_ii_cursor *c;
+ grn_posting *pos;
+ int skip, rep, policy;
+ grn_rc rc = GRN_SUCCESS;
+ grn_wv_mode wvm = grn_wv_none;
+ if (!ii || !string || !string_len || !s || !optarg) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (!(nstr = grn_string_open(ctx, string, string_len, NULL, 0))) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ policy = optarg->max_interval;
+ if (optarg->func) {
+ wvm = grn_wv_dynamic;
+ } else if (optarg->vector_size) {
+ wvm = optarg->weight_vector ? grn_wv_static : grn_wv_constant;
+ }
+ /* todo support subrec
+ if (policy == TERM_EXTRACT_EACH_POST) {
+ if ((rc = grn_records_reopen(s, grn_rec_section, grn_rec_none, 0))) { goto exit; }
+ }
+ rep = (s->record_unit == grn_rec_position || s->subrec_unit == grn_rec_position);
+ */
+ rep = 0;
+ grn_string_get_normalized(ctx, nstr, &normalized, &normalized_length_in_bytes,
+ NULL);
+ for (p = normalized, pe = p + normalized_length_in_bytes; p < pe; p += skip) {
+ if ((tid = grn_table_lcp_search(ctx, ii->lexicon, p, pe - p))) {
+ if (policy == TERM_EXTRACT_EACH_POST) {
+ if (!(skip = grn_table_get_key(ctx, ii->lexicon, tid, NULL, 0))) { break; }
+ } else {
+ if (!(skip = (int)grn_charlen(ctx, p, pe))) { break; }
+ }
+ if (!(c = grn_ii_cursor_open(ctx, ii, tid, GRN_ID_NIL, GRN_ID_MAX,
+ rep
+ ? ii->n_elements
+ : ii->n_elements - 1, 0))) {
+ GRN_LOG(ctx, GRN_LOG_ERROR, "cursor open failed (%d)", tid);
+ continue;
+ }
+ if (rep) {
+ while (grn_ii_cursor_next(ctx, c)) {
+ pos = c->post;
+ while (grn_ii_cursor_next_pos(ctx, c)) {
+ res_add(ctx, s, (grn_rset_posinfo *) pos,
+ get_weight(ctx, s, pos->rid, pos->sid, wvm, optarg), op);
+ }
+ }
+ } else {
+ while (grn_ii_cursor_next(ctx, c)) {
+ if (policy == TERM_EXTRACT_EACH_POST) {
+ pi.rid = c->post->rid;
+ pi.sid = p - normalized;
+ res_add(ctx, s, &pi, pi.sid + 1, op);
+ } else {
+ pos = c->post;
+ res_add(ctx, s, (grn_rset_posinfo *) pos,
+ get_weight(ctx, s, pos->rid, pos->sid, wvm, optarg), op);
+ }
+ }
+ }
+ grn_ii_cursor_close(ctx, c);
+ } else {
+ if (!(skip = (int)grn_charlen(ctx, p, pe))) {
+ break;
+ }
+ }
+ }
+ grn_obj_close(ctx, nstr);
+ 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_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: %-.256s",
+ 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: %-.256s",
+ 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: %-.256s",
+ 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: %-.256s",
+ 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_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(&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,
+ "%-.256s invalid encoding character: <%.*s|%#x|>",
+ log_tag,
+ (int)(current - string), string,
+ *current);
+ return ctx->rc;
+ }
+ target = current;
+ current += char_len;
+
+ if (escaping) {
+ escaping = GRN_FALSE;
+ if (char_len == 1) {
+ switch (*target) {
+ case 'A' :
+ if (nth_char == 0) {
+ target = GRN_TOKENIZER_BEGIN_MARK_UTF8;
+ char_len = GRN_TOKENIZER_BEGIN_MARK_UTF8_LEN;
+ }
+ break;
+ case 'z' :
+ if (current == string_end) {
+ target = GRN_TOKENIZER_END_MARK_UTF8;
+ char_len = GRN_TOKENIZER_END_MARK_UTF8_LEN;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+ } else {
+ 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, &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_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);
+
+ if (optarg) {
+ optarg->mode = GRN_OP_REGEXP;
+ }
+
+ return rc;
+}
+
+#ifdef GRN_II_SELECT_ENABLE_SEQUENTIAL_SEARCH
+static grn_bool
+grn_ii_select_sequential_search_should_use(grn_ctx *ctx,
+ grn_ii *ii,
+ const char *raw_query,
+ unsigned int raw_query_len,
+ grn_hash *result,
+ grn_operator op,
+ grn_wv_mode wvm,
+ grn_select_optarg *optarg,
+ token_info **token_infos,
+ uint32_t n_token_infos,
+ double too_many_index_match_ratio)
+{
+ int n_sources;
+
+ if (too_many_index_match_ratio < 0.0) {
+ return GRN_FALSE;
+ }
+
+ if (op != GRN_OP_AND) {
+ return GRN_FALSE;
+ }
+
+ if (optarg->mode != GRN_OP_EXACT) {
+ return GRN_FALSE;
+ }
+
+ n_sources = ii->obj.source_size / sizeof(grn_id);
+ if (n_sources == 0) {
+ return GRN_FALSE;
+ }
+
+ {
+ uint32_t i;
+ int n_existing_records;
+
+ n_existing_records = GRN_HASH_SIZE(result);
+ for (i = 0; i < n_token_infos; i++) {
+ token_info *info = token_infos[i];
+ if (n_existing_records <= (info->size * too_many_index_match_ratio)) {
+ return GRN_TRUE;
+ }
+ }
+ return GRN_FALSE;
+ }
+}
+
+static void
+grn_ii_select_sequential_search_body(grn_ctx *ctx,
+ grn_ii *ii,
+ grn_obj *normalizer,
+ grn_encoding encoding,
+ OnigRegex regex,
+ grn_hash *result,
+ grn_operator op,
+ grn_wv_mode wvm,
+ grn_select_optarg *optarg)
+{
+ int i, n_sources;
+ grn_id *source_ids = ii->obj.source;
+ grn_obj buffer;
+
+ GRN_TEXT_INIT(&buffer, 0);
+ n_sources = ii->obj.source_size / sizeof(grn_id);
+ for (i = 0; i < n_sources; i++) {
+ grn_id source_id = source_ids[i];
+ grn_obj *source;
+ grn_obj *accessor;
+
+ source = grn_ctx_at(ctx, source_id);
+ 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;
+ cursor = grn_hash_cursor_open(ctx, result, NULL, 0, NULL, 0, 0, -1, 0);
+ while ((id = grn_hash_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
+ OnigPosition position;
+ grn_obj *value;
+ const char *normalized_value;
+ unsigned int normalized_value_length;
+
+ GRN_BULK_REWIND(&buffer);
+ grn_obj_get_value(ctx, accessor, id, &buffer);
+ value = grn_string_open_(ctx,
+ GRN_TEXT_VALUE(&buffer),
+ GRN_TEXT_LEN(&buffer),
+ normalizer, 0, encoding);
+ grn_string_get_normalized(ctx, value,
+ &normalized_value, &normalized_value_length,
+ NULL);
+ position = onig_search(regex,
+ normalized_value,
+ normalized_value + normalized_value_length,
+ normalized_value,
+ normalized_value + normalized_value_length,
+ NULL,
+ 0);
+ if (position != ONIG_MISMATCH) {
+ grn_id *record_id;
+ grn_rset_posinfo info;
+ double score;
+
+ 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);
+ res_add(ctx, result, &info, score, op);
+ }
+ grn_obj_unlink(ctx, value);
+ }
+ grn_hash_cursor_close(ctx, cursor);
+ }
+ grn_obj_unlink(ctx, accessor);
+ }
+ grn_obj_unlink(ctx, &buffer);
+}
+
+static grn_bool
+grn_ii_select_sequential_search(grn_ctx *ctx,
+ grn_ii *ii,
+ const char *raw_query,
+ unsigned int raw_query_len,
+ grn_hash *result,
+ grn_operator op,
+ grn_wv_mode wvm,
+ grn_select_optarg *optarg,
+ token_info **token_infos,
+ uint32_t n_token_infos)
+{
+ grn_bool processed = GRN_TRUE;
+
+ {
+ if (!grn_ii_select_sequential_search_should_use(ctx,
+ ii,
+ raw_query,
+ raw_query_len,
+ result,
+ op,
+ wvm,
+ optarg,
+ token_infos,
+ n_token_infos,
+ grn_ii_select_too_many_index_match_ratio)) {
+ return GRN_FALSE;
+ }
+ }
+
+ {
+ grn_encoding encoding;
+ grn_obj *normalizer;
+ int nflags = 0;
+ grn_obj *query;
+ const char *normalized_query;
+ unsigned int normalized_query_length;
+
+ grn_table_get_info(ctx, ii->lexicon,
+ NULL, &encoding, NULL, &normalizer, NULL);
+ query = grn_string_open_(ctx, raw_query, raw_query_len,
+ normalizer, nflags, encoding);
+ grn_string_get_normalized(ctx, query,
+ &normalized_query, &normalized_query_length,
+ NULL);
+ {
+ OnigRegex regex;
+ int onig_result;
+ OnigErrorInfo error_info;
+ onig_result = onig_new(&regex,
+ normalized_query,
+ normalized_query + normalized_query_length,
+ ONIG_OPTION_NONE,
+ ONIG_ENCODING_UTF8,
+ ONIG_SYNTAX_ASIS,
+ &error_info);
+ if (onig_result == ONIG_NORMAL) {
+ grn_ii_select_sequential_search_body(ctx, ii, normalizer, encoding,
+ regex, result, op, wvm, optarg);
+ onig_free(regex);
+ } else {
+ char message[ONIG_MAX_ERROR_MESSAGE_LEN];
+ onig_error_code_to_str(message, onig_result, error_info);
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "[ii][select][sequential] "
+ "failed to create regular expression object: %-.256s",
+ message);
+ processed = GRN_FALSE;
+ }
+ }
+ grn_obj_unlink(ctx, query);
+ }
+
+ return processed;
+}
+#endif
+
+grn_rc
+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;
+ grn_rc rc = GRN_SUCCESS;
+ int rep, orp, weight, max_interval = 0;
+ token_info *ti, **tis = NULL, **tip, **tie;
+ uint32_t n = 0, rid, sid, nrid, nsid;
+ grn_bool only_skip_token = GRN_FALSE;
+ grn_operator mode = GRN_OP_EXACT;
+ grn_wv_mode wvm = grn_wv_none;
+ 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) {
+ mode = optarg->mode;
+ if (optarg->func) {
+ wvm = grn_wv_dynamic;
+ } 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);
+ }
+ if (mode == GRN_OP_TERM_EXTRACT) {
+ return grn_ii_term_extract(ctx, ii, string, string_len, s, op, optarg);
+ }
+ if (mode == GRN_OP_REGEXP) {
+ return grn_ii_select_regexp(ctx, ii, string, string_len, s, op, optarg);
+ }
+ /* todo : support subrec
+ rep = (s->record_unit == grn_rec_position || s->subrec_unit == grn_rec_position);
+ orp = (s->record_unit == grn_rec_position || op == GRN_OP_OR);
+ */
+ rep = 0;
+ orp = op == GRN_OP_OR;
+ if (!string_len) { goto exit; }
+ if (!(tis = GRN_MALLOC(sizeof(token_info *) * string_len * 2))) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ 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);
+ mode = GRN_OP_NEAR;
+ /* fallthru */
+ case GRN_OP_NEAR :
+ if (!(bt = bt_open(ctx, n))) { rc = GRN_NO_MEMORY_AVAILABLE; goto exit; }
+ max_interval = optarg->max_interval;
+ break;
+ default :
+ break;
+ }
+ qsort(tis, n, sizeof(token_info *), token_compare);
+ tie = tis + n;
+ /*
+ for (tip = tis; tip < tie; tip++) {
+ ti = *tip;
+ grn_log("o=%d n=%d s=%d r=%d", ti->offset, ti->ntoken, ti->size, ti->rid);
+ }
+ */
+ GRN_LOG(ctx, GRN_LOG_INFO, "n=%d (%.*s)", n, string_len, string);
+ /* todo : array as result
+ if (n == 1 && (*tis)->cursors->n_entries == 1 && op == GRN_OP_OR
+ && !GRN_HASH_SIZE(s) && !s->garbages
+ && s->record_unit == grn_rec_document && !s->max_n_subrecs
+ && grn_ii_max_section(ii) == 1) {
+ grn_ii_cursor *c = (*tis)->cursors->bins[0];
+ if ((rc = grn_hash_array_init(s, (*tis)->size + 32768))) { goto exit; }
+ do {
+ grn_rset_recinfo *ri;
+ 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;
+ ri->n_subrecs = 1;
+ }
+ } while (grn_ii_cursor_next(ctx, c));
+ goto exit;
+ }
+ */
+#ifdef GRN_II_SELECT_ENABLE_SEQUENTIAL_SEARCH
+ if (grn_ii_select_sequential_search(ctx, ii, string, string_len,
+ s, op, wvm, optarg, tis, n)) {
+ goto exit;
+ }
+#endif
+
+ if (optarg && optarg->scorer) {
+ grn_proc *scorer = (grn_proc *)(optarg->scorer);
+ score_func = scorer->callbacks.scorer.score;
+ record.table = grn_ctx_at(ctx, s->obj.header.domain);
+ record.lexicon = lexicon;
+ record.id = GRN_ID_NIL;
+ GRN_RECORD_INIT(&(record.terms), GRN_OBJ_VECTOR, lexicon->header.domain);
+ GRN_UINT32_INIT(&(record.term_weights), GRN_OBJ_VECTOR);
+ record.total_term_weights = 0;
+ record.n_documents = grn_table_size(ctx, record.table);
+ record.n_occurrences = 0;
+ record.n_candidates = 0;
+ record.n_tokens = 0;
+ record.weight = 0;
+ record.args_expr = optarg->scorer_args_expr;
+ record.args_expr_offset = optarg->scorer_args_expr_offset;
+ }
+
+ for (;;) {
+ rid = (*tis)->p->rid;
+ sid = (*tis)->p->sid;
+ for (tip = tis + 1, nrid = rid, nsid = sid + 1; tip < tie; tip++) {
+ ti = *tip;
+ if (token_info_skip(ctx, ti, rid, sid)) { goto exit; }
+ if (ti->p->rid != rid || ti->p->sid != sid) {
+ nrid = ti->p->rid;
+ nsid = ti->p->sid;
+ break;
+ }
+ }
+ weight = get_weight(ctx, s, rid, sid, wvm, optarg);
+ 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;
+
+ if (score_func) {
+ GRN_BULK_REWIND(&(record.terms));
+ GRN_BULK_REWIND(&(record.term_weights));
+ record.n_candidates = 0;
+ record.n_tokens = 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) { \
+ nrid = ti->p->rid; \
+ nsid = ti->p->sid; \
+ break; \
+ } \
+}
+ if (n == 1 && !rep) {
+ noccur = (*tis)->p->tf;
+ 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);
+ record.n_occurrences = noccur;
+ record.n_candidates = (*tis)->size;
+ record.n_tokens = (*tis)->ntoken;
+ }
+ } else if (mode == GRN_OP_NEAR) {
+ bt_zap(bt);
+ for (tip = tis; tip < tie; tip++) {
+ ti = *tip;
+ SKIP_OR_BREAK(pos);
+ bt_push(bt, ti);
+ }
+ if (tip == tie) {
+ for (;;) {
+ 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 *)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) {
+ break;
+ }
+ SKIP_OR_BREAK(max + 1);
+ } else {
+ if (ti->pos == max - max_interval) {
+ break;
+ }
+ SKIP_OR_BREAK(max - max_interval);
+ }
+ bt_pop(bt);
+ }
+ }
+ } else {
+ for (tip = tis; ; tip++) {
+ 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++;
+ } else {
+ 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));
+ record.n_candidates = 0;
+ record.n_tokens = 0;
+ }
+ }
+ 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 + 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);
+ }
+ tscore += score;
+ score = 0; count = 0; pos++;
+ noccur++;
+ }
+ }
+ }
+ if (noccur && !rep) {
+ double record_score;
+ if (score_func) {
+ record.id = rid;
+ record.weight = weight;
+ record.n_occurrences = noccur;
+ record.total_term_weights = tscore;
+ record_score = score_func(ctx, &record) * weight;
+ } 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
+ }
+ }
+ if (token_info_skip(ctx, *tis, nrid, nsid)) { goto exit; }
+ }
+exit :
+ if (score_func) {
+ 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); }
+ }
+ if (tis) { GRN_FREE(tis); }
+ if (!only_skip_token) {
+ grn_ii_resolve_sel_and(ctx, s, op);
+ }
+ // grn_hash_cursor_clear(r);
+ bt_close(ctx, bt);
+#ifdef DEBUG
+ {
+ uint32_t segno = GRN_II_MAX_LSEG, nnref = 0;
+ grn_io_mapinfo *info = ii->seg->maps;
+ for (; segno; segno--, info++) { if (info->nref) { nnref++; } }
+ GRN_LOG(ctx, GRN_LOG_INFO, "nnref=%d", nnref);
+ }
+#endif /* DEBUG */
+ 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,
+ grn_search_optarg *optarg)
+{
+ grn_rc rc;
+ grn_obj *lexicon = ii->lexicon;
+ token_info **tis = NULL;
+ uint32_t i;
+ uint32_t n_tis = 0;
+ 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;
+ }
+
+ if (optarg) {
+ switch (optarg->mode) {
+ case GRN_OP_NEAR :
+ case GRN_OP_NEAR2 :
+ mode = optarg->mode;
+ break;
+ case GRN_OP_SIMILAR :
+ mode = optarg->mode;
+ break;
+ 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;
+ }
+
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+
+ for (i = 0; i < n_tis; i++) {
+ token_info *ti = tis[i];
+ double term_estimated_size;
+ term_estimated_size = ((double)ti->size / ti->ntoken);
+ if (i == 0) {
+ estimated_size = term_estimated_size;
+ } else {
+ 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];
+ if (ti) {
+ token_info_close(ctx, ti);
+ }
+ }
+ if (tis) {
+ GRN_FREE(tis);
+ }
+
+ return estimated_size;
+}
+
+uint32_t
+grn_ii_estimate_size_for_lexicon_cursor(grn_ctx *ctx, grn_ii *ii,
+ grn_table_cursor *lexicon_cursor)
+{
+ grn_id term_id;
+ uint32_t estimated_size = 0;
+
+ while ((term_id = grn_table_cursor_next(ctx, lexicon_cursor)) != GRN_ID_NIL) {
+ uint32_t term_estimated_size;
+ term_estimated_size = grn_ii_estimate_size(ctx, ii, term_id);
+ estimated_size += term_estimated_size;
+ }
+
+ return estimated_size;
+}
+
+grn_rc
+grn_ii_sel(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_len,
+ grn_hash *s, grn_operator op, grn_search_optarg *optarg)
+{
+ ERRCLR(ctx);
+ GRN_LOG(ctx, GRN_LOG_INFO, "grn_ii_sel > (%.*s)", string_len, string);
+ {
+ 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 :
+ case GRN_OP_NEAR2 :
+ arg.mode = optarg->mode;
+ arg.max_interval = optarg->max_interval;
+ break;
+ case GRN_OP_SIMILAR :
+ arg.mode = optarg->mode;
+ arg.similarity_threshold = optarg->similarity_threshold;
+ break;
+ 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) {
+ 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);
+ */
+ 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(1) failed !");
+ return ctx->rc;
+ }
+ 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 !");
+ 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 !");
+ 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));
+ return GRN_SUCCESS;
+ }
+}
+
+grn_rc
+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_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))) {
+ res_add(ctx, s, (grn_rset_posinfo *) pos, (1 + pos->weight), op);
+ }
+ grn_ii_cursor_close(ctx, c);
+ }
+ return ctx->rc;
+}
+
+void
+grn_ii_resolve_sel_and(grn_ctx *ctx, grn_hash *s, grn_operator op)
+{
+ if (op == GRN_OP_AND
+ && !(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);
+ if (c) {
+ while ((eid = grn_hash_cursor_next(ctx, c))) {
+ grn_hash_cursor_get_value(ctx, c, (void **) &ri);
+ if ((ri->n_subrecs & GRN_RSET_UTIL_BIT)) {
+ ri->n_subrecs &= ~GRN_RSET_UTIL_BIT;
+ } else {
+ grn_hash_delete_by_id(ctx, s, eid, NULL);
+ }
+ }
+ grn_hash_cursor_close(ctx, c);
+ }
+ }
+}
+
+void
+grn_ii_cursor_inspect(grn_ctx *ctx, grn_ii_cursor *c, grn_obj *buf)
+{
+ grn_obj key_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,
+ key, GRN_TABLE_MAX_KEY_SIZE);
+ GRN_OBJ_INIT(&key_buf, GRN_BULK, 0, c->ii->lexicon->header.domain);
+ GRN_TEXT_SET(ctx, &key_buf, key, key_size);
+ grn_inspect(ctx, buf, &key_buf);
+ GRN_OBJ_FIN(ctx, &key_buf);
+
+ GRN_TEXT_PUTS(ctx, buf, "\n elements:[\n ");
+ while (grn_ii_cursor_next_internal(ctx, c, &options)) {
+ grn_posting *pos = c->post;
+ if (i > 0) {
+ GRN_TEXT_PUTS(ctx, buf, ",\n ");
+ }
+ i++;
+ GRN_TEXT_PUTS(ctx, buf, "{status:");
+ if (pos->tf && pos->sid) {
+ GRN_TEXT_PUTS(ctx, buf, "available");
+ } else {
+ GRN_TEXT_PUTS(ctx, buf, "garbage");
+ }
+ GRN_TEXT_PUTS(ctx, buf, ", rid:");
+ grn_text_lltoa(ctx, buf, pos->rid);
+ GRN_TEXT_PUTS(ctx, buf, ", sid:");
+ grn_text_lltoa(ctx, buf, pos->sid);
+ GRN_TEXT_PUTS(ctx, buf, ", pos:");
+ grn_text_lltoa(ctx, buf, pos->pos);
+ GRN_TEXT_PUTS(ctx, buf, ", tf:");
+ grn_text_lltoa(ctx, buf, pos->tf);
+ GRN_TEXT_PUTS(ctx, buf, ", weight:");
+ grn_text_lltoa(ctx, buf, pos->weight);
+ GRN_TEXT_PUTS(ctx, buf, ", rest:");
+ grn_text_lltoa(ctx, buf, pos->rest);
+ GRN_TEXT_PUTS(ctx, buf, "}");
+ }
+ GRN_TEXT_PUTS(ctx, buf, "\n ]\n >");
+}
+
+void
+grn_ii_inspect_values(grn_ctx *ctx, grn_ii *ii, grn_obj *buf)
+{
+ grn_table_cursor *tc;
+ GRN_TEXT_PUTS(ctx, buf, "[");
+ if ((tc = grn_table_cursor_open(ctx, ii->lexicon, NULL, 0, NULL, 0, 0, -1,
+ GRN_CURSOR_ASCENDING))) {
+ int i = 0;
+ grn_id tid;
+ grn_ii_cursor *c;
+ while ((tid = grn_table_cursor_next(ctx, tc))) {
+ if (i > 0) {
+ GRN_TEXT_PUTS(ctx, buf, ",");
+ }
+ i++;
+ GRN_TEXT_PUTS(ctx, buf, "\n");
+ if ((c = grn_ii_cursor_open(ctx, ii, tid, GRN_ID_NIL, GRN_ID_MAX,
+ ii->n_elements,
+ GRN_OBJ_WITH_POSITION|GRN_OBJ_WITH_SECTION))) {
+ grn_ii_cursor_inspect(ctx, c, buf);
+ grn_ii_cursor_close(ctx, c);
+ }
+ }
+ grn_table_cursor_close(ctx, tc);
+ }
+ GRN_TEXT_PUTS(ctx, buf, "]");
+}
+
+/********************** buffered index builder ***********************/
+
+const grn_id II_BUFFER_TYPE_MASK = 0xc0000000;
+#define II_BUFFER_TYPE_RID 0x80000000
+#define II_BUFFER_TYPE_WEIGHT 0x40000000
+#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))
+#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";
+const uint32_t II_BUFFER_NCOUNTERS_MARGIN = 0x100000;
+const size_t II_BUFFER_BLOCK_SIZE = 0x1000000;
+const uint32_t II_BUFFER_BLOCK_READ_UNIT_SIZE = 0x200000;
+
+typedef struct {
+ 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 {
+ off64_t head;
+ off64_t tail;
+ uint32_t nextsize;
+ uint8_t *buffer;
+ uint32_t buffersize;
+ uint8_t *bufcur;
+ uint32_t rest;
+ grn_id tid;
+ uint32_t nrecs;
+ uint32_t nposts;
+ grn_id *recs;
+ uint32_t *tfs;
+ uint32_t *posts;
+} ii_buffer_block;
+
+struct _grn_ii_buffer {
+ 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; /* 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;
+ uint32_t dseg;
+ buffer *term_buffer;
+ datavec data_vectors[MAX_N_ELEMENTS + 1];
+ uint8_t *packed_buf;
+ size_t packed_buf_size;
+ size_t packed_len;
+ 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)
+{
+ ii_buffer_block *block;
+ if (!(ii_buffer->nblocks & 0x3ff)) {
+ ii_buffer_block *blocks;
+ if (!(blocks = GRN_REALLOC(ii_buffer->blocks,
+ (ii_buffer->nblocks + 0x400) *
+ sizeof(ii_buffer_block)))) {
+ return NULL;
+ }
+ ii_buffer->blocks = blocks;
+ }
+ block = &ii_buffer->blocks[ii_buffer->nblocks];
+ block->head = ii_buffer->filepos;
+ block->rest = 0;
+ block->buffer = NULL;
+ block->buffersize = 0;
+ return block;
+}
+
+/* allocate_outbuf allocates memory to flush a block. */
+static uint8_t *
+allocate_outbuf(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
+{
+ size_t bufsize = 0, bufsize_ = 0;
+ uint32_t flags = ii_buffer->ii->header->flags;
+ ii_buffer_counter *counter = ii_buffer->counters;
+ grn_id tid, tid_max = grn_table_size(ctx, ii_buffer->tmp_lexicon);
+ for (tid = 1; tid <= tid_max; counter++, tid++) {
+ counter->offset_tf += GRN_B_ENC_SIZE(counter->last_tf - 1);
+ counter->last_rid = 0;
+ counter->last_tf = 0;
+ bufsize += 5;
+ bufsize += GRN_B_ENC_SIZE(counter->nrecs);
+ bufsize += GRN_B_ENC_SIZE(counter->nposts);
+ bufsize += counter->offset_rid;
+ if ((flags & GRN_OBJ_WITH_SECTION)) {
+ bufsize += counter->offset_sid;
+ }
+ bufsize += counter->offset_tf;
+ if ((flags & GRN_OBJ_WITH_WEIGHT)) {
+ bufsize += counter->offset_weight;
+ }
+ if ((flags & GRN_OBJ_WITH_POSITION)) {
+ bufsize += counter->offset_pos;
+ }
+ if (bufsize_ + II_BUFFER_BLOCK_READ_UNIT_SIZE < bufsize) {
+ bufsize += sizeof(uint32_t);
+ bufsize_ = bufsize;
+ }
+ }
+ GRN_LOG(ctx, GRN_LOG_INFO, "flushing:%d bufsize:%" GRN_FMT_SIZE,
+ ii_buffer->nblocks, bufsize);
+ 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)
+{
+ grn_id tid;
+ 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,
+ NULL, 0, NULL, 0, 0, -1, II_BUFFER_ORDER);
+ while ((tid = grn_table_cursor_next(ctx, tc)) != GRN_ID_NIL) {
+ 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) {
+ uint32_t offset_rid = counter->offset_rid;
+ uint32_t offset_sid = counter->offset_sid;
+ uint32_t offset_tf = counter->offset_tf;
+ uint32_t offset_weight = counter->offset_weight;
+ uint32_t offset_pos = counter->offset_pos;
+ GRN_B_ENC(gtid, outbufp);
+ GRN_B_ENC(counter->nrecs, outbufp);
+ GRN_B_ENC(counter->nposts, outbufp);
+ ii_buffer->total_size += counter->nrecs + counter->nposts;
+ counter->offset_rid = outbufp - outbuf;
+ outbufp += offset_rid;
+ if ((flags & GRN_OBJ_WITH_SECTION)) {
+ counter->offset_sid = outbufp - outbuf;
+ outbufp += offset_sid;
+ }
+ counter->offset_tf = outbufp - outbuf;
+ outbufp += offset_tf;
+ if ((flags & GRN_OBJ_WITH_WEIGHT)) {
+ counter->offset_weight = outbufp - outbuf;
+ outbufp += offset_weight;
+ }
+ if ((flags & GRN_OBJ_WITH_POSITION)) {
+ counter->offset_pos = outbufp - outbuf;
+ outbufp += offset_pos;
+ }
+ }
+ if (outbufp_ + II_BUFFER_BLOCK_READ_UNIT_SIZE < outbufp) {
+ uint32_t size = outbufp - outbufp_ + sizeof(uint32_t);
+ grn_memcpy(pnext, &size, sizeof(uint32_t));
+ pnext = outbufp;
+ outbufp += sizeof(uint32_t);
+ outbufp_ = outbufp;
+ }
+ }
+ grn_table_cursor_close(ctx, tc);
+ if (outbufp_ < outbufp) {
+ uint32_t size = outbufp - outbufp_;
+ grn_memcpy(pnext, &size, sizeof(uint32_t));
+ }
+ 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)
+{
+ grn_id rid = 0;
+ unsigned int sid = 1;
+ unsigned int weight = 0;
+ uint32_t pos = 0;
+ uint32_t rest;
+ grn_id *bp = ii_buffer->block_buf;
+ uint32_t flags = ii_buffer->ii->header->flags;
+ for (rest = ii_buffer->block_pos; rest; bp++, rest--) {
+ grn_id id = *bp;
+ switch (II_BUFFER_TYPE(id)) {
+ case II_BUFFER_TYPE_RID :
+ rid = II_BUFFER_UNPACK(id, II_BUFFER_TYPE_RID);
+ if ((flags & GRN_OBJ_WITH_SECTION) && rest) {
+ sid = *++bp;
+ rest--;
+ }
+ weight = 0;
+ pos = 0;
+ break;
+ case II_BUFFER_TYPE_WEIGHT :
+ weight = II_BUFFER_UNPACK(id, II_BUFFER_TYPE_WEIGHT);
+ break;
+ default :
+ {
+ ii_buffer_counter *counter = &ii_buffer->counters[id - 1];
+ if (counter->last_rid == rid && counter->last_sid == sid) {
+ counter->last_tf++;
+ counter->last_weight += weight;
+ } else {
+ if (counter->last_tf) {
+ uint8_t *p = outbuf + counter->offset_tf;
+ GRN_B_ENC(counter->last_tf - 1, p);
+ counter->offset_tf = p - outbuf;
+ if (flags & GRN_OBJ_WITH_WEIGHT) {
+ p = outbuf + counter->offset_weight;
+ GRN_B_ENC(counter->last_weight, p);
+ counter->offset_weight = p - outbuf;
+ }
+ }
+ {
+ uint8_t *p = outbuf + counter->offset_rid;
+ GRN_B_ENC(rid - counter->last_rid, p);
+ counter->offset_rid = p - outbuf;
+ }
+ if (flags & GRN_OBJ_WITH_SECTION) {
+ uint8_t *p = outbuf + counter->offset_sid;
+ if (counter->last_rid != rid) {
+ GRN_B_ENC(sid - 1, p);
+ } else {
+ GRN_B_ENC(sid - counter->last_sid - 1, p);
+ }
+ counter->offset_sid = p - outbuf;
+ }
+ counter->last_rid = rid;
+ counter->last_sid = sid;
+ counter->last_tf = 1;
+ counter->last_weight = weight;
+ counter->last_pos = 0;
+ }
+ if ((flags & GRN_OBJ_WITH_POSITION) && rest) {
+ uint8_t *p = outbuf + counter->offset_pos;
+ pos = *++bp;
+ rest--;
+ GRN_B_ENC(pos - counter->last_pos, p);
+ counter->offset_pos = p - outbuf;
+ counter->last_pos = pos;
+ }
+ }
+ break;
+ }
+ }
+}
+
+/* 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)
+{
+ ii_buffer_counter *counter = ii_buffer->counters;
+ grn_id tid, tid_max = grn_table_size(ctx, ii_buffer->tmp_lexicon);
+ for (tid = 1; tid <= tid_max; counter++, tid++) {
+ uint8_t *p = outbuf + counter->offset_tf;
+ GRN_B_ENC(counter->last_tf - 1, p);
+ }
+ if ((ii_buffer->ii->header->flags & GRN_OBJ_WITH_WEIGHT)) {
+ for (tid = 1; tid <= tid_max; counter++, tid++) {
+ uint8_t *p = outbuf + counter->offset_weight;
+ GRN_B_ENC(counter->last_weight, p);
+ }
+ }
+}
+
+/*
+ * 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_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; }
+ encsize = encode_terms(ctx, ii_buffer, outbuf, block);
+ encode_postings(ctx, ii_buffer, outbuf);
+ encode_last_tf(ctx, ii_buffer, outbuf);
+ {
+ 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,
+ (long long int)r, (unsigned long long int)encsize);
+ GRN_FREE(outbuf);
+ return;
+ }
+ ii_buffer->filepos += r;
+ block->tail = ii_buffer->filepos;
+ }
+ GRN_FREE(outbuf);
+ memset(ii_buffer->counters, 0,
+ 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_DEBUG, "flushed: %d encsize:%" GRN_FMT_SIZE,
+ ii_buffer->nblocks, encsize);
+ ii_buffer->tmp_lexicon = NULL;
+ ii_buffer->nblocks++;
+ ii_buffer->block_pos = 0;
+}
+
+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)
+{
+ grn_obj *tmp_lexicon = ii_buffer->tmp_lexicon;
+ if (!tmp_lexicon) {
+ grn_obj *domain = grn_ctx_at(ctx, ii_buffer->lexicon->header.domain);
+ grn_obj *range = grn_ctx_at(ctx, DB_OBJ(ii_buffer->lexicon)->range);
+ grn_obj *tokenizer;
+ grn_obj *normalizer;
+ grn_obj *token_filters;
+ grn_table_flags flags;
+ grn_table_get_info(ctx, ii_buffer->lexicon, &flags, NULL,
+ &tokenizer, &normalizer, &token_filters);
+ flags &= ~GRN_OBJ_PERSISTENT;
+ tmp_lexicon = grn_table_create(ctx, NULL, 0, NULL, flags, domain, range);
+ if (tmp_lexicon) {
+ ii_buffer->tmp_lexicon = tmp_lexicon;
+ grn_obj_set_info(ctx, tmp_lexicon,
+ GRN_INFO_DEFAULT_TOKENIZER, tokenizer);
+ grn_obj_set_info(ctx, tmp_lexicon,
+ GRN_INFO_NORMALIZER, normalizer);
+ grn_obj_set_info(ctx, tmp_lexicon,
+ GRN_INFO_TOKEN_FILTERS, token_filters);
+ if ((flags & GRN_OBJ_TABLE_TYPE_MASK) == GRN_OBJ_TABLE_PAT_KEY) {
+ grn_pat_cache_enable(ctx, (grn_pat *)tmp_lexicon, PAT_CACHE_SIZE);
+ }
+ }
+ }
+ 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)
+{
+ if (tid > ii_buffer->ncounters) {
+ ii_buffer_counter *counters;
+ uint32_t ncounters =
+ grn_table_size(ctx, tmp_lexicon) + II_BUFFER_NCOUNTERS_MARGIN;
+ counters = GRN_REALLOC(ii_buffer->counters,
+ ncounters * sizeof(ii_buffer_counter));
+ if (!counters) { return NULL; }
+ memset(&counters[ii_buffer->ncounters], 0,
+ (ncounters - ii_buffer->ncounters) * sizeof(ii_buffer_counter));
+ ii_buffer->ncounters = ncounters;
+ ii_buffer->counters = counters;
+ }
+ 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_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;
+ }
+ 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->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_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) {
+ void *r = GRN_REALLOC(block->buffer, bytesize);
+ if (r) {
+ block->buffer = (uint8_t *)r;
+ block->buffersize = block->nextsize;
+ } else {
+ GRN_LOG(ctx, GRN_LOG_WARNING, "realloc: %" GRN_FMT_LLU,
+ (unsigned long long int)bytesize);
+ return;
+ }
+ }
+ {
+ off64_t seeked_position;
+ seeked_position = grn_lseek(ii_buffer->tmpfd, block->head, SEEK_SET);
+ if (seeked_position != block->head) {
+ ERRNO_ERR("failed to "
+ "grn_lseek(%" GRN_FMT_OFF64_T ") -> %" GRN_FMT_OFF64_T,
+ block->head,
+ seeked_position);
+ 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;
+ if (block->head >= block->tail) {
+ if (block->head > block->tail) {
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "fetch error: %" GRN_FMT_INT64D " > %" GRN_FMT_INT64D,
+ block->head, block->tail);
+ }
+ block->rest = block->nextsize;
+ block->nextsize = 0;
+ } else {
+ block->rest = block->nextsize - sizeof(uint32_t);
+ grn_memcpy(&block->nextsize,
+ &block->buffer[block->rest], sizeof(uint32_t));
+ }
+ }
+ }
+ if (block->rest) {
+ uint8_t *p = block->bufcur;
+ GRN_B_DEC(block->tid, p);
+ GRN_B_DEC(block->nrecs, p);
+ GRN_B_DEC(block->nposts, p);
+ block->rest -= (p - block->bufcur);
+ block->bufcur = p;
+ } else {
+ block->tid = 0;
+ }
+}
+
+/* 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)
+{
+ grn_io_win io_win;
+ uint32_t chunk_number;
+ chunk_new(ctx, ii_buffer->ii, &chunk_number, ii_buffer->packed_len);
+ GRN_LOG(ctx, GRN_LOG_INFO, "chunk:%d, packed_len:%" GRN_FMT_SIZE,
+ chunk_number, ii_buffer->packed_len);
+ fake_map(ctx, ii_buffer->ii->chunk, &io_win, ii_buffer->packed_buf,
+ chunk_number, ii_buffer->packed_len);
+ grn_io_win_unmap(&io_win);
+ ii_buffer->term_buffer->header.chunk = chunk_number;
+ ii_buffer->term_buffer->header.chunk_size = ii_buffer->packed_len;
+ ii_buffer->term_buffer->header.buffer_free =
+ S_SEGMENT - sizeof(buffer_header) -
+ ii_buffer->term_buffer->header.nterms * sizeof(buffer_term);
+ ii_buffer->term_buffer->header.nterms_void = 0;
+ 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_DEBUG,
+ "nterms=%d chunk=%d total=%" GRN_FMT_INT64U "KB",
+ ii_buffer->term_buffer->header.nterms,
+ ii_buffer->term_buffer->header.chunk_size,
+ ii_buffer->ii->header->total_chunk_size >> 10);
+ ii_buffer->term_buffer = NULL;
+ ii_buffer->packed_buf = NULL;
+ ii_buffer->packed_len = 0;
+ ii_buffer->packed_buf_size = 0;
+ 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)
+{
+ uint64_t nrecs = 0;
+ uint64_t nposts = 0;
+ size_t max_size;
+ uint64_t flags = ii_buffer->ii->header->flags;
+ int i;
+ for (i = 0; i < nhits; i++) {
+ ii_buffer_block *block = hits[i];
+ nrecs += block->nrecs;
+ nposts += block->nposts;
+ }
+ ii_buffer->curr_size += nrecs + nposts;
+ max_size = nrecs * (ii_buffer->ii->n_elements);
+ if (flags & GRN_OBJ_WITH_POSITION) { max_size += nposts - nrecs; }
+ datavec_reset(ctx, ii_buffer->data_vectors,
+ ii_buffer->ii->n_elements, nrecs, max_size);
+ {
+ int i;
+ 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) {
+ sidp = ii_buffer->data_vectors[j++].data;
+ }
+ tfp = ii_buffer->data_vectors[j++].data;
+ if (flags & GRN_OBJ_WITH_WEIGHT) {
+ weightp = ii_buffer->data_vectors[j++].data;
+ }
+ if (flags & GRN_OBJ_WITH_POSITION) {
+ posp = ii_buffer->data_vectors[j++].data;
+ }
+ }
+ 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;
+ if (n) {
+ GRN_B_DEC(*ridp, p);
+ *ridp -= lr;
+ lr += *ridp++;
+ while (--n) {
+ GRN_B_DEC(*ridp, p);
+ lr += *ridp++;
+ }
+ }
+ if ((flags & GRN_OBJ_WITH_SECTION)) {
+ for (n = block->nrecs; n; n--) {
+ GRN_B_DEC(*sidp++, p);
+ }
+ }
+ for (n = block->nrecs; n; n--) {
+ GRN_B_DEC(*tfp++, p);
+ }
+ if ((flags & GRN_OBJ_WITH_WEIGHT)) {
+ for (n = block->nrecs; n; n--) {
+ GRN_B_DEC(*weightp++, p);
+ }
+ }
+ if ((flags & GRN_OBJ_WITH_POSITION)) {
+ for (n = block->nposts; n; n--) {
+ GRN_B_DEC(*posp, p);
+ spos += *posp++;
+ }
+ }
+ block->rest -= (p - block->bufcur);
+ block->bufcur = p;
+ 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;
+ ii_buffer->data_vectors[j].data_size = nrecs;
+ ii_buffer->data_vectors[j++].flags = f_d;
+ if ((flags & GRN_OBJ_WITH_SECTION)) {
+ ii_buffer->data_vectors[j].data_size = nrecs;
+ ii_buffer->data_vectors[j++].flags = f_s;
+ }
+ ii_buffer->data_vectors[j].data_size = nrecs;
+ ii_buffer->data_vectors[j++].flags = f_s;
+ if ((flags & GRN_OBJ_WITH_WEIGHT)) {
+ ii_buffer->data_vectors[j].data_size = nrecs;
+ ii_buffer->data_vectors[j++].flags = f_s;
+ }
+ if ((flags & GRN_OBJ_WITH_POSITION)) {
+ uint32_t f_p = (((nposts < 32) ||
+ (nposts <= (spos >> 13))) ? 0 : USE_P_ENC);
+ ii_buffer->data_vectors[j].data_size = nposts;
+ ii_buffer->data_vectors[j++].flags = f_p|ODD;
+ }
+ }
+ }
+ return (max_size + ii_buffer->ii->n_elements) * 4;
+}
+
+static buffer *
+get_term_buffer(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
+{
+ if (!ii_buffer->term_buffer) {
+ uint32_t lseg;
+ void *term_buffer;
+ for (lseg = 0; lseg < GRN_II_MAX_LSEG; lseg++) {
+ if (ii_buffer->ii->header->binfo[lseg] == GRN_II_PSEG_NOT_ASSIGNED) { break; }
+ }
+ if (lseg == GRN_II_MAX_LSEG) {
+ 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;
+ ii_buffer->dseg = segment_get(ctx, ii_buffer->ii);
+ GRN_IO_SEG_REF(ii_buffer->ii->seg, ii_buffer->dseg, term_buffer);
+ ii_buffer->term_buffer = (buffer *)term_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)
+{
+ if (nhits == 1 && hits[0]->nrecs == 1 && hits[0]->nposts == 1) {
+ grn_id rid;
+ uint32_t sid = 1, tf, pos = 0, weight = 0;
+ ii_buffer_block *block = hits[0];
+ uint8_t *p = block->bufcur;
+ uint32_t flags = ii_buffer->ii->header->flags;
+ GRN_B_DEC(rid, p);
+ if (flags & GRN_OBJ_WITH_SECTION) {
+ GRN_B_DEC(sid, p);
+ sid++;
+ }
+ GRN_B_DEC(tf, p);
+ if (tf != 0) { GRN_LOG(ctx, GRN_LOG_WARNING, "tf=%d", tf); }
+ if (flags & GRN_OBJ_WITH_WEIGHT) { GRN_B_DEC(weight, p); }
+ if (flags & GRN_OBJ_WITH_POSITION) { GRN_B_DEC(pos, p); }
+ if (!weight) {
+ if (flags & GRN_OBJ_WITH_SECTION) {
+ if (rid < 0x100000 && sid < 0x800) {
+ 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;
+ }
+ } else {
+ 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;
+ grn_ii_buffer_fetch(ctx, ii_buffer, block);
+ return GRN_TRUE;
+ }
+ }
+ 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) {
+ grn_ii_buffer_chunk_flush(ctx, ii_buffer);
+ }
+ if (!ii_buffer->packed_buf) {
+ size_t buf_size = (max_size > II_BUFFER_PACKED_BUF_SIZE)
+ ? max_size : II_BUFFER_PACKED_BUF_SIZE;
+ if ((ii_buffer->packed_buf = GRN_MALLOC(buf_size))) {
+ ii_buffer->packed_buf_size = buf_size;
+ }
+ }
+ {
+ /* Pack postings into the current buffer. */
+ uint16_t nterm;
+ size_t packed_len;
+ buffer_term *bt;
+ 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,
+ (sizeof(buffer_header) + sizeof(buffer_term) * nterm));
+ packed_len = grn_p_encv(ctx, ii_buffer->data_vectors,
+ ii_buffer->ii->n_elements,
+ ii_buffer->packed_buf +
+ ii_buffer->packed_len);
+ a[1] = ii_buffer->data_vectors[0].data_size;
+ bt->tid = tid;
+ bt->size_in_buffer = 0;
+ bt->pos_in_buffer = 0;
+ bt->size_in_chunk = packed_len;
+ bt->pos_in_chunk = ii_buffer->packed_len;
+ ii_buffer->packed_len += packed_len;
+ if (((ii_buffer->curr_size * ii_buffer->update_buffer_size) +
+ (ii_buffer->total_size * term_buffer->header.nterms * 16)) >=
+ (ii_buffer->total_size * II_BUFFER_NTERMS_PER_BUFFER * 16)) {
+ grn_ii_buffer_chunk_flush(ctx, ii_buffer);
+ }
+ array_unref(ii_buffer->ii, tid);
+ }
+ }
+}
+
+grn_ii_buffer *
+grn_ii_buffer_open(grn_ctx *ctx, grn_ii *ii,
+ long long unsigned int update_buffer_size)
+{
+ if (ii && ii->lexicon) {
+ grn_ii_buffer *ii_buffer = GRN_MALLOCN(grn_ii_buffer, 1);
+ if (ii_buffer) {
+ ii_buffer->ii = ii;
+ ii_buffer->lexicon = ii->lexicon;
+ ii_buffer->tmp_lexicon = NULL;
+ ii_buffer->nblocks = 0;
+ ii_buffer->blocks = NULL;
+ ii_buffer->ncounters = II_BUFFER_NCOUNTERS_MARGIN;
+ ii_buffer->block_pos = 0;
+ ii_buffer->filepos = 0;
+ ii_buffer->curr_size = 0;
+ ii_buffer->total_size = 0;
+ ii_buffer->update_buffer_size = update_buffer_size;
+ ii_buffer->counters = GRN_CALLOC(ii_buffer->ncounters *
+ sizeof(ii_buffer_counter));
+ ii_buffer->term_buffer = NULL;
+ ii_buffer->packed_buf = NULL;
+ 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) {
+ grn_snprintf(ii_buffer->tmpfpath, PATH_MAX, PATH_MAX,
+ "%-.256sXXXXXX", grn_io_path(ii->seg));
+ ii_buffer->block_buf_size = II_BUFFER_BLOCK_SIZE;
+ ii_buffer->tmpfd = grn_mkstemp(ii_buffer->tmpfpath);
+ if (ii_buffer->tmpfd != -1) {
+ 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("failed grn_mkstemp(%-.256s)",
+ ii_buffer->tmpfpath);
+ }
+ GRN_FREE(ii_buffer->block_buf);
+ }
+ GRN_FREE(ii_buffer->counters);
+ }
+ GRN_FREE(ii_buffer);
+ }
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "ii or ii->lexicon is NULL");
+ }
+ 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)
+{
+ 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);
+ }
+ if (ii_buffer->tmpfd != -1) {
+ grn_close(ii_buffer->tmpfd);
+ }
+ if (ii_buffer->block_buf) {
+ GRN_FREE(ii_buffer->block_buf);
+ ii_buffer->block_buf = NULL;
+ }
+ if (ii_buffer->counters) {
+ GRN_FREE(ii_buffer->counters);
+ ii_buffer->counters = NULL;
+ }
+
+ if (ii_buffer->update_buffer_size &&
+ ii_buffer->update_buffer_size < 20) {
+ if (ii_buffer->update_buffer_size < 10) {
+ ii_buffer->update_buffer_size =
+ ii_buffer->total_size >> (10 - ii_buffer->update_buffer_size);
+ } else {
+ ii_buffer->update_buffer_size =
+ ii_buffer->total_size << (ii_buffer->update_buffer_size - 10);
+ }
+ }
+
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
+ "nblocks=%d, update_buffer_size=%" GRN_FMT_INT64U,
+ ii_buffer->nblocks, ii_buffer->update_buffer_size);
+
+ datavec_init(ctx, ii_buffer->data_vectors, ii_buffer->ii->n_elements, 0, 0);
+ grn_open(ii_buffer->tmpfd,
+ ii_buffer->tmpfpath,
+ O_RDONLY | GRN_OPEN_FLAG_BINARY);
+ if (ii_buffer->tmpfd == -1) {
+ ERRNO_ERR("failed to open path: <%-.256s>", 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]);
+ }
+ }
+ {
+ ii_buffer_block **hits;
+ if ((hits = GRN_MALLOCN(ii_buffer_block *, ii_buffer->nblocks))) {
+ grn_id tid;
+ grn_table_cursor *tc;
+ tc = grn_table_cursor_open(ctx, ii_buffer->lexicon,
+ 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;
+ for (i = 0; i < ii_buffer->nblocks; i++) {
+ if (ii_buffer->blocks[i].tid == tid) {
+ hits[nhits++] = &ii_buffer->blocks[i];
+ }
+ if (ii_buffer->blocks[i].tid) { nrests++; }
+ }
+ if (nhits) { grn_ii_buffer_merge(ctx, ii_buffer, tid, hits, nhits); }
+ if (!nrests) { break; }
+ }
+ if (ii_buffer->packed_len) {
+ grn_ii_buffer_chunk_flush(ctx, ii_buffer);
+ }
+ grn_table_cursor_close(ctx, tc);
+ }
+ GRN_FREE(hits);
+ }
+ }
+ datavec_fin(ctx, ii_buffer->data_vectors);
+ 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);
+ if (grn_unlink(ii_buffer->tmpfpath) == 0) {
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "[ii][buffer][commit] removed temporary path: <%-.256s>",
+ ii_buffer->tmpfpath);
+ } else {
+ ERRNO_ERR("[ii][buffer][commit] failed to remove temporary path: <%-.256s>",
+ ii_buffer->tmpfpath);
+ }
+ ii_buffer->tmpfd = -1;
+ return ctx->rc;
+}
+
+grn_rc
+grn_ii_buffer_close(grn_ctx *ctx, grn_ii_buffer *ii_buffer)
+{
+ uint32_t i;
+ 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);
+ }
+ if (ii_buffer->tmp_lexicon) {
+ grn_obj_close(ctx, ii_buffer->tmp_lexicon);
+ }
+ if (ii_buffer->tmpfd != -1) {
+ grn_close(ii_buffer->tmpfd);
+ if (grn_unlink(ii_buffer->tmpfpath) == 0) {
+ GRN_LOG(ctx, GRN_LOG_INFO,
+ "[ii][buffer][close] removed temporary path: <%-.256s>",
+ ii_buffer->tmpfpath);
+ } else {
+ ERRNO_ERR("[ii][buffer][close] failed to remove temporary path: <%-.256s>",
+ ii_buffer->tmpfpath);
+ }
+ }
+ if (ii_buffer->block_buf) {
+ GRN_FREE(ii_buffer->block_buf);
+ }
+ if (ii_buffer->counters) {
+ GRN_FREE(ii_buffer->counters);
+ }
+ if (ii_buffer->blocks) {
+ for (i = 0; i < ii_buffer->nblocks; i++) {
+ if (ii_buffer->blocks[i].buffer) {
+ GRN_FREE(ii_buffer->blocks[i].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;
+ 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);
+ }
+ 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);
+ }
+ }
+ 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;
+ }
+ }
+ grn_ii_buffer_tokenize(ctx, ii_buffer, rid);
+ }
+ grn_table_cursor_close(ctx, tc);
+ }
+ for (i = 0; i < ncols; i++) {
+ GRN_OBJ_FIN(ctx, &vobjs[i]);
+ }
+ GRN_FREE(vobjs);
+ }
+}
+
+grn_rc
+grn_ii_build(grn_ctx *ctx, grn_ii *ii, uint64_t sparsity)
+{
+ grn_ii_buffer *ii_buffer;
+
+ {
+ /* 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;
+ }
+ if (grn_table_size(ctx, data_table) == 0) {
+ return ctx->rc;
+ }
+ }
+
+ ii_buffer = grn_ii_buffer_open(ctx, ii, sparsity);
+ if (ii_buffer) {
+ 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, source[i]))) { break; }
+ }
+ 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);
+ }
+ if (target) {
+ grn_ii_buffer_parse(ctx, ii_buffer, target, ncols, cols);
+ grn_ii_buffer_commit(ctx, ii_buffer);
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "failed to resolve the target");
+ }
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "failed to resolve a column (%d)", i);
+ }
+ GRN_FREE(cols);
+ }
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "ii->obj.source is void");
+ }
+ grn_ii_buffer_close(ctx, ii_buffer);
+ }
+ 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: <%-.256s>",
+ builder->path);
+ } else {
+ ERRNO_ERR("[ii][builder][fin] failed to remove path: <%-.256s>",
+ 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,
+ "%-.256sXXXXXX", grn_io_path(builder->ii->seg));
+ builder->fd = grn_mkstemp(builder->path);
+ if (builder->fd == -1) {
+ SERR("failed to create a temporary file: path = \"%-.256s\"",
+ 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 00000000..c4a2a7c6
--- /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-1335 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
new file mode 100644
index 00000000..01359521
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/io.c
@@ -0,0 +1,2201 @@
+/* -*- 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-1335 USA
+*/
+
+#include "grn.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include "grn_ctx.h"
+#include "grn_io.h"
+#include "grn_plugin.h"
+#include "grn_hash.h"
+#include "grn_ctx_impl.h"
+#include "grn_util.h"
+
+#ifdef WIN32
+# include <io.h>
+# include <share.h>
+#endif /* WIN32 */
+
+#define GRN_IO_IDSTR "GROONGA:IO:00001"
+#define GRN_IO_IDSTR_LEN (sizeof(GRN_IO_IDSTR) - 1)
+
+#define GRN_IO_VERSION_DEFAULT 1
+
+#define GRN_IO_FILE_SIZE_V1 1073741824UL
+
+#ifdef WIN32
+# define GRN_IO_FILE_SIZE_V0 134217728L
+#else /* WIN32 */
+# define GRN_IO_FILE_SIZE_V0 GRN_IO_FILE_SIZE_V1
+#endif /* WIN32 */
+
+typedef struct _grn_io_fileinfo {
+#ifdef WIN32
+ HANDLE fh;
+ HANDLE fmo;
+ grn_critical_section cs;
+#else /* WIN32 */
+ int fd;
+ dev_t dev;
+ ino_t inode;
+#endif /* WIN32 */
+} 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 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_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_ctx *owner_ctx,
+ grn_io *io, HANDLE *fmo, fileinfo *fi,
+ void *start, size_t 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_ctx *owner_ctx,
+ grn_io *io, fileinfo *fi,
+ off_t offset, size_t length);
+inline static int grn_munmap(grn_ctx *ctx, grn_ctx *owner_ctx,
+ grn_io *io, fileinfo *fi,
+ void *start, size_t 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_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,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,owner_ctx,io,fmo,fi,offset,length)\
+ (grn_mmap((ctx), (owner_ctx), (io), (fi), (offset), (length)))
+# endif /* USE_FAIL_MALLOC */
+#endif /* WIN32 */
+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];
+
+ 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;
+ }
+ }
+}
+
+static inline uint32_t
+grn_io_compute_base(uint32_t header_size)
+{
+ uint32_t total_header_size;
+ total_header_size = IO_HEADER_SIZE + header_size;
+ return (total_header_size + grn_pagesize - 1) & ~(grn_pagesize - 1);
+}
+
+static inline uint32_t
+grn_io_compute_base_segment(uint32_t base, uint32_t segment_size)
+{
+ return (base + segment_size - 1) / segment_size;
+}
+
+static uint32_t
+grn_io_compute_max_n_files(uint32_t segment_size, uint32_t max_segment,
+ unsigned int base_segument, unsigned long file_size)
+{
+ uint64_t last_segment_end;
+ last_segment_end = ((uint64_t)segment_size) * (max_segment + base_segument);
+ return (uint32_t)((last_segment_end + file_size - 1) / file_size);
+}
+
+static inline unsigned long
+grn_io_compute_file_size(uint32_t version)
+{
+ if (version == 0) {
+ return GRN_IO_FILE_SIZE_V0;
+ } else {
+ return GRN_IO_FILE_SIZE_V1;
+ }
+}
+
+static inline uint32_t
+grn_io_max_segment(grn_io *io)
+{
+ if (io->header->segment_tail) {
+ return io->header->segment_tail;
+ } else {
+ return io->header->max_segment;
+ }
+}
+
+static uint32_t
+grn_io_max_n_files(grn_io *io)
+{
+ unsigned long file_size;
+
+ file_size = grn_io_compute_file_size(io->header->version);
+ return grn_io_compute_max_n_files(io->header->segment_size,
+ grn_io_max_segment(io),
+ io->base_seg,
+ file_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(ctx, &grn_gctx, NULL, NULL, NULL,
+ 0, b);
+ if (header) {
+ header->version = grn_io_version_default;
+ header->header_size = header_size;
+ header->segment_size = segment_size;
+ header->max_segment = max_segment;
+ header->n_arrays = 0;
+ header->flags = flags;
+ header->lock = 0;
+ grn_memcpy(header->idstr, GRN_IO_IDSTR, 16);
+ if ((io = GRN_MALLOCN(grn_io, 1))) {
+ grn_io_mapinfo *maps = NULL;
+ if ((maps = GRN_CALLOC(sizeof(grn_io_mapinfo) * max_segment))) {
+ io->header = header;
+ io->user_header = (((byte *) header) + IO_HEADER_SIZE);
+ io->maps = maps;
+ io->base = b;
+ io->base_seg = 0;
+ io->mode = mode;
+ io->header->curr_size = b;
+ io->fis = NULL;
+ io->ainfo = NULL;
+ io->max_map_seg = 0;
+ io->nmaps = 0;
+ io->count = 0;
+ io->flags = GRN_IO_TEMPORARY;
+ io->lock = &header->lock;
+ io->path[0] = '\0';
+ return io;
+ }
+ GRN_FREE(io);
+ }
+ GRN_MUNMAP(ctx, &grn_gctx, NULL, NULL, NULL, header, b);
+ }
+ return NULL;
+}
+
+static void
+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;
+ CRITICAL_SECTION_ENTER(grn_glock);
+ if (grn_gctx.impl && grn_gctx.impl->ios &&
+ grn_hash_add(&grn_gctx, grn_gctx.impl->ios, io->path, strlen(io->path),
+ (void **)&io, NULL)) {
+ succeeded = GRN_TRUE;
+ }
+ CRITICAL_SECTION_LEAVE(grn_glock);
+ if (!succeeded) {
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "grn_io_register(%s) failed", io->path);
+ }
+ }
+}
+
+static void
+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;
+ CRITICAL_SECTION_ENTER(grn_glock);
+ if (grn_gctx.impl && grn_gctx.impl->ios) {
+ grn_hash_delete(&grn_gctx, grn_gctx.impl->ios,
+ io->path, strlen(io->path), NULL);
+ succeeded = GRN_TRUE;
+ }
+ CRITICAL_SECTION_LEAVE(grn_glock);
+ if (!succeeded) {
+ 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 *io;
+ fileinfo *fis;
+ uint32_t b, max_nfiles;
+ uint32_t bs;
+ struct _grn_io_header *header;
+ uint32_t version = grn_io_version_default;
+ unsigned long file_size;
+
+ if (!path) {
+ 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);
+ bs = grn_io_compute_base_segment(b, segment_size);
+ 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_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(ctx, &grn_gctx, NULL,
+ &fis->fmo, fis, 0, b);
+ if (header) {
+ header->version = version;
+ header->header_size = header_size;
+ header->segment_size = segment_size;
+ header->max_segment = max_segment;
+ header->n_arrays = 0;
+ header->flags = flags;
+ header->lock = 0;
+ grn_memcpy(header->idstr, GRN_IO_IDSTR, 16);
+ GRN_MSYNC(ctx, fis[0].fh, header, b);
+ if ((io = GRN_MALLOCN(grn_io, 1))) {
+ grn_io_mapinfo *maps = NULL;
+ 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);
+ io->maps = maps;
+ io->base = b;
+ io->base_seg = bs;
+ io->mode = mode;
+ io->header->curr_size = b;
+ io->fis = fis;
+ io->ainfo = NULL;
+ io->max_map_seg = 0;
+ io->nmaps = 0;
+ io->count = 0;
+ io->flags = flags;
+ io->lock = &header->lock;
+ grn_io_register(ctx, io);
+ return io;
+ }
+ GRN_FREE(io);
+ }
+ GRN_MUNMAP(ctx, &grn_gctx, NULL, &fis->fmo, fis, header, b);
+ }
+ grn_fileinfo_close(ctx, fis);
+ 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_FREE(fis);
+ }
+ return NULL;
+}
+
+static grn_rc
+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_CALLOC(msize))) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ io->ainfo = (grn_io_array_info *)mp;
+ hp += sizeof(grn_io_array_spec) * n_arrays;
+ mp += sizeof(grn_io_array_info) * n_arrays;
+ for (ws = 0; (1 << ws) < io->header->segment_size; ws++);
+ for (i = 0; i < n_arrays; i++) {
+ uint32_t we = ws - array_specs[i].w_of_element;
+ io->ainfo[i].w_of_elm_in_a_segment = we;
+ io->ainfo[i].elm_mask_in_a_segment = (1 << we) - 1;
+ io->ainfo[i].max_n_segments = array_specs[i].max_n_segments;
+ io->ainfo[i].element_size = 1 << array_specs[i].w_of_element;
+ io->ainfo[i].segments = (uint32_t *)hp;
+ io->ainfo[i].addrs = (void **)mp;
+ hp += sizeof(uint32_t) * array_specs[i].max_n_segments;
+ mp += sizeof(void *) * array_specs[i].max_n_segments;
+ }
+ io->user_header += hsize;
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+array_init(grn_ctx *ctx, grn_io *io, int n_arrays)
+{
+ if (n_arrays) {
+ int i;
+ grn_io_array_spec *array_specs = (grn_io_array_spec *)io->user_header;
+ size_t hsize = sizeof(grn_io_array_spec) * n_arrays;
+ size_t msize = sizeof(grn_io_array_info) * n_arrays;
+ for (i = 0; i < n_arrays; i++) {
+ hsize += sizeof(uint32_t) * array_specs[i].max_n_segments;
+ msize += sizeof(void *) * array_specs[i].max_n_segments;
+ }
+ return array_init_(ctx, io, n_arrays, hsize, msize);
+ }
+ return GRN_SUCCESS;
+}
+
+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)
+{
+ if (n_arrays) {
+ int i;
+ grn_io *io;
+ byte *hp;
+ uint32_t nsegs = 0;
+ size_t hsize = sizeof(grn_io_array_spec) * n_arrays;
+ size_t msize = sizeof(grn_io_array_info) * n_arrays;
+ for (i = 0; i < n_arrays; i++) {
+ nsegs += array_specs[i].max_n_segments;
+ hsize += sizeof(uint32_t) * array_specs[i].max_n_segments;
+ msize += sizeof(void *) * array_specs[i].max_n_segments;
+ }
+ 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;
+ 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");
+ grn_io_close(ctx, io);
+ }
+ }
+ return NULL;
+}
+
+inline static uint32_t
+segment_alloc(grn_ctx *ctx, grn_io *io)
+{
+ uint32_t n, s;
+ grn_io_array_info *ai;
+ if (io->header->segment_tail) {
+ if (io->header->segment_tail > io->header->max_segment) {
+ s = 0;
+ } else {
+ s = io->header->segment_tail++;
+ }
+ } else {
+ 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++) {
+ used[ai->segments[s]] = 1;
+ }
+ }
+ for (s = 1; ; s++) {
+ if (s > io->header->max_segment) {
+ io->header->segment_tail = s;
+ s = 0;
+ break;
+ }
+ if (!used[s]) {
+ io->header->segment_tail = s + 1;
+ break;
+ }
+ }
+ 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)
+{
+ uint32_t *sp = &ai->segments[lseg];
+ if (!*sp) {
+ if ((*flags & GRN_TABLE_ADD)) {
+ if ((*sp = segment_alloc(ctx, io))) {
+ *flags |= GRN_TABLE_ADDED;
+ }
+ }
+ }
+ if (*sp) {
+ uint32_t pseg = *sp - 1;
+ GRN_IO_SEG_REF(io, pseg, *p);
+ if (*p) { GRN_IO_SEG_UNREF(io, pseg); };
+ }
+}
+
+void *
+grn_io_array_at(grn_ctx *ctx, grn_io *io, uint32_t array, off_t offset, int *flags)
+{
+ void *res;
+ GRN_IO_ARRAY_AT(io,array,offset,flags,res);
+ return res;
+}
+
+uint32_t
+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_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 (!memcmp(h.idstr, GRN_IO_IDSTR, GRN_IO_IDSTR_LEN)) {
+ res = h.type;
+ } else {
+ ERR(GRN_INCOMPATIBLE_FILE_FORMAT,
+ "failed to detect type: format ID is different: <%s>: <%.*s>",
+ path,
+ (int)GRN_IO_IDSTR_LEN, GRN_IO_IDSTR);
+ }
+ } else {
+ 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("failed to open path for detecting type: <%s>",
+ path);
+ }
+ return res;
+}
+
+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) {
+ 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("failed to open path: <%s>",
+ path);
+ return NULL;
+ }
+ 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 == 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(ctx, &grn_gctx, NULL, &(fi.fmo), &fi, 0, b);
+ if (header) {
+ unsigned long file_size;
+ unsigned int max_nfiles;
+ fileinfo *fis;
+
+ 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_MALLOCN(fileinfo, max_nfiles);
+ if (!fis) {
+ 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_MALLOC(sizeof(grn_io)))) {
+ grn_io_mapinfo *maps = NULL;
+ 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);
+ {
+ io->maps = maps;
+ io->base = b;
+ io->base_seg = bs;
+ io->mode = mode;
+ io->fis = fis;
+ io->ainfo = NULL;
+ io->max_map_seg = 0;
+ io->nmaps = 0;
+ io->count = 0;
+ io->flags = header->flags;
+ io->lock = &header->lock;
+ if (!array_init(ctx, io, io->header->n_arrays)) {
+ grn_io_register(ctx, io);
+ return io;
+ }
+ }
+ if (io->maps) { GRN_FREE(io->maps); }
+ }
+ GRN_FREE(io);
+ }
+ GRN_FREE(fis);
+ GRN_MUNMAP(ctx, &grn_gctx, NULL, &(fi.fmo), &fi, header, b);
+ }
+ grn_fileinfo_close(ctx, &fi);
+ }
+ return NULL;
+}
+
+grn_rc
+grn_io_close(grn_ctx *ctx, grn_io *io)
+{
+ uint32_t max_nfiles;
+
+ max_nfiles = grn_io_max_n_files(io);
+ grn_io_unregister(ctx, io);
+ if (io->ainfo) { GRN_FREE(io->ainfo); }
+ if (io->maps) {
+ int i;
+ uint32_t max_segment;
+ uint32_t segment_size;
+ unsigned long file_size;
+ uint32_t segments_per_file;
+
+ max_segment = grn_io_max_segment(io);
+ segment_size = io->header->segment_size;
+ file_size = grn_io_compute_file_size(io->header->version);
+ segments_per_file = file_size / segment_size;
+ for (i = 0; i < max_segment; i++) {
+ grn_io_mapinfo *mi;
+ mi = &(io->maps[i]);
+ if (mi->map) {
+ fileinfo *fi = NULL;
+ /* if (atomic_read(mi->nref)) { return STILL_IN_USE ; } */
+ if (io->fis) {
+ uint32_t bseg = i + io->base_seg;
+ uint32_t fno = bseg / segments_per_file;
+ fi = &io->fis[fno];
+ }
+ GRN_MUNMAP(ctx, &grn_gctx, io, &mi->fmo, fi, mi->map, segment_size);
+ }
+ }
+ GRN_FREE(io->maps);
+ }
+ GRN_MUNMAP(ctx, &grn_gctx, io, (io->fis ? &io->fis->fmo : NULL),
+ io->fis, io->header, io->base);
+ if (io->fis) {
+ int i;
+ for (i = 0; i < max_nfiles; i++) {
+ fileinfo *fi = &(io->fis[i]);
+ grn_fileinfo_close(ctx, fi);
+ }
+ GRN_FREE(io->fis);
+ }
+ GRN_FREE(io);
+ return GRN_SUCCESS;
+}
+
+uint32_t
+grn_io_base_seg(grn_io *io)
+{
+ return io->base_seg;
+}
+
+const char *
+grn_io_path(grn_io *io)
+{
+ return io->path;
+}
+
+void *
+grn_io_header(grn_io *io)
+{
+ return io->user_header;
+}
+
+grn_rc
+grn_io_set_type(grn_io *io, uint32_t type)
+{
+ if (!io || !io->header) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ io->header->type = type;
+ return GRN_SUCCESS;
+}
+
+uint32_t
+grn_io_get_type(grn_io *io)
+{
+ if (!io || !io->header) { return GRN_VOID; }
+ return io->header->type;
+}
+
+inline static void
+gen_pathname(const char *path, char *buffer, int fno)
+{
+ size_t len = strlen(path);
+ grn_memcpy(buffer, path, len);
+ if (fno) {
+ buffer[len] = '.';
+ grn_itoh(fno, buffer + len + 1, 3);
+ buffer[len + 4] = '\0';
+ } else {
+ buffer[len] = '\0';
+ }
+}
+
+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)
+{
+ int fno;
+ struct stat s;
+ uint64_t tsize = 0;
+ char buffer[PATH_MAX];
+ uint32_t n_files;
+
+ 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("failed to stat path to compute size: <%s>",
+ buffer);
+ } else {
+ tsize += s.st_size;
+ }
+ }
+ *size = tsize;
+ return GRN_SUCCESS;
+}
+
+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) != 0) {
+ SERR("failed to stat: <%s>", path);
+ return ctx->rc;
+ }
+
+ 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
+grn_io_rename(grn_ctx *ctx, const char *old_name, const char *new_name)
+{
+ struct stat s;
+ if (stat(old_name, &s)) {
+ SERR("failed to stat path to be renamed: <%s>", old_name);
+ return ctx->rc;
+ } else if (rename(old_name, new_name)) {
+ SERR("failed to rename path: <%s> -> <%s>",
+ old_name, new_name);
+ return ctx->rc;
+ } else {
+ int fno;
+ char old_buffer[PATH_MAX];
+ char new_buffer[PATH_MAX];
+ for (fno = 1; ; fno++) {
+ gen_pathname(old_name, old_buffer, fno);
+ if (!stat(old_buffer, &s)) {
+ gen_pathname(new_name, new_buffer, fno);
+ if (rename(old_buffer, new_buffer)) {
+ SERR("failed to rename path: <%s> -> <%s>",
+ old_buffer, new_buffer);
+ }
+ } else {
+ SERR("failed to stat path to be renamed: <%s>",
+ old_buffer);
+ return ctx->rc;
+ }
+ }
+ return GRN_SUCCESS;
+ }
+}
+
+typedef struct {
+ grn_io_ja_ehead head;
+ char body[256];
+} 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)
+{
+ uint32_t rest = 0, size = *value_len + sizeof(grn_io_ja_ehead);
+ uint32_t segment_size = io->header->segment_size;
+ unsigned long file_size = grn_io_compute_file_size(io->header->version);
+ uint32_t segments_per_file = file_size / segment_size;
+ uint32_t bseg = segment + io->base_seg;
+ int fno = bseg / segments_per_file;
+ fileinfo *fi = &io->fis[fno];
+ off_t base = fno ? 0 : io->base - (uint64_t)segment_size * io->base_seg;
+ off_t pos = (uint64_t)segment_size * (bseg % segments_per_file) + offset + base;
+ ja_element *v = GRN_MALLOC(size);
+ if (!v) {
+ *value = NULL;
+ *value_len = 0;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ if (pos + size > file_size) {
+ rest = pos + size - file_size;
+ size = file_size - pos;
+ }
+ if (!grn_fileinfo_opened(fi)) {
+ char path[PATH_MAX];
+ gen_pathname(io->path, path, fno);
+ if (grn_fileinfo_open(ctx, fi, path, O_RDWR|O_CREAT)) {
+ *value = NULL;
+ *value_len = 0;
+ GRN_FREE(v);
+ return ctx->rc;
+ }
+ }
+ if (grn_pread(ctx, fi, v, size, pos)) {
+ *value = NULL;
+ *value_len = 0;
+ GRN_FREE(v);
+ return ctx->rc;
+ }
+ if (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);
+ *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);
+ *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);
+ *value = NULL;
+ *value_len = 0;
+ GRN_FREE(v);
+ return GRN_INVALID_FORMAT;
+ }
+ if (rest) {
+ byte *vr = (byte *)v + size;
+ do {
+ fi = &io->fis[++fno];
+ if (!grn_fileinfo_opened(fi)) {
+ char path[PATH_MAX];
+ gen_pathname(io->path, path, fno);
+ if (grn_fileinfo_open(ctx, fi, path, O_RDWR|O_CREAT)) {
+ *value = NULL;
+ *value_len = 0;
+ GRN_FREE(v);
+ return ctx->rc;
+ }
+ }
+ size = rest > file_size ? file_size : rest;
+ if (grn_pread(ctx, fi, vr, size, 0)) {
+ *value = NULL;
+ *value_len = 0;
+ GRN_FREE(v);
+ return ctx->rc;
+ }
+ vr += size;
+ rest -= size;
+ } while (rest);
+ }
+ *value = v->body;
+ return GRN_SUCCESS;
+}
+
+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)
+{
+ grn_rc rc;
+ uint32_t rest = 0, size = value_len + sizeof(grn_io_ja_ehead);
+ uint32_t segment_size = io->header->segment_size;
+ unsigned long file_size = grn_io_compute_file_size(io->header->version);
+ uint32_t segments_per_file = file_size / segment_size;
+ uint32_t bseg = segment + io->base_seg;
+ int fno = bseg / segments_per_file;
+ fileinfo *fi = &io->fis[fno];
+ off_t base = fno ? 0 : io->base - (uint64_t)segment_size * io->base_seg;
+ off_t pos = (uint64_t)segment_size * (bseg % segments_per_file) + offset + base;
+ if (pos + size > file_size) {
+ rest = pos + size - file_size;
+ size = file_size - pos;
+ }
+ 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 (value_len <= 256) {
+ ja_element je;
+ je.head.size = value_len;
+ je.head.key = key;
+ grn_memcpy(je.body, value, value_len);
+ rc = grn_pwrite(ctx, fi, &je, size, pos);
+ } else {
+ 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;
+ }
+ pos += sizeof(grn_io_ja_ehead);
+ rc = grn_pwrite(ctx, fi, value, size - sizeof(grn_io_ja_ehead), pos);
+ }
+ if (rc) { return rc; }
+ if (rest) {
+ byte *vr = (byte *)value + size - sizeof(grn_io_ja_ehead);
+ do {
+ fi = &io->fis[++fno];
+ 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;
+ }
+ }
+ size = rest > file_size ? file_size : rest;
+ if ((rc = grn_pwrite(ctx, fi, vr, size, 0))) { return rc; }
+ vr += size;
+ rest -= size;
+ } while (rest);
+ }
+ return rc;
+}
+
+grn_rc
+grn_io_write_ja_ehead(grn_io *io, grn_ctx *ctx, uint32_t key,
+ uint32_t segment, uint32_t offset, uint32_t value_len)
+{
+ grn_rc rc;
+ uint32_t segment_size = io->header->segment_size;
+ unsigned long file_size = grn_io_compute_file_size(io->header->version);
+ uint32_t segments_per_file = file_size / segment_size;
+ uint32_t bseg = segment + io->base_seg;
+ int fno = bseg / segments_per_file;
+ fileinfo *fi = &io->fis[fno];
+ off_t base = fno ? 0 : io->base - (uint64_t)segment_size + io->base_seg;
+ off_t pos = (uint64_t)segment_size * (bseg % segments_per_file) + offset + base;
+ 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; }
+ }
+ {
+ grn_io_ja_ehead eh;
+ eh.size = value_len;
+ eh.key = key;
+ return grn_pwrite(ctx, fi, &eh, sizeof(grn_io_ja_ehead), pos);
+ }
+}
+
+void *
+grn_io_win_map(grn_io *io, grn_ctx *ctx, grn_io_win *iw, uint32_t segment,
+ uint32_t offset, uint32_t size, grn_io_rw_mode mode)
+{
+ uint32_t nseg, segment_size = io->header->segment_size;
+ if (offset >= segment_size) {
+ segment += offset / segment_size;
+ offset = offset % segment_size;
+ }
+ nseg = (offset + size + segment_size - 1) / segment_size;
+ if (!size || !ctx || segment + nseg > io->header->max_segment) {
+ return NULL;
+ }
+ iw->ctx = ctx;
+ iw->diff = 0;
+ iw->io = io;
+ iw->mode = mode;
+ iw->tiny_p = 0;
+ iw->segment = segment;
+ iw->offset = offset;
+ iw->nseg = nseg;
+ iw->size = size;
+ if (nseg == 1) {
+ byte *addr = NULL;
+ GRN_IO_SEG_REF(io, segment, addr);
+ if (!addr) { return NULL; }
+ iw->cached = 1;
+ iw->addr = addr + offset;
+ } else {
+ if (!(iw->addr = GRN_MALLOC(size))) { return NULL; }
+ iw->cached = 0;
+ switch (mode) {
+ case grn_io_rdonly:
+ case grn_io_rdwr:
+ {
+ byte *p, *q = NULL;
+ uint32_t s, r;
+ for (p = iw->addr, r = size; r; p += s, r -= s, segment++, offset = 0) {
+ GRN_IO_SEG_REF(io, segment, q);
+ if (!q) {
+ GRN_FREE(iw->addr);
+ return NULL;
+ }
+ s = (offset + r > segment_size) ? segment_size - offset : r;
+ grn_memcpy(p, q + offset, s);
+ GRN_IO_SEG_UNREF(io, segment);
+ }
+ }
+ break;
+ case grn_io_wronly:
+ break;
+ default :
+ return NULL;
+ }
+ }
+ return iw->addr;
+}
+
+grn_rc
+grn_io_win_unmap(grn_io_win *iw)
+{
+ if (!iw || !iw->io ||!iw->ctx) { return GRN_INVALID_ARGUMENT; }
+ if (iw->cached) {
+ if (!iw->tiny_p) { GRN_IO_SEG_UNREF(iw->io, iw->segment); }
+ return GRN_SUCCESS;
+ }
+ {
+ grn_io *io = iw->io;
+ grn_ctx *ctx = iw->ctx;
+ switch (iw->mode) {
+ case grn_io_rdonly:
+ if (!iw->addr) { return GRN_INVALID_ARGUMENT; }
+ GRN_FREE(iw->addr);
+ return GRN_SUCCESS;
+ case grn_io_rdwr:
+ case grn_io_wronly:
+ {
+ 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) {
+ GRN_IO_SEG_REF(io, segment, q);
+ if (!q) { return GRN_NO_MEMORY_AVAILABLE; }
+ s = (offset + r > segment_size) ? segment_size - offset : r;
+ grn_memcpy(q + offset, p, s);
+ GRN_IO_SEG_UNREF(io, segment);
+ }
+ }
+ GRN_FREE(iw->addr);
+ return GRN_SUCCESS;
+ default :
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+}
+
+#define DO_MAP(io,fmo,fi,pos,size,segno,res) do {\
+ (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);\
+ {\
+ uint64_t tail = io->base + (uint64_t)(size) * ((segno) + 1);\
+ if (tail > io->header->curr_size) { io->header->curr_size = tail; }\
+ }\
+ }\
+} while (0)
+
+void
+grn_io_seg_map_(grn_ctx *ctx, grn_io *io, uint32_t segno, grn_io_mapinfo *info)
+{
+ uint32_t segment_size = io->header->segment_size;
+ if ((io->flags & GRN_IO_TEMPORARY)) {
+ DO_MAP(io, &info->fmo, NULL, 0, segment_size, segno, info->map);
+ } else {
+ unsigned long file_size = grn_io_compute_file_size(io->header->version);
+ uint32_t segments_per_file = file_size / segment_size;
+ uint32_t bseg = segno + io->base_seg;
+ uint32_t fno = bseg / segments_per_file;
+ off_t base = fno ? 0 : io->base - (uint64_t)segment_size * io->base_seg;
+ off_t pos = (uint64_t)segment_size * (bseg % segments_per_file) + base;
+ 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);
+ }
+ }
+}
+
+grn_rc
+grn_io_seg_expire(grn_ctx *ctx, grn_io *io, uint32_t segno, uint32_t nretry)
+{
+ uint32_t retry, *pnref;
+ grn_io_mapinfo *info;
+ if (!io->maps || segno >= io->header->max_segment) { return GRN_INVALID_ARGUMENT; }
+ info = &io->maps[segno];
+ if (!info->map) { return GRN_INVALID_ARGUMENT; }
+ pnref = &info->nref;
+ for (retry = 0;; retry++) {
+ uint32_t nref;
+ GRN_ATOMIC_ADD_EX(pnref, 1, nref);
+ 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);
+ return GRN_RESOURCE_DEADLOCK_AVOIDED;
+ }
+ } else {
+ GRN_ATOMIC_ADD_EX(pnref, GRN_IO_MAX_REF, nref);
+ if (nref > 1) {
+ 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);
+ return GRN_RESOURCE_DEADLOCK_AVOIDED;
+ }
+ } else {
+ uint32_t nmaps;
+ fileinfo *fi = &(io->fis[segno]);
+ 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);
+ GRN_ATOMIC_ADD_EX(&io->nmaps, -1, nmaps);
+ GRN_FUTEX_WAKE(pnref);
+ return GRN_SUCCESS;
+ }
+ }
+ if (retry >= nretry) { return GRN_RESOURCE_DEADLOCK_AVOIDED; }
+ GRN_FUTEX_WAIT(pnref);
+ }
+}
+
+uint32_t
+grn_io_expire(grn_ctx *ctx, grn_io *io, int count_thresh, uint32_t limit)
+{
+ uint32_t m, n = 0, ln = io->nmaps;
+ switch ((io->flags & (GRN_IO_EXPIRE_GTICK|GRN_IO_EXPIRE_SEGMENT))) {
+ case GRN_IO_EXPIRE_GTICK :
+ {
+ uint32_t nref, nmaps, *pnref = &io->nref;
+ GRN_ATOMIC_ADD_EX(pnref, 1, nref);
+ if (!nref && grn_gtick - io->count > count_thresh) {
+ {
+ 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);
+ }
+ }
+ {
+ uint32_t fno;
+ for (fno = 0; fno < io->max_map_seg; fno++) {
+ grn_io_mapinfo *info = &(io->maps[fno]);
+ if (info->map) {
+ fileinfo *fi = &(io->fis[fno]);
+ GRN_MUNMAP(ctx, &grn_gctx, io, &info->fmo, fi,
+ info->map, io->header->segment_size);
+ info->map = NULL;
+ info->nref = 0;
+ info->count = grn_gtick;
+ GRN_ATOMIC_ADD_EX(&io->nmaps, -1, nmaps);
+ n++;
+ }
+ }
+ }
+ }
+ GRN_ATOMIC_ADD_EX(pnref, -1, nref);
+ }
+ break;
+ case GRN_IO_EXPIRE_SEGMENT :
+ for (m = io->max_map_seg; n < limit && m; m--) {
+ if (!grn_io_seg_expire(ctx, io, m, 0)) { n++; }
+ }
+ break;
+ case (GRN_IO_EXPIRE_GTICK|GRN_IO_EXPIRE_SEGMENT) :
+ {
+ grn_io_mapinfo *info = io->maps;
+ for (m = io->max_map_seg; n < limit && m; info++, m--) {
+ if (info->map && (grn_gtick - info->count) > count_thresh) {
+ 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(ctx, &grn_gctx, io, &info->fmo, NULL,
+ info->map, io->header->segment_size);
+ GRN_ATOMIC_ADD_EX(&io->nmaps, -1, nmaps);
+ info->map = NULL;
+ info->count = grn_gtick;
+ n++;
+ }
+ GRN_ATOMIC_ADD_EX(pnref, -1, nref);
+ }
+ }
+ }
+ break;
+ }
+ if (n) {
+ 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;
+}
+
+void *
+grn_io_anon_map(grn_ctx *ctx, grn_io_mapinfo *mi, size_t 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, ctx, NULL, &mi->fmo, NULL, mi->map, length);
+}
+
+grn_rc
+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++) {
+ uint32_t lock;
+ GRN_ATOMIC_ADD_EX(io->lock, 1, lock);
+ if (lock) {
+ GRN_ATOMIC_ADD_EX(io->lock, -1, lock);
+ if (count == count_log_border) {
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
+ "io(%s) collisions(%d/%d): lock failed %d times",
+ io->path, _ncolls, _ncalls, count_log_border);
+ }
+ if (!timeout || (timeout > 0 && timeout == count)) {
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "[DB Locked] time out(%d): io(%s) collisions(%d/%d)",
+ timeout, io->path, _ncolls, _ncalls);
+ break;
+ }
+ if (!(++_ncolls % 1000000) && (_ncolls > _ncalls)) {
+ if (_ncolls < 0 || _ncalls < 0) {
+ _ncolls = 0; _ncalls = 0;
+ } else {
+ GRN_LOG(ctx, GRN_LOG_NOTICE,
+ "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;
+ }
+ return GRN_SUCCESS;
+ }
+ ERR(GRN_RESOURCE_DEADLOCK_AVOIDED, "grn_io_lock failed");
+ return ctx->rc;
+}
+
+void
+grn_io_unlock(grn_io *io)
+{
+ if (io) {
+ uint32_t lock;
+ GRN_ATOMIC_ADD_EX(io->lock, -1, lock);
+ }
+}
+
+void
+grn_io_clear_lock(grn_io *io)
+{
+ if (io) { *io->lock = 0; }
+}
+
+uint32_t
+grn_io_is_locked(grn_io *io)
+{
+ return io ? *io->lock : 0;
+}
+
+grn_rc
+grn_io_flush(grn_ctx *ctx, grn_io *io)
+{
+ grn_rc rc = GRN_SUCCESS;
+ struct _grn_io_header *header;
+ uint32_t aligned_header_size;
+
+ 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, io->fis[0].fh, header, aligned_header_size) != 0) {
+ return ctx->rc;
+ }
+
+ if (io->maps) {
+ uint32_t i;
+ uint32_t max_mapped_segment;
+ uint32_t segment_size;
+
+ max_mapped_segment = grn_io_max_segment(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;
+ }
+
+ 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;
+ }
+ }
+ }
+
+ 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;
+
+#ifdef WIN32
+
+inline static grn_rc
+grn_fileinfo_open_v1(grn_ctx *ctx, fileinfo *fi, const char *path, int flags)
+{
+ CRITICAL_SECTION_INIT(fi->cs);
+ return GRN_SUCCESS;
+}
+
+inline static void *
+grn_mmap_v1(grn_ctx *ctx, grn_ctx *owner_ctx, HANDLE *fmo, fileinfo *fi,
+ off_t offset, size_t length)
+{
+ void *res;
+ if (!fi) {
+ if (fmo) {
+ *fmo = NULL;
+ }
+ /* TODO: Try to support VirtualAlloc() as anonymous mmap in POSIX.
+ * If VirtualAlloc() provides better performance rather than malloc(),
+ * we'll use it.
+ */
+ 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(%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(%lu,%" GRN_FMT_SIZE ") failed <%" GRN_FMT_SIZE ">",
+ (DWORD)offset, length, mmap_size);
+ return NULL;
+ }
+ /* CRITICAL_SECTION_LEAVE(fi->cs); */
+ mmap_size += length;
+ return res;
+}
+
+inline static int
+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_FREE(start);
+ return r;
+ }
+
+ if (!fmo) {
+ GRN_FREE(start);
+ return r;
+ }
+
+ if (*fmo) {
+ if (UnmapViewOfFile(start)) {
+ mmap_size -= length;
+ } else {
+ SERR("UnmapViewOfFile(%p,%" GRN_FMT_SIZE ") failed <%" GRN_FMT_SIZE ">",
+ start, length, mmap_size);
+ r = -1;
+ }
+ if (!CloseHandle(*fmo)) {
+ SERR("CloseHandle(%p,%" GRN_FMT_SIZE ") failed <%" GRN_FMT_SIZE ">",
+ start, length, mmap_size);
+ }
+ *fmo = NULL;
+ } else {
+ GRN_FREE(start);
+ }
+
+ return r;
+}
+
+inline static grn_rc
+grn_fileinfo_open_v0(grn_ctx *ctx, fileinfo *fi, const char *path, int flags)
+{
+ /* signature may be wrong.. */
+ fi->fmo = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, NULL);
+ /* open failed */
+ if (fi->fmo == NULL) {
+ // flock
+ /* retry to open */
+ fi->fmo = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, NULL);
+ /* 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);
+ }
+ // funlock
+ }
+ if (fi->fmo != NULL) {
+ if (GetLastError() != ERROR_ALREADY_EXISTS) {
+ CRITICAL_SECTION_INIT(fi->cs);
+ return GRN_SUCCESS;
+ } else {
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "fmo object already exists! handle=%p", fi->fh);
+ CloseHandle(fi->fmo);
+ }
+ } else {
+ GRN_LOG(ctx, GRN_LOG_ALERT,
+ "failed to get FileMappingObject #%lu", GetLastError());
+ }
+ CloseHandle(fi->fh);
+ SERR("OpenFileMapping");
+ return ctx->rc;
+}
+
+inline static void *
+grn_mmap_v0(grn_ctx *ctx, grn_ctx *owner_ctx, fileinfo *fi, off_t offset,
+ size_t length)
+{
+ void *res;
+ 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);
+ DWORD filesize = GetFileSize(fi->fh, NULL);
+ if (filesize < tail) {
+ if (SetFilePointer(fi->fh, tail, NULL, FILE_BEGIN) != tail) {
+ grn_log("SetFilePointer failed");
+ return NULL;
+ }
+ if (!SetEndOfFile(fi->fh)) {
+ grn_log("SetEndOfFile failed");
+ return NULL;
+ }
+ filesize = tail;
+ }
+ */
+ res = MapViewOfFile(fi->fmo, FILE_MAP_WRITE, 0, (DWORD)offset, (SIZE_T)length);
+ if (!res) {
+ MERR("MapViewOfFile failed: <%" GRN_FMT_SIZE ">: %s",
+ mmap_size, grn_current_error_message());
+ return NULL;
+ }
+ mmap_size += length;
+ return res;
+}
+
+inline static int
+grn_munmap_v0(grn_ctx *ctx, grn_ctx *owner_ctx, fileinfo *fi, void *start,
+ size_t length)
+{
+ if (!fi) {
+ GRN_FREE(start);
+ return 0;
+ }
+
+ if (UnmapViewOfFile(start)) {
+ mmap_size -= length;
+ return 0;
+ } else {
+ SERR("UnmapViewOfFile(%p,%" GRN_FMT_SIZE ") failed <%" GRN_FMT_SIZE ">",
+ start, length, mmap_size);
+ return -1;
+ }
+}
+
+inline static grn_rc
+grn_fileinfo_open_common(grn_ctx *ctx, fileinfo *fi, const char *path, int flags)
+{
+ /* may be wrong if flags is just only O_RDWR */
+ if ((flags & O_CREAT)) {
+ DWORD dwCreationDisposition;
+ const char *flags_description;
+ if (flags & O_EXCL) {
+ dwCreationDisposition = CREATE_NEW;
+ flags_description = "O_RDWR|O_CREAT|O_EXCL";
+ } else {
+ dwCreationDisposition = OPEN_ALWAYS;
+ flags_description = "O_RDWR|O_CREAT";
+ }
+ fi->fh = CreateFile(path, GRN_IO_FILE_CREATE_MODE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, 0);
+ if (fi->fh == INVALID_HANDLE_VALUE) {
+ 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 | FILE_SHARE_DELETE,
+ NULL,
+ TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+ if (fi->fh == INVALID_HANDLE_VALUE) {
+ 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 | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+ if (fi->fh == INVALID_HANDLE_VALUE) {
+ 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;
+}
+
+inline static grn_rc
+grn_fileinfo_open(grn_ctx *ctx, fileinfo *fi, const char *path, int flags)
+{
+ grn_rc rc;
+ struct _grn_io_header io_header;
+ 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 (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) {
+ version = io_header.version;
+ }
+ SetFilePointer(fi->fh, 0, NULL, FILE_BEGIN);
+ }
+
+ if (version == 0) {
+ return grn_fileinfo_open_v0(ctx, fi, path, flags);
+ } else {
+ return grn_fileinfo_open_v1(ctx, fi, path, flags);
+ }
+}
+
+inline static int
+grn_guess_io_version(grn_ctx *ctx, grn_io *io, fileinfo *fi)
+{
+ if (io) {
+ return io->header->version;
+ }
+
+ if (fi) {
+ if (fi->fmo) {
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+
+ return grn_io_version_default;
+}
+
+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)
+{
+ int version;
+
+ version = grn_guess_io_version(ctx, io, fi);
+
+ if (version == 0) {
+ return grn_mmap_v0(ctx, owner_ctx, fi, offset, length);
+ } else {
+ return grn_mmap_v1(ctx, owner_ctx, fmo, fi, offset, length);
+ }
+}
+
+inline static int
+grn_munmap(grn_ctx *ctx, grn_ctx *owner_ctx, grn_io *io,
+ HANDLE *fmo, fileinfo *fi, void *start, size_t length)
+{
+ int version;
+
+ version = grn_guess_io_version(ctx, io, fi);
+
+ if (version == 0) {
+ return grn_munmap_v0(ctx, owner_ctx, fi, start, length);
+ } else {
+ return grn_munmap_v1(ctx, owner_ctx, fmo, fi, start, length);
+ }
+}
+
+inline static grn_rc
+grn_fileinfo_close(grn_ctx *ctx, fileinfo *fi)
+{
+ if (fi->fmo != NULL) {
+ CloseHandle(fi->fmo);
+ fi->fmo = NULL;
+ }
+ if (fi->fh != INVALID_HANDLE_VALUE) {
+ CloseHandle(fi->fh);
+ CRITICAL_SECTION_FIN(fi->cs);
+ fi->fh = INVALID_HANDLE_VALUE;
+ }
+ return GRN_SUCCESS;
+}
+
+inline static void
+grn_fileinfo_init(fileinfo *fis, int nfis)
+{
+ for (; nfis--; fis++) {
+ fis->fh = INVALID_HANDLE_VALUE;
+ fis->fmo = NULL;
+ }
+}
+
+inline static int
+grn_fileinfo_opened(fileinfo *fi)
+{
+ return fi->fh != INVALID_HANDLE_VALUE;
+}
+
+inline static int
+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) {
+ SERR("FlushViewOfFile(<%p>, <%" GRN_FMT_SIZE ">) failed",
+ start, length);
+ return -1;
+ }
+
+ if (handle == INVALID_HANDLE_VALUE) {
+ return 0;
+ }
+
+ 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
+grn_pread(grn_ctx *ctx, fileinfo *fi, void *buf, size_t count, off_t offset)
+{
+ DWORD r, len;
+ CRITICAL_SECTION_ENTER(fi->cs);
+ r = SetFilePointer(fi->fh, offset, NULL, FILE_BEGIN);
+ if (r == INVALID_SET_FILE_POINTER) {
+ SERR("SetFilePointer");
+ } else {
+ if (!ReadFile(fi->fh, buf, (DWORD)count, &len, NULL)) {
+ SERR("ReadFile");
+ } else if (len != count) {
+ /* todo : should retry ? */
+ ERR(GRN_INPUT_OUTPUT_ERROR,
+ "ReadFile %" GRN_FMT_SIZE " != %lu",
+ count, len);
+ }
+ }
+ CRITICAL_SECTION_LEAVE(fi->cs);
+ return ctx->rc;
+}
+
+inline static grn_rc
+grn_pwrite(grn_ctx *ctx, fileinfo *fi, void *buf, size_t count, off_t offset)
+{
+ DWORD r, len;
+ CRITICAL_SECTION_ENTER(fi->cs);
+ r = SetFilePointer(fi->fh, offset, NULL, FILE_BEGIN);
+ if (r == INVALID_SET_FILE_POINTER) {
+ SERR("SetFilePointer");
+ } else {
+ if (!WriteFile(fi->fh, buf, (DWORD)count, &len, NULL)) {
+ SERR("WriteFile");
+ } else if (len != count) {
+ /* todo : should retry ? */
+ ERR(GRN_INPUT_OUTPUT_ERROR,
+ "WriteFile %" GRN_FMT_SIZE " != %lu",
+ count, len);
+ }
+ }
+ CRITICAL_SECTION_LEAVE(fi->cs);
+ return ctx->rc;
+}
+
+#else /* WIN32 */
+
+inline static grn_rc
+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("failed to open file info path: <%s>",
+ path);
+ return ctx->rc;
+ }
+ if (fstat(fi->fd, &st) == -1) {
+ ERRNO_ERR("failed to stat file info path: <%s>",
+ path);
+ return ctx->rc;
+ }
+ fi->dev = st.st_dev;
+ fi->inode = st.st_ino;
+ return GRN_SUCCESS;
+}
+
+inline static void
+grn_fileinfo_init(fileinfo *fis, int nfis)
+{
+ for (; nfis--; fis++) { fis->fd = -1; }
+}
+
+inline static int
+grn_fileinfo_opened(fileinfo *fi)
+{
+ return fi->fd != -1;
+}
+
+inline static grn_rc
+grn_fileinfo_close(grn_ctx *ctx, fileinfo *fi)
+{
+ if (fi->fd != -1) {
+ if (grn_close(fi->fd) == -1) {
+ SERR("close");
+ return ctx->rc;
+ }
+ fi->fd = -1;
+ }
+ return GRN_SUCCESS;
+}
+
+#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+#include <sys/mman.h>
+
+inline static void *
+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;
+ if (fi) {
+ struct stat s;
+ off_t tail = offset + length;
+ fd = fi->fd;
+ if ((fstat(fd, &s) == -1) || (s.st_size < tail && ftruncate(fd, tail) == -1)) {
+ SERR("fstat");
+ return NULL;
+ }
+ flags = MAP_SHARED;
+ } else {
+ fd = -1;
+ flags = MAP_PRIVATE|MAP_ANONYMOUS;
+ }
+ 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);
+ return NULL;
+ }
+ mmap_size += length;
+ return res;
+}
+
+#ifdef USE_FAIL_MALLOC
+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)
+{
+ if (grn_fail_malloc_check(length, file, line, func)) {
+ return grn_mmap(ctx, io, fi, offset, length);
+ } else {
+ MERR("fail_mmap(%" GRN_FMT_SIZE ",%d,%" GRN_FMT_LLU ") "
+ "(%s:%d@%s) <%" GRN_FMT_SIZE ">",
+ length,
+ fi ? fi->fd : 0,
+ (long long unsigned int)offset,
+ file,
+ line,
+ func,
+ mmap_size);
+ return NULL;
+ }
+}
+#endif /* USE_FAIL_MALLOC */
+
+inline static int
+grn_msync(grn_ctx *ctx, void *start, size_t length)
+{
+ int r = msync(start, length, MS_SYNC);
+ if (r == -1) { SERR("msync"); }
+ return r;
+}
+
+inline static int
+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(%p,%" GRN_FMT_LLU ") failed <%" GRN_FMT_LLU ">",
+ start,
+ (unsigned long long int)length,
+ (unsigned long long int)mmap_size);
+ } else {
+ mmap_size -= length;
+ }
+ return res;
+}
+
+inline static grn_rc
+grn_pread(grn_ctx *ctx, fileinfo *fi, void *buf, size_t count, off_t offset)
+{
+ ssize_t r = pread(fi->fd, buf, count, offset);
+ if (r != count) {
+ if (r == -1) {
+ SERR("pread");
+ } else {
+ /* todo : should retry ? */
+ 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;
+ }
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+grn_pwrite(grn_ctx *ctx, fileinfo *fi, void *buf, size_t count, off_t offset)
+{
+ ssize_t r = pwrite(fi->fd, buf, count, offset);
+ if (r != count) {
+ if (r == -1) {
+ SERR("pwrite");
+ } else {
+ /* todo : should retry ? */
+ 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;
+ }
+ return GRN_SUCCESS;
+}
+
+#endif /* WIN32 */
diff --git a/storage/mroonga/vendor/groonga/lib/load.c b/storage/mroonga/vendor/groonga/lib/load.c
new file mode 100644
index 00000000..b840a0dc
--- /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-1335 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
new file mode 100644
index 00000000..9c1a2dbd
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/logger.c
@@ -0,0 +1,810 @@
+/* -*- 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-1335 USA
+*/
+
+#include "grn_logger.h"
+#include "grn_ctx.h"
+#include "grn_ctx_impl.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#ifdef WIN32
+# include <share.h>
+#endif /* WIN32 */
+
+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)
+{
+ char rotated_path[PATH_MAX];
+ grn_timeval now;
+ struct tm tm_buffer;
+ struct tm *tm;
+
+ grn_timeval_now(ctx, &now);
+ tm = grn_timeval2tm(ctx, &now, &tm_buffer);
+ grn_snprintf(rotated_path, PATH_MAX, PATH_MAX,
+ "%s.%04d-%02d-%02d-%02d-%02d-%02d-%06d",
+ current_path,
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec,
+ (int)(GRN_TIME_NSEC_TO_USEC(now.tv_nsec)));
+ 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;
+static off_t default_logger_size = 0;
+static off_t default_logger_rotate_threshold_size = 0;
+
+#define LOGGER_NEED_ROTATE(size, threshold) \
+ ((threshold) > 0 && (size) >= (threshold))
+
+static void
+default_logger_log(grn_ctx *ctx, grn_log_level level,
+ const char *timestamp, const char *title,
+ const char *message, const char *location, void *user_data)
+{
+ const char slev[] = " EACewnid-";
+ if (default_logger_path) {
+ CRITICAL_SECTION_ENTER(default_logger_lock);
+ if (!default_logger_file) {
+ default_logger_file = grn_fopen(default_logger_path, "a");
+ default_logger_size = 0;
+ if (default_logger_file) {
+ struct stat stat;
+ 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) {
+ 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, label, title, message);
+ }
+ if (written > 0) {
+ default_logger_size += written;
+ if (LOGGER_NEED_ROTATE(default_logger_size,
+ default_logger_rotate_threshold_size)) {
+ fclose(default_logger_file);
+ default_logger_file = NULL;
+ rotate_log_file(ctx, default_logger_path);
+ } else {
+ fflush(default_logger_file);
+ }
+ }
+ }
+ CRITICAL_SECTION_LEAVE(default_logger_lock);
+ }
+}
+
+static void
+default_logger_reopen(grn_ctx *ctx, void *user_data)
+{
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "log will be closed.");
+ CRITICAL_SECTION_ENTER(default_logger_lock);
+ if (default_logger_file) {
+ fclose(default_logger_file);
+ default_logger_file = NULL;
+ }
+ CRITICAL_SECTION_LEAVE(default_logger_lock);
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "log opened.");
+}
+
+static void
+default_logger_fin(grn_ctx *ctx, void *user_data)
+{
+ CRITICAL_SECTION_ENTER(default_logger_lock);
+ if (default_logger_file) {
+ fclose(default_logger_file);
+ default_logger_file = NULL;
+ }
+ CRITICAL_SECTION_LEAVE(default_logger_lock);
+}
+
+static grn_logger default_logger = {
+ GRN_LOG_DEFAULT_LEVEL,
+ GRN_LOG_TIME|GRN_LOG_MESSAGE,
+ NULL,
+ default_logger_log,
+ default_logger_reopen,
+ default_logger_fin
+};
+
+#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)
+{
+ default_logger.max_level = max_level;
+ if (current_logger.log == default_logger_log) {
+ current_logger.max_level = max_level;
+ }
+}
+
+grn_log_level
+grn_default_logger_get_max_level(void)
+{
+ return default_logger.max_level;
+}
+
+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);
+ }
+
+ if (path) {
+ default_logger_path = grn_strdup_raw(path);
+ } else {
+ default_logger_path = NULL;
+ }
+
+ if (logger_inited) {
+ CRITICAL_SECTION_LEAVE(default_logger_lock);
+ }
+}
+
+const char *
+grn_default_logger_get_path(void)
+{
+ return default_logger_path;
+}
+
+void
+grn_default_logger_set_rotate_threshold_size(off_t threshold)
+{
+ default_logger_rotate_threshold_size = threshold;
+}
+
+off_t
+grn_default_logger_get_rotate_threshold_size(void)
+{
+ return default_logger_rotate_threshold_size;
+}
+
+void
+grn_logger_reopen(grn_ctx *ctx)
+{
+ if (current_logger.reopen) {
+ current_logger.reopen(ctx, current_logger.user_data);
+ }
+}
+
+static void
+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
+logger_info_func_wrapper(grn_ctx *ctx, grn_log_level level,
+ const char *timestamp, const char *title,
+ const char *message, const char *location,
+ void *user_data)
+{
+ grn_logger_info *info = user_data;
+ info->func(level, timestamp, title, message, location, info->func_arg);
+}
+
+/* Deprecated since 2.1.2. */
+grn_rc
+grn_logger_info_set(grn_ctx *ctx, const grn_logger_info *info)
+{
+ if (info) {
+ grn_logger logger;
+
+ memset(&logger, 0, sizeof(grn_logger));
+ logger.max_level = info->max_level;
+ logger.flags = info->flags;
+ if (info->func) {
+ logger.log = logger_info_func_wrapper;
+ logger.user_data = (grn_logger_info *)info;
+ } else {
+ logger.log = default_logger_log;
+ logger.reopen = default_logger_reopen;
+ logger.fin = default_logger_fin;
+ }
+ return grn_logger_set(ctx, &logger);
+ } else {
+ return grn_logger_set(ctx, NULL);
+ }
+}
+
+grn_rc
+grn_logger_set(grn_ctx *ctx, const grn_logger *logger)
+{
+ current_logger_fin(ctx);
+ if (logger) {
+ current_logger = *logger;
+ } else {
+ current_logger = default_logger;
+ }
+ return GRN_SUCCESS;
+}
+
+void
+grn_logger_set_max_level(grn_ctx *ctx, grn_log_level max_level)
+{
+ current_logger.max_level = max_level;
+}
+
+grn_log_level
+grn_logger_get_max_level(grn_ctx *ctx)
+{
+ return current_logger.max_level;
+}
+
+grn_bool
+grn_logger_pass(grn_ctx *ctx, grn_log_level level)
+{
+ return level <= current_logger.max_level;
+}
+
+#define TBUFSIZE GRN_TIMEVAL_STR_SIZE
+#define MBUFSIZE 0x1000
+#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,
+ ...)
+{
+ 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];
+ char mbuf[MBUFSIZE];
+ char lbuf[LBUFSIZE];
+ tbuf[0] = '\0';
+ if (current_logger.flags & GRN_LOG_TIME) {
+ grn_timeval tv;
+ grn_timeval_now(ctx, &tv);
+ grn_timeval2str(ctx, &tv, tbuf, TBUFSIZE);
+ }
+ if (current_logger.flags & GRN_LOG_MESSAGE) {
+ 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()", 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';
+ }
+ current_logger.log(ctx, level, tbuf, "", mbuf, lbuf,
+ current_logger.user_data);
+ }
+}
+
+void
+grn_logger_init(void)
+{
+ CRITICAL_SECTION_INIT(default_logger_lock);
+ if (!current_logger.log) {
+ current_logger = default_logger;
+ }
+
+ logger_inited = GRN_TRUE;
+}
+
+void
+grn_logger_fin(grn_ctx *ctx)
+{
+ current_logger_fin(ctx);
+ if (default_logger_path) {
+ free(default_logger_path);
+ 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,
+ const char *message, void *user_data)
+{
+ if (default_query_logger_path) {
+ CRITICAL_SECTION_ENTER(default_query_logger_lock);
+ if (!default_query_logger_file) {
+ default_query_logger_file = grn_fopen(default_query_logger_path, "a");
+ default_query_logger_size = 0;
+ if (default_query_logger_file) {
+ struct stat stat;
+ if (fstat(grn_fileno(default_query_logger_file), &stat) != -1) {
+ default_query_logger_size = stat.st_size;
+ }
+ }
+ }
+ if (default_query_logger_file) {
+ int written;
+ written = fprintf(default_query_logger_file, "%s|%s%s\n",
+ timestamp, info, message);
+ if (written > 0) {
+ default_query_logger_size += written;
+ if (LOGGER_NEED_ROTATE(default_query_logger_size,
+ default_query_logger_rotate_threshold_size)) {
+ fclose(default_query_logger_file);
+ default_query_logger_file = NULL;
+ rotate_log_file(ctx, default_query_logger_path);
+ } else {
+ fflush(default_query_logger_file);
+ }
+ }
+ }
+ CRITICAL_SECTION_LEAVE(default_query_logger_lock);
+ }
+}
+
+static void
+default_query_logger_close(grn_ctx *ctx, void *user_data)
+{
+ GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_DESTINATION, " ",
+ "query log will be closed: <%s>", default_query_logger_path);
+ CRITICAL_SECTION_ENTER(default_query_logger_lock);
+ if (default_query_logger_file) {
+ fclose(default_query_logger_file);
+ default_query_logger_file = NULL;
+ }
+ CRITICAL_SECTION_LEAVE(default_query_logger_lock);
+}
+
+static void
+default_query_logger_reopen(grn_ctx *ctx, void *user_data)
+{
+ default_query_logger_close(ctx, user_data);
+ if (default_query_logger_path) {
+ GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_DESTINATION, " ",
+ "query log is opened: <%s>", default_query_logger_path);
+ }
+}
+
+static void
+default_query_logger_fin(grn_ctx *ctx, void *user_data)
+{
+ if (default_query_logger_file) {
+ default_query_logger_close(ctx, user_data);
+ }
+}
+
+static grn_query_logger default_query_logger = {
+ GRN_QUERY_LOG_DEFAULT,
+ NULL,
+ default_query_logger_log,
+ default_query_logger_reopen,
+ default_query_logger_fin
+};
+
+#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)
+{
+ default_query_logger.flags = flags;
+ if (current_query_logger.log == default_query_logger_log) {
+ current_query_logger.flags = flags;
+ }
+}
+
+unsigned int
+grn_default_query_logger_get_flags(void)
+{
+ return default_query_logger.flags;
+}
+
+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);
+ }
+
+ if (path) {
+ default_query_logger_path = grn_strdup_raw(path);
+ } else {
+ default_query_logger_path = NULL;
+ }
+
+ if (query_logger_inited) {
+ CRITICAL_SECTION_LEAVE(default_query_logger_lock);
+ }
+}
+
+const char *
+grn_default_query_logger_get_path(void)
+{
+ return default_query_logger_path;
+}
+
+void
+grn_default_query_logger_set_rotate_threshold_size(off_t threshold)
+{
+ default_query_logger_rotate_threshold_size = threshold;
+}
+
+off_t
+grn_default_query_logger_get_rotate_threshold_size(void)
+{
+ return default_query_logger_rotate_threshold_size;
+}
+
+void
+grn_query_logger_reopen(grn_ctx *ctx)
+{
+ if (current_query_logger.reopen) {
+ current_query_logger.reopen(ctx, current_query_logger.user_data);
+ }
+}
+
+static void
+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
+grn_query_logger_set(grn_ctx *ctx, const grn_query_logger *logger)
+{
+ current_query_logger_fin(ctx);
+ if (logger) {
+ current_query_logger = *logger;
+ } else {
+ current_query_logger = default_query_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)
+{
+ return current_query_logger.flags & flag;
+}
+
+#define TIMESTAMP_BUFFER_SIZE TBUFSIZE
+/* 8+a(%p) + 1(|) + 1(mark) + 15(elapsed time) = 25+a */
+#define INFO_BUFFER_SIZE 40
+
+void
+grn_query_logger_put(grn_ctx *ctx, unsigned int flag, const char *mark,
+ const char *format, ...)
+{
+ char timestamp[TIMESTAMP_BUFFER_SIZE];
+ char info[INFO_BUFFER_SIZE];
+ grn_obj *message = &ctx->impl->query_log_buf;
+
+ if (!current_query_logger.log) {
+ return;
+ }
+
+ {
+ grn_timeval tv;
+ timestamp[0] = '\0';
+ grn_timeval_now(ctx, &tv);
+ grn_timeval2str(ctx, &tv, timestamp, TIMESTAMP_BUFFER_SIZE);
+ }
+
+ if (flag & (GRN_QUERY_LOG_COMMAND | GRN_QUERY_LOG_DESTINATION)) {
+ grn_snprintf(info, INFO_BUFFER_SIZE, INFO_BUFFER_SIZE,
+ "%p|%s", ctx, mark);
+ info[INFO_BUFFER_SIZE - 1] = '\0';
+ } else {
+ grn_timeval tv;
+ uint64_t elapsed_time;
+ grn_timeval_now(ctx, &tv);
+ elapsed_time =
+ (uint64_t)(tv.tv_sec - ctx->impl->tv.tv_sec) * GRN_TIME_NSEC_PER_SEC +
+ (tv.tv_nsec - ctx->impl->tv.tv_nsec);
+
+ grn_snprintf(info, INFO_BUFFER_SIZE, INFO_BUFFER_SIZE,
+ "%p|%s%015" GRN_FMT_INT64U " ", ctx, mark, elapsed_time);
+ info[INFO_BUFFER_SIZE - 1] = '\0';
+ }
+
+ {
+ va_list args;
+
+ va_start(args, format);
+ GRN_BULK_REWIND(message);
+ grn_text_vprintf(ctx, message, format, args);
+ va_end(args);
+ GRN_TEXT_PUTC(ctx, message, '\0');
+ }
+
+ current_query_logger.log(ctx, flag, timestamp, info, GRN_TEXT_VALUE(message),
+ current_query_logger.user_data);
+}
+
+void
+grn_query_logger_init(void)
+{
+ current_query_logger = default_query_logger;
+ CRITICAL_SECTION_INIT(default_query_logger_lock);
+
+ query_logger_inited = GRN_TRUE;
+}
+
+void
+grn_query_logger_fin(grn_ctx *ctx)
+{
+ current_query_logger_fin(ctx);
+ if (default_query_logger_path) {
+ free(default_query_logger_path);
+ default_query_logger_path = NULL;
+ }
+ CRITICAL_SECTION_FIN(default_query_logger_lock);
+
+ query_logger_inited = GRN_FALSE;
+}
+
+void
+grn_log_reopen(grn_ctx *ctx)
+{
+ grn_logger_reopen(ctx);
+ grn_query_logger_reopen(ctx);
+}
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 00000000..0c43cd7d
--- /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
new file mode 100644
index 00000000..f5bb49fb
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb.c
@@ -0,0 +1,220 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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 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-1335 USA
+*/
+
+#include "grn_mrb.h"
+#include "grn_ctx_impl.h"
+#include "grn_util.h"
+
+#include <string.h>
+
+#ifdef GRN_WITH_MRUBY
+# include <mruby/proc.h>
+# include <mruby/compile.h>
+# include <mruby/string.h>
+#endif
+
+#include <ctype.h>
+
+#ifdef WIN32
+# include <share.h>
+#endif /* WIN32 */
+
+#define BUFFER_SIZE 2048
+#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)
+{
+ 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 *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 (!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_windows_base_dir();
+ base_dir_length = strlen(base_dir);
+ 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 windows_ruby_scripts_dir;
+}
+
+# else /* WIN32 */
+static const char *
+grn_mrb_get_default_system_ruby_scripts_dir(void)
+{
+ return GRN_RUBY_SCRIPTS_DIR;
+}
+# endif /* WIN32 */
+
+const char *
+grn_mrb_get_system_ruby_scripts_dir(grn_ctx *ctx)
+{
+ if (grn_mrb_ruby_scripts_dir[0]) {
+ return grn_mrb_ruby_scripts_dir;
+ } else {
+ return grn_mrb_get_default_system_ruby_scripts_dir();
+ }
+}
+
+static grn_bool
+grn_mrb_is_absolute_path(const char *path)
+{
+ if (path[0] == '/') {
+ return GRN_TRUE;
+ }
+
+ if (isalpha((unsigned char)path[0]) && path[1] == ':' && path[2] == '/') {
+ return GRN_TRUE;
+ }
+
+ return GRN_FALSE;
+}
+
+static grn_bool
+grn_mrb_expand_script_path(grn_ctx *ctx, const char *path,
+ char *expanded_path, size_t expanded_path_size)
+{
+ const char *ruby_scripts_dir;
+ char dir_last_char;
+ int path_length, max_path_length;
+
+ if (grn_mrb_is_absolute_path(path)) {
+ expanded_path[0] = '\0';
+ } else if (path[0] == '.' && path[1] == '/') {
+ grn_strcpy(expanded_path, expanded_path_size, ctx->impl->mrb.base_directory);
+ grn_strcat(expanded_path, expanded_path_size, "/");
+ } else {
+ ruby_scripts_dir = grn_mrb_get_system_ruby_scripts_dir(ctx);
+ grn_strcpy(expanded_path, expanded_path_size, ruby_scripts_dir);
+
+ dir_last_char = ruby_scripts_dir[strlen(expanded_path) - 1];
+ if (dir_last_char != '/') {
+ grn_strcat(expanded_path, expanded_path_size, "/");
+ }
+ }
+
+ path_length = strlen(path);
+ max_path_length = PATH_MAX - strlen(expanded_path) - 1;
+ if (path_length > max_path_length) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "script path is too long: %d (max: %d) <%s%s>",
+ path_length, max_path_length,
+ expanded_path, path);
+ return GRN_FALSE;
+ }
+
+ grn_strcat(expanded_path, expanded_path_size, path);
+
+ return GRN_TRUE;
+}
+
+mrb_value
+grn_mrb_load(grn_ctx *ctx, const char *path)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ char expanded_path[PATH_MAX];
+ FILE *file;
+ mrb_value result;
+ struct mrb_parser_state *parser;
+
+ if (!mrb) {
+ return mrb_nil_value();
+ }
+
+ if (!grn_mrb_expand_script_path(ctx, path, expanded_path, PATH_MAX)) {
+ return mrb_nil_value();
+ }
+
+ file = grn_fopen(expanded_path, "r");
+ if (!file) {
+ mrb_value exception;
+ 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);
+ return mrb_nil_value();
+ }
+
+ {
+ char current_base_directory[PATH_MAX];
+ char *last_directory;
+
+ grn_strcpy(current_base_directory, PATH_MAX, data->base_directory);
+ grn_strcpy(data->base_directory, PATH_MAX, expanded_path);
+ last_directory = strrchr(data->base_directory, '/');
+ if (last_directory) {
+ last_directory[0] = '\0';
+ }
+
+ parser = mrb_parser_new(mrb);
+ mrb_parser_set_filename(parser, expanded_path);
+ parser->s = parser->send = NULL;
+ parser->f = file;
+ mrb_parser_parse(parser, NULL);
+ fclose(file);
+
+ {
+ 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);
+
+ grn_strcpy(data->base_directory, PATH_MAX, current_base_directory);
+ }
+
+ return result;
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/Makefile.am
new file mode 100644
index 00000000..0e4db634
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/Makefile.am
@@ -0,0 +1,21 @@
+SUBDIRS = \
+ scripts
+
+AM_CPPFLAGS = \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ $(MRUBY_CPPFLAGS)
+
+AM_CFLAGS = \
+ $(NO_STRICT_ALIASING_CFLAGS) \
+ $(COVERAGE_CFLAGS) \
+ $(GRN_CFLAGS) \
+ $(MESSAGE_PACK_CFLAGS) \
+ $(MRUBY_CFLAGS)
+
+noinst_LTLIBRARIES = libgrnmrb.la
+
+include sources.am
+
+CLEANFILES = *.gcno *.gcda
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.c
new file mode 100644
index 00000000..ef341d3a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.c
@@ -0,0 +1,121 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2013-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-1335 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_ctx.h"
+#include "mrb_accessor.h"
+#include "mrb_converter.h"
+
+static struct mrb_data_type mrb_grn_accessor_type = {
+ "Groonga::Accessor",
+ NULL
+};
+
+static mrb_value
+mrb_grn_accessor_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_accessor_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_accessor_ptr);
+ DATA_TYPE(self) = &mrb_grn_accessor_type;
+ DATA_PTR(self) = mrb_cptr(mrb_accessor_ptr);
+ return self;
+}
+
+static mrb_value
+mrb_grn_accessor_next(mrb_state *mrb, mrb_value self)
+{
+ grn_accessor *accessor;
+
+ accessor = DATA_PTR(self);
+ return grn_mrb_value_from_grn_obj(mrb, (grn_obj *)(accessor->next));
+}
+
+static mrb_value
+mrb_grn_accessor_have_next_p(mrb_state *mrb, mrb_value self)
+{
+ grn_accessor *accessor;
+
+ accessor = DATA_PTR(self);
+ return mrb_bool_value(accessor->next != NULL);
+}
+
+static mrb_value
+mrb_grn_accessor_object(mrb_state *mrb, mrb_value self)
+{
+ grn_accessor *accessor;
+
+ accessor = DATA_PTR(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)
+{
+ 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, "Accessor", data->object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+ mrb_define_method(mrb, klass, "initialize",
+ mrb_grn_accessor_initialize, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "next",
+ mrb_grn_accessor_next, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "have_next?",
+ 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
new file mode 100644
index 00000000..4443f7d5
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_accessor.h
@@ -0,0 +1,33 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+#include "../grn_db.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_accessor_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c
new file mode 100644
index 00000000..2d1e84cc
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c
@@ -0,0 +1,92 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+
+#include "mrb_ctx.h"
+#include "mrb_array.h"
+
+static struct mrb_data_type mrb_grn_array_type = {
+ "Groonga::Array",
+ NULL
+};
+
+static mrb_value
+mrb_grn_array_class_create(mrb_state *mrb, mrb_value klass)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ char *name;
+ mrb_int name_length;
+ const char *path = NULL;
+ mrb_value mrb_value_type;
+ grn_obj *value_type = NULL;
+ grn_obj *array;
+
+ mrb_get_args(mrb, "so", &name, &name_length, &mrb_value_type);
+ if (!mrb_nil_p(mrb_value_type)) {
+ value_type = DATA_PTR(mrb_value_type);
+ }
+
+ array = grn_table_create(ctx,
+ name, name_length,
+ path,
+ GRN_TABLE_NO_KEY,
+ NULL,
+ value_type);
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_funcall(mrb, klass, "new", 1, mrb_cptr_value(mrb, array));
+}
+
+static mrb_value
+mrb_grn_array_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_array_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_array_ptr);
+ DATA_TYPE(self) = &mrb_grn_array_type;
+ DATA_PTR(self) = mrb_cptr(mrb_array_ptr);
+ return self;
+}
+
+void
+grn_mrb_array_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *table_class;
+ struct RClass *klass;
+
+ table_class = mrb_class_get_under(mrb, module, "Table");
+ klass = mrb_define_class_under(mrb, module, "Array", table_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+
+ 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));
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.h
new file mode 100644
index 00000000..77ef94d5
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_array_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c
new file mode 100644
index 00000000..b3c47795
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c
@@ -0,0 +1,373 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+#include <string.h>
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/variable.h>
+#include <mruby/data.h>
+#include <mruby/numeric.h>
+#include <mruby/string.h>
+
+#include "../grn_db.h"
+#include "mrb_bulk.h"
+#include "mrb_object.h"
+
+static struct mrb_data_type mrb_grn_bulk_type = {
+ "Groonga::Bulk",
+ NULL
+};
+
+grn_obj *
+grn_mrb_value_to_bulk(mrb_state *mrb, mrb_value mrb_value_, grn_obj *bulk)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+
+ switch (mrb_type(mrb_value_)) {
+ case MRB_TT_FALSE :
+ if (mrb_nil_p(mrb_value_)) {
+ grn_obj_reinit(ctx, bulk, GRN_DB_VOID, 0);
+ } else {
+ grn_obj_reinit(ctx, bulk, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, bulk, GRN_FALSE);
+ }
+ break;
+ case MRB_TT_TRUE :
+ grn_obj_reinit(ctx, bulk, GRN_DB_BOOL, 0);
+ GRN_BOOL_SET(ctx, bulk, GRN_TRUE);
+ break;
+ case MRB_TT_FIXNUM :
+ grn_obj_reinit(ctx, bulk, GRN_DB_INT64, 0);
+ GRN_INT64_SET(ctx, bulk, mrb_fixnum(mrb_value_));
+ break;
+ case MRB_TT_SYMBOL :
+ {
+ const char *name;
+ mrb_int name_length;
+
+ grn_obj_reinit(ctx, bulk, GRN_DB_TEXT, 0);
+ name = mrb_sym2name_len(mrb, mrb_symbol(mrb_value_), &name_length);
+ GRN_TEXT_SET(ctx, bulk, name, name_length);
+ }
+ break;
+ case MRB_TT_FLOAT :
+ grn_obj_reinit(ctx, bulk, GRN_DB_FLOAT, 0);
+ GRN_FLOAT_SET(ctx, bulk, mrb_float(mrb_value_));
+ break;
+ case MRB_TT_STRING :
+ 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 :
+ {
+ 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;
+ }
+
+ return bulk;
+}
+
+mrb_value
+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;
+ value = GRN_INT32_VALUE(bulk);
+ mrb_value_ = mrb_fixnum_value(value);
+ }
+ break;
+ case GRN_DB_UINT32 :
+ {
+ int64_t value;
+ value = GRN_UINT32_VALUE(bulk);
+ if (FIXABLE(value)) {
+ mrb_value_ = mrb_fixnum_value(value);
+ } else {
+ mrb_value_ = mrb_float_value(mrb, 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;
+ 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_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(mrb,
+ GRN_TEXT_VALUE(bulk),
+ GRN_TEXT_LEN(bulk));
+ break;
+ default :
+ {
+ grn_obj *domain;
+ grn_bool is_record = GRN_FALSE;
+
+ domain = grn_ctx_at(ctx, bulk->header.domain);
+ if (domain) {
+ switch (domain->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ is_record = GRN_TRUE;
+ break;
+ default :
+ break;
+ }
+ }
+
+ if (is_record) {
+ mrb_value_ = mrb_fixnum_value(GRN_RECORD_VALUE(bulk));
+ grn_obj_unlink(ctx, domain);
+ } else {
+#define MESSAGE_SIZE 4096
+ char message[MESSAGE_SIZE];
+ char domain_name[GRN_TABLE_MAX_KEY_SIZE];
+ int domain_name_size;
+
+ if (domain) {
+ domain_name_size = grn_obj_name(ctx, domain,
+ domain_name, GRN_TABLE_MAX_KEY_SIZE);
+ grn_obj_unlink(ctx, domain);
+ } 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 bulk value type: <%d>(%.*s)",
+ bulk->header.domain,
+ domain_name_size,
+ domain_name);
+ mrb_raise(mrb, E_RANGE_ERROR, message);
+ }
+#undef MESSAGE_SIZE
+ }
+ break;
+ }
+
+ return mrb_value_;
+}
+
+grn_bool
+grn_mrb_bulk_cast(mrb_state *mrb, grn_obj *from, grn_obj *to, grn_id domain_id)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_rc rc;
+
+ grn_obj_reinit(ctx, to, domain_id, 0);
+ rc = grn_obj_cast(ctx, from, to, GRN_FALSE);
+ return rc == GRN_SUCCESS;
+}
+
+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;
+
+ mrb_get_args(mrb, "o", &mrb_bulk_ptr);
+ DATA_TYPE(self) = &mrb_grn_bulk_type;
+ DATA_PTR(self) = mrb_cptr(mrb_bulk_ptr);
+ return self;
+}
+
+static mrb_value
+mrb_grn_bulk_get_domain(mrb_state *mrb, mrb_value self)
+{
+ grn_obj *bulk;
+
+ bulk = DATA_PTR(self);
+ return mrb_fixnum_value(bulk->header.domain);
+}
+
+static mrb_value
+mrb_grn_bulk_get_value(mrb_state *mrb, mrb_value self)
+{
+ return grn_mrb_value_from_bulk(mrb, DATA_PTR(self));
+}
+
+static mrb_value
+mrb_grn_bulk_equal(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_other;
+
+ mrb_get_args(mrb, "o", &mrb_other);
+
+ if (!mrb_obj_is_kind_of(mrb, mrb_other, mrb_class(mrb, self))) {
+ return mrb_false_value();
+ }
+
+ return mrb_bool_value(DATA_PTR(self) == DATA_PTR(mrb_other));
+}
+
+void
+grn_mrb_bulk_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, "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",
+ mrb_grn_bulk_get_domain, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "value",
+ mrb_grn_bulk_get_value, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "==",
+ mrb_grn_bulk_equal, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "inspect",
+ grn_mrb_object_inspect, MRB_ARGS_NONE());
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.h
new file mode 100644
index 00000000..f8f14b5f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.h
@@ -0,0 +1,41 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+#include "../grn_db.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_bulk_init(grn_ctx *ctx);
+
+mrb_value grn_mrb_value_from_bulk(mrb_state *mrb, grn_obj *bulk);
+grn_obj *grn_mrb_value_to_bulk(mrb_state *mrb,
+ mrb_value mrb_value_,
+ grn_obj *bulk);
+grn_bool grn_mrb_bulk_cast(mrb_state *mrb,
+ grn_obj *from,
+ grn_obj *to,
+ grn_id domain_id);
+
+#ifdef __cplusplus
+}
+#endif
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 00000000..843350f9
--- /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-1335 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 00000000..14628ba8
--- /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-1335 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
new file mode 100644
index 00000000..b36a42bf
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_column.c
@@ -0,0 +1,173 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+#include "../grn_proc.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+
+#include "mrb_ctx.h"
+#include "mrb_column.h"
+#include "mrb_bulk.h"
+#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;
+ mrb_int record_id;
+ grn_obj *column_value;
+
+ column = DATA_PTR(self);
+ mrb_get_args(mrb, "i", &record_id);
+
+ column_value = grn_obj_get_value(ctx, column, record_id, NULL);
+ return grn_mrb_value_from_grn_obj(mrb, column_value);
+}
+
+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;
+ unsigned int is_locked;
+
+ is_locked = grn_obj_is_locked(ctx, DATA_PTR(self));
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_bool_value(is_locked != 0);
+}
+
+static mrb_value
+mrb_grn_column_get_table(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *table;
+
+ table = grn_column_table(ctx, DATA_PTR(self));
+ if (!table) {
+ return mrb_nil_value();
+ }
+
+ 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)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *object_class = data->object_class;
+ struct RClass *klass;
+
+ 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
new file mode 100644
index 00000000..110b294c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_column.h
@@ -0,0 +1,32 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_column_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_command.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command.c
new file mode 100644
index 00000000..0c9c7481
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command.c
@@ -0,0 +1,196 @@
+/* -*- 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+#include <groonga/command.h>
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+#include <mruby/value.h>
+#include <mruby/string.h>
+
+#include "mrb_ctx.h"
+#include "mrb_command.h"
+
+static struct mrb_data_type mrb_grn_command_type = {
+ "Groonga::Command",
+ NULL
+};
+
+mrb_value
+mrb_grn_command_instantiate(grn_ctx *ctx, grn_obj *command)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+ mrb_value mrb_name;
+ struct RClass *command_class;
+ struct RClass *target_command_class;
+ mrb_value mrb_target_command_class;
+ mrb_value mrb_arguments[1];
+
+ name_size = grn_obj_name(ctx, command, name, GRN_TABLE_MAX_KEY_SIZE);
+ mrb_name = mrb_str_new(mrb, name, name_size);
+
+ command_class = mrb_class_get_under(mrb, module, "Command");
+ mrb_target_command_class = mrb_funcall(mrb,
+ mrb_obj_value(command_class),
+ "find_class", 1, mrb_name);
+ if (mrb_nil_p(mrb_target_command_class)) {
+ target_command_class = command_class;
+ } else {
+ target_command_class = mrb_class_ptr(mrb_target_command_class);
+ }
+ mrb_arguments[0] = mrb_cptr_value(mrb, command);
+ return mrb_obj_new(mrb, target_command_class, 1, mrb_arguments);
+}
+
+static void
+mrb_grn_command_run_wrapper(grn_ctx *ctx,
+ grn_obj *command,
+ grn_command_input *input,
+ void *user_data)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ int arena_index;
+ mrb_value mrb_command;
+ mrb_value mrb_input;
+
+ arena_index = mrb_gc_arena_save(mrb);
+ mrb_command = mrb_grn_command_instantiate(ctx, command);
+ {
+ struct RClass *command_input_class;
+ mrb_value mrb_arguments[1];
+ command_input_class = mrb_class_get_under(mrb, module, "CommandInput");
+ mrb_arguments[0] = mrb_cptr_value(mrb, input);
+ 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_class_register(mrb_state *mrb, mrb_value klass)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_value mrb_name;
+ mrb_value *mrb_arguments;
+ mrb_int n_arguments;
+
+ mrb_get_args(mrb, "Sa", &mrb_name, &mrb_arguments, &n_arguments);
+
+ {
+ grn_expr_var *vars;
+ mrb_int i;
+
+ for (i = 0; i < n_arguments; i++) {
+ mrb_arguments[i] = mrb_convert_type(mrb, mrb_arguments[i],
+ MRB_TT_STRING, "String", "to_str");
+ }
+ vars = GRN_MALLOCN(grn_expr_var, n_arguments);
+ for (i = 0; i < n_arguments; i++) {
+ mrb_value mrb_argument = mrb_arguments[i];
+ grn_expr_var *var = &vars[i];
+ var->name = RSTRING_PTR(mrb_argument);
+ var->name_size = RSTRING_LEN(mrb_argument);
+ GRN_TEXT_INIT(&(var->value), 0);
+ }
+
+ grn_command_register(ctx,
+ RSTRING_PTR(mrb_name),
+ RSTRING_LEN(mrb_name),
+ mrb_grn_command_run_wrapper,
+ vars,
+ n_arguments,
+ NULL);
+
+ for (i = 0; i < n_arguments; i++) {
+ grn_expr_var *var = &vars[i];
+ GRN_OBJ_FIN(ctx, &(var->value));
+ }
+ GRN_FREE(vars);
+ }
+
+ grn_mrb_ctx_check(mrb);
+
+ {
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ struct RClass *command_class;
+ command_class = mrb_class_get_under(mrb, data->module, "Command");
+ mrb_funcall(mrb,
+ mrb_obj_value(command_class),
+ "register_class", 2, mrb_name, klass);
+ }
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_command_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_command_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_command_ptr);
+ DATA_TYPE(self) = &mrb_grn_command_type;
+ DATA_PTR(self) = mrb_cptr(mrb_command_ptr);
+ return self;
+}
+
+void
+grn_mrb_command_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *procedure_class;
+ struct RClass *klass;
+
+ procedure_class = mrb_class_get_under(mrb, module, "Procedure");
+ klass = mrb_define_class_under(mrb, module, "Command", procedure_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+
+ 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));
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_command.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command.h
new file mode 100644
index 00000000..1872ca9f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command.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 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_command_init(grn_ctx *ctx);
+
+mrb_value grn_mrb_command_instantiate(grn_ctx *ctx, grn_obj *command);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.c
new file mode 100644
index 00000000..36570fd1
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.c
@@ -0,0 +1,139 @@
+/* -*- 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+#include <groonga/command.h>
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+#include <mruby/value.h>
+#include <mruby/string.h>
+
+#include "mrb_ctx.h"
+#include "mrb_converter.h"
+#include "mrb_command_input.h"
+
+static struct mrb_data_type mrb_grn_command_input_type = {
+ "Groonga::CommandInput",
+ NULL
+};
+
+static mrb_value
+mrb_grn_command_input_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_command_input_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_command_input_ptr);
+ DATA_TYPE(self) = &mrb_grn_command_input_type;
+ DATA_PTR(self) = mrb_cptr(mrb_command_input_ptr);
+ return self;
+}
+
+static mrb_value
+mrb_grn_command_input_array_reference(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_command_input *input;
+ mrb_value mrb_key_or_offset;
+ grn_obj *argument;
+
+ input = DATA_PTR(self);
+ mrb_get_args(mrb, "o", &mrb_key_or_offset);
+
+ switch (mrb_type(mrb_key_or_offset)) {
+ case MRB_TT_FIXNUM :
+ {
+ mrb_int offset = mrb_fixnum(mrb_key_or_offset);
+ argument = grn_command_input_at(ctx, input, offset);
+ }
+ break;
+ case MRB_TT_SYMBOL :
+ {
+ mrb_sym mrb_key_symbol;
+ const char *key;
+ mrb_int key_length;
+
+ mrb_key_symbol = mrb_symbol(mrb_key_or_offset);
+ key = mrb_sym2name_len(mrb, mrb_key_symbol, &key_length);
+ argument = grn_command_input_get(ctx, input, key, key_length);
+ }
+ break;
+ case MRB_TT_STRING :
+ {
+ mrb_value mrb_key = mrb_key_or_offset;
+ argument = grn_command_input_get(ctx, input,
+ RSTRING_PTR(mrb_key),
+ RSTRING_LEN(mrb_key));
+ }
+ break;
+ default :
+ mrb_raisef(mrb, E_ARGUMENT_ERROR,
+ "must be offset (as integer) or key (as symbol or string): %S",
+ mrb_key_or_offset);
+ break;
+ }
+
+ if (!argument) {
+ return mrb_nil_value();
+ }
+
+ if (GRN_TEXT_LEN(argument) == 0) {
+ return mrb_nil_value();
+ }
+
+ return mrb_str_new_static(mrb,
+ GRN_TEXT_VALUE(argument),
+ GRN_TEXT_LEN(argument));
+}
+
+static mrb_value
+mrb_grn_command_input_get_arguments(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_command_input *input;
+ grn_obj *arguments;
+
+ input = DATA_PTR(self);
+ arguments = grn_command_input_get_arguments(ctx, input);
+
+ return grn_mrb_value_from_grn_obj(mrb, arguments);
+}
+
+void
+grn_mrb_command_input_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, "CommandInput", mrb->object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+
+ mrb_define_method(mrb, klass, "initialize",
+ mrb_grn_command_input_initialize, MRB_ARGS_REQ(1));
+
+ mrb_define_method(mrb, klass, "[]",
+ mrb_grn_command_input_array_reference, MRB_ARGS_REQ(1));
+
+ mrb_define_method(mrb, klass, "arguments",
+ mrb_grn_command_input_get_arguments, MRB_ARGS_NONE());
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.h
new file mode 100644
index 00000000..7766d819
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_command_input_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
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 00000000..8c7c0789
--- /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-1335 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 00000000..167b7cb9
--- /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-1335 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 00000000..52c722a4
--- /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-1335 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 00000000..a460db09
--- /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-1335 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.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_content_type.c
new file mode 100644
index 00000000..1010a429
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_content_type.c
@@ -0,0 +1,49 @@
+/* -*- 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+
+#include "mrb_ctx.h"
+#include "mrb_content_type.h"
+
+void
+grn_mrb_content_type_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, "ContentType");
+
+ mrb_define_const(mrb, module, "NONE",
+ mrb_fixnum_value(GRN_CONTENT_NONE));
+ mrb_define_const(mrb, module, "TSV",
+ mrb_fixnum_value(GRN_CONTENT_TSV));
+ mrb_define_const(mrb, module, "JSON",
+ mrb_fixnum_value(GRN_CONTENT_JSON));
+ mrb_define_const(mrb, module, "XML",
+ mrb_fixnum_value(GRN_CONTENT_XML));
+ mrb_define_const(mrb, module, "MSGPACK",
+ mrb_fixnum_value(GRN_CONTENT_MSGPACK));
+ mrb_define_const(mrb, module, "GROONGA_COMMAND_LIST",
+ mrb_fixnum_value(GRN_CONTENT_GROONGA_COMMAND_LIST));
+}
+#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
new file mode 100644
index 00000000..094f3df0
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_content_type.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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_content_type_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c
new file mode 100644
index 00000000..147c47a3
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c
@@ -0,0 +1,350 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2013-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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+#include "../grn_db.h"
+#include <string.h>
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+#include <mruby/string.h>
+
+#include "mrb_converter.h"
+#include "mrb_bulk.h"
+
+void
+grn_mrb_value_to_raw_data_buffer_init(mrb_state *mrb,
+ grn_mrb_value_to_raw_data_buffer *buffer)
+{
+ GRN_VOID_INIT(&(buffer->from));
+ GRN_VOID_INIT(&(buffer->to));
+}
+
+void
+grn_mrb_value_to_raw_data_buffer_fin(mrb_state *mrb,
+ grn_mrb_value_to_raw_data_buffer *buffer)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+
+ GRN_OBJ_FIN(ctx, &(buffer->from));
+ GRN_OBJ_FIN(ctx, &(buffer->to));
+}
+
+void
+grn_mrb_value_to_raw_data(mrb_state *mrb,
+ const char *context,
+ mrb_value mrb_value_,
+ grn_id domain_id,
+ grn_mrb_value_to_raw_data_buffer *buffer,
+ void **raw_value,
+ unsigned int *raw_value_size)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ enum mrb_vtype mrb_value_type;
+ grn_bool try_cast = GRN_FALSE;
+ grn_obj *from_bulk = NULL;
+
+ if (mrb_nil_p(mrb_value_)) {
+ *raw_value = NULL;
+ *raw_value_size = 0;
+ return;
+ }
+
+ mrb_value_type = mrb_type(mrb_value_);
+
+ switch (mrb_value_type) {
+ case MRB_TT_STRING :
+ switch (domain_id) {
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ *raw_value = RSTRING_PTR(mrb_value_);
+ *raw_value_size = RSTRING_LEN(mrb_value_);
+ break;
+ default :
+ try_cast = GRN_TRUE;
+ break;
+ }
+ break;
+ default :
+ {
+ struct RClass *klass;
+ grn_mrb_data *data = &(ctx->impl->mrb);
+
+ klass = mrb_class(mrb, mrb_value_);
+ if (domain_id == GRN_DB_TIME &&
+ klass == data->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);
+ buffer->value.time_value = GRN_TIME_PACK(mrb_fixnum(mrb_sec),
+ mrb_fixnum(mrb_usec));
+ *raw_value = &(buffer->value.time_value);
+ *raw_value_size = sizeof(buffer->value.time_value);
+ } else {
+ try_cast = GRN_TRUE;
+ if (mrb_value_type == MRB_TT_DATA &&
+ klass == mrb_class_get_under(mrb, data->module, "Bulk")) {
+ from_bulk = DATA_PTR(mrb_value_);
+ }
+ }
+ }
+ break;
+ }
+
+ if (!try_cast) {
+ return;
+ }
+
+ if (!from_bulk) {
+ from_bulk = &(buffer->from);
+ grn_mrb_value_to_bulk(mrb, mrb_value_, from_bulk);
+ }
+ if (!grn_mrb_bulk_cast(mrb, from_bulk, &(buffer->to), domain_id)) {
+ grn_obj *domain;
+ char domain_name[GRN_TABLE_MAX_KEY_SIZE];
+ int domain_name_size;
+
+ domain = grn_ctx_at(ctx, domain_id);
+ domain_name_size = grn_obj_name(ctx, domain, domain_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ mrb_raisef(mrb, E_ARGUMENT_ERROR,
+ "%S: failed to convert to %S: %S",
+ mrb_str_new_static(mrb, context, strlen(context)),
+ mrb_str_new_static(mrb, domain_name, domain_name_size),
+ mrb_funcall(mrb, mrb_value_, "inspect", 0));
+ }
+ *raw_value = GRN_BULK_HEAD(&(buffer->to));
+ *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)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_mrb_data *data;
+ struct RClass *klass = NULL;
+
+ data = &(ctx->impl->mrb);
+ switch (object->header.type) {
+ 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;
+ case GRN_COLUMN_FIX_SIZE :
+ klass = mrb_class_get_under(mrb, data->module, "FixedSizeColumn");
+ break;
+ case GRN_COLUMN_VAR_SIZE :
+ klass = mrb_class_get_under(mrb, data->module, "VariableSizeColumn");
+ break;
+ case GRN_COLUMN_INDEX :
+ klass = mrb_class_get_under(mrb, data->module, "IndexColumn");
+ break;
+ case GRN_TYPE :
+ klass = mrb_class_get_under(mrb, data->module, "Type");
+ break;
+ case GRN_PROC :
+ klass = mrb_class_get_under(mrb, data->module, "Procedure");
+ break;
+ case GRN_EXPR :
+ klass = mrb_class_get_under(mrb, data->module, "Expression");
+ break;
+ case GRN_TABLE_NO_KEY :
+ klass = mrb_class_get_under(mrb, data->module, "Array");
+ break;
+ case GRN_TABLE_HASH_KEY :
+ klass = mrb_class_get_under(mrb, data->module, "HashTable");
+ break;
+ case GRN_TABLE_PAT_KEY :
+ klass = mrb_class_get_under(mrb, data->module, "PatriciaTrie");
+ break;
+ case GRN_TABLE_DAT_KEY :
+ klass = mrb_class_get_under(mrb, data->module, "DoubleArrayTrie");
+ break;
+ case GRN_DB :
+ klass = mrb_class_get_under(mrb, data->module, "Database");
+ break;
+ case GRN_VOID :
+ klass = mrb_class_get_under(mrb, data->module, "Void");
+ break;
+ default :
+ break;
+ }
+
+ if (!klass) {
+#define BUFFER_SIZE 1024
+ char buffer[BUFFER_SIZE];
+ grn_snprintf(buffer, BUFFER_SIZE, BUFFER_SIZE,
+ "can't find class for object type: %#x", object->header.type);
+ mrb_raise(mrb, E_ARGUMENT_ERROR, buffer);
+#undef BUFFER_SIZE
+ }
+
+ return klass;
+}
+
+mrb_value
+grn_mrb_value_from_grn_obj(mrb_state *mrb, grn_obj *object)
+{
+ struct RClass *mrb_class;
+ mrb_value mrb_new_arguments[1];
+ mrb_value mrb_object;
+
+ if (!object) {
+ return mrb_nil_value();
+ }
+
+ mrb_class = grn_mrb_class_from_grn_obj(mrb, object);
+ mrb_new_arguments[0] = mrb_cptr_value(mrb, object);
+ mrb_object = mrb_obj_new(mrb, mrb_class, 1, mrb_new_arguments);
+ return mrb_object;
+}
+
+grn_id
+grn_mrb_class_to_type(mrb_state *mrb, struct RClass *klass)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_id type = GRN_DB_VOID;
+
+ if (klass == mrb->nil_class) {
+ type = GRN_DB_VOID;
+ } else if (klass == mrb->true_class ||
+ klass == mrb->false_class) {
+ type = GRN_DB_BOOL;
+ } else if (klass == mrb->symbol_class) {
+ type = GRN_DB_TEXT;
+ } else if (klass == mrb->fixnum_class) {
+ type = GRN_DB_INT64;
+ } else if (klass == mrb->float_class) {
+ type = GRN_DB_FLOAT;
+ } else if (klass == mrb->string_class) {
+ type = GRN_DB_TEXT;
+ } else if (klass == ctx->impl->mrb.builtin.time_class) {
+ type = GRN_DB_TIME;
+ } else {
+ mrb_raisef(mrb, E_ARGUMENT_ERROR,
+ "unsupported class: %S", mrb_obj_value(klass));
+ }
+
+ return type;
+}
+
+static mrb_value
+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);
+ grn_obj *to = &(ctx->impl->mrb.buffer.to);
+ mrb_value mrb_from;
+ mrb_value mrb_to_class;
+ grn_id to_type;
+
+ mrb_get_args(mrb, "oC", &mrb_from, &mrb_to_class);
+
+ grn_mrb_value_to_bulk(mrb, mrb_from, from);
+ to_type = grn_mrb_class_to_type(mrb, mrb_class_ptr(mrb_to_class));
+ if (!grn_mrb_bulk_cast(mrb, from, to, to_type)) {
+ mrb_raisef(mrb, E_ARGUMENT_ERROR,
+ "failed to convert to %S: %S",
+ mrb_to_class,
+ mrb_from);
+ }
+
+ return grn_mrb_value_from_bulk(mrb, to);
+}
+
+void
+grn_mrb_converter_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, "Converter");
+
+ 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
new file mode 100644
index 00000000..9b8546dd
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.h
@@ -0,0 +1,64 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+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 {
+ grn_obj from;
+ grn_obj to;
+ union {
+ int64_t time_value;
+ } value;
+} grn_mrb_value_to_raw_data_buffer;
+
+void grn_mrb_value_to_raw_data_buffer_init(mrb_state *mrb,
+ grn_mrb_value_to_raw_data_buffer *buffer);
+void grn_mrb_value_to_raw_data_buffer_fin(mrb_state *mrb,
+ grn_mrb_value_to_raw_data_buffer *buffer);
+void grn_mrb_value_to_raw_data(mrb_state *mrb,
+ const char *context,
+ mrb_value mrb_value_,
+ grn_id domain_id,
+ 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);
+
+grn_id grn_mrb_class_to_grn_type(mrb_state *mrb, struct RClass *klass);
+grn_id grn_mrb_value_to_grn_type(mrb_state *mrb, mrb_value value);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.c
new file mode 100644
index 00000000..e89df53e
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.c
@@ -0,0 +1,838 @@
+/* -*- 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-1335 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_ctx.h"
+#include "mrb_bulk.h"
+#include "mrb_converter.h"
+
+static mrb_value
+ctx_class_instance(mrb_state *mrb, mrb_value klass)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_value mrb_ctx;
+ mrb_sym iv_name;
+
+ iv_name = mrb_intern_lit(mrb, "@instance");
+ mrb_ctx = mrb_iv_get(mrb, klass, iv_name);
+ if (mrb_nil_p(mrb_ctx)) {
+ struct RBasic *raw_mrb_ctx;
+ raw_mrb_ctx = mrb_obj_alloc(mrb, MRB_TT_DATA, mrb_class_ptr(klass));
+ mrb_ctx = mrb_obj_value(raw_mrb_ctx);
+ DATA_PTR(mrb_ctx) = ctx;
+ mrb_iv_set(mrb, klass, iv_name, mrb_ctx);
+ }
+
+ return mrb_ctx;
+}
+
+static mrb_value
+ctx_array_reference(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_value mrb_id_or_name;
+ grn_obj *object;
+
+ mrb_get_args(mrb, "o", &mrb_id_or_name);
+
+ if (mrb_nil_p(mrb_id_or_name)) {
+ return mrb_nil_value();
+ }
+
+ if (mrb_fixnum_p(mrb_id_or_name)) {
+ grn_id id = mrb_fixnum(mrb_id_or_name);
+ object = grn_ctx_at(ctx, id);
+ } else {
+ mrb_value mrb_name;
+ mrb_name = mrb_convert_type(mrb, mrb_id_or_name,
+ MRB_TT_STRING, "String", "to_str");
+ object = grn_ctx_get(ctx,
+ RSTRING_PTR(mrb_name),
+ RSTRING_LEN(mrb_name));
+ }
+
+ return grn_mrb_value_from_grn_obj(mrb, object);
+}
+
+static mrb_value
+ctx_get_rc(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+
+ return mrb_fixnum_value(ctx->rc);
+}
+
+static mrb_value
+ctx_set_rc(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_int rc;
+
+ mrb_get_args(mrb, "i", &rc);
+ ctx->rc = rc;
+
+ return mrb_fixnum_value(ctx->rc);
+}
+
+static mrb_value
+ctx_get_error_level(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+
+ return mrb_fixnum_value(ctx->errlvl);
+}
+
+static mrb_value
+ctx_set_error_level(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_int error_level;
+
+ mrb_get_args(mrb, "i", &error_level);
+ ctx->errlvl = error_level;
+
+ return mrb_fixnum_value(ctx->errlvl);
+}
+
+static mrb_value
+ctx_get_error_file(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+
+ return mrb_str_new_cstr(mrb, ctx->errfile);
+}
+
+static mrb_value
+ctx_set_error_file(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_value error_file;
+
+ mrb_get_args(mrb, "S", &error_file);
+ mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@error_file"), error_file);
+ ctx->errfile = mrb_string_value_cstr(mrb, &error_file);
+
+ return error_file;
+}
+
+static mrb_value
+ctx_get_error_line(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+
+ return mrb_fixnum_value(ctx->errline);
+}
+
+static mrb_value
+ctx_set_error_line(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_int error_line;
+
+ mrb_get_args(mrb, "i", &error_line);
+ ctx->errline = error_line;
+
+ return mrb_fixnum_value(ctx->errline);
+}
+
+static mrb_value
+ctx_get_error_method(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+
+ return mrb_str_new_cstr(mrb, ctx->errfunc);
+}
+
+static mrb_value
+ctx_set_error_method(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_value error_method;
+
+ mrb_get_args(mrb, "S", &error_method);
+ mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@error_method"), error_method);
+ ctx->errfunc = mrb_string_value_cstr(mrb, &error_method);
+
+ return error_method;
+}
+
+static mrb_value
+ctx_get_error_message(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+
+ return mrb_str_new_cstr(mrb, ctx->errbuf);
+}
+
+static mrb_value
+ctx_set_error_message(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_value error_message;
+
+ mrb_get_args(mrb, "S", &error_message);
+ grn_ctx_log(ctx, "%.*s",
+ (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;
+
+ 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 = NULL;
+#define MESSAGE_SIZE 4096
+ char message[MESSAGE_SIZE];
+
+ switch (ctx->rc) {
+ case GRN_SUCCESS:
+ return;
+ case GRN_END_OF_DATA:
+ error_class = mrb_class_get_under(mrb, module, "EndOfData");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "end of data: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_UNKNOWN_ERROR:
+ error_class = mrb_class_get_under(mrb, module, "UnknownError");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "unknown error: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_OPERATION_NOT_PERMITTED:
+ error_class = mrb_class_get_under(mrb, module, "OperationNotPermitted");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "operation not permitted: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_NO_SUCH_FILE_OR_DIRECTORY:
+ error_class = mrb_class_get_under(mrb, module, "NoSuchFileOrDirectory");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "no such file or directory: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_NO_SUCH_PROCESS:
+ error_class = mrb_class_get_under(mrb, module, "NoSuchProcess");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "no such process: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_INTERRUPTED_FUNCTION_CALL:
+ error_class = mrb_class_get_under(mrb, module, "InterruptedFunctionCall");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "interrupted function call: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_INPUT_OUTPUT_ERROR:
+ error_class = mrb_class_get_under(mrb, module, "InputOutputError");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "input output error: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_NO_SUCH_DEVICE_OR_ADDRESS:
+ error_class = mrb_class_get_under(mrb, module, "NoSuchDeviceOrAddress");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "no such device or address: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_ARG_LIST_TOO_LONG:
+ error_class = mrb_class_get_under(mrb, module, "ArgListTooLong");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "arg list too long: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_EXEC_FORMAT_ERROR:
+ error_class = mrb_class_get_under(mrb, module, "ExecFormatError");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "exec format error: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_BAD_FILE_DESCRIPTOR:
+ error_class = mrb_class_get_under(mrb, module, "BadFileDescriptor");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "bad file descriptor: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_NO_CHILD_PROCESSES:
+ error_class = mrb_class_get_under(mrb, module, "NoChildProcesses");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "no child processes: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_RESOURCE_TEMPORARILY_UNAVAILABLE:
+ error_class = mrb_class_get_under(mrb, module,
+ "ResourceTemporarilyUnavailable");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "resource temporarily unavailable: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_NOT_ENOUGH_SPACE:
+ error_class = mrb_class_get_under(mrb, module, "NotEnoughSpace");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "not enough space: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_PERMISSION_DENIED:
+ error_class = mrb_class_get_under(mrb, module, "PermissionDenied");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "permission denied: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_BAD_ADDRESS:
+ error_class = mrb_class_get_under(mrb, module, "BadAddress");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "bad address: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_RESOURCE_BUSY:
+ error_class = mrb_class_get_under(mrb, module, "ResourceBusy");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "resource busy: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_FILE_EXISTS:
+ error_class = mrb_class_get_under(mrb, module, "FileExists");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "file exists: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_IMPROPER_LINK:
+ error_class = mrb_class_get_under(mrb, module, "ImproperLink");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "improper link: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_NO_SUCH_DEVICE:
+ error_class = mrb_class_get_under(mrb, module, "NoSuchDevice");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "no such device: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_NOT_A_DIRECTORY:
+ error_class = mrb_class_get_under(mrb, module, "NotDirectory");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "not directory: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_IS_A_DIRECTORY:
+ error_class = mrb_class_get_under(mrb, module, "IsDirectory");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "is directory: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_INVALID_ARGUMENT:
+ error_class = mrb_class_get_under(mrb, module, "InvalidArgument");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "invalid argument: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_TOO_MANY_OPEN_FILES_IN_SYSTEM:
+ error_class = mrb_class_get_under(mrb, module, "TooManyOpenFilesInSystem");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "too many open files in system: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_TOO_MANY_OPEN_FILES:
+ error_class = mrb_class_get_under(mrb, module, "TooManyOpenFiles");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "too many open files: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_INAPPROPRIATE_I_O_CONTROL_OPERATION:
+ error_class = mrb_class_get_under(mrb, module,
+ "InappropriateIOControlOperation");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "inappropriate IO control operation: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_FILE_TOO_LARGE:
+ error_class = mrb_class_get_under(mrb, module, "FileTooLarge");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "file too large: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_NO_SPACE_LEFT_ON_DEVICE:
+ error_class = mrb_class_get_under(mrb, module, "NoSpaceLeftOnDevice");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "no space left on device: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_INVALID_SEEK:
+ error_class = mrb_class_get_under(mrb, module, "InvalidSeek");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "invalid seek: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_READ_ONLY_FILE_SYSTEM:
+ error_class = mrb_class_get_under(mrb, module, "ReadOnlyFileSystem");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "read only file system: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_TOO_MANY_LINKS:
+ error_class = mrb_class_get_under(mrb, module, "TooManyLinks");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "too many links: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_BROKEN_PIPE:
+ error_class = mrb_class_get_under(mrb, module, "BrokenPipe");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "broken pipe: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_DOMAIN_ERROR:
+ error_class = mrb_class_get_under(mrb, module, "DomainError");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "domain error: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_RESULT_TOO_LARGE:
+ error_class = mrb_class_get_under(mrb, module, "ResultTooLarge");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "result too large: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_RESOURCE_DEADLOCK_AVOIDED:
+ error_class = mrb_class_get_under(mrb, module, "ResourceDeadlockAvoided");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "resource deadlock avoided: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_NO_MEMORY_AVAILABLE:
+ error_class = mrb_class_get_under(mrb, module, "NoMemoryAvailable");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "no memory available: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_FILENAME_TOO_LONG:
+ error_class = mrb_class_get_under(mrb, module, "FilenameTooLong");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "filename too long: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_NO_LOCKS_AVAILABLE:
+ error_class = mrb_class_get_under(mrb, module, "NoLocksAvailable");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "no locks available: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_FUNCTION_NOT_IMPLEMENTED:
+ error_class = mrb_class_get_under(mrb, module, "FunctionNotImplemented");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "function not implemented: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_DIRECTORY_NOT_EMPTY:
+ error_class = mrb_class_get_under(mrb, module, "DirectoryNotEmpty");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "directory not empty: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_ILLEGAL_BYTE_SEQUENCE:
+ error_class = mrb_class_get_under(mrb, module, "IllegalByteSequence");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "illegal byte sequence: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_SOCKET_NOT_INITIALIZED:
+ error_class = mrb_class_get_under(mrb, module, "SocketNotInitialized");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "socket not initialized: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_OPERATION_WOULD_BLOCK:
+ error_class = mrb_class_get_under(mrb, module, "OperationWouldBlock");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "operation would block: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_ADDRESS_IS_NOT_AVAILABLE:
+ error_class = mrb_class_get_under(mrb, module, "AddressIsNotAvailable");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "address is not available: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_NETWORK_IS_DOWN:
+ error_class = mrb_class_get_under(mrb, module, "NetworkIsDown");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "network is down: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_NO_BUFFER:
+ error_class = mrb_class_get_under(mrb, module, "NoBuffer");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "no buffer: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_SOCKET_IS_ALREADY_CONNECTED:
+ error_class = mrb_class_get_under(mrb, module, "SocketIsAlreadyConnected");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "socket is already connected: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_SOCKET_IS_NOT_CONNECTED:
+ error_class = mrb_class_get_under(mrb, module, "SocketIsNotConnected");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "socket is not connected: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_SOCKET_IS_ALREADY_SHUTDOWNED:
+ error_class = mrb_class_get_under(mrb, module, "SocketIsAlreadyShutdowned");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "socket is already shutdowned: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_OPERATION_TIMEOUT:
+ error_class = mrb_class_get_under(mrb, module, "OperationTimeout");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "operation timeout: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_CONNECTION_REFUSED:
+ error_class = mrb_class_get_under(mrb, module, "ConnectionRefused");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "connection refused: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_RANGE_ERROR:
+ error_class = mrb_class_get_under(mrb, module, "RangeError");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "range error: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_TOKENIZER_ERROR:
+ error_class = mrb_class_get_under(mrb, module, "TokenizerError");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "tokenizer error: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_FILE_CORRUPT:
+ error_class = mrb_class_get_under(mrb, module, "FileCorrupt");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "file corrupt: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_INVALID_FORMAT:
+ error_class = mrb_class_get_under(mrb, module, "InvalidFormat");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "invalid format: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_OBJECT_CORRUPT:
+ error_class = mrb_class_get_under(mrb, module, "ObjectCorrupt");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "object corrupt: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_TOO_MANY_SYMBOLIC_LINKS:
+ error_class = mrb_class_get_under(mrb, module, "TooManySymbolicLinks");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "too many symbolic links: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_NOT_SOCKET:
+ error_class = mrb_class_get_under(mrb, module, "NotSocket");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "not socket: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_OPERATION_NOT_SUPPORTED:
+ error_class = mrb_class_get_under(mrb, module, "OperationNotSupported");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "operation not supported: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_ADDRESS_IS_IN_USE:
+ error_class = mrb_class_get_under(mrb, module, "AddressIsInUse");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "address is in use: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_ZLIB_ERROR:
+ error_class = mrb_class_get_under(mrb, module, "ZlibError");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "zlib error: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_LZ4_ERROR:
+ error_class = mrb_class_get_under(mrb, module, "LZ4Error");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "LZ4 error: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_STACK_OVER_FLOW:
+ error_class = mrb_class_get_under(mrb, module, "StackOverFlow");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "stack over flow: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_SYNTAX_ERROR:
+ error_class = mrb_class_get_under(mrb, module, "SyntaxError");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "syntax error: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_RETRY_MAX:
+ error_class = mrb_class_get_under(mrb, module, "RetryMax");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "retry max: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_INCOMPATIBLE_FILE_FORMAT:
+ error_class = mrb_class_get_under(mrb, module, "IncompatibleFileFormat");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "incompatible file format: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_UPDATE_NOT_ALLOWED:
+ error_class = mrb_class_get_under(mrb, module, "UpdateNotAllowed");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "update not allowed: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_TOO_SMALL_OFFSET:
+ error_class = mrb_class_get_under(mrb, module, "TooSmallOffset");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "too small offset: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_TOO_LARGE_OFFSET:
+ error_class = mrb_class_get_under(mrb, module, "TooLargeOffset");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "too large offset: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_TOO_SMALL_LIMIT:
+ error_class = mrb_class_get_under(mrb, module, "TooSmallLimit");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "too small limit: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_CAS_ERROR:
+ error_class = mrb_class_get_under(mrb, module, "CASError");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "CAS error: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_UNSUPPORTED_COMMAND_VERSION:
+ error_class = mrb_class_get_under(mrb, module, "UnsupportedCommandVersion");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "unsupported command version: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ case GRN_NORMALIZER_ERROR:
+ error_class = mrb_class_get_under(mrb, module, "NormalizerError");
+ grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE,
+ "normalizer error: <%s>(%d)",
+ ctx->errbuf, ctx->rc);
+ break;
+ 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);
+ }
+#undef MESSAGE_SIZE
+
+ mrb_raise(mrb, error_class, message);
+}
+
+void
+grn_mrb_ctx_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, "Context", mrb->object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+
+ mrb_define_class_method(mrb, klass, "instance",
+ ctx_class_instance, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "[]", ctx_array_reference, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "rc", ctx_get_rc, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "rc=", ctx_set_rc, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "error_level", ctx_get_error_level,
+ MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "error_level=", ctx_set_error_level,
+ MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "error_file", ctx_get_error_file,
+ MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "error_file=", ctx_set_error_file,
+ MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "error_line", ctx_get_error_line,
+ MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "error_line=", ctx_set_error_line,
+ MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "error_method", ctx_get_error_method,
+ MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "error_method=", ctx_set_error_method,
+ MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "error_message", ctx_get_error_message,
+ 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
new file mode 100644
index 00000000..72519ae6
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_ctx.h
@@ -0,0 +1,33 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_ctx_init(grn_ctx *ctx);
+void grn_mrb_ctx_check(mrb_state *mrb);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_database.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_database.c
new file mode 100644
index 00000000..5ff2bdbe
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_database.c
@@ -0,0 +1,206 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+
+#include "mrb_ctx.h"
+#include "mrb_database.h"
+#include "mrb_converter.h"
+
+static struct mrb_data_type mrb_grn_database_type = {
+ "Groonga::Database",
+ NULL
+};
+
+static mrb_value
+mrb_grn_database_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_database_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_database_ptr);
+ DATA_TYPE(self) = &mrb_grn_database_type;
+ DATA_PTR(self) = mrb_cptr(mrb_database_ptr);
+ return self;
+}
+
+static mrb_value
+mrb_grn_database_class_open(mrb_state *mrb, mrb_value klass)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *database;
+ char *path;
+
+ mrb_get_args(mrb, "z", &path);
+
+ database = grn_db_open(ctx, path);
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_funcall(mrb, klass, "new", 1, mrb_cptr_value(mrb, database));
+}
+
+static mrb_value
+mrb_grn_database_class_create(mrb_state *mrb, mrb_value klass)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *database;
+ char *path;
+
+ mrb_get_args(mrb, "z", &path);
+
+ database = grn_db_create(ctx, path, NULL);
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_funcall(mrb, klass, "new", 1, mrb_cptr_value(mrb, database));
+}
+
+static mrb_value
+mrb_grn_database_recover(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+
+ grn_db_recover(ctx, DATA_PTR(self));
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_database_is_locked(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ unsigned int is_locked;
+
+ is_locked = grn_obj_is_locked(ctx, DATA_PTR(self));
+ grn_mrb_ctx_check(mrb);
+
+ 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)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *object_class = data->object_class;
+ struct RClass *klass;
+
+ klass = mrb_define_class_under(mrb, module, "Database", object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+
+ 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));
+ mrb_define_method(mrb, klass, "recover",
+ 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
new file mode 100644
index 00000000..512e33c9
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_database.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_database_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_double_array_trie.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_double_array_trie.c
new file mode 100644
index 00000000..20007fef
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_double_array_trie.c
@@ -0,0 +1,60 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2014 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+
+#include "mrb_double_array_trie.h"
+
+static struct mrb_data_type mrb_grn_double_array_trie_type = {
+ "Groonga::DoubleArrayTrie",
+ NULL
+};
+
+static mrb_value
+mrb_grn_double_array_trie_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_double_array_trie_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_double_array_trie_ptr);
+ DATA_TYPE(self) = &mrb_grn_double_array_trie_type;
+ DATA_PTR(self) = mrb_cptr(mrb_double_array_trie_ptr);
+ return self;
+}
+
+void
+grn_mrb_double_array_trie_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *table_class;
+ struct RClass *klass;
+
+ table_class = mrb_class_get_under(mrb, module, "Table");
+ klass = mrb_define_class_under(mrb, module, "DoubleArrayTrie", table_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+
+ mrb_define_method(mrb, klass, "initialize",
+ mrb_grn_double_array_trie_initialize, MRB_ARGS_REQ(1));
+}
+#endif
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
new file mode 100644
index 00000000..4e7bd59d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_double_array_trie.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_double_array_trie_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_error.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_error.c
new file mode 100644
index 00000000..f162d499
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_error.c
@@ -0,0 +1,202 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2014 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+
+#include "../grn_mrb.h"
+#include "mrb_error.h"
+
+void
+grn_mrb_error_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *error_class;
+ struct RClass *groonga_error_class;
+
+ error_class = mrb_define_class_under(mrb, module, "Error",
+ mrb->eStandardError_class);
+ groonga_error_class = mrb_define_class_under(mrb, module, "GroongaError",
+ error_class);
+
+ mrb_define_class_under(mrb, module, "EndOfData",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "UnknownError",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "OperationNotPermitted",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "NoSuchFileOrDirectory",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "NoSuchProcess",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "InterruptedFunctionCall",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "InputOutputError",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "NoSuchDeviceOrAddress",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "ArgListTooLong",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "ExecFormatError",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "BadFileDescriptor",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "NoChildProcesses",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "ResourceTemporarilyUnavailable",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "NotEnoughSpace",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "PermissionDenied",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "BadAddress",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "ResourceBusy",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "FileExists",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "ImproperLink",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "NoSuchDevice",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "NotDirectory",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "IsDirectory",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "InvalidArgument",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "TooManyOpenFilesInSystem",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "TooManyOpenFiles",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "InappropriateIOControlOperation",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "FileTooLarge",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "NoSpaceLeftOnDevice",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "InvalidSeek",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "ReadOnlyFileSystem",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "TooManyLinks",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "BrokenPipe",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "DomainError",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "ResultTooLarge",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "ResourceDeadlockAvoided",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "NoMemoryAvailable",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "FilenameTooLong",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "NoLocksAvailable",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "FunctionNotImplemented",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "DirectoryNotEmpty",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "IllegalByteSequence",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "SocketNotInitialized",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "OperationWouldBlock",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "AddressIsNotAvailable",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "NetworkIsDown",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "NoBuffer",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "SocketIsAlreadyConnected",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "SocketIsNotConnected",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "SocketIsAlreadyShutdowned",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "OperationTimeout",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "ConnectionRefused",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "RangeError",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "TokenizerError",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "FileCorrupt",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "InvalidFormat",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "ObjectCorrupt",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "TooManySymbolicLinks",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "NotSocket",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "OperationNotSupported",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "AddressIsInUse",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "ZlibError",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "LZ4Error",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "StackOverFlow",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "SyntaxError",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "RetryMax",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "IncompatibleFileFormat",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "UpdateNotAllowed",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "TooSmallOffset",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "TooLargeOffset",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "TooSmallLimit",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "CASError",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "UnsupportedCommandVersion",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "NormalizerError",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "TokenFilterError",
+ groonga_error_class);
+ mrb_define_class_under(mrb, module, "CommandError",
+ 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
new file mode 100644
index 00000000..917bfec5
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_error.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_error_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
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 00000000..fd5be59c
--- /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-1335 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 00000000..c277ed5e
--- /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-1335 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
new file mode 100644
index 00000000..2b8f6a04
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c
@@ -0,0 +1,1079 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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 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-1335 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 <mruby/string.h>
+#include <mruby/array.h>
+#include <mruby/hash.h>
+
+#include "../grn_expr.h"
+#include "../grn_proc.h"
+#include "../grn_util.h"
+#include "../grn_mrb.h"
+#include "mrb_accessor.h"
+#include "mrb_ctx.h"
+#include "mrb_expr.h"
+#include "mrb_operator.h"
+#include "mrb_converter.h"
+#include "mrb_options.h"
+
+static struct mrb_data_type mrb_grn_scan_info_type = {
+ "Groonga::ScanInfo",
+ NULL
+};
+static struct mrb_data_type mrb_grn_expr_code_type = {
+ "Groonga::ExpressionCode",
+ NULL
+};
+static struct mrb_data_type mrb_grn_expression_type = {
+ "Groonga::Expression",
+ NULL
+};
+
+static mrb_value
+mrb_grn_scan_info_new(mrb_state *mrb, scan_info *scan_info)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ struct RClass *module = ctx->impl->mrb.module;
+ struct RClass *klass;
+ mrb_value mrb_scan_info;
+
+ mrb_scan_info = mrb_cptr_value(mrb, scan_info);
+ klass = mrb_class_get_under(mrb, module, "ScanInfo");
+ return mrb_obj_new(mrb, klass, 1, &mrb_scan_info);
+}
+
+static mrb_value
+mrb_grn_expr_code_new(mrb_state *mrb, grn_expr_code *code)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ struct RClass *module = ctx->impl->mrb.module;
+ struct RClass *klass;
+ mrb_value mrb_code;
+
+ mrb_code = mrb_cptr_value(mrb, code);
+ klass = mrb_class_get_under(mrb, module, "ExpressionCode");
+ return mrb_obj_new(mrb, klass, 1, &mrb_code);
+}
+
+static mrb_value
+mrb_grn_scan_info_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_ptr);
+ DATA_TYPE(self) = &mrb_grn_scan_info_type;
+ DATA_PTR(self) = mrb_cptr(mrb_ptr);
+ return self;
+}
+
+static mrb_value
+mrb_grn_expr_code_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_code;
+
+ mrb_get_args(mrb, "o", &mrb_code);
+ DATA_TYPE(self) = &mrb_grn_expr_code_type;
+ DATA_PTR(self) = mrb_cptr(mrb_code);
+ return self;
+}
+
+static mrb_value
+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;
+ mrb_int sid;
+ mrb_int weight;
+ mrb_value mrb_scorer;
+ mrb_value mrb_scorer_args_expr;
+ mrb_int scorer_args_expr_offset;
+ grn_obj *index;
+ grn_obj *scorer = NULL;
+ grn_obj *scorer_args_expr = NULL;
+
+ mrb_get_args(mrb, "oiiooi",
+ &mrb_index, &sid, &weight,
+ &mrb_scorer,
+ &mrb_scorer_args_expr,
+ &scorer_args_expr_offset);
+ si = DATA_PTR(self);
+ index = DATA_PTR(mrb_index);
+ if (!mrb_nil_p(mrb_scorer)) {
+ scorer = DATA_PTR(mrb_scorer);
+ }
+ if (!mrb_nil_p(mrb_scorer_args_expr)) {
+ scorer_args_expr = DATA_PTR(mrb_scorer_args_expr);
+ }
+ grn_scan_info_put_index(ctx, si, index, sid, weight,
+ scorer,
+ scorer_args_expr,
+ scorer_args_expr_offset);
+ return self;
+}
+
+static mrb_value
+mrb_grn_scan_info_get_op(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ grn_operator op;
+
+ si = DATA_PTR(self);
+ op = grn_scan_info_get_op(si);
+ return grn_mrb_value_from_operator(mrb, op);
+}
+
+static mrb_value
+mrb_grn_scan_info_set_op(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ mrb_value mrb_op;
+ grn_operator 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);
+ return self;
+}
+
+static mrb_value
+mrb_grn_scan_info_set_end(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ mrb_int end;
+
+ mrb_get_args(mrb, "i", &end);
+ si = DATA_PTR(self);
+ grn_scan_info_set_end(si, end);
+ return self;
+}
+
+static mrb_value
+mrb_grn_scan_info_set_query(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ mrb_value mrb_query;
+
+ mrb_get_args(mrb, "o", &mrb_query);
+ si = DATA_PTR(self);
+ if (mrb_nil_p(mrb_query)) {
+ grn_scan_info_set_query(si, NULL);
+ } else {
+ grn_scan_info_set_query(si, DATA_PTR(mrb_query));
+ }
+ return self;
+}
+
+static mrb_value
+mrb_grn_scan_info_set_flags(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ mrb_int flags;
+
+ mrb_get_args(mrb, "i", &flags);
+ si = DATA_PTR(self);
+ grn_scan_info_set_flags(si, flags);
+ return self;
+}
+
+static mrb_value
+mrb_grn_scan_info_get_flags(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ int flags;
+
+ si = DATA_PTR(self);
+ flags = grn_scan_info_get_flags(si);
+ return mrb_fixnum_value(flags);
+}
+
+static mrb_value
+mrb_grn_scan_info_set_logical_op(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ mrb_value mrb_logical_op;
+ grn_operator logical_op;
+
+ mrb_get_args(mrb, "o", &mrb_logical_op);
+ si = DATA_PTR(self);
+ logical_op = grn_mrb_value_to_operator(mrb, mrb_logical_op);
+ grn_scan_info_set_logical_op(si, logical_op);
+ return self;
+}
+
+static mrb_value
+mrb_grn_scan_info_get_logical_op(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ grn_operator logical_op;
+
+ si = DATA_PTR(self);
+ logical_op = grn_scan_info_get_logical_op(si);
+ return grn_mrb_value_from_operator(mrb, logical_op);
+}
+
+static mrb_value
+mrb_grn_scan_info_set_max_interval(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ mrb_int max_interval;
+
+ mrb_get_args(mrb, "i", &max_interval);
+ si = DATA_PTR(self);
+ grn_scan_info_set_max_interval(si, max_interval);
+ return self;
+}
+
+static mrb_value
+mrb_grn_scan_info_get_max_interval(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ int max_interval;
+
+ si = DATA_PTR(self);
+ max_interval = grn_scan_info_get_max_interval(si);
+ return mrb_fixnum_value(max_interval);
+}
+
+static mrb_value
+mrb_grn_scan_info_set_similarity_threshold(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ mrb_int similarity_threshold;
+
+ mrb_get_args(mrb, "i", &similarity_threshold);
+ si = DATA_PTR(self);
+ grn_scan_info_set_similarity_threshold(si, similarity_threshold);
+ return self;
+}
+
+static mrb_value
+mrb_grn_scan_info_get_similarity_threshold(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ int similarity_threshold;
+
+ si = DATA_PTR(self);
+ similarity_threshold = grn_scan_info_get_similarity_threshold(si);
+ return mrb_fixnum_value(similarity_threshold);
+}
+
+static mrb_value
+mrb_grn_scan_info_get_arg(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ scan_info *si;
+ mrb_int index;
+ grn_obj *arg;
+
+ mrb_get_args(mrb, "i", &index);
+
+ si = DATA_PTR(self);
+ arg = grn_scan_info_get_arg(ctx, si, index);
+
+ return grn_mrb_value_from_grn_obj(mrb, arg);
+}
+
+static mrb_value
+mrb_grn_scan_info_push_arg(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ mrb_value mrb_arg;
+ grn_bool success;
+
+ mrb_get_args(mrb, "o", &mrb_arg);
+
+ si = DATA_PTR(self);
+ success = grn_scan_info_push_arg(si, DATA_PTR(mrb_arg));
+
+ return mrb_bool_value(success);
+}
+
+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;
+ grn_expr_code *code;
+ mrb_value inspected;
+
+ code = DATA_PTR(self);
+
+ inspected = mrb_str_buf_new(mrb, 48);
+
+ mrb_str_cat_lit(mrb, inspected, "#<");
+ mrb_str_cat_cstr(mrb, inspected, mrb_obj_classname(mrb, self));
+ mrb_str_cat_lit(mrb, inspected, ":");
+ mrb_str_concat(mrb, inspected, mrb_ptr_to_str(mrb, mrb_cptr(self)));
+
+ {
+ int32_t weight;
+ uint32_t offset;
+
+ weight = grn_expr_code_get_weight(ctx, DATA_PTR(self), &offset);
+
+ mrb_str_cat_lit(mrb, inspected, " weight=");
+ mrb_str_concat(mrb, inspected,
+ mrb_funcall(mrb,
+ mrb_fixnum_value(weight),
+ "inspect",
+ 0));
+ mrb_str_cat_lit(mrb, inspected, ", offset=");
+ mrb_str_concat(mrb, inspected,
+ mrb_funcall(mrb,
+ mrb_fixnum_value(offset),
+ "inspect",
+ 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,
+ mrb_fixnum_value(code->modify),
+ "inspect",
+ 0));
+
+ mrb_str_cat_lit(mrb, inspected, ", op=");
+ mrb_str_concat(mrb, inspected,
+ mrb_funcall(mrb,
+ grn_mrb_value_from_operator(mrb, code->op),
+ "inspect",
+ 0));
+
+ mrb_str_cat_lit(mrb, inspected, ", flags=");
+ mrb_str_concat(mrb, inspected,
+ mrb_funcall(mrb,
+ mrb_fixnum_value(code->flags),
+ "inspect",
+ 0));
+
+ mrb_str_cat_lit(mrb, inspected, ", value=");
+ mrb_str_concat(mrb, inspected,
+ mrb_funcall(mrb,
+ grn_mrb_value_from_grn_obj(mrb, code->value),
+ "inspect",
+ 0));
+
+ mrb_str_cat_lit(mrb, inspected, ">");
+
+ return inspected;
+}
+
+static mrb_value
+mrb_grn_expr_code_get_weight(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ int32_t weight;
+ uint32_t offset;
+ mrb_value mrb_values[2];
+
+ weight = grn_expr_code_get_weight(ctx, DATA_PTR(self), &offset);
+ mrb_values[0] = mrb_fixnum_value(weight);
+ mrb_values[1] = mrb_fixnum_value(offset);
+ return mrb_ary_new_from_values(mrb, 2, mrb_values);
+}
+
+static mrb_value
+mrb_grn_expr_code_get_value(mrb_state *mrb, mrb_value self)
+{
+ grn_expr_code *expr_code;
+
+ expr_code = DATA_PTR(self);
+ return grn_mrb_value_from_grn_obj(mrb, expr_code->value);
+}
+
+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;
+
+ expr_code = DATA_PTR(self);
+ return grn_mrb_value_from_operator(mrb, expr_code->op);
+}
+
+static mrb_value
+mrb_grn_expr_code_get_flags(mrb_state *mrb, mrb_value self)
+{
+ grn_expr_code *expr_code;
+
+ expr_code = DATA_PTR(self);
+ return mrb_fixnum_value(expr_code->flags);
+}
+
+static mrb_value
+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;
+ mrb_value mrb_table;
+ mrb_value mrb_new_arguments[1];
+ grn_obj *expr, *variable = NULL;
+
+ mrb_get_args(mrb, "o", &mrb_table);
+ if (mrb_nil_p(mrb_table)) {
+ expr = grn_expr_create(ctx, NULL, 0);
+ } else {
+ grn_obj *table = DATA_PTR(mrb_table);
+ GRN_EXPR_CREATE_FOR_QUERY(ctx, table, expr, variable);
+ }
+
+ if (!expr) {
+ grn_mrb_ctx_check(mrb);
+ return mrb_nil_value();
+ }
+
+ mrb_new_arguments[0] = mrb_cptr_value(mrb, expr);
+ mrb_expr = mrb_obj_new(mrb, mrb_class_ptr(klass), 1, mrb_new_arguments);
+ {
+ mrb_value mrb_variable = mrb_nil_value();
+ if (variable) {
+ mrb_variable = grn_mrb_value_from_grn_obj(mrb, variable);
+ }
+ mrb_iv_set(mrb, mrb_expr, mrb_intern_lit(mrb, "@variable"), mrb_variable);
+ }
+
+ return mrb_expr;
+}
+
+static mrb_value
+mrb_grn_expression_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_expression_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_expression_ptr);
+ DATA_TYPE(self) = &mrb_grn_expression_type;
+ DATA_PTR(self) = mrb_cptr(mrb_expression_ptr);
+ return 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;
+ mrb_value mrb_codes;
+ int i;
+
+ expr = DATA_PTR(self);
+ mrb_codes = mrb_ary_new_capa(mrb, expr->codes_curr);
+ for (i = 0; i < expr->codes_curr; i++) {
+ grn_expr_code *code = expr->codes + i;
+ mrb_ary_push(mrb, mrb_codes, mrb_grn_expr_code_new(mrb, code));
+ }
+
+ return mrb_codes;
+}
+
+static mrb_value
+mrb_grn_expression_array_reference(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *expr;
+ mrb_value mrb_key;
+ grn_obj *var;
+
+ mrb_get_args(mrb, "o", &mrb_key);
+
+ expr = DATA_PTR(self);
+ 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;
+ grn_obj *expr;
+ mrb_value mrb_object;
+ grn_obj *grn_object;
+
+ mrb_get_args(mrb, "o", &mrb_object);
+ expr = DATA_PTR(self);
+ grn_object = DATA_PTR(mrb_object);
+ grn_expr_take_obj(ctx, expr, grn_object);
+
+ return mrb_object;
+}
+
+static mrb_value
+mrb_grn_expression_allocate_constant(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *expr;
+ mrb_value mrb_object;
+ grn_obj *grn_object;
+
+ mrb_get_args(mrb, "o", &mrb_object);
+ expr = DATA_PTR(self);
+
+ switch (mrb_type(mrb_object)) {
+ case MRB_TT_STRING:
+ grn_object = grn_expr_alloc_const(ctx, expr);
+ if (!grn_object) {
+ grn_mrb_ctx_check(mrb);
+ }
+ GRN_TEXT_INIT(grn_object, 0);
+ 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;
+ }
+
+ return grn_mrb_value_from_grn_obj(mrb, grn_object);
+}
+
+static mrb_value
+mrb_grn_expression_parse(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *expr;
+ char *query;
+ mrb_int query_size;
+ grn_obj *default_column = NULL;
+ grn_operator default_mode = GRN_OP_MATCH;
+ grn_operator default_operator = GRN_OP_AND;
+ grn_expr_flags flags = GRN_EXPR_SYNTAX_SCRIPT;
+ mrb_value mrb_options = mrb_nil_value();
+
+ expr = DATA_PTR(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);
+ }
+ }
+
+ grn_expr_parse(ctx, expr, query, query_size, default_column,
+ default_mode, default_operator, flags);
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_expression_append_object(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *expr;
+ mrb_value mrb_object;
+ grn_obj *object;
+ mrb_value mrb_op;
+ grn_operator op;
+ mrb_int n_args;
+
+ expr = DATA_PTR(self);
+ mrb_get_args(mrb, "ooi", &mrb_object, &mrb_op, &n_args);
+
+ object = DATA_PTR(mrb_object);
+ op = grn_mrb_value_to_operator(mrb, mrb_op);
+ grn_expr_append_obj(ctx, expr, object, op, n_args);
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_expression_append_constant(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *expr;
+ mrb_value mrb_constant;
+ mrb_value mrb_op;
+ grn_operator op;
+ mrb_int n_args;
+
+ expr = DATA_PTR(self);
+ mrb_get_args(mrb, "ooi", &mrb_constant, &mrb_op, &n_args);
+
+ op = grn_mrb_value_to_operator(mrb, mrb_op);
+ switch (mrb_type(mrb_constant)) {
+ case MRB_TT_FALSE :
+ if (mrb_nil_p(mrb_constant)) {
+ grn_obj constant;
+ GRN_VOID_INIT(&constant);
+ grn_expr_append_const(ctx, expr, &constant, op, n_args);
+ GRN_OBJ_FIN(ctx, &constant);
+ } else {
+ grn_obj constant;
+ GRN_BOOL_INIT(&constant, 0);
+ GRN_BOOL_SET(ctx, &constant, GRN_FALSE);
+ grn_expr_append_const(ctx, expr, &constant, op, n_args);
+ GRN_OBJ_FIN(ctx, &constant);
+ }
+ break;
+ case MRB_TT_TRUE :
+ {
+ grn_obj constant;
+ GRN_BOOL_INIT(&constant, 0);
+ GRN_BOOL_SET(ctx, &constant, GRN_TRUE);
+ grn_expr_append_const(ctx, expr, &constant, op, n_args);
+ GRN_OBJ_FIN(ctx, &constant);
+ }
+ break;
+ case MRB_TT_FIXNUM :
+ grn_expr_append_const_int(ctx, expr, mrb_fixnum(mrb_constant), op, n_args);
+ break;
+ case MRB_TT_SYMBOL :
+ {
+ const char *value;
+ mrb_int value_length;
+
+ value = mrb_sym2name_len(mrb, mrb_symbol(mrb_constant), &value_length);
+ grn_expr_append_const_str(ctx, expr, value, value_length, op, n_args);
+ }
+ break;
+ case MRB_TT_FLOAT :
+ {
+ grn_obj constant;
+ GRN_FLOAT_INIT(&constant, 0);
+ GRN_FLOAT_SET(ctx, &constant, mrb_float(mrb_constant));
+ grn_expr_append_const(ctx, expr, &constant, op, n_args);
+ GRN_OBJ_FIN(ctx, &constant);
+ }
+ break;
+ case MRB_TT_STRING :
+ grn_expr_append_const_str(ctx, expr,
+ RSTRING_PTR(mrb_constant),
+ RSTRING_LEN(mrb_constant),
+ op, n_args);
+ break;
+ default :
+ {
+ struct RClass *klass;
+
+ klass = mrb_class(mrb, mrb_constant);
+ if (klass == ctx->impl->mrb.builtin.time_class) {
+ grn_obj constant;
+ mrb_value mrb_sec;
+ mrb_value mrb_usec;
+
+ mrb_sec = mrb_funcall(mrb, mrb_constant, "to_i", 0);
+ mrb_usec = mrb_funcall(mrb, mrb_constant, "usec", 0);
+ GRN_TIME_INIT(&constant, 0);
+ GRN_TIME_SET(ctx, &constant,
+ GRN_TIME_PACK(mrb_fixnum(mrb_sec), mrb_fixnum(mrb_usec)));
+ grn_expr_append_const(ctx, expr, &constant, op, n_args);
+ GRN_OBJ_FIN(ctx, &constant);
+ } else {
+ mrb_raisef(mrb, E_ARGUMENT_ERROR,
+ "unsupported constant to append to expression: %S",
+ mrb_constant);
+ }
+ }
+ break;
+ }
+
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+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;
+ mrb_int n_args;
+ grn_operator op;
+
+ expr = DATA_PTR(self);
+ mrb_get_args(mrb, "oi", &mrb_op, &n_args);
+
+ op = grn_mrb_value_to_operator(mrb, mrb_op);
+ grn_expr_append_op(ctx, expr, op, n_args);
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_nil_value();
+}
+
+void
+grn_mrb_expr_init(grn_ctx *ctx)
+{
+ mrb_state *mrb = ctx->impl->mrb.state;
+ struct RClass *module = ctx->impl->mrb.module;
+ struct RClass *object_class = ctx->impl->mrb.object_class;
+ struct RClass *klass;
+
+ klass = mrb_define_class_under(mrb, module, "ScanInfo", mrb->object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+ mrb_define_method(mrb, klass, "initialize",
+ mrb_grn_scan_info_initialize, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "put_index",
+ mrb_grn_scan_info_put_index, MRB_ARGS_REQ(6));
+ mrb_define_method(mrb, klass, "op",
+ mrb_grn_scan_info_get_op, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "op=",
+ mrb_grn_scan_info_set_op, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "end=",
+ mrb_grn_scan_info_set_end, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "query=",
+ mrb_grn_scan_info_set_query, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "flags",
+ mrb_grn_scan_info_get_flags, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "flags=",
+ mrb_grn_scan_info_set_flags, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "logical_op",
+ mrb_grn_scan_info_get_logical_op, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "logical_op=",
+ mrb_grn_scan_info_set_logical_op, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "max_interval",
+ mrb_grn_scan_info_get_max_interval, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "max_interval=",
+ mrb_grn_scan_info_set_max_interval, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "similarity_threshold",
+ mrb_grn_scan_info_get_similarity_threshold, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "similarity_threshold=",
+ mrb_grn_scan_info_set_similarity_threshold, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "get_arg",
+ 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);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+ mrb_define_method(mrb, klass, "initialize",
+ mrb_grn_expr_code_initialize, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "inspect",
+ mrb_grn_expr_code_inspect, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "weight",
+ 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;
+ struct RClass *flags_module;
+ flags_module = mrb_define_module_under(mrb, expression_code_class, "Flags");
+ mrb_define_const(mrb, flags_module, "RELATIONAL_EXPRESSION",
+ mrb_fixnum_value(GRN_EXPR_CODE_RELATIONAL_EXPRESSION));
+ }
+
+ klass = mrb_define_class_under(mrb, module, "Expression", object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+
+#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, "[]",
+ 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",
+ mrb_grn_expression_allocate_constant, MRB_ARGS_REQ(1));
+
+ mrb_define_method(mrb, klass, "parse",
+ mrb_grn_expression_parse, MRB_ARGS_ARG(1, 1));
+
+ mrb_define_method(mrb, klass, "append_object",
+ mrb_grn_expression_append_object, MRB_ARGS_REQ(2));
+ mrb_define_method(mrb, klass, "append_constant",
+ mrb_grn_expression_append_constant, MRB_ARGS_REQ(3));
+ mrb_define_method(mrb, klass, "append_operator",
+ 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,
+ grn_bool record_exist)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ mrb_value mrb_expression;
+ mrb_value mrb_sis;
+ scan_info **sis = NULL;
+ int i;
+ int arena_index;
+
+ arena_index = mrb_gc_arena_save(mrb);
+
+ 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_bool_value(record_exist));
+
+ if (mrb_nil_p(mrb_sis)) {
+ goto exit;
+ }
+
+ if (mrb_type(mrb_sis) == MRB_TT_EXCEPTION) {
+ mrb->exc = mrb_obj_ptr(mrb_sis);
+ mrb_print_error(mrb);
+ goto exit;
+ }
+
+ *n = RARRAY_LEN(mrb_sis);
+ sis = GRN_MALLOCN(scan_info *, *n);
+ for (i = 0; i < *n; i++) {
+ mrb_value mrb_si;
+ mrb_value mrb_si_data;
+ scan_info *si;
+ int start;
+
+ mrb_si_data = RARRAY_PTR(mrb_sis)[i];
+ start = mrb_fixnum(mrb_funcall(mrb, mrb_si_data, "start", 0));
+ si = grn_scan_info_open(ctx, start);
+ mrb_si = mrb_grn_scan_info_new(mrb, si);
+ mrb_funcall(mrb, mrb_si, "apply", 1, mrb_si_data);
+ sis[i] = si;
+ }
+
+exit:
+ mrb_gc_arena_restore(mrb, arena_index);
+
+ return sis;
+}
+
+unsigned int
+grn_mrb_expr_estimate_size(grn_ctx *ctx, grn_obj *expr, grn_obj *table)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ mrb_value mrb_expression;
+ mrb_value mrb_table;
+ mrb_value mrb_size;
+ unsigned int size;
+ int arena_index;
+
+ arena_index = mrb_gc_arena_save(mrb);
+
+ mrb_expression = grn_mrb_value_from_grn_obj(mrb, expr);
+ mrb_table = grn_mrb_value_from_grn_obj(mrb, table);
+ mrb_size = mrb_funcall(mrb, mrb_expression, "estimate_size", 1, mrb_table);
+ if (mrb->exc) {
+ size = grn_table_size(ctx, table);
+ } else {
+ size = mrb_fixnum(mrb_size);
+ }
+
+ mrb_gc_arena_restore(mrb, arena_index);
+
+ return size;
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.h
new file mode 100644
index 00000000..22b20220
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.h
@@ -0,0 +1,43 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+#include "../grn_expr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_expr_init(grn_ctx *ctx);
+
+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);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_fixed_size_column.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_fixed_size_column.c
new file mode 100644
index 00000000..b1545dbc
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_fixed_size_column.c
@@ -0,0 +1,59 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2013-2014 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+
+#include "mrb_fixed_size_column.h"
+
+static struct mrb_data_type mrb_grn_fixed_size_column_type = {
+ "Groonga::FixedSizeColumn",
+ NULL
+};
+
+static mrb_value
+mrb_grn_fixed_size_column_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_fixed_size_column_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_fixed_size_column_ptr);
+ DATA_TYPE(self) = &mrb_grn_fixed_size_column_type;
+ DATA_PTR(self) = mrb_cptr(mrb_fixed_size_column_ptr);
+ return self;
+}
+
+void
+grn_mrb_fixed_size_column_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *column_class;
+ struct RClass *klass;
+
+ column_class = mrb_class_get_under(mrb, module, "Column");
+ klass = mrb_define_class_under(mrb, module, "FixedSizeColumn", column_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+ mrb_define_method(mrb, klass, "initialize",
+ mrb_grn_fixed_size_column_initialize, MRB_ARGS_REQ(1));
+}
+#endif
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
new file mode 100644
index 00000000..9498d337
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_fixed_size_column.h
@@ -0,0 +1,32 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_fixed_size_column_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.c
new file mode 100644
index 00000000..cf9a0d91
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.c
@@ -0,0 +1,117 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+#include <mruby/string.h>
+
+#include "mrb_ctx.h"
+#include "mrb_hash_table.h"
+#include "mrb_options.h"
+
+static struct mrb_data_type mrb_grn_hash_table_type = {
+ "Groonga::HashTable",
+ NULL
+};
+
+static mrb_value
+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();
+ const char *name = NULL;
+ unsigned int name_size = 0;
+ const char *path = NULL;
+ grn_obj_flags flags = GRN_OBJ_TABLE_HASH_KEY;
+ grn_obj *key_type = NULL;
+ grn_obj *value_type = NULL;
+ grn_obj *table;
+
+ mrb_get_args(mrb, "|H", &mrb_options);
+
+ if (!mrb_nil_p(mrb_options)) {
+ mrb_value mrb_name;
+ mrb_value mrb_flags;
+ mrb_value mrb_key_type;
+ mrb_value mrb_value_type;
+
+ mrb_name = grn_mrb_options_get_lit(mrb, mrb_options, "name");
+ if (!mrb_nil_p(mrb_name)) {
+ name = RSTRING_PTR(mrb_name);
+ name_size = RSTRING_LEN(mrb_name);
+ }
+
+ mrb_flags = grn_mrb_options_get_lit(mrb, mrb_options, "flags");
+ if (!mrb_nil_p(mrb_flags)) {
+ flags |= mrb_fixnum(mrb_flags);
+ }
+
+ mrb_key_type = grn_mrb_options_get_lit(mrb, mrb_options, "key_type");
+ if (!mrb_nil_p(mrb_key_type)) {
+ key_type = DATA_PTR(mrb_key_type);
+ }
+
+ mrb_value_type = grn_mrb_options_get_lit(mrb, mrb_options, "value_type");
+ if (!mrb_nil_p(mrb_value_type)) {
+ key_type = DATA_PTR(mrb_value_type);
+ }
+ }
+
+ table = grn_table_create(ctx, name, name_size, path, flags,
+ key_type, value_type);
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_funcall(mrb, klass, "new", 1, mrb_cptr_value(mrb, table));
+}
+
+static mrb_value
+mrb_grn_hash_table_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_hash_table_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_hash_table_ptr);
+ DATA_TYPE(self) = &mrb_grn_hash_table_type;
+ DATA_PTR(self) = mrb_cptr(mrb_hash_table_ptr);
+ return self;
+}
+
+void
+grn_mrb_hash_table_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *table_class;
+ struct RClass *klass;
+
+ table_class = mrb_class_get_under(mrb, module, "Table");
+ klass = mrb_define_class_under(mrb, module, "HashTable", table_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+
+ 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));
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.h
new file mode 100644
index 00000000..d6b747f0
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_hash_table_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_id.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_id.c
new file mode 100644
index 00000000..d5970fee
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_id.c
@@ -0,0 +1,79 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2014 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+
+#include "mrb_id.h"
+
+void
+grn_mrb_id_init(grn_ctx *ctx)
+{
+ mrb_state *mrb = ctx->impl->mrb.state;
+ struct RClass *module = ctx->impl->mrb.module;
+ struct RClass *id_module;
+
+ id_module = mrb_define_module_under(mrb, module, "ID");
+
+ mrb_define_const(mrb, id_module, "NIL",
+ mrb_fixnum_value(GRN_ID_NIL));
+ mrb_define_const(mrb, id_module, "MAX",
+ mrb_fixnum_value(GRN_ID_MAX));
+
+ mrb_define_const(mrb, id_module, "VOID",
+ mrb_fixnum_value(GRN_DB_VOID));
+ mrb_define_const(mrb, id_module, "DB",
+ mrb_fixnum_value(GRN_DB_DB));
+ mrb_define_const(mrb, id_module, "OBJECT",
+ mrb_fixnum_value(GRN_DB_OBJECT));
+ mrb_define_const(mrb, id_module, "BOOL",
+ mrb_fixnum_value(GRN_DB_BOOL));
+ mrb_define_const(mrb, id_module, "INT8",
+ mrb_fixnum_value(GRN_DB_INT8));
+ mrb_define_const(mrb, id_module, "UINT8",
+ mrb_fixnum_value(GRN_DB_UINT8));
+ mrb_define_const(mrb, id_module, "INT16",
+ mrb_fixnum_value(GRN_DB_INT16));
+ mrb_define_const(mrb, id_module, "UINT16",
+ mrb_fixnum_value(GRN_DB_UINT16));
+ mrb_define_const(mrb, id_module, "INT32",
+ mrb_fixnum_value(GRN_DB_INT32));
+ mrb_define_const(mrb, id_module, "UINT32",
+ mrb_fixnum_value(GRN_DB_UINT32));
+ mrb_define_const(mrb, id_module, "INT64",
+ mrb_fixnum_value(GRN_DB_INT64));
+ mrb_define_const(mrb, id_module, "UINT64",
+ mrb_fixnum_value(GRN_DB_UINT64));
+ mrb_define_const(mrb, id_module, "FLOAT",
+ mrb_fixnum_value(GRN_DB_FLOAT));
+ mrb_define_const(mrb, id_module, "TIME",
+ mrb_fixnum_value(GRN_DB_TIME));
+ mrb_define_const(mrb, id_module, "SHORT_TEXT",
+ mrb_fixnum_value(GRN_DB_SHORT_TEXT));
+ mrb_define_const(mrb, id_module, "TEXT",
+ mrb_fixnum_value(GRN_DB_TEXT));
+ mrb_define_const(mrb, id_module, "LONG_TEXT",
+ mrb_fixnum_value(GRN_DB_LONG_TEXT));
+ mrb_define_const(mrb, id_module, "TOKYO_GEO_POINT",
+ mrb_fixnum_value(GRN_DB_TOKYO_GEO_POINT));
+ mrb_define_const(mrb, id_module, "WGS84_GEO_POINT",
+ mrb_fixnum_value(GRN_DB_WGS84_GEO_POINT));
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_id.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_id.h
new file mode 100644
index 00000000..b5418b73
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_id.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_id_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c
new file mode 100644
index 00000000..02a3901b
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c
@@ -0,0 +1,199 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#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>
+
+#include "mrb_ctx.h"
+#include "mrb_converter.h"
+#include "mrb_index_column.h"
+#include "mrb_operator.h"
+#include "mrb_options.h"
+
+static struct mrb_data_type mrb_grn_index_column_type = {
+ "Groonga::IndexColumn",
+ NULL
+};
+
+static mrb_value
+mrb_grn_index_column_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_index_column_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_index_column_ptr);
+ DATA_TYPE(self) = &mrb_grn_index_column_type;
+ DATA_PTR(self) = mrb_cptr(mrb_index_column_ptr);
+ return self;
+}
+
+static mrb_value
+mrb_grn_index_column_get_lexicon(mrb_state *mrb, mrb_value self)
+{
+ grn_obj *index_column;
+ grn_obj *lexicon;
+
+ index_column = DATA_PTR(self);
+ lexicon = ((grn_ii *)index_column)->lexicon;
+
+ return grn_mrb_value_from_grn_obj(mrb, lexicon);
+}
+
+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;
+ grn_obj *index_column;
+ mrb_int term_id;
+ unsigned int size;
+
+ index_column = DATA_PTR(self);
+ mrb_get_args(mrb, "i", &term_id);
+
+ size = grn_ii_estimate_size(ctx, (grn_ii *)index_column, term_id);
+ return mrb_fixnum_value(size);
+}
+
+static mrb_value
+mrb_grn_index_column_estimate_size_for_query(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *index_column;
+ grn_obj *lexicon;
+ mrb_value mrb_query;
+ void *query;
+ unsigned int query_size;
+ grn_mrb_value_to_raw_data_buffer buffer;
+ mrb_value mrb_options = mrb_nil_value();
+ grn_search_optarg optarg;
+ unsigned int size;
+
+ index_column = DATA_PTR(self);
+ mrb_get_args(mrb, "o|H", &mrb_query, &mrb_options);
+
+ lexicon = grn_ctx_at(ctx, index_column->header.domain);
+ grn_mrb_value_to_raw_data_buffer_init(mrb, &buffer);
+ grn_mrb_value_to_raw_data(mrb, "query", mrb_query, lexicon->header.domain,
+ &buffer, &query, &query_size);
+
+ memset(&optarg, 0, sizeof(grn_search_optarg));
+ optarg.mode = GRN_OP_EXACT;
+
+ if (!mrb_nil_p(mrb_options)) {
+ mrb_value mrb_mode;
+
+ mrb_mode = grn_mrb_options_get_lit(mrb, mrb_options, "mode");
+ if (!mrb_nil_p(mrb_mode)) {
+ optarg.mode = grn_mrb_value_to_operator(mrb, mrb_mode);
+ }
+ }
+
+ size = grn_ii_estimate_size_for_query(ctx, (grn_ii *)index_column,
+ query, query_size, &optarg);
+ grn_mrb_value_to_raw_data_buffer_fin(mrb, &buffer);
+
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_fixnum_value(size);
+}
+
+static mrb_value
+mrb_grn_index_column_estimate_size_for_lexicon_cursor(mrb_state *mrb,
+ mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *index_column;
+ mrb_value mrb_lexicon_cursor;
+ grn_table_cursor *lexicon_cursor;
+ unsigned int size;
+
+ index_column = DATA_PTR(self);
+ mrb_get_args(mrb, "o", &mrb_lexicon_cursor);
+
+ lexicon_cursor = DATA_PTR(mrb_lexicon_cursor);
+ size = grn_ii_estimate_size_for_lexicon_cursor(ctx,
+ (grn_ii *)index_column,
+ lexicon_cursor);
+ return mrb_fixnum_value(size);
+}
+
+void
+grn_mrb_index_column_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *column_class;
+ struct RClass *klass;
+
+ column_class = mrb_class_get_under(mrb, module, "Column");
+ klass = mrb_define_class_under(mrb, module, "IndexColumn", column_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+ mrb_define_method(mrb, klass, "initialize",
+ mrb_grn_index_column_initialize, MRB_ARGS_REQ(1));
+
+ mrb_define_method(mrb, klass, "lexicon",
+ 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));
+ mrb_define_method(mrb, klass, "estimate_size_for_query",
+ mrb_grn_index_column_estimate_size_for_query,
+ MRB_ARGS_ARG(1, 1));
+ mrb_define_method(mrb, klass, "estimate_size_for_lexicon_cursor",
+ mrb_grn_index_column_estimate_size_for_lexicon_cursor,
+ MRB_ARGS_REQ(1));
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.h
new file mode 100644
index 00000000..085a2d3a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_index_column_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.c
new file mode 100644
index 00000000..20f1e64f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.c
@@ -0,0 +1,245 @@
+/* -*- 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+#include "../grn_ii.h"
+#include "../grn_db.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+#include <mruby/string.h>
+#include <mruby/hash.h>
+#include <mruby/variable.h>
+
+#include "mrb_ctx.h"
+#include "mrb_index_cursor.h"
+#include "mrb_converter.h"
+#include "mrb_options.h"
+
+static struct mrb_data_type mrb_grn_index_cursor_type = {
+ "Groonga::IndexCursor",
+ NULL
+};
+
+static mrb_value
+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;
+ mrb_value mrb_index;
+ mrb_value mrb_options = mrb_nil_value();
+ grn_obj *index_cursor;
+ grn_table_cursor *table_cursor;
+ grn_obj *index;
+ grn_id rid_min = GRN_ID_NIL;
+ grn_id rid_max = GRN_ID_MAX;
+ int flags = 0;
+ mrb_value mrb_index_cursor;
+
+ mrb_get_args(mrb, "oo|H", &mrb_table_cursor, &mrb_index, &mrb_options);
+
+ table_cursor = DATA_PTR(mrb_table_cursor);
+ index = DATA_PTR(mrb_index);
+ if (!mrb_nil_p(mrb_options)) {
+ /* TODO */
+ }
+ index_cursor = grn_index_cursor_open(ctx, table_cursor, index,
+ rid_min, rid_max, flags);
+ grn_mrb_ctx_check(mrb);
+
+ mrb_index_cursor = mrb_funcall(mrb, klass, "new", 1,
+ mrb_cptr_value(mrb, index_cursor));
+ mrb_iv_set(mrb, mrb_index_cursor, mrb_intern_lit(mrb, "@index"), mrb_index);
+ return mrb_index_cursor;
+}
+
+static mrb_value
+mrb_grn_index_cursor_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_index_cursor_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_index_cursor_ptr);
+ DATA_TYPE(self) = &mrb_grn_index_cursor_type;
+ DATA_PTR(self) = mrb_cptr(mrb_index_cursor_ptr);
+
+ return self;
+}
+
+static mrb_value
+mrb_grn_index_cursor_close(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *index_cursor;
+
+ index_cursor = DATA_PTR(self);
+ if (index_cursor) {
+ DATA_PTR(self) = NULL;
+ grn_obj_close(ctx, index_cursor);
+ grn_mrb_ctx_check(mrb);
+ }
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_index_cursor_count(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_id term_id;
+ int n_records = 0;
+
+ while (grn_index_cursor_next(ctx, DATA_PTR(self), &term_id)) {
+ n_records++;
+ }
+
+ return mrb_fixnum_value(n_records);
+}
+
+static mrb_value
+mrb_grn_index_cursor_select(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_value mrb_result_set;
+ mrb_value mrb_options;
+ grn_obj *index_cursor;
+ grn_obj *expr = NULL;
+ 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;
+ grn_obj *data_table;
+ grn_hash *result_set;
+ grn_posting *posting;
+ grn_id term_id;
+ grn_operator op = GRN_OP_OR;
+
+ mrb_get_args(mrb, "o|H", &mrb_result_set, &mrb_options);
+
+ index_cursor = DATA_PTR(self);
+ result_set = DATA_PTR(mrb_result_set);
+
+ if (!mrb_nil_p(mrb_options)) {
+ 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)) {
+ expr = DATA_PTR(mrb_expr);
+ expr_variable = grn_expr_get_var_by_offset(ctx, expr, 0);
+ }
+
+ mrb_offset = grn_mrb_options_get_lit(mrb, mrb_options, "offset");
+ if (!mrb_nil_p(mrb_offset)) {
+ offset = mrb_fixnum(mrb_offset);
+ }
+
+ mrb_limit = grn_mrb_options_get_lit(mrb, mrb_options, "limit");
+ 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) {
+ return mrb_fixnum_value(n_matched_records);
+ }
+
+ mrb_index = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@index"));
+ index = DATA_PTR(mrb_index);
+ 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_FALSE;
+ grn_obj *matched;
+
+ GRN_RECORD_SET(ctx, expr_variable, posting->rid);
+ matched = grn_expr_exec(ctx, expr, 0);
+ 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;
+ }
+ }
+ n_matched_records++;
+ if (offset > 0) {
+ offset--;
+ continue;
+ }
+ grn_ii_posting_add(ctx, posting, result_set, op);
+ limit--;
+ if (limit == 0) {
+ break;
+ }
+ }
+ grn_ii_resolve_sel_and(ctx, result_set, op);
+
+ return mrb_fixnum_value(n_matched_records);
+}
+
+void
+grn_mrb_index_cursor_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, "IndexCursor", mrb->object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+
+ 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));
+ mrb_define_method(mrb, klass, "close",
+ mrb_grn_index_cursor_close, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "count",
+ mrb_grn_index_cursor_count, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "select",
+ mrb_grn_index_cursor_select, MRB_ARGS_ARG(1, 1));
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.h
new file mode 100644
index 00000000..c1026002
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_index_cursor_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
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 00000000..cd8f44ae
--- /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-1335 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 00000000..3b191c72
--- /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-1335 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
new file mode 100644
index 00000000..d5ed72df
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_logger.c
@@ -0,0 +1,99 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 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_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;
+ mrb_int level;
+
+ mrb_get_args(mrb, "i", &level);
+
+ return mrb_bool_value(grn_logger_pass(ctx, level));
+}
+
+static mrb_value
+logger_log(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_int level;
+ char *file;
+ mrb_int line;
+ char *method;
+ char *message;
+ mrb_int message_size;
+
+ mrb_get_args(mrb, "izizs",
+ &level, &file, &line, &method, &message, &message_size);
+ grn_logger_put(ctx, level, file, line, method,
+ "%.*s", (int)message_size, message);
+
+ return self;
+}
+
+void
+grn_mrb_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, "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));
+
+ grn_mrb_load(ctx, "logger/level.rb");
+ grn_mrb_load(ctx, "logger.rb");
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_logger.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_logger.h
new file mode 100644
index 00000000..d23ddb19
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_logger.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_logger_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c
new file mode 100644
index 00000000..874d4add
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c
@@ -0,0 +1,346 @@
+/* -*- 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+#include "../grn_util.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/string.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+
+#include "../grn_mrb.h"
+#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)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *object;
+ mrb_value inspected;
+
+ object = DATA_PTR(self);
+ inspected = mrb_str_buf_new(mrb, 48);
+
+ mrb_str_cat_lit(mrb, inspected, "#<");
+ mrb_str_cat_cstr(mrb, inspected, mrb_obj_classname(mrb, self));
+ mrb_str_cat_lit(mrb, inspected, ":");
+ mrb_str_concat(mrb, inspected, mrb_ptr_to_str(mrb, mrb_cptr(self)));
+ if (object) {
+ grn_obj buffer;
+ GRN_TEXT_INIT(&buffer, 0);
+ grn_inspect(ctx, &buffer, object);
+ mrb_str_cat_lit(mrb, inspected, " ");
+ mrb_str_cat(mrb, inspected, GRN_TEXT_VALUE(&buffer), GRN_TEXT_LEN(&buffer));
+ GRN_OBJ_FIN(ctx, &buffer);
+ } else {
+ mrb_str_cat_lit(mrb, inspected, " (closed)");
+ }
+ mrb_str_cat_lit(mrb, inspected, ">");
+
+ return inspected;
+}
+
+static mrb_value
+object_get_id(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_id id;
+
+ id = grn_obj_id(ctx, DATA_PTR(self));
+
+ return mrb_fixnum_value(id);
+}
+
+static mrb_value
+object_get_name(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *object;
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_length;
+
+ object = DATA_PTR(self);
+ name_length = grn_obj_name(ctx, object, name, GRN_TABLE_MAX_KEY_SIZE);
+
+ if (name_length == 0) {
+ return mrb_nil_value();
+ } else {
+ return mrb_str_new(mrb, name, name_length);
+ }
+}
+
+static mrb_value
+object_get_path(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *object;
+ const char *path;
+
+ object = DATA_PTR(self);
+ path = grn_obj_path(ctx, object);
+
+ if (path) {
+ return mrb_str_new_cstr(mrb, path);
+ } else {
+ return mrb_nil_value();
+ }
+}
+
+static mrb_value
+object_grn_inspect(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj buffer;
+ mrb_value inspected;
+
+ GRN_TEXT_INIT(&buffer, 0);
+ grn_inspect(ctx, &buffer, DATA_PTR(self));
+ inspected = mrb_str_new(mrb, GRN_TEXT_VALUE(&buffer), GRN_TEXT_LEN(&buffer));
+ GRN_OBJ_FIN(ctx, &buffer);
+
+ return inspected;
+}
+
+static mrb_value
+object_equal(mrb_state *mrb, mrb_value self)
+{
+ grn_obj *object, *other_object;
+ mrb_value mrb_other;
+
+ mrb_get_args(mrb, "o", &mrb_other);
+ if (!mrb_obj_is_kind_of(mrb, mrb_other, mrb_obj_class(mrb, self))) {
+ return mrb_false_value();
+ }
+
+ object = DATA_PTR(self);
+ other_object = DATA_PTR(mrb_other);
+ 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
+object_close(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *object;
+
+ object = DATA_PTR(self);
+ if (!object) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "already closed object");
+ }
+
+ grn_obj_close(ctx, object);
+ DATA_PTR(self) = NULL;
+
+ return mrb_nil_value();
+}
+
+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);
+ if (dependent) {
+ grn_obj_remove_dependent(ctx, object);
+ } else {
+ grn_obj_remove(ctx, object);
+ }
+ grn_mrb_ctx_check(mrb);
+
+ DATA_PTR(self) = NULL;
+
+ return mrb_nil_value();
+}
+
+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;
+ grn_id domain_id;
+
+ object = DATA_PTR(self);
+ domain_id = object->header.domain;
+
+ if (domain_id == GRN_ID_NIL) {
+ return mrb_nil_value();
+ } else {
+ return mrb_fixnum_value(domain_id);
+ }
+}
+
+static mrb_value
+object_get_range_id(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *object;
+ grn_id range_id;
+
+ object = DATA_PTR(self);
+ range_id = grn_obj_get_range(ctx, object);
+
+ if (range_id == GRN_ID_NIL) {
+ return mrb_nil_value();
+ } else {
+ return mrb_fixnum_value(range_id);
+ }
+}
+
+static mrb_value
+object_is_temporary(mrb_state *mrb, mrb_value self)
+{
+ grn_obj *object;
+ grn_obj_flags flags;
+
+ object = DATA_PTR(self);
+ flags = object->header.flags;
+ return mrb_bool_value((flags & GRN_OBJ_PERSISTENT) != GRN_OBJ_PERSISTENT);
+}
+
+static mrb_value
+object_is_persistent(mrb_state *mrb, mrb_value self)
+{
+ grn_obj *object;
+ grn_obj_flags flags;
+
+ object = DATA_PTR(self);
+ flags = object->header.flags;
+ 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)
+{
+ 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, "Object", mrb->object_class);
+ 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, "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_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());
+ mrb_define_method(mrb, klass, "range_id", object_get_range_id,
+ MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "temporary?", object_is_temporary,
+ MRB_ARGS_NONE());
+ 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
new file mode 100644
index 00000000..5650ba28
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.h
@@ -0,0 +1,34 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_object_init(grn_ctx *ctx);
+
+mrb_value grn_mrb_object_inspect(mrb_state *mrb, mrb_value self);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.c
new file mode 100644
index 00000000..1fb70299
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.c
@@ -0,0 +1,96 @@
+/* -*- 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+# include <mruby.h>
+# include <mruby/string.h>
+# include <mruby/class.h>
+# include <mruby/data.h>
+
+# include "../grn_mrb.h"
+# include "mrb_object.h"
+# include "mrb_operator.h"
+# include "mrb_converter.h"
+
+void
+grn_mrb_object_flags_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *flags_module;
+
+ flags_module = mrb_define_module_under(mrb, module, "ObjectFlags");
+
+#define MRB_DEFINE_FLAG(name) \
+ mrb_define_const(mrb, flags_module, #name, \
+ mrb_fixnum_value(GRN_OBJ_ ## name))
+
+ MRB_DEFINE_FLAG(TABLE_TYPE_MASK);
+ MRB_DEFINE_FLAG(TABLE_HASH_KEY);
+ MRB_DEFINE_FLAG(TABLE_PAT_KEY);
+ MRB_DEFINE_FLAG(TABLE_DAT_KEY);
+ MRB_DEFINE_FLAG(TABLE_NO_KEY);
+
+ MRB_DEFINE_FLAG(KEY_MASK);
+ MRB_DEFINE_FLAG(KEY_UINT);
+ MRB_DEFINE_FLAG(KEY_INT);
+ MRB_DEFINE_FLAG(KEY_FLOAT);
+ MRB_DEFINE_FLAG(KEY_GEO_POINT);
+
+ MRB_DEFINE_FLAG(KEY_WITH_SIS);
+ MRB_DEFINE_FLAG(KEY_NORMALIZE);
+
+ MRB_DEFINE_FLAG(COLUMN_TYPE_MASK);
+ MRB_DEFINE_FLAG(COLUMN_SCALAR);
+ MRB_DEFINE_FLAG(COLUMN_VECTOR);
+ MRB_DEFINE_FLAG(COLUMN_INDEX);
+
+ MRB_DEFINE_FLAG(COMPRESS_MASK);
+ 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);
+ MRB_DEFINE_FLAG(WITH_POSITION);
+ MRB_DEFINE_FLAG(RING_BUFFER);
+
+ MRB_DEFINE_FLAG(UNIT_MASK);
+ MRB_DEFINE_FLAG(UNIT_DOCUMENT_NONE);
+ MRB_DEFINE_FLAG(UNIT_DOCUMENT_SECTION);
+ MRB_DEFINE_FLAG(UNIT_DOCUMENT_POSITION);
+ MRB_DEFINE_FLAG(UNIT_SECTION_NONE);
+ MRB_DEFINE_FLAG(UNIT_SECTION_POSITION);
+ MRB_DEFINE_FLAG(UNIT_POSITION_NONE);
+ MRB_DEFINE_FLAG(UNIT_USERDEF_DOCUMENT);
+ MRB_DEFINE_FLAG(UNIT_USERDEF_SECTION);
+ MRB_DEFINE_FLAG(UNIT_USERDEF_POSITION);
+
+ MRB_DEFINE_FLAG(NO_SUBREC);
+ MRB_DEFINE_FLAG(WITH_SUBREC);
+
+ MRB_DEFINE_FLAG(KEY_VAR_SIZE);
+
+ MRB_DEFINE_FLAG(TEMPORARY);
+ MRB_DEFINE_FLAG(PERSISTENT);
+}
+#endif /* GRN_WITH_MRUBY */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.h
new file mode 100644
index 00000000..6f7bd7f7
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object_flags.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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_object_flags_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.c
new file mode 100644
index 00000000..e0ef4727
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.c
@@ -0,0 +1,155 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+
+#include "mrb_operator.h"
+
+mrb_value
+grn_mrb_value_from_operator(mrb_state *mrb, grn_operator op)
+{
+ grn_ctx *ctx = (grn_ctx *)(mrb->ud);
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_value mrb_op_raw;
+ mrb_value mrb_op;
+
+ mrb_op_raw = mrb_fixnum_value(op);
+ mrb_op = mrb_funcall(mrb, mrb_obj_value(data->groonga.operator_class),
+ "find", 1, mrb_op_raw);
+ if (mrb_nil_p(mrb_op)) {
+ return mrb_op_raw;
+ } else {
+ return mrb_op;
+ }
+}
+
+grn_operator
+grn_mrb_value_to_operator(mrb_state *mrb, mrb_value mrb_op)
+{
+ if (!mrb_fixnum_p(mrb_op)) {
+ mrb_op = mrb_funcall(mrb, mrb_op, "value", 0);
+ }
+
+ return mrb_fixnum(mrb_op);
+}
+
+void
+grn_mrb_operator_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = ctx->impl->mrb.module;
+ struct RClass *klass;
+ mrb_value klass_obj;
+
+ klass = mrb_class_get_under(mrb, module, "Operator");
+ data->groonga.operator_class = klass;
+
+ klass_obj = mrb_obj_value(klass);
+#define DEFINE_OPERATOR(name) \
+ mrb_funcall(mrb, klass_obj, "register", 1, \
+ mrb_funcall(mrb, klass_obj, "new", 2, \
+ mrb_str_new_lit(mrb, #name), \
+ mrb_fixnum_value(GRN_OP_ ## name)))
+
+ DEFINE_OPERATOR(PUSH);
+ DEFINE_OPERATOR(POP);
+ DEFINE_OPERATOR(NOP);
+ DEFINE_OPERATOR(CALL);
+ DEFINE_OPERATOR(INTERN);
+ DEFINE_OPERATOR(GET_REF);
+ DEFINE_OPERATOR(GET_VALUE);
+ DEFINE_OPERATOR(AND);
+ DEFINE_OPERATOR(AND_NOT);
+ DEFINE_OPERATOR(OR);
+ DEFINE_OPERATOR(ASSIGN);
+ DEFINE_OPERATOR(STAR_ASSIGN);
+ DEFINE_OPERATOR(SLASH_ASSIGN);
+ DEFINE_OPERATOR(MOD_ASSIGN);
+ DEFINE_OPERATOR(PLUS_ASSIGN);
+ DEFINE_OPERATOR(MINUS_ASSIGN);
+ DEFINE_OPERATOR(SHIFTL_ASSIGN);
+ DEFINE_OPERATOR(SHIFTR_ASSIGN);
+ DEFINE_OPERATOR(SHIFTRR_ASSIGN);
+ DEFINE_OPERATOR(AND_ASSIGN);
+ DEFINE_OPERATOR(XOR_ASSIGN);
+ DEFINE_OPERATOR(OR_ASSIGN);
+ DEFINE_OPERATOR(JUMP);
+ DEFINE_OPERATOR(CJUMP);
+ DEFINE_OPERATOR(COMMA);
+ DEFINE_OPERATOR(BITWISE_OR);
+ DEFINE_OPERATOR(BITWISE_XOR);
+ DEFINE_OPERATOR(BITWISE_AND);
+ DEFINE_OPERATOR(BITWISE_NOT);
+ DEFINE_OPERATOR(EQUAL);
+ DEFINE_OPERATOR(NOT_EQUAL);
+ DEFINE_OPERATOR(LESS);
+ DEFINE_OPERATOR(GREATER);
+ DEFINE_OPERATOR(LESS_EQUAL);
+ DEFINE_OPERATOR(GREATER_EQUAL);
+ DEFINE_OPERATOR(IN);
+ DEFINE_OPERATOR(MATCH);
+ DEFINE_OPERATOR(NEAR);
+ DEFINE_OPERATOR(NEAR2);
+ DEFINE_OPERATOR(SIMILAR);
+ DEFINE_OPERATOR(TERM_EXTRACT);
+ DEFINE_OPERATOR(SHIFTL);
+ DEFINE_OPERATOR(SHIFTR);
+ DEFINE_OPERATOR(SHIFTRR);
+ DEFINE_OPERATOR(PLUS);
+ DEFINE_OPERATOR(MINUS);
+ DEFINE_OPERATOR(STAR);
+ DEFINE_OPERATOR(SLASH);
+ DEFINE_OPERATOR(MOD);
+ DEFINE_OPERATOR(DELETE);
+ DEFINE_OPERATOR(INCR);
+ DEFINE_OPERATOR(DECR);
+ DEFINE_OPERATOR(INCR_POST);
+ DEFINE_OPERATOR(DECR_POST);
+ DEFINE_OPERATOR(NOT);
+ DEFINE_OPERATOR(ADJUST);
+ DEFINE_OPERATOR(EXACT);
+ DEFINE_OPERATOR(LCP);
+ DEFINE_OPERATOR(PARTIAL);
+ DEFINE_OPERATOR(UNSPLIT);
+ DEFINE_OPERATOR(PREFIX);
+ DEFINE_OPERATOR(SUFFIX);
+ DEFINE_OPERATOR(GEO_DISTANCE1);
+ DEFINE_OPERATOR(GEO_DISTANCE2);
+ DEFINE_OPERATOR(GEO_DISTANCE3);
+ DEFINE_OPERATOR(GEO_DISTANCE4);
+ DEFINE_OPERATOR(GEO_WITHINP5);
+ DEFINE_OPERATOR(GEO_WITHINP6);
+ DEFINE_OPERATOR(GEO_WITHINP8);
+ DEFINE_OPERATOR(OBJ_SEARCH);
+ DEFINE_OPERATOR(EXPR_GET_VAR);
+ DEFINE_OPERATOR(TABLE_CREATE);
+ DEFINE_OPERATOR(TABLE_SELECT);
+ DEFINE_OPERATOR(TABLE_SORT);
+ DEFINE_OPERATOR(TABLE_GROUP);
+ DEFINE_OPERATOR(JSON_PUT);
+ DEFINE_OPERATOR(GET_MEMBER);
+ DEFINE_OPERATOR(REGEXP);
+ DEFINE_OPERATOR(FUZZY);
+
+#undef DEFINE_OPERATOR
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.h
new file mode 100644
index 00000000..6f27e137
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_operator.h
@@ -0,0 +1,34 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_operator_init(grn_ctx *ctx);
+mrb_value grn_mrb_value_from_operator(mrb_state *mrb, grn_operator op);
+grn_operator grn_mrb_value_to_operator(mrb_state *mrb, mrb_value mrb_op);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_options.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_options.c
new file mode 100644
index 00000000..445bcaf6
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_options.c
@@ -0,0 +1,39 @@
+/* -*- 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+#include "../grn_db.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/hash.h>
+
+#include "mrb_options.h"
+
+mrb_value
+grn_mrb_options_get_static(mrb_state *mrb,
+ mrb_value mrb_options,
+ const char *key,
+ size_t key_size)
+{
+ mrb_sym mrb_key;
+
+ mrb_key = mrb_intern_static(mrb, key, key_size);
+ return mrb_hash_get(mrb, mrb_options, mrb_symbol_value(mrb_key));
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_options.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_options.h
new file mode 100644
index 00000000..0cbd7bb7
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_options.h
@@ -0,0 +1,38 @@
+/* -*- 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+mrb_value grn_mrb_options_get_static(mrb_state *mrb,
+ mrb_value mrb_options,
+ const char *key,
+ size_t key_size);
+#define grn_mrb_options_get_lit(mrb, mrb_options, literal) \
+ grn_mrb_options_get_static(mrb, mrb_options, \
+ (literal), mrb_strlen_lit(literal))
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_patricia_trie.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_patricia_trie.c
new file mode 100644
index 00000000..bd206b5c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_patricia_trie.c
@@ -0,0 +1,59 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2014 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+
+#include "mrb_patricia_trie.h"
+
+static struct mrb_data_type mrb_grn_patricia_trie_type = {
+ "Groonga::PatriciaTrie",
+ NULL
+};
+
+static mrb_value
+mrb_grn_patricia_trie_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_patricia_trie_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_patricia_trie_ptr);
+ DATA_TYPE(self) = &mrb_grn_patricia_trie_type;
+ DATA_PTR(self) = mrb_cptr(mrb_patricia_trie_ptr);
+ return self;
+}
+
+void
+grn_mrb_patricia_trie_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *table_class;
+ struct RClass *klass;
+
+ table_class = mrb_class_get_under(mrb, module, "Table");
+ klass = mrb_define_class_under(mrb, module, "PatriciaTrie", table_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+ mrb_define_method(mrb, klass, "initialize",
+ mrb_grn_patricia_trie_initialize, MRB_ARGS_REQ(1));
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_patricia_trie.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_patricia_trie.h
new file mode 100644
index 00000000..11da13a3
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_patricia_trie.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_patricia_trie_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
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 00000000..b0d60f18
--- /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-1335 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 00000000..5fe1dfb4
--- /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-1335 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
new file mode 100644
index 00000000..f5045dc1
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_procedure.c
@@ -0,0 +1,108 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+
+#include "mrb_procedure.h"
+
+#include "mrb_operator.h"
+
+static struct mrb_data_type mrb_grn_procedure_type = {
+ "Groonga::Procedure",
+ NULL
+};
+
+static mrb_value
+mrb_grn_procedure_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_procedure_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_procedure_ptr);
+ DATA_TYPE(self) = &mrb_grn_procedure_type;
+ DATA_PTR(self) = mrb_cptr(mrb_procedure_ptr);
+ return 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;
+ grn_obj *proc = DATA_PTR(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)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *object_class = data->object_class;
+ struct RClass *klass;
+
+ klass = mrb_define_class_under(mrb, module, "Procedure", object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+ 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
new file mode 100644
index 00000000..5d64fcd0
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_procedure.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_procedure_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
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 00000000..d19ca780
--- /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-1335 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 00000000..c0ea5eaf
--- /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-1335 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 00000000..57411d27
--- /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-1335 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 00000000..9c0e6ece
--- /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-1335 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
new file mode 100644
index 00000000..fecc6e3d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c
@@ -0,0 +1,493 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 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 <mruby/hash.h>
+#include <mruby/array.h>
+#include <mruby/string.h>
+
+#include "mrb_ctx.h"
+#include "mrb_table.h"
+#include "mrb_converter.h"
+#include "mrb_options.h"
+
+static mrb_value
+mrb_grn_table_array_reference(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *table;
+ grn_id key_domain_id;
+ mrb_value mrb_key;
+ grn_id record_id;
+ grn_mrb_value_to_raw_data_buffer buffer;
+ void *key;
+ unsigned int key_size;
+
+ mrb_get_args(mrb, "o", &mrb_key);
+
+ table = DATA_PTR(self);
+ if (table->header.type == GRN_DB) {
+ key_domain_id = GRN_DB_SHORT_TEXT;
+ } else {
+ key_domain_id = table->header.domain;
+ }
+
+ grn_mrb_value_to_raw_data_buffer_init(mrb, &buffer);
+ grn_mrb_value_to_raw_data(mrb, "key", mrb_key, key_domain_id,
+ &buffer, &key, &key_size);
+ record_id = grn_table_get(ctx, table, key, key_size);
+ grn_mrb_value_to_raw_data_buffer_fin(mrb, &buffer);
+
+ if (record_id == GRN_ID_NIL) {
+ return mrb_nil_value();
+ } else {
+ return mrb_fixnum_value(record_id);
+ }
+}
+
+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;
+ grn_obj *table;
+ mrb_value mrb_column_name;
+ grn_obj *column;
+
+ mrb_get_args(mrb, "o", &mrb_column_name);
+
+ table = DATA_PTR(self);
+ column = grn_obj_column(ctx, table,
+ RSTRING_PTR(mrb_column_name),
+ RSTRING_LEN(mrb_column_name));
+ grn_mrb_ctx_check(mrb);
+
+ return grn_mrb_value_from_grn_obj(mrb, column);
+}
+
+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;
+ unsigned int is_locked;
+
+ is_locked = grn_obj_is_locked(ctx, DATA_PTR(self));
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_bool_value(is_locked != 0);
+}
+
+static mrb_value
+mrb_grn_table_get_size(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ unsigned int size;
+
+ size = grn_table_size(ctx, DATA_PTR(self));
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_fixnum_value(size);
+}
+
+static mrb_value
+mrb_grn_table_is_empty(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ unsigned int size;
+
+ size = grn_table_size(ctx, DATA_PTR(self));
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_bool_value(size == 0);
+}
+
+static mrb_value
+mrb_grn_table_select(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *table;
+ grn_obj *expr;
+ grn_obj *result = NULL;
+ grn_operator operator = GRN_OP_OR;
+ mrb_value mrb_expr;
+ mrb_value mrb_options = mrb_nil_value();
+
+ table = DATA_PTR(self);
+ mrb_get_args(mrb, "o|H", &mrb_expr, &mrb_options);
+
+ expr = DATA_PTR(mrb_expr);
+
+ if (!mrb_nil_p(mrb_options)) {
+ mrb_value mrb_result;
+ mrb_value mrb_operator;
+
+ mrb_result = grn_mrb_options_get_lit(mrb, mrb_options, "result");
+ if (!mrb_nil_p(mrb_result)) {
+ result = DATA_PTR(mrb_result);
+ }
+
+ mrb_operator = grn_mrb_options_get_lit(mrb, mrb_options, "operator");
+ if (!mrb_nil_p(mrb_operator)) {
+ operator = mrb_fixnum(mrb_operator);
+ }
+ }
+
+ result = grn_table_select(ctx, table, expr, result, operator);
+ if (ctx->rc != GRN_SUCCESS) {
+ grn_mrb_ctx_check(mrb);
+ }
+
+ return grn_mrb_value_from_grn_obj(mrb, result);
+}
+
+static mrb_value
+mrb_grn_table_sort_raw(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *table;
+ mrb_value mrb_keys;
+ grn_table_sort_key *keys;
+ int i, n_keys;
+ mrb_int offset;
+ mrb_int limit;
+ mrb_value mrb_result;
+ grn_obj *result;
+
+ table = DATA_PTR(self);
+ mrb_get_args(mrb, "oiio", &mrb_keys, &offset, &limit, &mrb_result);
+
+ mrb_keys = mrb_convert_type(mrb, mrb_keys,
+ MRB_TT_ARRAY, "Array", "to_ary");
+
+ n_keys = RARRAY_LEN(mrb_keys);
+ keys = GRN_MALLOCN(grn_table_sort_key, n_keys);
+ for (i = 0; i < n_keys; i++) {
+ 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);
+ GRN_FREE(keys);
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_result;
+}
+
+static mrb_value
+mrb_grn_table_group_raw(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *table;
+ mrb_value mrb_keys;
+ grn_table_sort_key *keys;
+ int i, n_keys;
+ mrb_value mrb_result;
+ grn_table_group_result *result;
+
+ table = DATA_PTR(self);
+ mrb_get_args(mrb, "oo", &mrb_keys, &mrb_result);
+
+ mrb_keys = mrb_convert_type(mrb, mrb_keys,
+ MRB_TT_ARRAY, "Array", "to_ary");
+
+ n_keys = RARRAY_LEN(mrb_keys);
+ keys = GRN_MALLOCN(grn_table_sort_key, n_keys);
+ for (i = 0; i < n_keys; i++) {
+ 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);
+ GRN_FREE(keys);
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_result;
+}
+
+static mrb_value
+mrb_grn_table_delete(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *table;
+ mrb_value mrb_options;
+ mrb_value mrb_id;
+ mrb_value mrb_key;
+ mrb_value mrb_expression;
+
+ table = DATA_PTR(self);
+ mrb_get_args(mrb, "H", &mrb_options);
+
+ mrb_id = grn_mrb_options_get_lit(mrb, mrb_options, "id");
+ if (!mrb_nil_p(mrb_id)) {
+ grn_table_delete_by_id(ctx, table, mrb_fixnum(mrb_id));
+ grn_mrb_ctx_check(mrb);
+ return mrb_nil_value();
+ }
+
+ mrb_key = grn_mrb_options_get_lit(mrb, mrb_options, "key");
+ if (!mrb_nil_p(mrb_key)) {
+ grn_id key_domain_id;
+ void *key;
+ unsigned int key_size;
+ grn_mrb_value_to_raw_data_buffer buffer;
+
+ key_domain_id = table->header.domain;
+ grn_mrb_value_to_raw_data_buffer_init(mrb, &buffer);
+ grn_mrb_value_to_raw_data(mrb, "key", mrb_key, key_domain_id,
+ &buffer, &key, &key_size);
+ grn_table_delete(ctx, table, key, key_size);
+ grn_mrb_value_to_raw_data_buffer_fin(mrb, &buffer);
+ grn_mrb_ctx_check(mrb);
+ return mrb_nil_value();
+ }
+
+ mrb_expression = grn_mrb_options_get_lit(mrb, mrb_options, "expression");
+ if (!mrb_nil_p(mrb_expression)) {
+ grn_obj *expression;
+ grn_obj *selected_records;
+ grn_table_cursor *cursor;
+
+ expression = DATA_PTR(mrb_expression);
+ selected_records = grn_table_select(ctx, table, expression, NULL, GRN_OP_OR);
+ grn_mrb_ctx_check(mrb);
+ cursor = grn_table_cursor_open(ctx, selected_records,
+ NULL, 0,
+ NULL, 0,
+ 0, -1, 0);
+ if (cursor) {
+ while (grn_table_cursor_next(ctx, cursor) != GRN_ID_NIL) {
+ grn_id *id;
+ grn_table_cursor_get_key(ctx, cursor, (void **)&id);
+ grn_table_delete_by_id(ctx, table, *id);
+ }
+ grn_table_cursor_close(ctx, cursor);
+ }
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_nil_value();
+ }
+
+ mrb_raisef(mrb, E_ARGUMENT_ERROR,
+ "must have :id, :key or :expression: %S",
+ mrb_options);
+
+ 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)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *object_class = data->object_class;
+ struct RClass *klass;
+
+ klass = mrb_define_class_under(mrb, module, "Table", object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+
+ 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());
+
+ mrb_define_method(mrb, klass, "size",
+ mrb_grn_table_get_size, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "empty?",
+ mrb_grn_table_is_empty, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "select",
+ mrb_grn_table_select, MRB_ARGS_ARG(1, 1));
+ mrb_define_method(mrb, klass, "sort_raw",
+ mrb_grn_table_sort_raw, MRB_ARGS_REQ(4));
+ mrb_define_method(mrb, klass, "group_raw",
+ mrb_grn_table_group_raw, MRB_ARGS_REQ(2));
+
+ 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
new file mode 100644
index 00000000..fd06db56
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_table_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.c
new file mode 100644
index 00000000..a7748168
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.c
@@ -0,0 +1,208 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+#include <mruby/string.h>
+#include <mruby/hash.h>
+#include <mruby/variable.h>
+
+#include "mrb_ctx.h"
+#include "mrb_bulk.h"
+#include "mrb_table_cursor.h"
+
+#include "mrb_converter.h"
+#include "mrb_options.h"
+
+static struct mrb_data_type mrb_grn_table_cursor_type = {
+ "Groonga::TableCursor",
+ NULL
+};
+
+static mrb_value
+mrb_grn_table_cursor_class_open_raw(mrb_state *mrb, mrb_value klass)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_value mrb_table;
+ mrb_value mrb_options = mrb_nil_value();
+ grn_table_cursor *table_cursor;
+ grn_obj *table;
+ void *min = NULL;
+ unsigned int min_size = 0;
+ grn_mrb_value_to_raw_data_buffer min_buffer;
+ void *max = NULL;
+ unsigned int max_size = 0;
+ grn_mrb_value_to_raw_data_buffer max_buffer;
+ int offset = 0;
+ int limit = -1;
+ int flags = 0;
+
+ mrb_get_args(mrb, "o|H", &mrb_table, &mrb_options);
+
+ table = DATA_PTR(mrb_table);
+ grn_mrb_value_to_raw_data_buffer_init(mrb, &min_buffer);
+ grn_mrb_value_to_raw_data_buffer_init(mrb, &max_buffer);
+ if (!mrb_nil_p(mrb_options)) {
+ grn_id key_domain_id;
+ mrb_value mrb_min;
+ mrb_value mrb_max;
+ mrb_value mrb_flags;
+
+ if (table->header.type == GRN_DB) {
+ key_domain_id = GRN_DB_SHORT_TEXT;
+ } else {
+ key_domain_id = table->header.domain;
+ }
+
+ mrb_min = grn_mrb_options_get_lit(mrb, mrb_options, "min");
+ grn_mrb_value_to_raw_data(mrb, "min", mrb_min,
+ key_domain_id, &min_buffer, &min, &min_size);
+
+ mrb_max = grn_mrb_options_get_lit(mrb, mrb_options, "max");
+ grn_mrb_value_to_raw_data(mrb, "max", mrb_max,
+ key_domain_id, &max_buffer, &max, &max_size);
+
+ mrb_flags = grn_mrb_options_get_lit(mrb, mrb_options, "flags");
+ if (!mrb_nil_p(mrb_flags)) {
+ flags = mrb_fixnum(mrb_flags);
+ }
+ }
+ table_cursor = grn_table_cursor_open(ctx, table,
+ min, min_size,
+ max, max_size,
+ offset, limit, flags);
+ grn_mrb_value_to_raw_data_buffer_fin(mrb, &min_buffer);
+ grn_mrb_value_to_raw_data_buffer_fin(mrb, &max_buffer);
+ grn_mrb_ctx_check(mrb);
+
+ {
+ 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
+mrb_grn_table_cursor_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_table_cursor_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_table_cursor_ptr);
+ DATA_TYPE(self) = &mrb_grn_table_cursor_type;
+ DATA_PTR(self) = mrb_cptr(mrb_table_cursor_ptr);
+
+ return self;
+}
+
+static mrb_value
+mrb_grn_table_cursor_close(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_table_cursor *table_cursor;
+
+ table_cursor = DATA_PTR(self);
+ if (table_cursor) {
+ DATA_PTR(self) = NULL;
+ grn_table_cursor_close(ctx, table_cursor);
+ grn_mrb_ctx_check(mrb);
+ }
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_table_cursor_next(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_id id;
+
+ id = grn_table_cursor_next(ctx, DATA_PTR(self));
+ grn_mrb_ctx_check(mrb);
+
+ return mrb_fixnum_value(id);
+}
+
+static mrb_value
+mrb_grn_table_cursor_count(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ int n_records = 0;
+
+ while (grn_table_cursor_next(ctx, DATA_PTR(self)) != GRN_ID_NIL) {
+ n_records++;
+ }
+
+ 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)
+{
+ 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, "TableCursor", mrb->object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+
+ 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));
+ mrb_define_method(mrb, klass, "close",
+ mrb_grn_table_cursor_close, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "next",
+ 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
new file mode 100644
index 00000000..6ffd51af
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_table_cursor_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor_flags.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor_flags.c
new file mode 100644
index 00000000..58a3137a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor_flags.c
@@ -0,0 +1,60 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2014 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+
+#include "mrb_table_cursor_flags.h"
+
+void
+grn_mrb_table_cursor_flags_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *flags_module;
+
+ flags_module = mrb_define_module_under(mrb, module, "TableCursorFlags");
+
+ mrb_define_const(mrb, flags_module, "ASCENDING",
+ mrb_fixnum_value(GRN_CURSOR_ASCENDING));
+ mrb_define_const(mrb, flags_module, "DESCENDING",
+ mrb_fixnum_value(GRN_CURSOR_DESCENDING));
+ mrb_define_const(mrb, flags_module, "GE",
+ mrb_fixnum_value(GRN_CURSOR_GE));
+ mrb_define_const(mrb, flags_module, "GT",
+ mrb_fixnum_value(GRN_CURSOR_GT));
+ mrb_define_const(mrb, flags_module, "LE",
+ mrb_fixnum_value(GRN_CURSOR_LE));
+ mrb_define_const(mrb, flags_module, "LT",
+ mrb_fixnum_value(GRN_CURSOR_LT));
+ mrb_define_const(mrb, flags_module, "BY_KEY",
+ mrb_fixnum_value(GRN_CURSOR_BY_KEY));
+ mrb_define_const(mrb, flags_module, "BY_ID",
+ mrb_fixnum_value(GRN_CURSOR_BY_ID));
+ mrb_define_const(mrb, flags_module, "PREFIX",
+ mrb_fixnum_value(GRN_CURSOR_PREFIX));
+ mrb_define_const(mrb, flags_module, "SIZE_BY_BIT",
+ mrb_fixnum_value(GRN_CURSOR_SIZE_BY_BIT));
+ mrb_define_const(mrb, flags_module, "RK",
+ mrb_fixnum_value(GRN_CURSOR_RK));
+}
+#endif
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
new file mode 100644
index 00000000..5db915a7
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor_flags.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_table_cursor_flags_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_flags.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_flags.c
new file mode 100644
index 00000000..8984ebef
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_flags.c
@@ -0,0 +1,48 @@
+/* -*- 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+
+#include "mrb_table_group_flags.h"
+
+void
+grn_mrb_table_group_flags_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *flags_module;
+
+ flags_module = mrb_define_module_under(mrb, module, "TableGroupFlags");
+
+ mrb_define_const(mrb, flags_module, "CALC_COUNT",
+ mrb_fixnum_value(GRN_TABLE_GROUP_CALC_COUNT));
+ mrb_define_const(mrb, flags_module, "CALC_MAX",
+ mrb_fixnum_value(GRN_TABLE_GROUP_CALC_MAX));
+ mrb_define_const(mrb, flags_module, "CALC_MIN",
+ mrb_fixnum_value(GRN_TABLE_GROUP_CALC_MIN));
+ mrb_define_const(mrb, flags_module, "CALC_SUM",
+ mrb_fixnum_value(GRN_TABLE_GROUP_CALC_SUM));
+ mrb_define_const(mrb, flags_module, "CALC_AVG",
+ mrb_fixnum_value(GRN_TABLE_GROUP_CALC_AVG));
+}
+#endif
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
new file mode 100644
index 00000000..4230a240
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_flags.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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_table_group_flags_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
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
new file mode 100644
index 00000000..c4aaafa4
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.c
@@ -0,0 +1,254 @@
+/* -*- 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+#include <mruby/hash.h>
+#include <mruby/array.h>
+#include <mruby/string.h>
+
+#include "mrb_ctx.h"
+#include "mrb_converter.h"
+#include "mrb_operator.h"
+#include "mrb_table_group_result.h"
+
+static void
+mrb_grn_table_group_result_free(mrb_state *mrb, void *data)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_table_group_result *result = data;
+
+ if (!result) {
+ return;
+ }
+
+ if (result->calc_target) {
+ grn_obj_unlink(ctx, result->calc_target);
+ }
+ if (result->table) {
+ grn_obj_unlink(ctx, result->table);
+ }
+ mrb_free(mrb, result);
+}
+
+static struct mrb_data_type mrb_grn_table_group_result_type = {
+ "Groonga::TableGroupResult",
+ mrb_grn_table_group_result_free
+};
+
+static mrb_value
+mrb_grn_table_group_result_initialize(mrb_state *mrb, mrb_value self)
+{
+ grn_table_group_result *result;
+
+ DATA_TYPE(self) = &mrb_grn_table_group_result_type;
+
+ result = mrb_calloc(mrb, 1, sizeof(grn_table_group_result));
+ DATA_PTR(self) = result;
+
+ return self;
+}
+
+
+static mrb_value
+mrb_grn_table_group_result_close(mrb_state *mrb, mrb_value self)
+{
+ grn_table_group_result *result;
+
+ result = DATA_PTR(self);
+ if (result) {
+ mrb_grn_table_group_result_free(mrb, result);
+ DATA_PTR(self) = NULL;
+ }
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_table_group_result_get_table(mrb_state *mrb, mrb_value self)
+{
+ grn_table_group_result *result;
+
+ result = DATA_PTR(self);
+
+ return grn_mrb_value_from_grn_obj(mrb, result->table);
+}
+
+static mrb_value
+mrb_grn_table_group_result_set_table(mrb_state *mrb, mrb_value self)
+{
+ grn_table_group_result *result;
+ mrb_value mrb_table;
+
+ result = DATA_PTR(self);
+ mrb_get_args(mrb, "o", &mrb_table);
+
+ if (mrb_nil_p(mrb_table)) {
+ result->table = NULL;
+ } else {
+ result->table = DATA_PTR(mrb_table);
+ }
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_table_group_result_set_key_begin(mrb_state *mrb, mrb_value self)
+{
+ grn_table_group_result *result;
+ mrb_int key_begin;
+
+ result = DATA_PTR(self);
+ mrb_get_args(mrb, "i", &key_begin);
+
+ result->key_begin = key_begin;
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_table_group_result_set_key_end(mrb_state *mrb, mrb_value self)
+{
+ grn_table_group_result *result;
+ mrb_int key_end;
+
+ result = DATA_PTR(self);
+ mrb_get_args(mrb, "i", &key_end);
+
+ result->key_end = key_end;
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_table_group_result_set_limit(mrb_state *mrb, mrb_value self)
+{
+ grn_table_group_result *result;
+ mrb_int limit;
+
+ result = DATA_PTR(self);
+ mrb_get_args(mrb, "i", &limit);
+
+ result->limit = limit;
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_table_group_result_set_flags(mrb_state *mrb, mrb_value self)
+{
+ grn_table_group_result *result;
+ mrb_int flags;
+
+ result = DATA_PTR(self);
+ mrb_get_args(mrb, "i", &flags);
+
+ result->flags = flags;
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_table_group_result_set_operator(mrb_state *mrb, mrb_value self)
+{
+ grn_table_group_result *result;
+ mrb_value mrb_operator;
+
+ result = DATA_PTR(self);
+ mrb_get_args(mrb, "o", &mrb_operator);
+
+ result->op = grn_mrb_value_to_operator(mrb, mrb_operator);
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+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_sub_records;
+
+ result = DATA_PTR(self);
+ mrb_get_args(mrb, "i", &max_n_sub_records);
+
+ result->max_n_subrecs = max_n_sub_records;
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_table_group_result_set_calc_target(mrb_state *mrb, mrb_value self)
+{
+ grn_table_group_result *result;
+ mrb_value mrb_calc_target;
+
+ result = DATA_PTR(self);
+ mrb_get_args(mrb, "o", &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();
+}
+
+void
+grn_mrb_table_group_result_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, "TableGroupResult",
+ mrb->object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+
+ mrb_define_method(mrb, klass, "initialize",
+ mrb_grn_table_group_result_initialize, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "close",
+ mrb_grn_table_group_result_close, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "table",
+ mrb_grn_table_group_result_get_table, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "table=",
+ mrb_grn_table_group_result_set_table, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "key_begin=",
+ mrb_grn_table_group_result_set_key_begin, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "key_end=",
+ mrb_grn_table_group_result_set_key_end, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "limit=",
+ mrb_grn_table_group_result_set_limit, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "flags=",
+ 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_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));
+}
+#endif
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
new file mode 100644
index 00000000..c3b17af2
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_table_group_result_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.c
new file mode 100644
index 00000000..47f0169e
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.c
@@ -0,0 +1,42 @@
+/* -*- 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+
+#include "mrb_table_sort_flags.h"
+
+void
+grn_mrb_table_sort_flags_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *flags_module;
+
+ flags_module = mrb_define_module_under(mrb, module, "TableSortFlags");
+
+ mrb_define_const(mrb, flags_module, "ASCENDING",
+ mrb_fixnum_value(GRN_TABLE_SORT_ASC));
+ mrb_define_const(mrb, flags_module, "DESCENDING",
+ mrb_fixnum_value(GRN_TABLE_SORT_DESC));
+}
+#endif
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
new file mode 100644
index 00000000..7450399e
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_table_sort_flags_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
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
new file mode 100644
index 00000000..f8692d48
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.c
@@ -0,0 +1,159 @@
+/* -*- 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+#include <mruby/hash.h>
+#include <mruby/array.h>
+#include <mruby/string.h>
+
+#include "mrb_ctx.h"
+#include "mrb_table_sort_key.h"
+
+static void
+mrb_grn_table_sort_key_free(mrb_state *mrb, void *data)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_table_sort_key *sort_key = data;
+
+ if (!sort_key) {
+ return;
+ }
+
+ if (sort_key->key) {
+ if (sort_key->key->header.type == GRN_ACCESSOR) {
+ grn_obj_unlink(ctx, sort_key->key);
+ }
+ }
+ mrb_free(mrb, sort_key);
+}
+
+static struct mrb_data_type mrb_grn_table_sort_key_type = {
+ "Groonga::TableSortKey",
+ mrb_grn_table_sort_key_free
+};
+
+static mrb_value
+mrb_grn_table_sort_key_initialize(mrb_state *mrb, mrb_value self)
+{
+ grn_table_sort_key *result;
+
+ DATA_TYPE(self) = &mrb_grn_table_sort_key_type;
+
+ result = mrb_calloc(mrb, 1, sizeof(grn_table_sort_key));
+ DATA_PTR(self) = result;
+
+ return self;
+}
+
+
+static mrb_value
+mrb_grn_table_sort_key_close(mrb_state *mrb, mrb_value self)
+{
+ grn_table_sort_key *sort_key;
+
+ sort_key = DATA_PTR(self);
+ if (sort_key) {
+ mrb_grn_table_sort_key_free(mrb, sort_key);
+ DATA_PTR(self) = NULL;
+ }
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_table_sort_key_set_key(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_table_sort_key *sort_key;
+ mrb_value mrb_key;
+
+ sort_key = DATA_PTR(self);
+ mrb_get_args(mrb, "o", &mrb_key);
+
+ if (sort_key->key) {
+ grn_obj_unlink(ctx, sort_key->key);
+ }
+
+ if (mrb_nil_p(mrb_key)) {
+ sort_key->key = NULL;
+ } else {
+ sort_key->key = DATA_PTR(mrb_key);
+ }
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_table_sort_key_set_flags(mrb_state *mrb, mrb_value self)
+{
+ grn_table_sort_key *sort_key;
+ mrb_int flags;
+
+ sort_key = DATA_PTR(self);
+ mrb_get_args(mrb, "i", &flags);
+
+ sort_key->flags = flags;
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_table_sort_key_set_offset(mrb_state *mrb, mrb_value self)
+{
+ grn_table_sort_key *sort_key;
+ mrb_int offset;
+
+ sort_key = DATA_PTR(self);
+ mrb_get_args(mrb, "i", &offset);
+
+ sort_key->offset = offset;
+
+ return mrb_nil_value();
+}
+
+void
+grn_mrb_table_sort_key_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, "TableSortKey",
+ mrb->object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+
+ mrb_define_method(mrb, klass, "initialize",
+ mrb_grn_table_sort_key_initialize, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "close",
+ mrb_grn_table_sort_key_close, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "key=",
+ mrb_grn_table_sort_key_set_key, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "flags=",
+ mrb_grn_table_sort_key_set_flags, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "offset=",
+ mrb_grn_table_sort_key_set_offset, MRB_ARGS_REQ(1));
+}
+#endif
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
new file mode 100644
index 00000000..9ca38bfc
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_table_sort_key_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
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 00000000..ba3a7e7b
--- /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-1335 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 00000000..030eafed
--- /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-1335 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.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_type.c
new file mode 100644
index 00000000..a288d60f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_type.c
@@ -0,0 +1,60 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2014 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+
+#include "mrb_ctx.h"
+#include "mrb_type.h"
+
+static struct mrb_data_type mrb_grn_type_type = {
+ "Groonga::Type",
+ NULL
+};
+
+static mrb_value
+mrb_grn_type_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_type_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_type_ptr);
+ DATA_TYPE(self) = &mrb_grn_type_type;
+ DATA_PTR(self) = mrb_cptr(mrb_type_ptr);
+ return self;
+}
+
+void
+grn_mrb_type_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *object_class = data->object_class;
+ struct RClass *klass;
+
+ klass = mrb_define_class_under(mrb, module, "Type", object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+
+ mrb_define_method(mrb, klass, "initialize",
+ mrb_grn_type_initialize, MRB_ARGS_REQ(1));
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_type.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_type.h
new file mode 100644
index 00000000..8dc74b79
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_type.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_type_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_variable_size_column.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_variable_size_column.c
new file mode 100644
index 00000000..78f3de86
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_variable_size_column.c
@@ -0,0 +1,60 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2014 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+
+#include "mrb_variable_size_column.h"
+
+static struct mrb_data_type mrb_grn_variable_size_column_type = {
+ "Groonga::VariableSizeColumn",
+ NULL
+};
+
+static mrb_value
+mrb_grn_variable_size_column_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_variable_size_column_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_variable_size_column_ptr);
+ DATA_TYPE(self) = &mrb_grn_variable_size_column_type;
+ DATA_PTR(self) = mrb_cptr(mrb_variable_size_column_ptr);
+ return self;
+}
+
+void
+grn_mrb_variable_size_column_init(grn_ctx *ctx)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ struct RClass *module = data->module;
+ struct RClass *column_class;
+ struct RClass *klass;
+
+ column_class = mrb_class_get_under(mrb, module, "Column");
+ klass = mrb_define_class_under(mrb, module,
+ "VariableSizeColumn", column_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+ mrb_define_method(mrb, klass, "initialize",
+ mrb_grn_variable_size_column_initialize, MRB_ARGS_REQ(1));
+}
+#endif
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
new file mode 100644
index 00000000..1bac1238
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_variable_size_column.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_variable_size_column_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_void.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_void.c
new file mode 100644
index 00000000..33cdea6c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_void.c
@@ -0,0 +1,59 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2014 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-1335 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_void.h"
+
+static struct mrb_data_type mrb_grn_void_type = {
+ "Groonga::Void",
+ NULL
+};
+
+static mrb_value
+mrb_grn_void_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_void_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_void_ptr);
+ DATA_TYPE(self) = &mrb_grn_void_type;
+ DATA_PTR(self) = mrb_cptr(mrb_void_ptr);
+ return self;
+}
+
+void
+grn_mrb_void_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, "Void", mrb->object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+ mrb_define_method(mrb, klass, "initialize",
+ mrb_grn_void_initialize, MRB_ARGS_REQ(1));
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_void.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_void.h
new file mode 100644
index 00000000..dced2747
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_void.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_void_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
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 00000000..86ff372e
--- /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-1335 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 00000000..ea1b8ef6
--- /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-1335 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
new file mode 100644
index 00000000..b2ca09f9
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.c
@@ -0,0 +1,253 @@
+/* -*- 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-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/data.h>
+#include <mruby/hash.h>
+#include <mruby/string.h>
+
+#include "../grn_mrb.h"
+#include "../grn_output.h"
+#include "mrb_ctx.h"
+#include "mrb_writer.h"
+#include "mrb_options.h"
+
+static mrb_value
+writer_write(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_value target;
+
+ mrb_get_args(mrb, "o", &target);
+
+ switch (mrb_type(target)) {
+ case MRB_TT_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);
+ break;
+ case MRB_TT_FIXNUM :
+ GRN_OUTPUT_INT32(mrb_fixnum(target));
+ break;
+ 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 nil, true, false, number, float, symbol or string: "
+ "%S",
+ target);
+ break;
+ }
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+writer_open_array(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ char *name;
+ mrb_int n_elements;
+
+ mrb_get_args(mrb, "zi", &name, &n_elements);
+ GRN_OUTPUT_ARRAY_OPEN(name, n_elements);
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+writer_close_array(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+
+ GRN_OUTPUT_ARRAY_CLOSE();
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+writer_open_map(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ char *name;
+ mrb_int n_elements;
+
+ mrb_get_args(mrb, "zi", &name, &n_elements);
+ GRN_OUTPUT_MAP_OPEN(name, n_elements);
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+writer_close_map(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+
+ GRN_OUTPUT_MAP_CLOSE();
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+writer_write_table_columns(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_value mrb_table;
+ char *columns;
+ mrb_int columns_size;
+ grn_obj *table;
+ grn_obj_format format;
+ int n_hits = 0;
+ int offset = 0;
+ int limit = 0;
+ int hits_offset = 0;
+
+ mrb_get_args(mrb, "os", &mrb_table, &columns, &columns_size);
+
+ table = DATA_PTR(mrb_table);
+ GRN_OBJ_FORMAT_INIT(&format, n_hits, offset, limit, hits_offset);
+ format.flags |= GRN_OBJ_FORMAT_WITH_COLUMN_NAMES;
+ {
+ grn_rc rc;
+ rc = grn_output_format_set_columns(ctx, &format,
+ table, columns, columns_size);
+ if (rc != GRN_SUCCESS) {
+ GRN_OBJ_FORMAT_FIN(ctx, &format);
+ grn_mrb_ctx_check(mrb);
+ }
+ }
+ GRN_OUTPUT_TABLE_COLUMNS(table, &format);
+ GRN_OBJ_FORMAT_FIN(ctx, &format);
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+writer_write_table_records(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_value mrb_table;
+ mrb_value mrb_options = mrb_nil_value();
+ char *columns;
+ mrb_int columns_size;
+ grn_obj *table;
+ grn_obj_format format;
+ int n_hits = 0;
+ int offset = 0;
+ int limit = -1;
+ int hits_offset = 0;
+
+ mrb_get_args(mrb, "os|H", &mrb_table, &columns, &columns_size, &mrb_options);
+
+ table = DATA_PTR(mrb_table);
+ if (!mrb_nil_p(mrb_options)) {
+ mrb_value mrb_offset;
+ mrb_value mrb_limit;
+
+ mrb_offset = grn_mrb_options_get_lit(mrb, mrb_options, "offset");
+ if (!mrb_nil_p(mrb_offset)) {
+ offset = mrb_fixnum(mrb_offset);
+ }
+
+ mrb_limit = grn_mrb_options_get_lit(mrb, mrb_options, "limit");
+ if (!mrb_nil_p(mrb_limit)) {
+ limit = mrb_fixnum(mrb_limit);
+ }
+ }
+ if (limit < 0) {
+ limit = grn_table_size(ctx, table) + limit + 1;
+ }
+ GRN_OBJ_FORMAT_INIT(&format, n_hits, offset, limit, hits_offset);
+ {
+ grn_rc rc;
+ rc = grn_output_format_set_columns(ctx, &format,
+ table, columns, columns_size);
+ if (rc != GRN_SUCCESS) {
+ GRN_OBJ_FORMAT_FIN(ctx, &format);
+ grn_mrb_ctx_check(mrb);
+ }
+ }
+ GRN_OUTPUT_TABLE_RECORDS(table, &format);
+ GRN_OBJ_FORMAT_FIN(ctx, &format);
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+writer_set_content_type(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ mrb_int content_type;
+
+ mrb_get_args(mrb, "i", &content_type);
+
+ grn_ctx_set_output_type(ctx, content_type);
+
+ return mrb_nil_value();
+}
+
+void
+grn_mrb_writer_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, "Writer", mrb->object_class);
+
+ mrb_define_method(mrb, klass, "write", writer_write, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "open_array",
+ writer_open_array, MRB_ARGS_REQ(2));
+ mrb_define_method(mrb, klass, "close_array",
+ writer_close_array, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "open_map",
+ writer_open_map, MRB_ARGS_REQ(2));
+ mrb_define_method(mrb, klass, "close_map",
+ writer_close_map, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, klass, "write_table_columns",
+ writer_write_table_columns, MRB_ARGS_REQ(2));
+ mrb_define_method(mrb, klass, "write_table_records",
+ writer_write_table_records, MRB_ARGS_ARG(2, 1));
+
+ mrb_define_method(mrb, klass, "content_type=",
+ writer_set_content_type, MRB_ARGS_REQ(1));
+}
+#endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.h
new file mode 100644
index 00000000..7b5b32d4
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.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-1335 USA
+*/
+
+#pragma once
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_writer_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/Makefile.am
new file mode 100644
index 00000000..835d881b
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/Makefile.am
@@ -0,0 +1,16 @@
+SUBDIRS = \
+ command_line \
+ context \
+ expression_tree \
+ initialize \
+ logger \
+ query_logger
+
+include sources.am
+
+EXTRA_DIST = \
+ $(RUBY_SCRIPT_FILES)
+
+if WITH_MRUBY
+ruby_scripts_DATA = $(RUBY_SCRIPT_FILES)
+endif
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 00000000..3ae08fb6
--- /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/backtrace_entry.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/backtrace_entry.rb
new file mode 100644
index 00000000..34f95e96
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/backtrace_entry.rb
@@ -0,0 +1,28 @@
+module Groonga
+ class BacktraceEntry
+ class << self
+ def parse(entry)
+ match_data = /:(\d+):?/.match(entry)
+ file = match_data.pre_match
+ line = match_data[1].to_i
+ detail_match_data = /\A(in )?(\S+)\s*/.match(match_data.post_match)
+ if detail_match_data[1]
+ method = detail_match_data[2]
+ message = detail_match_data.post_match
+ else
+ method = ""
+ message = match_data.post_match
+ end
+ new(file, line, method, message)
+ end
+ end
+
+ attr_reader :file, :line, :method, :message
+ def initialize(file, line, method, message)
+ @file = file
+ @line = line
+ @method = method
+ @message = message
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/command.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command.rb
new file mode 100644
index 00000000..26dfe68c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command.rb
@@ -0,0 +1,64 @@
+module Groonga
+ class Command
+ @@classes = {}
+ class << self
+ def register_class(name, klass)
+ @@classes[name] = klass
+ end
+
+ def find_class(name)
+ @@classes[name]
+ end
+ end
+
+ private
+ def context
+ @context ||= Context.instance
+ end
+
+ def writer
+ @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
+ 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
+ rescue => error
+ context.record_error(:command_error, error)
+ nil
+ end
+ end
+ end
+end
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 00000000..779edb47
--- /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/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/Makefile.am
new file mode 100644
index 00000000..8d580810
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/Makefile.am
@@ -0,0 +1,9 @@
+include sources.am
+
+EXTRA_DIST = \
+ $(RUBY_SCRIPT_FILES)
+
+if WITH_MRUBY
+ruby_scripts_command_linedir = $(ruby_scriptsdir)/command_line
+ruby_scripts_command_line_DATA = $(RUBY_SCRIPT_FILES)
+endif
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
new file mode 100644
index 00000000..edd16d58
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/grndb.rb
@@ -0,0 +1,452 @@
+module Groonga
+ module CommandLine
+ class Grndb
+ def initialize(argv)
+ @program_path, *@arguments = argv
+ @succeeded = true
+ @database_path = nil
+ end
+
+ def run
+ command_line_parser = create_command_line_parser
+ options = nil
+ begin
+ 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_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
+
+ parser.add_command("recover") do |command|
+ command.description = "Recover database"
+
+ 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
+
+ parser
+ end
+
+ 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
+
+ database = nil
+ @database_path, *rest_arguments = arguments
+ begin
+ database = Database.open(@database_path)
+ rescue Error => error
+ $stderr.puts("Failed to open database: <#{@database_path}>")
+ $stderr.puts(error.message)
+ @succeeded = false
+ return
+ end
+
+ begin
+ yield(database, rest_arguments)
+ ensure
+ database.close
+ end
+ end
+
+ 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
+ recoverer.recover
+ rescue Error => error
+ failed("Failed to recover database: <#{@database_path}>",
+ error.message)
+ end
+ end
+
+ def check(database, options, arguments)
+ 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."
+ failed(message)
+ end
+
+ 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
+ return unless object.locked?
+ message =
+ "[#{object.name}] Index column is locked. " +
+ "It may be broken. " +
+ "Re-create index by '#{@program_path} recover #{@database_path}'."
+ failed(message)
+ when Column
+ return unless object.locked?
+ name = object.name
+ message =
+ "[#{name}] Data column is locked. " +
+ "It may be broken. " +
+ "(1) Truncate the column (truncate #{name}) or " +
+ "clear lock of the column (lock_clear #{name}) " +
+ "and (2) load data again."
+ failed(message)
+ when Table
+ return unless object.locked?
+ name = object.name
+ message =
+ "[#{name}] Table is locked. " +
+ "It may be broken. " +
+ "(1) Truncate the table (truncate #{name}) or " +
+ "clear lock of the table (lock_clear #{name}) " +
+ "and (2) load data again."
+ 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
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/sources.am
new file mode 100644
index 00000000..759948ee
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/sources.am
@@ -0,0 +1,2 @@
+RUBY_SCRIPT_FILES = \
+ grndb.rb
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 00000000..7dad55a7
--- /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
new file mode 100644
index 00000000..b6f59dc3
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context.rb
@@ -0,0 +1,85 @@
+require "context/error_level"
+require "context/rc"
+
+module Groonga
+ class Context
+ def guard(fallback=nil)
+ begin
+ yield
+ rescue => error
+ logger.log_error(error)
+ fallback
+ end
+ end
+
+ def logger
+ @logger ||= Logger.new
+ end
+
+ def query_logger
+ @query_logger ||= QueryLogger.new
+ end
+
+ def writer
+ @writer ||= Writer.new
+ end
+
+ def set_groonga_error(groonga_error)
+ set_error_raw(groonga_error.class.rc,
+ ErrorLevel::ERROR,
+ groonga_error.message,
+ groonga_error.backtrace)
+ end
+
+ def record_error(rc, error)
+ rc = RC.find(rc) if rc.is_a?(Symbol)
+ set_error_raw(rc, ErrorLevel::ERROR, error.message, error.backtrace)
+
+ 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
+ self.error_level = error_level.to_i
+
+ self.error_message = message
+
+ if backtrace
+ entry = BacktraceEntry.parse(backtrace.first)
+ self.error_file = entry.file
+ self.error_line = entry.line
+ self.error_method = entry.method
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/Makefile.am
new file mode 100644
index 00000000..8d862082
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/Makefile.am
@@ -0,0 +1,9 @@
+include sources.am
+
+EXTRA_DIST = \
+ $(RUBY_SCRIPT_FILES)
+
+if WITH_MRUBY
+ruby_scripts_contextdir = $(ruby_scriptsdir)/context
+ruby_scripts_context_DATA = $(RUBY_SCRIPT_FILES)
+endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/error_level.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/error_level.rb
new file mode 100644
index 00000000..c0685f16
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/error_level.rb
@@ -0,0 +1,30 @@
+module Groonga
+ class Context
+ class ErrorLevel
+ @@names = {}
+
+ class << self
+ def find(name)
+ @@names[name]
+ end
+ end
+
+ attr_reader :name
+ def initialize(name, level)
+ @@names[name] = self
+ @name = name
+ @level = level
+ end
+
+ def to_i
+ @level
+ end
+
+ EMERGENCY = new(:emergency, 1)
+ ALERT = new(:alert, 2)
+ CRITICAL = new(:critical, 3)
+ ERROR = new(:error, 4)
+ WARNING = new(:warning, 5)
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/rc.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/rc.rb
new file mode 100644
index 00000000..45187c22
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/rc.rb
@@ -0,0 +1,205 @@
+module Groonga
+ class Context
+ class RC
+ @@codes = {}
+ @@names = {}
+
+ class << self
+ 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, error_class)
+ @@codes[code] = rc
+ @@names[name] = rc
+ error_class.rc = rc if error_class
+ rc
+ end
+ end
+
+ attr_reader :name
+ attr_reader :error_class
+ def initialize(name, code, error_class)
+ @name = name
+ @code = code
+ @error_class = error_class
+ end
+
+ def to_i
+ @code
+ end
+
+ SUCCESS =
+ register(:success, 0, nil)
+ END_OF_DATA =
+ register(:end_of_data, 1, EndOfData)
+ UNKNOWN_ERROR =
+ register(:unknown_error, -1, UnknownError)
+ OPERATION_NOT_PERMITTED =
+ register(:operation_not_permitted, -2, OperationNotPermitted)
+ NO_SUCH_FILE_OR_DIRECTORY =
+ register(:no_such_file_or_directory, -3, NoSuchFileOrDirectory)
+ NO_SUCH_PROCESS =
+ register(:no_such_process, -4, NoSuchProcess)
+ INTERRUPTED_FUNCTION_CALL =
+ register(:interrupted_function_call, -5, InterruptedFunctionCall)
+ INPUT_OUTPUT_ERROR =
+ register(:input_output_error, -6, InputOutputError)
+ NO_SUCH_DEVICE_OR_ADDRESS =
+ register(:no_such_device_or_address, -7, NoSuchDeviceOrAddress)
+ ARG_LIST_TOO_LONG =
+ register(:arg_list_too_long, -8, ArgListTooLong)
+ EXEC_FORMAT_ERROR =
+ register(:exec_format_error, -9, ExecFormatError)
+ BAD_FILE_DESCRIPTOR =
+ register(:bad_file_descriptor, -10, BadFileDescriptor)
+ NO_CHILD_PROCESSES =
+ register(:no_child_processes, -11, NoChildProcesses)
+ RESOURCE_TEMPORARILY_UNAVAILABLE =
+ register(:resource_temporarily_unavailable, -12,
+ ResourceTemporarilyUnavailable)
+ NOT_ENOUGH_SPACE =
+ register(:not_enough_space, -13, NotEnoughSpace)
+ PERMISSION_DENIED =
+ register(:permission_denied, -14, PermissionDenied)
+ BAD_ADDRESS =
+ register(:bad_address, -15, BadAddress)
+ RESOURCE_BUSY =
+ register(:resource_busy, -16, ResourceBusy)
+ FILE_EXISTS =
+ register(:file_exists, -17, FileExists)
+ IMPROPER_LINK =
+ register(:improper_link, -18, ImproperLink)
+ NO_SUCH_DEVICE =
+ register(:no_such_device, -19, NoSuchDevice)
+ NOT_DIRECTORY =
+ register(:not_directory, -20, NotDirectory)
+ IS_DIRECTORY =
+ register(:is_directory, -21, IsDirectory)
+ INVALID_ARGUMENT =
+ register(:invalid_argument, -22, InvalidArgument)
+ TOO_MANY_OPEN_FILES_IN_SYSTEM =
+ register(:too_many_open_files_in_system, -23, TooManyOpenFilesInSystem)
+ TOO_MANY_OPEN_FILES =
+ register(:too_many_open_files, -24, TooManyOpenFiles)
+ INAPPROPRIATE_IO_CONTROL_OPERATION =
+ register(:inappropriate_io_control_operation, -25,
+ InappropriateIOControlOperation)
+ FILE_TOO_LARGE =
+ register(:file_too_large, -26, FileTooLarge)
+ NO_SPACE_LEFT_ON_DEVICE =
+ register(:no_space_left_on_device, -27, NoSpaceLeftOnDevice)
+ INVALID_SEEK =
+ register(:invalid_seek, -28, InvalidSeek)
+ READ_ONLY_FILE_SYSTEM =
+ register(:read_only_file_system, -29, ReadOnlyFileSystem)
+ TOO_MANY_LINKS =
+ register(:too_many_links, -30, TooManyLinks)
+ BROKEN_PIPE =
+ register(:broken_pipe, -31, BrokenPipe)
+ DOMAIN_ERROR =
+ register(:domain_error, -32, DomainError)
+ RESULT_TOO_LARGE =
+ register(:result_too_large, -33, ResultTooLarge)
+ RESOURCE_DEADLOCK_AVOIDED =
+ register(:resource_deadlock_avoided, -34, ResourceDeadlockAvoided)
+ NO_MEMORY_AVAILABLE =
+ register(:no_memory_available, -35, NoMemoryAvailable)
+ FILENAME_TOO_LONG =
+ register(:filename_too_long, -36, FilenameTooLong)
+ NO_LOCKS_AVAILABLE =
+ register(:no_locks_available, -37, NoLocksAvailable)
+ FUNCTION_NOT_IMPLEMENTED =
+ register(:function_not_implemented, -38, FunctionNotImplemented)
+ DIRECTORY_NOT_EMPTY =
+ register(:directory_not_empty, -39, DirectoryNotEmpty)
+ ILLEGAL_BYTE_SEQUENCE =
+ register(:illegal_byte_sequence, -40, IllegalByteSequence)
+ SOCKET_NOT_INITIALIZED =
+ register(:socket_not_initialized, -41, SocketNotInitialized)
+ OPERATION_WOULD_BLOCK =
+ register(:operation_would_block, -42, OperationWouldBlock)
+ ADDRESS_IS_NOT_AVAILABLE =
+ register(:address_is_not_available, -43, AddressIsNotAvailable)
+ NETWORK_IS_DOWN =
+ register(:network_is_down, -44, NetworkIsDown)
+ NO_BUFFER =
+ register(:no_buffer, -45, NoBuffer)
+ SOCKET_IS_ALREADY_CONNECTED =
+ register(:socket_is_already_connected, -46, SocketIsAlreadyConnected)
+ SOCKET_IS_NOT_CONNECTED =
+ register(:socket_is_not_connected, -47, SocketIsNotConnected)
+ SOCKET_IS_ALREADY_SHUTDOWNED =
+ register(:socket_is_already_shutdowned, -48, SocketIsAlreadyShutdowned)
+ OPERATION_TIMEOUT =
+ register(:operation_timeout, -49, OperationTimeout)
+ CONNECTION_REFUSED =
+ register(:connection_refused, -50, ConnectionRefused)
+ RANGE_ERROR =
+ register(:range_error, -51, RangeError)
+ TOKENIZER_ERROR =
+ register(:tokenizer_error, -52, TokenizerError)
+ FILE_CORRUPT =
+ register(:file_corrupt, -53, FileCorrupt)
+ INVALID_FORMAT =
+ register(:invalid_format, -54, InvalidFormat)
+ OBJECT_CORRUPT =
+ register(:object_corrupt, -55, ObjectCorrupt)
+ TOO_MANY_SYMBOLIC_LINKS =
+ register(:too_many_symbolic_links, -56, TooManySymbolicLinks)
+ NOT_SOCKET =
+ register(:not_socket, -57, NotSocket)
+ OPERATION_NOT_SUPPORTED =
+ register(:operation_not_supported, -58, OperationNotSupported)
+ ADDRESS_IS_IN_USE =
+ register(:address_is_in_use, -59, AddressIsInUse)
+ ZLIB_ERROR =
+ register(:zlib_error, -60, ZlibError)
+ LZ4_ERROR =
+ register(:lz4_error, -61, LZ4Error)
+ STACK_OVER_FLOW =
+ register(:stack_over_flow, -62, StackOverFlow)
+ SYNTAX_ERROR =
+ register(:syntax_error, -63, SyntaxError)
+ RETRY_MAX =
+ register(:retry_max, -64, RetryMax)
+ INCOMPATIBLE_FILE_FORMAT =
+ register(:incompatible_file_format, -65, IncompatibleFileFormat)
+ UPDATE_NOT_ALLOWED =
+ register(:update_not_allowed, -66, UpdateNotAllowed)
+ TOO_SMALL_OFFSET =
+ register(:too_small_offset, -67, TooSmallOffset)
+ TOO_LARGE_OFFSET =
+ register(:too_large_offset, -68, TooLargeOffset)
+ TOO_SMALL_LIMIT =
+ register(:too_small_limit, -69, TooSmallLimit)
+ CAS_ERROR =
+ register(:cas_error, -70, CASError)
+ UNSUPPORTED_COMMAND_VERSION =
+ register(:unsupported_command_version, -71, UnsupportedCommandVersion)
+ NORMALIZER_ERROR =
+ register(:normalizer_error, -72, NormalizerError)
+ TOKEN_FILTER_ERROR =
+ register(:token_filter_error, -73, TokenFilterError)
+ COMMAND_ERROR =
+ 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
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/sources.am
new file mode 100644
index 00000000..1f0d1624
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/context/sources.am
@@ -0,0 +1,3 @@
+RUBY_SCRIPT_FILES = \
+ error_level.rb \
+ rc.rb
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/database.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/database.rb
new file mode 100644
index 00000000..e0c6b4a0
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/database.rb
@@ -0,0 +1,65 @@
+module Groonga
+ class Database
+ def each_raw(options=nil)
+ return to_enum(__method__, options) unless block_given?
+
+ 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 order == :descending
+ flags |= TableCursorFlags::DESCENDING
+ else
+ flags |= TableCursorFlags::ASCENDING
+ end
+ if order_by == :id
+ flags |= TableCursorFlags::BY_ID
+ else
+ flags |= TableCursorFlags::BY_KEY
+ end
+ flags |= TableCursorFlags::PREFIX if min
+ TableCursor.open(self, :min => min, :flags => flags) do |cursor|
+ cursor.each do |id|
+ 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/error.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/error.rb
new file mode 100644
index 00000000..e39c9045
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/error.rb
@@ -0,0 +1,16 @@
+module Groonga
+ class GroongaError
+ class << self
+ def rc
+ @rc
+ end
+
+ def rc=(rc)
+ @rc = rc
+ end
+ end
+ end
+
+ class ErrorMessage < Error
+ 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
new file mode 100644
index 00000000..05c7ee8d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/eval_context.rb
@@ -0,0 +1,18 @@
+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?
+
+ object = Context.instance[id.to_s]
+ return super if object.nil?
+
+ object
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression.rb
new file mode 100644
index 00000000..27dadcb7
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression.rb
@@ -0,0 +1,68 @@
+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 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, record_exist)
+ builder.build
+ rescue => error
+ context.record_error(:invalid_argument, error)
+ nil
+ end
+ end
+
+ def estimate_size(table)
+ begin
+ estimator = ExpressionSizeEstimator.new(self, table)
+ estimator.estimate
+ rescue GroongaError => groonga_error
+ context.set_groonga_error(groonga_error)
+ table.size
+ rescue => error
+ context.record_error(:unknown_error, error)
+ table.size
+ end
+ end
+
+ private
+ def context
+ @context ||= Context.instance
+ end
+ 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 00000000..8f56ca7c
--- /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 00000000..ae773541
--- /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
new file mode 100644
index 00000000..597b56f9
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb
@@ -0,0 +1,54 @@
+module Groonga
+ class ExpressionSizeEstimator
+ def initialize(expression, table)
+ @expression = expression
+ @table = table
+ @table_size = @table.size
+ end
+
+ def estimate
+ builder = ScanInfoBuilder.new(@expression, Operator::OR, false)
+ data_list = builder.build
+ return @table_size if data_list.nil?
+
+ current_size = 0
+ sizes = []
+ data_list.each do |data|
+ if (data.flags & ScanInfo::Flags::POP) != 0
+ size = sizes.pop
+ case data.logical_op
+ when Operator::AND, Operator::AND_NOT
+ 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
+ else
+ if (data.flags & ScanInfo::Flags::PUSH) != 0
+ sizes.push(current_size)
+ current_size = 0
+ end
+
+ 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
+ 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 00000000..124ace0e
--- /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 00000000..1235932f
--- /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 00000000..ac4b122f
--- /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 00000000..d59c65c7
--- /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 00000000..228a1fc8
--- /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 00000000..0c7438d6
--- /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 00000000..c62a8d19
--- /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 00000000..e8d494f8
--- /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 00000000..1504b57a
--- /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 00000000..1d63149c
--- /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 00000000..d8a776bf
--- /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 00000000..e99ad9a8
--- /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 00000000..f2cc297c
--- /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 00000000..4fab9fb7
--- /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 00000000..a49e4fde
--- /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/index_column.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/index_column.rb
new file mode 100644
index 00000000..25ebc149
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/index_column.rb
@@ -0,0 +1,39 @@
+module Groonga
+ class IndexColumn
+ private :estimate_size_for_term_id
+ private :estimate_size_for_query
+ private :estimate_size_for_lexicon_cursor
+
+ # Estimate the number of matched records for term ID or query.
+ #
+ # @overload estimate_size(:term_id => term_id)
+ # @return [Integer] the number of matched records for the term ID.
+ #
+ # @overload estimate_size(:query => query)
+ # @return [Integer] the number of matched records for the query.
+ #
+ # @overload estimate_size(:lexicon_cursor => lexicon_cursor)
+ # @return [Integer] the number of matched records for the lexicon cursor.
+ #
+ def estimate_size(parameters)
+ term_id = parameters[:term_id]
+ if term_id
+ return estimate_size_for_term_id(term_id)
+ end
+
+ query = parameters[:query]
+ if query
+ return estimate_size_for_query(query, parameters)
+ end
+
+ lexicon_cursor = parameters[:lexicon_cursor]
+ if lexicon_cursor
+ return estimate_size_for_lexicon_cursor(lexicon_cursor)
+ end
+
+ message =
+ "must specify :term_id, :query, :lexicon_cursor: #{parameters.inspect}"
+ raise InvalidArgument, message
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/index_cursor.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/index_cursor.rb
new file mode 100644
index 00000000..80440669
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/index_cursor.rb
@@ -0,0 +1,18 @@
+module Groonga
+ class IndexCursor
+ class << self
+ def open(*arguments)
+ cursor = open_raw(*arguments)
+ if block_given?
+ begin
+ yield(cursor)
+ ensure
+ cursor.close
+ end
+ else
+ cursor
+ end
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/index_info.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/index_info.rb
new file mode 100644
index 00000000..cf8336e5
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/index_info.rb
@@ -0,0 +1,10 @@
+module Groonga
+ class IndexInfo
+ attr_reader :index
+ attr_reader :section_id
+ def initialize(index, section_id)
+ @index = index
+ @section_id = section_id
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/Makefile.am
new file mode 100644
index 00000000..e7531fdc
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/Makefile.am
@@ -0,0 +1,9 @@
+include sources.am
+
+EXTRA_DIST = \
+ $(RUBY_SCRIPT_FILES)
+
+if WITH_MRUBY
+ruby_scripts_initializedir = $(ruby_scriptsdir)/initialize
+ruby_scripts_initialize_DATA = $(RUBY_SCRIPT_FILES)
+endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb
new file mode 100644
index 00000000..c1215f3e
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb
@@ -0,0 +1,28 @@
+require "error"
+
+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"
+
+require "expression"
+
+require "plugin_loader"
+
+require "eval_context"
+
+require "command_line_parser"
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/pre.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/pre.rb
new file mode 100644
index 00000000..99300d11
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/pre.rb
@@ -0,0 +1,3 @@
+require "backtrace_entry"
+
+require "operator"
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/sources.am
new file mode 100644
index 00000000..3c26e19b
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/sources.am
@@ -0,0 +1,3 @@
+RUBY_SCRIPT_FILES = \
+ pre.rb \
+ post.rb
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger.rb
new file mode 100644
index 00000000..95f86974
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger.rb
@@ -0,0 +1,34 @@
+module Groonga
+ class Logger
+ def log_error(error)
+ log_level = Level::ERROR.to_i
+
+ if error.is_a?(Error)
+ message = error.message
+ else
+ message = "#{error.class}: #{error.message}"
+ end
+ backtrace = error.backtrace
+ 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 = ""
+ line = 0
+ method = ""
+ end
+ log(log_level, file, line, method, message)
+
+ backtrace.each_with_index do |raw_entry, i|
+ entry = BacktraceEntry.parse(raw_entry)
+ message = entry.message
+ message = raw_entry if message.empty?
+ log(log_level, entry.file, entry.line, entry.method, raw_entry)
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/Makefile.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/Makefile.am
new file mode 100644
index 00000000..448e72ca
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/Makefile.am
@@ -0,0 +1,9 @@
+include sources.am
+
+EXTRA_DIST = \
+ $(RUBY_SCRIPT_FILES)
+
+if WITH_MRUBY
+ruby_scripts_loggerdir = $(ruby_scriptsdir)/logger
+ruby_scripts_logger_DATA = $(RUBY_SCRIPT_FILES)
+endif
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/level.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/level.rb
new file mode 100644
index 00000000..4b8afa2c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/level.rb
@@ -0,0 +1,40 @@
+module Groonga
+ class Logger
+ class Level
+ @@names = {}
+ @@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
+
+ def to_i
+ @level
+ end
+
+ NONE = new(:none, 0)
+ EMERG = new(:emerg, 1)
+ ALERT = new(:alert, 2)
+ CRIT = new(:crit, 3)
+ ERROR = new(:error, 4)
+ WARNING = new(:warning, 5)
+ NOTICE = new(:notice, 6)
+ INFO = new(:info, 7)
+ DEBUG = new(:debug, 8)
+ DUMP = new(:dump, 9)
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/sources.am
new file mode 100644
index 00000000..7231ee4e
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/logger/sources.am
@@ -0,0 +1,2 @@
+RUBY_SCRIPT_FILES = \
+ level.rb
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/object.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/object.rb
new file mode 100644
index 00000000..aa8e9e65
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/object.rb
@@ -0,0 +1,18 @@
+module Groonga
+ class Object
+ def domain
+ Context.instance[domain_id]
+ end
+
+ 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/operator.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/operator.rb
new file mode 100644
index 00000000..349695e1
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/operator.rb
@@ -0,0 +1,22 @@
+module Groonga
+ class Operator
+ @values = {}
+ class << self
+ def register(operator)
+ const_set(operator.name, operator)
+ @values[operator.value] = operator
+ end
+
+ def find(value)
+ @values[value]
+ end
+ end
+
+ attr_reader :name
+ attr_reader :value
+ def initialize(name, value)
+ @name = name
+ @value = value
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/plugin_loader.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/plugin_loader.rb
new file mode 100644
index 00000000..09b972f1
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/plugin_loader.rb
@@ -0,0 +1,14 @@
+module Groonga
+ class PluginLoader
+ class << self
+ def load_file(path)
+ begin
+ load(path)
+ rescue => error
+ Context.instance.record_error(:plugin_error, error)
+ nil
+ end
+ end
+ 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 00000000..386ec0e2
--- /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 00000000..14b4f61c
--- /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 00000000..659570f6
--- /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 00000000..44871a85
--- /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 00000000..cd7d1a4c
--- /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
new file mode 100644
index 00000000..1352b327
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/require.rb
@@ -0,0 +1,71 @@
+$" = [__FILE__]
+
+class ScriptLoader
+ @@loading_paths = {}
+
+ def initialize(path)
+ @base_path = path
+ end
+
+ def load_once
+ if absolute_path?(@base_path)
+ loaded = load_once_path(@base_path)
+ if loaded.nil?
+ raise LoadError, error_message
+ else
+ loaded
+ end
+ else
+ $LOAD_PATH.each do |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?
+ end
+ raise LoadError, error_message
+ end
+ end
+
+ private
+ def error_message
+ "cannot load such file -- #{@base_path}"
+ end
+
+ def absolute_path?(path)
+ path.start_with?("/") or (/\A[a-z]:\\/i === path)
+ end
+
+ def load_once_path(path)
+ loaded = load_once_absolute_path(path)
+ return loaded unless loaded.nil?
+
+ return nil unless File.extname(path).empty?
+
+ load_once_absolute_path("#{path}.rb")
+ end
+
+ def load_once_absolute_path(path)
+ return false if $".include?(path)
+ return false if @@loading_paths.key?(path)
+
+ return nil unless File.file?(path)
+
+ @@loading_paths[path] = true
+ load(path)
+ $" << path
+ @@loading_paths.delete(path)
+
+ true
+ end
+end
+
+module Kernel
+ def require(path)
+ loader = ScriptLoader.new(path)
+ loader.load_once
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info.rb
new file mode 100644
index 00000000..acdb2eeb
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info.rb
@@ -0,0 +1,38 @@
+module Groonga
+ class ScanInfo
+ module Flags
+ ACCESSOR = 0x01
+ PUSH = 0x02
+ POP = 0x04
+ PRE_CONST = 0x08
+ end
+
+ def apply(data)
+ self.op = data.op
+ self.logical_op = data.logical_op
+ self.end = data.end
+ self.query = data.query
+ self.flags = data.flags
+ if data.max_interval
+ self.max_interval = data.max_interval
+ end
+ if data.similarity_threshold
+ self.similarity_threshold = data.similarity_threshold
+ end
+ data.args.each do |arg|
+ push_arg(arg)
+ end
+ data.search_indexes.each do |search_index|
+ put_index(search_index.index_column,
+ search_index.section_id,
+ search_index.weight,
+ search_index.scorer,
+ 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
new file mode 100644
index 00000000..66dad9ea
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_builder.rb
@@ -0,0 +1,577 @@
+require "scan_info_data"
+
+module Groonga
+ class ScanInfoBuilder
+ def initialize(expression, operator, record_exist)
+ @data_list = []
+ @expression = expression
+ @operator = operator
+ @record_exist = record_exist
+ @variable = @expression[0]
+ @table = Context.instance[@variable.domain]
+ end
+
+ 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 build
+ return nil unless valid?
+
+ 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
+ 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
+ context.data = nil
+ when *LOGICAL_OPERATORS
+ 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
+ context.status = :start
+ when Operator::PUSH
+ context.data ||= ScanInfoData.new(i)
+ data = context.data
+ if code.value == @variable
+ context.status = :var
+ else
+ data.args << code.value
+ if context.status == :start
+ data.flags |= ScanInfo::Flags::PRE_CONST
+ end
+ 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 context.status
+ when :start
+ context.data ||= ScanInfoData.new(i)
+ data = context.data
+ context.status = :column1
+ data.args << code.value
+ when :const, :var
+ context.status = :column1
+ data.args << code.value
+ 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
+ context.data ||= ScanInfoData.new(i)
+ data = context.data
+ if (code.flags & ExpressionCode::Flags::RELATIONAL_EXPRESSION) != 0 or
+ (not context.have_next?)
+ context.status = :start
+ data.op = code_op
+ data.end = i
+ data.call_relational_resolve_indexes
+ @data_list << data
+ context.data = nil
+ else
+ 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 !@record_exist
+ first_data = @data_list.first
+ if (first_data.flags & ScanInfo::Flags::PUSH) == 0 or
+ first_data.logical_op != @operator
+ raise ErrorMessage, "invalid expr"
+ else
+ first_data.flags &= ~ScanInfo::Flags::PUSH
+ first_data.logical_op = @operator
+ end
+ else
+ put_logical_op(@operator, context.n_codes)
+ end
+
+ optimize
+ end
+
+ private
+ def valid?
+ n_relation_expressions = 0
+ n_logical_expressions = 0
+ status = :start
+ codes = @expression.codes
+ codes.each_with_index do |code, i|
+ case code.op
+ when *RELATION_OPERATORS
+ if status == :start || status == :var
+ return false
+ end
+ status = :start
+ n_relation_expressions += 1
+ when *ARITHMETIC_OPERATORS
+ if status == :start || status == :var
+ return false
+ end
+ status = :start
+ return false if n_relation_expressions != (n_logical_expressions + 1)
+ when *LOGICAL_OPERATORS
+ 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.modify > 0 and
+ LOGICAL_OPERATORS.include?(codes[i + code.modify].op)
+ n_relation_expressions += 1
+ status = :start
+ else
+ if code.value == @variable
+ status = :var
+ else
+ status = :const
+ end
+ end
+ when Operator::GET_VALUE
+ case status
+ when :start, :const, :var
+ status = :column1
+ when :column1
+ status = :column2
+ when :column2
+ # Do nothing
+ else
+ return false
+ end
+ when Operator::CALL
+ if (code.flags & ExpressionCode::Flags::RELATIONAL_EXPRESSION) != 0 or
+ code == codes.last
+ status = :start
+ n_relation_expressions += 1
+ else
+ 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 != :start
+ return false if n_relation_expressions != (n_logical_expressions + 1)
+
+ true
+ end
+
+ def put_logical_op(operator, start)
+ n_parens = 1
+ n_dif_ops = 0
+ r = 0
+ j = @data_list.size
+ while j > 0
+ j -= 1
+ data = @data_list[j]
+ if (data.flags & ScanInfo::Flags::POP) != 0
+ n_dif_ops += 1
+ n_parens += 1
+ else
+ if (data.flags & ScanInfo::Flags::PUSH) != 0
+ n_parens -= 1
+ if n_parens == 0
+ if r == 0
+ if n_dif_ops > 0
+ if j > 0 and operator != Operator::AND_NOT
+ n_parens = 1
+ n_dif_ops = 0
+ r = j
+ else
+ new_data = ScanInfoData.new(start)
+ new_data.flags = ScanInfo::Flags::POP
+ new_data.logical_op = operator
+ @data_list << new_data
+ break
+ end
+ else
+ data.flags &= ~ScanInfo::Flags::PUSH
+ data.logical_op = operator
+ break
+ end
+ else
+ if n_dif_ops > 0
+ new_data = ScanInfoData.new(start)
+ new_data.flags = ScanInfo::Flags::POP
+ new_data.logical_op = operator
+ @data_list << new_data
+ else
+ data.flags &= ~ScanInfo::Flags::PUSH
+ data.logical_op = operator
+ @data_list =
+ @data_list[0...j] +
+ @data_list[r..-1] +
+ @data_list[j...r]
+ end
+ break
+ end
+ end
+ else
+ if operator == Operator::AND_NOT or operator != data.logical_op
+ n_dif_ops += 1
+ end
+ end
+ end
+
+ if j < 0
+ raise ErrorMessage, "unmatched nesting level"
+ end
+ 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
+ n = @data_list.size
+ while i < n
+ data = @data_list[i]
+ next_data = @data_list[i + 1]
+ i += 1
+ if next_data.nil?
+ optimized_data_list << data
+ next
+ end
+ if range_operations?(data, next_data)
+ between_data = create_between_data(data, next_data)
+ optimized_data_list << between_data
+ i += 1
+ next
+ end
+ optimized_data_list << data
+ end
+
+ 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)
+ return false unless next_data.logical_op == Operator::AND
+
+ op, next_op = data.op, next_data.op
+ return false if !(lower_condition?(op) or lower_condition?(next_op))
+ return false if !(upper_condition?(op) or upper_condition?(next_op))
+
+ return false if data.args[0] != next_data.args[0]
+
+ data_search_indexes = data.search_indexes
+ return false if data_search_indexes.empty?
+
+ data_search_indexes == next_data.search_indexes
+ end
+
+ def lower_condition?(operator)
+ case operator
+ when Operator::GREATER, Operator::GREATER_EQUAL
+ true
+ else
+ false
+ end
+ end
+
+ def upper_condition?(operator)
+ case operator
+ when Operator::LESS, Operator::LESS_EQUAL
+ true
+ else
+ false
+ 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
+ between_data.flags = data.flags
+ between_data.op = Operator::CALL
+ between_data.logical_op = data.logical_op
+ between_data.args = create_between_data_args(data, next_data)
+ between_data.search_indexes = data.search_indexes
+ between_data
+ end
+
+ def create_between_data_args(data, next_data)
+ between = Context.instance["between"]
+ @expression.take_object(between)
+ column = data.args[0]
+ op, next_op = data.op, next_data.op
+ if lower_condition?(op)
+ min = data.args[1]
+ min_operator = op
+ max = next_data.args[1]
+ max_operator = next_op
+ else
+ min = next_data.args[1]
+ min_operator = next_op
+ max = data.args[1]
+ max_operator = op
+ end
+ if min_operator == Operator::GREATER
+ min_border = "exclude"
+ else
+ min_border = "include"
+ end
+ if max_operator == Operator::LESS
+ max_border = "exclude"
+ else
+ max_border = "include"
+ end
+
+ [
+ between,
+ column,
+ min,
+ @expression.allocate_constant(min_border),
+ max,
+ @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
new file mode 100644
index 00000000..342f7a7a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_data.rb
@@ -0,0 +1,324 @@
+require "scan_info_search_index"
+
+module Groonga
+ class ScanInfoData
+ attr_accessor :start
+ attr_accessor :end
+ attr_accessor :op
+ attr_accessor :logical_op
+ attr_accessor :query
+ attr_accessor :args
+ attr_accessor :search_indexes
+ 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
+ @op = Operator::NOP
+ @logical_op = Operator::OR
+ @query = nil
+ @args = []
+ @search_indexes = []
+ @flags = ScanInfo::Flags::PUSH
+ @max_interval = nil
+ @similarity_threshold = nil
+ @start_position = nil
+ @weight = 0
+ end
+
+ def match_resolve_index
+ if near_search?
+ match_near_resolve_index
+ elsif similar_search?
+ match_similar_resolve_index
+ else
+ match_generic_resolve_index
+ end
+ end
+
+ def call_relational_resolve_indexes
+ 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
+
+ private
+ def near_search?
+ (@op == Operator::NEAR or @op == Operator::NEAR2) and @args.size == 3
+ end
+
+ def match_near_resolve_index
+ arg = @args[0]
+ case arg
+ when Expression
+ match_resolve_index_expression(arg)
+ when Accessor
+ match_resolve_index_accessor(arg)
+ when Indexable
+ match_resolve_index_indexable(arg)
+ else
+ message =
+ "The first argument of NEAR/NEAR2 must be Expression, Accessor or Indexable: #{arg.class}"
+ raise ErrorMessage, message
+ end
+
+ self.query = @args[1]
+ self.max_interval = @args[2].value
+ end
+
+ def similar_search?
+ @op == Operator::SIMILAR and @args.size == 3
+ end
+
+ def match_similar_resolve_index
+ arg = @args[0]
+ case arg
+ when Expression
+ match_resolve_index_expression(arg)
+ when Accessor
+ match_resolve_index_accessor(arg)
+ when Indexable
+ match_resolve_index_indexable(arg)
+ else
+ message =
+ "The first argument of SIMILAR must be Expression, Accessor or Indexable: #{arg.class}"
+ raise ErrorMesesage, message
+ end
+
+ self.query = @args[1]
+ self.similarity_threshold = @args[2].value
+ end
+
+ def match_generic_resolve_index
+ @args.each do |arg|
+ case arg
+ when Expression
+ match_resolve_index_expression(arg)
+ when Accessor
+ match_resolve_index_accessor(arg)
+ when IndexColumn
+ match_resolve_index_index_column(arg)
+ when Indexable
+ match_resolve_index_indexable(arg)
+ when Procedure
+ break
+ else
+ self.query = arg
+ end
+ end
+ if @op == Operator::REGEXP and not index_searchable_regexp?(@query)
+ @search_indexes.clear
+ end
+ end
+
+ def index_searchable_regexp?(pattern)
+ return false if pattern.nil?
+
+ previous_char = nil
+ pattern.value.each_char do |char|
+ if previous_char == "\\"
+ case char
+ when "Z"
+ return false
+ when "b", "B"
+ return false
+ when "d", "D", "h", "H", "p", "s", "S", "w", "W"
+ return false
+ when "X"
+ return false
+ when "k", "g", "1", "2", "3", "4", "5", "6", "7", "8", "9"
+ return false
+ when "\\"
+ previous_char = nil
+ next
+ end
+ else
+ case char
+ when ".", "[", "]", "|", "?", "+", "*", "{", "}", "^", "$", "(", ")"
+ return false
+ end
+ end
+ previous_char = char
+ end
+ true
+ end
+
+ def match_resolve_index_expression(expression)
+ codes = expression.codes
+ n_codes = codes.size
+ i = 0
+ while i < n_codes
+ i = match_resolve_index_expression_codes(expression, codes, i, n_codes)
+ end
+ end
+
+ def match_resolve_index_expression_codes(expression, codes, i, n_codes)
+ code = codes[i]
+ value = code.value
+ return i + 1 if value.nil?
+
+ case value
+ when Accessor, Column
+ index_info, offset =
+ match_resolve_index_expression_find_index(expression,
+ codes, i, n_codes)
+ i += offset - 1
+ if index_info
+ if value.is_a?(Accessor)
+ self.flags |= ScanInfo::Flags::ACCESSOR
+ end
+ weight, offset = codes[i].weight
+ i += offset
+ put_search_index(index_info.index, index_info.section_id, weight)
+ end
+ when Procedure
+ unless value.scorer?
+ message = "procedure must be scorer: #{scorer.name}>"
+ raise ErrorMessage, message
+ end
+ scorer = value
+ i += 1
+ index_info, offset =
+ match_resolve_index_expression_find_index(expression,
+ codes, i, n_codes)
+ i += offset
+ if index_info
+ scorer_args_expr_offset = 0
+ if codes[i].op != Operator::CALL
+ scorer_args_expr_offset = i
+ end
+ while i < n_codes and codes[i].op != Operator::CALL
+ i += 1
+ end
+ weight, offset = codes[i].weight
+ i += offset
+ 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}>"
+ end
+ i + 1
+ end
+
+ def match_resolve_index_expression_find_index(expression, codes, i, n_codes)
+ code = codes[i]
+ value = code.value
+ index_info = nil
+ offset = 1
+ case value
+ when Accessor
+ accessor = value
+ index_info = accessor.find_index(@op)
+ if index_info
+ if accessor.have_next? and index_info.index != accessor.object
+ index_info = IndexInfo.new(accessor, index_info.section_id)
+ end
+ end
+ when FixedSizeColumn, VariableSizeColumn
+ index_info = value.find_index(@op)
+ when IndexColumn
+ index = value
+ section_id = 0
+ rest_n_codes = n_codes - i
+ if rest_n_codes >= 2 and
+ codes[i + 1].value.is_a?(Bulk) and
+ (codes[i + 1].value.domain == ID::UINT32 or
+ codes[i + 1].value.domain == ID::INT32) and
+ codes[i + 2].op == Operator::GET_MEMBER
+ section_id = codes[i + 1].value.value + 1
+ offset += 2
+ end
+ index_info = IndexInfo.new(index, section_id)
+ end
+
+ [index_info, offset]
+ end
+
+ def match_resolve_index_expression_accessor(expr_code)
+ accessor = expr_code.value
+ self.flags |= ScanInfo::Flags::ACCESSOR
+ index_info = accessor.find_index(op)
+ return if index_info.nil?
+
+ section_id = index_info.section_id
+ weight = expr_code.weight
+ if accessor.next
+ put_search_index(accessor, section_id, weight)
+ else
+ put_search_index(index_info.index, section_id, weight)
+ end
+ end
+
+ def match_resolve_index_expression_data_column(expr_code)
+ column = expr_code.value
+ index_info = column.find_index(op)
+ return if index_info.nil?
+ put_search_index(index_info.index, index_info.section_id, expr_code.weight)
+ end
+
+ 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
+
+ def match_resolve_index_accessor(accessor)
+ self.flags |= ScanInfo::Flags::ACCESSOR
+ index_info = accessor.find_index(op)
+ return if index_info.nil?
+ if accessor.next
+ put_search_index(accessor, index_info.section_id, 1)
+ else
+ put_search_index(index_info.index, index_info.section_id, 1)
+ end
+ end
+
+ def call_relational_resolve_index(object, selector_op)
+ case object
+ when Accessor
+ call_relational_resolve_index_accessor(object, selector_op)
+ when Bulk
+ self.query = object
+ when Indexable
+ call_relational_resolve_index_indexable(object, selector_op)
+ end
+ end
+
+ 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, selector_op)
+ self.flags |= ScanInfo::Flags::ACCESSOR
+ 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, *args)
+ search_index = ScanInfoSearchIndex.new(index,
+ section_id,
+ weight + @weight,
+ *args)
+ @search_indexes << search_index
+ end
+ 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 00000000..5d3dc4e0
--- /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/scan_info_search_index.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_search_index.rb
new file mode 100644
index 00000000..a2818160
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/scan_info_search_index.rb
@@ -0,0 +1,9 @@
+module Groonga
+ class ScanInfoSearchIndex < Struct.new(:index_column,
+ :section_id,
+ :weight,
+ :scorer,
+ :scorer_args_expr,
+ :scorer_args_expr_offset)
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am
new file mode 100644
index 00000000..9a9e2bae
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am
@@ -0,0 +1,37 @@
+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 \
+ logger.rb \
+ 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
new file mode 100644
index 00000000..75c91894
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/table.rb
@@ -0,0 +1,144 @@
+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
+ ensure_sort_keys(keys) do |sort_keys|
+ sorted = Array.create("", self)
+ begin
+ sort_raw(sort_keys, offset, limit, sorted)
+ rescue Exception
+ sorted.close
+ raise
+ end
+ sorted
+ end
+ end
+
+ def group(keys, result)
+ ensure_sort_keys(keys) do |sort_keys|
+ group_raw(sort_keys, result)
+ 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)
+ end
+
+ converted_keys = []
+
+ begin
+ keys = [keys] unless keys.is_a?(::Array)
+ sort_keys = keys.collect do |key|
+ ensure_sort_key(key, converted_keys)
+ end
+ yield(sort_keys)
+ ensure
+ converted_keys.each do |converted_key|
+ converted_key.close
+ end
+ end
+ end
+
+ def ensure_sort_key(key, converted_keys)
+ return key if key.is_a?(TableSortKey)
+
+ sort_key = TableSortKey.new
+ converted_keys << sort_key
+
+ key_name = nil
+ order = :ascending
+ offset = 0
+ if key.is_a?(::Hash)
+ key_name = key[:key]
+ order = key[:order] || order
+ offset = key[:offset] || offset
+ else
+ key_name = key
+ end
+
+ case key_name
+ when String
+ # Do nothing
+ when Symbol
+ key_name = key_name.to_s
+ else
+ message = "sort key name must be String or Symbol: " +
+ "#{key_name.inspect}: #{key.inspect}"
+ raise ArgumentError, message
+ end
+
+ if key_name.start_with?("-")
+ key_name[0] = ""
+ order = :descending
+ elsif key_name.start_with?("+")
+ key_name[0] = ""
+ end
+
+ 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
+ sort_key.flags = Groonga::TableSortFlags::DESCENDING
+ end
+ sort_key.offset = offset
+ sort_key
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/table_cursor.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/table_cursor.rb
new file mode 100644
index 00000000..45949b71
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/table_cursor.rb
@@ -0,0 +1,28 @@
+module Groonga
+ class TableCursor
+ include Enumerable
+
+ class << self
+ def open(*arguments)
+ cursor = open_raw(*arguments)
+ if block_given?
+ begin
+ yield(cursor)
+ ensure
+ cursor.close
+ end
+ else
+ cursor
+ end
+ end
+ end
+
+ def each
+ loop do
+ id = self.next
+ return if id == Groonga::ID::NIL
+ yield(id)
+ end
+ end
+ end
+end
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 00000000..3d75502f
--- /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/scripts/writer.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/writer.rb
new file mode 100644
index 00000000..de2bc261
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/writer.rb
@@ -0,0 +1,21 @@
+module Groonga
+ class Writer
+ def array(name, n_elements)
+ open_array(name, n_elements)
+ begin
+ yield
+ ensure
+ close_array
+ end
+ end
+
+ def map(name, n_elements)
+ open_map(name, n_elements)
+ begin
+ yield
+ ensure
+ close_map
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/sources.am
new file mode 100644
index 00000000..9db16737
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/sources.am
@@ -0,0 +1,93 @@
+libgrnmrb_la_SOURCES = \
+ mrb_accessor.c \
+ mrb_accessor.h \
+ mrb_array.c \
+ 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 \
+ mrb_converter.h \
+ mrb_ctx.c \
+ mrb_ctx.h \
+ mrb_database.c \
+ mrb_database.h \
+ mrb_double_array_trie.c \
+ 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 \
+ mrb_fixed_size_column.h \
+ mrb_hash_table.c \
+ 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 \
+ mrb_index_cursor.h \
+ mrb_logger.c \
+ mrb_logger.h \
+ mrb_object.c \
+ mrb_object.h \
+ mrb_object_flags.c \
+ mrb_object_flags.h \
+ mrb_operator.c \
+ mrb_operator.h \
+ mrb_options.c \
+ 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 \
+ mrb_table_cursor.h \
+ mrb_table_cursor_flags.c \
+ mrb_table_cursor_flags.h \
+ mrb_table_group_flags.c \
+ mrb_table_group_flags.h \
+ mrb_table_group_result.c \
+ mrb_table_group_result.h \
+ mrb_table_sort_flags.c \
+ 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-custom-rules.txt b/storage/mroonga/vendor/groonga/lib/nfkc-custom-rules.txt
new file mode 100644
index 00000000..496751a5
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/nfkc-custom-rules.txt
@@ -0,0 +1 @@
+〜 ~
diff --git a/storage/mroonga/vendor/groonga/lib/nfkc.c b/storage/mroonga/vendor/groonga/lib/nfkc.c
new file mode 100644
index 00000000..e83fe610
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/nfkc.c
@@ -0,0 +1,45 @@
+/* -*- 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-1335 USA
+*/
+
+#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 *utf8)
+{
+ return grn_nfkc50_char_type(utf8);
+}
+
+const char *
+grn_nfkc_decompose(const unsigned char *utf8)
+{
+ return grn_nfkc50_decompose(utf8);
+}
+
+const char *
+grn_nfkc_compose(const unsigned char *prefix_utf8,
+ const unsigned char *suffix_utf8)
+{
+ 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
new file mode 100755
index 00000000..0c0e7fe7
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/nfkc.rb
@@ -0,0 +1,897 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+#
+# 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-1335 USA
+
+CUSTOM_RULE_PATH = 'nfkc-custom-rules.txt'
+
+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
+ @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
+ 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
+ }
+ 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
+ suffix[s] = {chars.join=>dst}
+ end
+ }
+ 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
+ end
+ 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
+ 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
+ default
+ end
+ 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 create_bc(option)
+ bc = {}
+ open("|./icudump --#{option}").each{|l|
+ src,_,code = l.chomp.split("\t")
+ str = src.split(':').collect(&:hex).pack("c*")
+ str.force_encoding("UTF-8")
+ bc[str] = code
+ }
+ bc
+end
+
+def ccpush(hash, src, dst)
+ head = src.shift
+ hash[head] = {} unless hash[head]
+ if head
+ ccpush(hash[head], src, dst)
+ else
+ hash[head] = dst
+ end
+end
+
+def subst(hash, str)
+ cand = nil
+ src = str.chars
+ for i in 0..src.size-1
+ h = hash
+ for j in i..src.size-1
+ head = src[j]
+ h = h[head]
+ break unless h
+ if h[nil]
+ cand = src[0,i].join("") + h[nil] + src[j + 1..-1].join("")
+ end
+ end
+ return cand if cand
+ end
+ return str
+end
+
+def map_entry(decompose, cc, src, dst)
+ dst.downcase! unless $case_sensitive
+ loop {
+ dst2 = subst(cc, dst)
+ break if dst2 == dst
+ dst = dst2
+ }
+ unless $keep_space
+ dst = $1 if dst =~ /^ +([^ ].*)$/
+ end
+ decompose[src] = dst if src != dst
+end
+
+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.chars, dst)
+ }
+ decompose_map = {}
+ open('|./icudump --nfkd').each{|l|
+ n,src,dst = l.chomp.split("\t")
+ 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(decompose_map, cc, src, dst)
+ }
+ end
+ unless $case_sensitive
+ for c in 'A'..'Z'
+ decompose_map[c] = c.downcase
+ end
+ end
+ return decompose_map
+end
+
+def create_compose_map(decompose_map)
+ cc = {}
+ open('|./icudump --cc').each{|l|
+ _,src,dst = l.chomp.split("\t")
+ 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
+ cc[src] = dst if src != dst
+ }
+ loop {
+ noccur = 0
+ cc2 = {}
+ cc.each {|src,dst|
+ src2 = src
+ 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 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 : '')
+ noccur += 1
+ end
+ end
+ end
+ cc2[src2] = dst if src2 != dst
+ }
+ cc = cc2
+ STDERR.puts("substituted #{noccur} patterns.")
+ break if noccur == 0
+ STDERR.puts('try again..')
+ }
+ return cc
+end
+
+######## main #######
+
+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
+}
+
+STDERR.puts('compiling icudump')
+system('cc -Wall -O3 -o icudump -I/tmp/local/include -L/tmp/local/lib icudump.c -licuuc -licui18n')
+
+STDERR.puts('getting Unicode version')
+unicode_version = `./icudump --version`.strip.gsub(".", "")
+
+STDERR.puts('creating bc..')
+bc = create_bc("gc")
+
+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-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-1335 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
+ HEADER
+
+ generator = generator_class.new(unicode_version, output)
+ generator.generate(bc, decompose_map, compose_map)
+
+ output.puts(<<-FOOTER)
+
+#endif /* GRN_WITH_NFKC */
+
+ 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 00000000..f734e832
--- /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-1335 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
new file mode 100644
index 00000000..7e69d684
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/normalizer.c
@@ -0,0 +1,1193 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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-1335 USA
+*/
+
+#include <string.h>
+
+#include "grn_normalizer.h"
+#include "grn_string.h"
+#include "grn_nfkc.h"
+#include <groonga/normalizer.h>
+#include <groonga/tokenizer.h>
+
+grn_rc
+grn_normalizer_register(grn_ctx *ctx,
+ const char *name_ptr,
+ int name_length,
+ grn_proc_func *init,
+ grn_proc_func *next,
+ grn_proc_func *fin)
+{
+ grn_expr_var vars[] = {
+ { NULL, 0 }
+ };
+ GRN_PTR_INIT(&vars[0].value, 0, GRN_ID_NIL);
+
+ if (name_length < 0) {
+ name_length = strlen(name_ptr);
+ }
+
+ {
+ grn_obj * const normalizer = grn_proc_create(ctx,
+ name_ptr, name_length,
+ GRN_PROC_NORMALIZER,
+ init, next, fin,
+ sizeof(*vars) / sizeof(vars),
+ vars);
+ if (!normalizer) {
+ GRN_PLUGIN_ERROR(ctx, GRN_NORMALIZER_ERROR,
+ "[normalizer] failed to register normalizer: <%.*s>",
+ name_length, name_ptr);
+ return ctx->rc;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_normalizer_init(void)
+{
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_normalizer_fin(void)
+{
+ return GRN_SUCCESS;
+}
+
+static unsigned char symbol[] = {
+ ',', '.', 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
+};
+
+inline static grn_obj *
+eucjp_normalize(grn_ctx *ctx, grn_string *nstr)
+{
+ static uint16_t hankana[] = {
+ 0xa1a1, 0xa1a3, 0xa1d6, 0xa1d7, 0xa1a2, 0xa1a6, 0xa5f2, 0xa5a1, 0xa5a3,
+ 0xa5a5, 0xa5a7, 0xa5a9, 0xa5e3, 0xa5e5, 0xa5e7, 0xa5c3, 0xa1bc, 0xa5a2,
+ 0xa5a4, 0xa5a6, 0xa5a8, 0xa5aa, 0xa5ab, 0xa5ad, 0xa5af, 0xa5b1, 0xa5b3,
+ 0xa5b5, 0xa5b7, 0xa5b9, 0xa5bb, 0xa5bd, 0xa5bf, 0xa5c1, 0xa5c4, 0xa5c6,
+ 0xa5c8, 0xa5ca, 0xa5cb, 0xa5cc, 0xa5cd, 0xa5ce, 0xa5cf, 0xa5d2, 0xa5d5,
+ 0xa5d8, 0xa5db, 0xa5de, 0xa5df, 0xa5e0, 0xa5e1, 0xa5e2, 0xa5e4, 0xa5e6,
+ 0xa5e8, 0xa5e9, 0xa5ea, 0xa5eb, 0xa5ec, 0xa5ed, 0xa5ef, 0xa5f3, 0xa1ab,
+ 0xa1eb
+ };
+ static unsigned char dakuten[] = {
+ 0xf4, 0, 0, 0, 0, 0xac, 0, 0xae, 0, 0xb0, 0, 0xb2, 0, 0xb4, 0, 0xb6, 0,
+ 0xb8, 0, 0xba, 0, 0xbc, 0, 0xbe, 0, 0xc0, 0, 0xc2, 0, 0, 0xc5, 0, 0xc7,
+ 0, 0xc9, 0, 0, 0, 0, 0, 0, 0xd0, 0, 0, 0xd3, 0, 0, 0xd6, 0, 0, 0xd9, 0,
+ 0, 0xdc
+ };
+ static unsigned char handaku[] = {
+ 0xd1, 0, 0, 0xd4, 0, 0, 0xd7, 0, 0, 0xda, 0, 0, 0xdd
+ };
+ int16_t *ch;
+ const unsigned char *s, *s_, *e;
+ unsigned char *d, *d0, *d_, b;
+ uint_least8_t *cp, *ctypes, ctype;
+ size_t size = nstr->original_length_in_bytes, length = 0;
+ int removeblankp = nstr->flags & GRN_STRING_REMOVE_BLANK;
+ if (!(nstr->normalized = GRN_MALLOC(size * 2 + 1))) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][eucjp] failed to allocate normalized text space");
+ return NULL;
+ }
+ d0 = (unsigned char *) nstr->normalized;
+ if (nstr->flags & GRN_STRING_WITH_CHECKS) {
+ if (!(nstr->checks = GRN_MALLOC(size * 2 * sizeof(int16_t) + 1))) {
+ GRN_FREE(nstr->normalized);
+ nstr->normalized = NULL;
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][eucjp] failed to allocate checks space");
+ return NULL;
+ }
+ }
+ ch = nstr->checks;
+ if (nstr->flags & GRN_STRING_WITH_TYPES) {
+ if (!(nstr->ctypes = GRN_MALLOC(size + 1))) {
+ GRN_FREE(nstr->checks);
+ GRN_FREE(nstr->normalized);
+ nstr->checks = NULL;
+ nstr->normalized = NULL;
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][eucjp] failed to allocate character types space");
+ return NULL;
+ }
+ }
+ cp = ctypes = nstr->ctypes;
+ e = (unsigned char *)nstr->original + size;
+ for (s = s_ = (unsigned char *) nstr->original, d = d_ = d0; s < e; s++) {
+ if ((*s & 0x80)) {
+ if (((s + 1) < e) && (*(s + 1) & 0x80)) {
+ unsigned char c1 = *s++, c2 = *s, c3 = 0;
+ switch (c1 >> 4) {
+ case 0x08 :
+ if (c1 == 0x8e && 0xa0 <= c2 && c2 <= 0xdf) {
+ uint16_t c = hankana[c2 - 0xa0];
+ switch (c) {
+ case 0xa1ab :
+ if (d > d0 + 1 && d[-2] == 0xa5
+ && 0xa6 <= d[-1] && d[-1] <= 0xdb && (b = dakuten[d[-1] - 0xa6])) {
+ *(d - 1) = b;
+ if (ch) { ch[-1] += 2; s_ += 2; }
+ continue;
+ } else {
+ *d++ = c >> 8; *d = c & 0xff;
+ }
+ break;
+ case 0xa1eb :
+ if (d > d0 + 1 && d[-2] == 0xa5
+ && 0xcf <= d[-1] && d[-1] <= 0xdb && (b = handaku[d[-1] - 0xcf])) {
+ *(d - 1) = b;
+ if (ch) { ch[-1] += 2; s_ += 2; }
+ continue;
+ } else {
+ *d++ = c >> 8; *d = c & 0xff;
+ }
+ break;
+ default :
+ *d++ = c >> 8; *d = c & 0xff;
+ break;
+ }
+ ctype = GRN_CHAR_KATAKANA;
+ } else {
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_OTHERS;
+ }
+ break;
+ case 0x09 :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_OTHERS;
+ break;
+ case 0x0a :
+ switch (c1 & 0x0f) {
+ case 1 :
+ switch (c2) {
+ case 0xbc :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_KATAKANA;
+ break;
+ case 0xb9 :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_KANJI;
+ break;
+ case 0xa1 :
+ if (removeblankp) {
+ if (cp > ctypes) { *(cp - 1) |= GRN_CHAR_BLANK; }
+ continue;
+ } else {
+ *d = ' ';
+ ctype = GRN_CHAR_BLANK|GRN_CHAR_SYMBOL;
+ }
+ break;
+ default :
+ if (c2 >= 0xa4 && (c3 = symbol[c2 - 0xa4])) {
+ *d = c3;
+ ctype = GRN_CHAR_SYMBOL;
+ } else {
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_OTHERS;
+ }
+ break;
+ }
+ break;
+ case 2 :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_SYMBOL;
+ break;
+ case 3 :
+ c3 = c2 - 0x80;
+ if ('a' <= c3 && c3 <= 'z') {
+ ctype = GRN_CHAR_ALPHA;
+ *d = c3;
+ } else if ('A' <= c3 && c3 <= 'Z') {
+ ctype = GRN_CHAR_ALPHA;
+ *d = c3 + 0x20;
+ } else if ('0' <= c3 && c3 <= '9') {
+ ctype = GRN_CHAR_DIGIT;
+ *d = c3;
+ } else {
+ ctype = GRN_CHAR_OTHERS;
+ *d++ = c1; *d = c2;
+ }
+ break;
+ case 4 :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_HIRAGANA;
+ break;
+ case 5 :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_KATAKANA;
+ break;
+ case 6 :
+ case 7 :
+ case 8 :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_SYMBOL;
+ break;
+ default :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_OTHERS;
+ break;
+ }
+ break;
+ default :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_KANJI;
+ break;
+ }
+ } else {
+ /* skip invalid character */
+ continue;
+ }
+ } else {
+ unsigned char c = *s;
+ switch (c >> 4) {
+ case 0 :
+ case 1 :
+ /* skip unprintable ascii */
+ if (cp > ctypes) { *(cp - 1) |= GRN_CHAR_BLANK; }
+ continue;
+ case 2 :
+ if (c == 0x20) {
+ if (removeblankp) {
+ if (cp > ctypes) { *(cp - 1) |= GRN_CHAR_BLANK; }
+ continue;
+ } else {
+ *d = ' ';
+ ctype = GRN_CHAR_BLANK|GRN_CHAR_SYMBOL;
+ }
+ } else {
+ *d = c;
+ ctype = GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 3 :
+ *d = c;
+ ctype = (c <= 0x39) ? GRN_CHAR_DIGIT : GRN_CHAR_SYMBOL;
+ break;
+ case 4 :
+ *d = ('A' <= c) ? c + 0x20 : c;
+ ctype = (c == 0x40) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 5 :
+ *d = (c <= 'Z') ? c + 0x20 : c;
+ ctype = (c <= 0x5a) ? GRN_CHAR_ALPHA : GRN_CHAR_SYMBOL;
+ break;
+ case 6 :
+ *d = c;
+ ctype = (c == 0x60) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 7 :
+ *d = c;
+ ctype = (c <= 0x7a) ? GRN_CHAR_ALPHA : (c == 0x7f ? GRN_CHAR_OTHERS : GRN_CHAR_SYMBOL);
+ break;
+ default :
+ *d = c;
+ ctype = GRN_CHAR_OTHERS;
+ break;
+ }
+ }
+ d++;
+ length++;
+ if (cp) { *cp++ = ctype; }
+ if (ch) {
+ *ch++ = (int16_t)(s + 1 - s_);
+ s_ = s + 1;
+ while (++d_ < d) { *ch++ = 0; }
+ }
+ }
+ if (cp) { *cp = GRN_CHAR_NULL; }
+ *d = '\0';
+ nstr->n_characters = length;
+ nstr->normalized_length_in_bytes = (size_t)(d - (unsigned char *)nstr->normalized);
+ return NULL;
+}
+
+inline static grn_obj *
+sjis_normalize(grn_ctx *ctx, grn_string *nstr)
+{
+ static uint16_t hankana[] = {
+ 0x8140, 0x8142, 0x8175, 0x8176, 0x8141, 0x8145, 0x8392, 0x8340, 0x8342,
+ 0x8344, 0x8346, 0x8348, 0x8383, 0x8385, 0x8387, 0x8362, 0x815b, 0x8341,
+ 0x8343, 0x8345, 0x8347, 0x8349, 0x834a, 0x834c, 0x834e, 0x8350, 0x8352,
+ 0x8354, 0x8356, 0x8358, 0x835a, 0x835c, 0x835e, 0x8360, 0x8363, 0x8365,
+ 0x8367, 0x8369, 0x836a, 0x836b, 0x836c, 0x836d, 0x836e, 0x8371, 0x8374,
+ 0x8377, 0x837a, 0x837d, 0x837e, 0x8380, 0x8381, 0x8382, 0x8384, 0x8386,
+ 0x8388, 0x8389, 0x838a, 0x838b, 0x838c, 0x838d, 0x838f, 0x8393, 0x814a,
+ 0x814b
+ };
+ static unsigned char dakuten[] = {
+ 0x94, 0, 0, 0, 0, 0x4b, 0, 0x4d, 0, 0x4f, 0, 0x51, 0, 0x53, 0, 0x55, 0,
+ 0x57, 0, 0x59, 0, 0x5b, 0, 0x5d, 0, 0x5f, 0, 0x61, 0, 0, 0x64, 0, 0x66,
+ 0, 0x68, 0, 0, 0, 0, 0, 0, 0x6f, 0, 0, 0x72, 0, 0, 0x75, 0, 0, 0x78, 0,
+ 0, 0x7b
+ };
+ static unsigned char handaku[] = {
+ 0x70, 0, 0, 0x73, 0, 0, 0x76, 0, 0, 0x79, 0, 0, 0x7c
+ };
+ int16_t *ch;
+ const unsigned char *s, *s_;
+ unsigned char *d, *d0, *d_, b, *e;
+ uint_least8_t *cp, *ctypes, ctype;
+ size_t size = nstr->original_length_in_bytes, length = 0;
+ int removeblankp = nstr->flags & GRN_STRING_REMOVE_BLANK;
+ if (!(nstr->normalized = GRN_MALLOC(size * 2 + 1))) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][sjis] failed to allocate normalized text space");
+ return NULL;
+ }
+ d0 = (unsigned char *) nstr->normalized;
+ if (nstr->flags & GRN_STRING_WITH_CHECKS) {
+ if (!(nstr->checks = GRN_MALLOC(size * 2 * sizeof(int16_t) + 1))) {
+ GRN_FREE(nstr->normalized);
+ nstr->normalized = NULL;
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][sjis] failed to allocate checks space");
+ return NULL;
+ }
+ }
+ ch = nstr->checks;
+ if (nstr->flags & GRN_STRING_WITH_TYPES) {
+ if (!(nstr->ctypes = GRN_MALLOC(size + 1))) {
+ GRN_FREE(nstr->checks);
+ GRN_FREE(nstr->normalized);
+ nstr->checks = NULL;
+ nstr->normalized = NULL;
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][sjis] failed to allocate character types space");
+ return NULL;
+ }
+ }
+ cp = ctypes = nstr->ctypes;
+ e = (unsigned char *)nstr->original + size;
+ for (s = s_ = (unsigned char *) nstr->original, d = d_ = d0; s < e; s++) {
+ if ((*s & 0x80)) {
+ if (0xa0 <= *s && *s <= 0xdf) {
+ uint16_t c = hankana[*s - 0xa0];
+ switch (c) {
+ case 0x814a :
+ if (d > d0 + 1 && d[-2] == 0x83
+ && 0x45 <= d[-1] && d[-1] <= 0x7a && (b = dakuten[d[-1] - 0x45])) {
+ *(d - 1) = b;
+ if (ch) { ch[-1]++; s_++; }
+ continue;
+ } else {
+ *d++ = c >> 8; *d = c & 0xff;
+ }
+ break;
+ case 0x814b :
+ if (d > d0 + 1 && d[-2] == 0x83
+ && 0x6e <= d[-1] && d[-1] <= 0x7a && (b = handaku[d[-1] - 0x6e])) {
+ *(d - 1) = b;
+ if (ch) { ch[-1]++; s_++; }
+ continue;
+ } else {
+ *d++ = c >> 8; *d = c & 0xff;
+ }
+ break;
+ default :
+ *d++ = c >> 8; *d = c & 0xff;
+ break;
+ }
+ ctype = GRN_CHAR_KATAKANA;
+ } else {
+ if ((s + 1) < e && 0x40 <= *(s + 1) && *(s + 1) <= 0xfc) {
+ unsigned char c1 = *s++, c2 = *s, c3 = 0;
+ if (0x81 <= c1 && c1 <= 0x87) {
+ switch (c1 & 0x0f) {
+ case 1 :
+ switch (c2) {
+ case 0x5b :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_KATAKANA;
+ break;
+ case 0x58 :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_KANJI;
+ break;
+ case 0x40 :
+ if (removeblankp) {
+ if (cp > ctypes) { *(cp - 1) |= GRN_CHAR_BLANK; }
+ continue;
+ } else {
+ *d = ' ';
+ ctype = GRN_CHAR_BLANK|GRN_CHAR_SYMBOL;
+ }
+ break;
+ default :
+ if (0x43 <= c2 && c2 <= 0x7e && (c3 = symbol[c2 - 0x43])) {
+ *d = c3;
+ ctype = GRN_CHAR_SYMBOL;
+ } else if (0x7f <= c2 && c2 <= 0x97 && (c3 = symbol[c2 - 0x44])) {
+ *d = c3;
+ ctype = GRN_CHAR_SYMBOL;
+ } else {
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_OTHERS;
+ }
+ break;
+ }
+ break;
+ case 2 :
+ c3 = c2 - 0x1f;
+ if (0x4f <= c2 && c2 <= 0x58) {
+ ctype = GRN_CHAR_DIGIT;
+ *d = c2 - 0x1f;
+ } else if (0x60 <= c2 && c2 <= 0x79) {
+ ctype = GRN_CHAR_ALPHA;
+ *d = c2 + 0x01;
+ } else if (0x81 <= c2 && c2 <= 0x9a) {
+ ctype = GRN_CHAR_ALPHA;
+ *d = c2 - 0x20;
+ } else if (0x9f <= c2 && c2 <= 0xf1) {
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_HIRAGANA;
+ } else {
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_OTHERS;
+ }
+ break;
+ case 3 :
+ if (0x40 <= c2 && c2 <= 0x96) {
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_KATAKANA;
+ } else {
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 4 :
+ case 7 :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_SYMBOL;
+ break;
+ default :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_OTHERS;
+ break;
+ }
+ } else {
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_KANJI;
+ }
+ } else {
+ /* skip invalid character */
+ continue;
+ }
+ }
+ } else {
+ unsigned char c = *s;
+ switch (c >> 4) {
+ case 0 :
+ case 1 :
+ /* skip unprintable ascii */
+ if (cp > ctypes) { *(cp - 1) |= GRN_CHAR_BLANK; }
+ continue;
+ case 2 :
+ if (c == 0x20) {
+ if (removeblankp) {
+ if (cp > ctypes) { *(cp - 1) |= GRN_CHAR_BLANK; }
+ continue;
+ } else {
+ *d = ' ';
+ ctype = GRN_CHAR_BLANK|GRN_CHAR_SYMBOL;
+ }
+ } else {
+ *d = c;
+ ctype = GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 3 :
+ *d = c;
+ ctype = (c <= 0x39) ? GRN_CHAR_DIGIT : GRN_CHAR_SYMBOL;
+ break;
+ case 4 :
+ *d = ('A' <= c) ? c + 0x20 : c;
+ ctype = (c == 0x40) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 5 :
+ *d = (c <= 'Z') ? c + 0x20 : c;
+ ctype = (c <= 0x5a) ? GRN_CHAR_ALPHA : GRN_CHAR_SYMBOL;
+ break;
+ case 6 :
+ *d = c;
+ ctype = (c == 0x60) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 7 :
+ *d = c;
+ ctype = (c <= 0x7a) ? GRN_CHAR_ALPHA : (c == 0x7f ? GRN_CHAR_OTHERS : GRN_CHAR_SYMBOL);
+ break;
+ default :
+ *d = c;
+ ctype = GRN_CHAR_OTHERS;
+ break;
+ }
+ }
+ d++;
+ length++;
+ if (cp) { *cp++ = ctype; }
+ if (ch) {
+ *ch++ = (int16_t)(s + 1 - s_);
+ s_ = s + 1;
+ while (++d_ < d) { *ch++ = 0; }
+ }
+ }
+ if (cp) { *cp = GRN_CHAR_NULL; }
+ *d = '\0';
+ nstr->n_characters = length;
+ nstr->normalized_length_in_bytes = (size_t)(d - (unsigned char *)nstr->normalized);
+ return NULL;
+}
+
+#ifdef GRN_WITH_NFKC
+static inline int
+grn_str_charlen_utf8(grn_ctx *ctx, const unsigned char *str, const unsigned char *end)
+{
+ /* MEMO: This function allows non-null-terminated string as str. */
+ /* But requires the end of string. */
+ const unsigned char *p = str;
+ if (end <= p || !*p) { return 0; }
+ if (*p & 0x80) {
+ int b, w;
+ int size;
+ int i;
+ for (b = 0x40, w = 0; b && (*p & b); b >>= 1, w++);
+ if (!w) {
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "invalid utf8 string: the first bit is 0x80: <%.*s>: <%.*s>",
+ (int)(end - p), p,
+ (int)(end - str), str);
+ return 0;
+ }
+ size = w + 1;
+ for (i = 1; i < size; i++) {
+ if (++p >= end) {
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "invalid utf8 string: too short: "
+ "%d byte is required but %d byte is given: <%.*s>",
+ size, i,
+ (int)(end - str), str);
+ return 0;
+ }
+ if (!*p) {
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "invalid utf8 string: NULL character is found: <%.*s>",
+ (int)(end - str), str);
+ return 0;
+ }
+ if ((*p & 0xc0) != 0x80) {
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "invalid utf8 string: 0x80 is not allowed: <%.*s>: <%.*s>",
+ (int)(end - p), p,
+ (int)(end - str), str);
+ return 0;
+ }
+ }
+ return size;
+ } else {
+ return 1;
+ }
+ return 0;
+}
+
+inline static grn_obj *
+utf8_normalize(grn_ctx *ctx, grn_string *nstr)
+{
+ int16_t *ch;
+ const unsigned char *s, *s_, *s__ = NULL, *p, *p2, *pe, *e;
+ unsigned char *d, *d_, *de;
+ uint_least8_t *cp;
+ size_t length = 0, ls, lp, size = nstr->original_length_in_bytes, ds = size * 3;
+ int removeblankp = nstr->flags & GRN_STRING_REMOVE_BLANK;
+ grn_bool remove_tokenized_delimiter_p =
+ nstr->flags & GRN_STRING_REMOVE_TOKENIZED_DELIMITER;
+ if (!(nstr->normalized = GRN_MALLOC(ds + 1))) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][utf8] failed to allocate normalized text space");
+ return NULL;
+ }
+ if (nstr->flags & GRN_STRING_WITH_CHECKS) {
+ if (!(nstr->checks = GRN_MALLOC(ds * sizeof(int16_t) + 1))) {
+ GRN_FREE(nstr->normalized);
+ nstr->normalized = NULL;
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][utf8] failed to allocate checks space");
+ return NULL;
+ }
+ }
+ ch = nstr->checks;
+ if (nstr->flags & GRN_STRING_WITH_TYPES) {
+ if (!(nstr->ctypes = GRN_MALLOC(ds + 1))) {
+ if (nstr->checks) { GRN_FREE(nstr->checks); nstr->checks = NULL; }
+ GRN_FREE(nstr->normalized); nstr->normalized = NULL;
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][utf8] failed to allocate character types space");
+ return NULL;
+ }
+ }
+ cp = nstr->ctypes;
+ d = (unsigned char *)nstr->normalized;
+ de = d + ds;
+ d_ = NULL;
+ e = (unsigned char *)nstr->original + size;
+ for (s = s_ = (unsigned char *)nstr->original; ; s += ls) {
+ if (!(ls = grn_str_charlen_utf8(ctx, s, e))) {
+ break;
+ }
+ if (remove_tokenized_delimiter_p &&
+ grn_tokenizer_is_tokenized_delimiter(ctx, (const char *)s, ls,
+ GRN_ENC_UTF8)) {
+ continue;
+ }
+ 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_compose(d_, p))) {
+ p = p2;
+ pe = p + strlen((char *)p);
+ if (cp) { cp--; }
+ if (ch) {
+ ch -= (d - d_);
+ if (ch[0] >= 0) {
+ s_ = s__;
+ }
+ }
+ d = d_;
+ length--;
+ }
+ for (; ; p += lp) {
+ if (!(lp = grn_str_charlen_utf8(ctx, p, pe))) {
+ break;
+ }
+ if ((*p == ' ' && removeblankp) || *p < 0x20 /* skip unprintable ascii */ ) {
+ if (cp > nstr->ctypes) { *(cp - 1) |= GRN_CHAR_BLANK; }
+ } else {
+ if (de <= d + lp) {
+ unsigned char *normalized;
+ ds += (ds >> 1) + lp;
+ if (!(normalized = GRN_REALLOC(nstr->normalized, ds + 1))) {
+ if (nstr->ctypes) { GRN_FREE(nstr->ctypes); nstr->ctypes = NULL; }
+ if (nstr->checks) { GRN_FREE(nstr->checks); nstr->checks = NULL; }
+ GRN_FREE(nstr->normalized); nstr->normalized = NULL;
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][utf8] failed to expand normalized text space");
+ return NULL;
+ }
+ de = normalized + ds;
+ d = normalized + (d - (unsigned char *)nstr->normalized);
+ nstr->normalized = (char *)normalized;
+ if (ch) {
+ int16_t *checks;
+ if (!(checks = GRN_REALLOC(nstr->checks, ds * sizeof(int16_t) + 1))) {
+ if (nstr->ctypes) { GRN_FREE(nstr->ctypes); nstr->ctypes = NULL; }
+ GRN_FREE(nstr->checks); nstr->checks = NULL;
+ GRN_FREE(nstr->normalized); nstr->normalized = NULL;
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][utf8] failed to expand checks space");
+ return NULL;
+ }
+ ch = checks + (ch - nstr->checks);
+ nstr->checks = checks;
+ }
+ if (cp) {
+ uint_least8_t *ctypes;
+ if (!(ctypes = GRN_REALLOC(nstr->ctypes, ds + 1))) {
+ GRN_FREE(nstr->ctypes); nstr->ctypes = NULL;
+ if (nstr->checks) { GRN_FREE(nstr->checks); nstr->checks = NULL; }
+ GRN_FREE(nstr->normalized); nstr->normalized = NULL;
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][utf8] failed to expand character types space");
+ return NULL;
+ }
+ cp = ctypes + (cp - nstr->ctypes);
+ nstr->ctypes = ctypes;
+ }
+ }
+ grn_memcpy(d, p, lp);
+ d_ = d;
+ d += lp;
+ length++;
+ if (cp) { *cp++ = grn_nfkc_char_type(p); }
+ if (ch) {
+ size_t i;
+ if (s_ == s + ls) {
+ *ch++ = -1;
+ } else {
+ *ch++ = (int16_t)(s + ls - s_);
+ s__ = s_;
+ s_ = s + ls;
+ }
+ for (i = lp; i > 1; i--) { *ch++ = 0; }
+ }
+ }
+ }
+ }
+ if (cp) { *cp = GRN_CHAR_NULL; }
+ *d = '\0';
+ nstr->n_characters = length;
+ nstr->normalized_length_in_bytes = (size_t)(d - (unsigned char *)nstr->normalized);
+ return NULL;
+}
+#endif /* GRN_WITH_NFKC */
+
+inline static grn_obj *
+ascii_normalize(grn_ctx *ctx, grn_string *nstr)
+{
+ int16_t *ch;
+ const unsigned char *s, *s_, *e;
+ unsigned char *d, *d0, *d_;
+ uint_least8_t *cp, *ctypes, ctype;
+ size_t size = nstr->original_length_in_bytes, length = 0;
+ int removeblankp = nstr->flags & GRN_STRING_REMOVE_BLANK;
+ if (!(nstr->normalized = GRN_MALLOC(size + 1))) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][ascii] failed to allocate normalized text space");
+ return NULL;
+ }
+ d0 = (unsigned char *) nstr->normalized;
+ if (nstr->flags & GRN_STRING_WITH_CHECKS) {
+ if (!(nstr->checks = GRN_MALLOC(size * sizeof(int16_t) + 1))) {
+ GRN_FREE(nstr->normalized);
+ nstr->normalized = NULL;
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][ascii] failed to allocate checks space");
+ return NULL;
+ }
+ }
+ ch = nstr->checks;
+ if (nstr->flags & GRN_STRING_WITH_TYPES) {
+ if (!(nstr->ctypes = GRN_MALLOC(size + 1))) {
+ GRN_FREE(nstr->checks);
+ GRN_FREE(nstr->normalized);
+ nstr->checks = NULL;
+ nstr->normalized = NULL;
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][ascii] failed to allocate character types space");
+ return NULL;
+ }
+ }
+ cp = ctypes = nstr->ctypes;
+ e = (unsigned char *)nstr->original + size;
+ for (s = s_ = (unsigned char *) nstr->original, d = d_ = d0; s < e; s++) {
+ unsigned char c = *s;
+ switch (c >> 4) {
+ case 0 :
+ case 1 :
+ /* skip unprintable ascii */
+ if (cp > ctypes) { *(cp - 1) |= GRN_CHAR_BLANK; }
+ continue;
+ case 2 :
+ if (c == 0x20) {
+ if (removeblankp) {
+ if (cp > ctypes) { *(cp - 1) |= GRN_CHAR_BLANK; }
+ continue;
+ } else {
+ *d = ' ';
+ ctype = GRN_CHAR_BLANK|GRN_CHAR_SYMBOL;
+ }
+ } else {
+ *d = c;
+ ctype = GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 3 :
+ *d = c;
+ ctype = (c <= 0x39) ? GRN_CHAR_DIGIT : GRN_CHAR_SYMBOL;
+ break;
+ case 4 :
+ *d = ('A' <= c) ? c + 0x20 : c;
+ ctype = (c == 0x40) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 5 :
+ *d = (c <= 'Z') ? c + 0x20 : c;
+ ctype = (c <= 0x5a) ? GRN_CHAR_ALPHA : GRN_CHAR_SYMBOL;
+ break;
+ case 6 :
+ *d = c;
+ ctype = (c == 0x60) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 7 :
+ *d = c;
+ ctype = (c <= 0x7a) ? GRN_CHAR_ALPHA : (c == 0x7f ? GRN_CHAR_OTHERS : GRN_CHAR_SYMBOL);
+ break;
+ default :
+ *d = c;
+ ctype = GRN_CHAR_OTHERS;
+ break;
+ }
+ d++;
+ length++;
+ if (cp) { *cp++ = ctype; }
+ if (ch) {
+ *ch++ = (int16_t)(s + 1 - s_);
+ s_ = s + 1;
+ while (++d_ < d) { *ch++ = 0; }
+ }
+ }
+ if (cp) { *cp = GRN_CHAR_NULL; }
+ *d = '\0';
+ nstr->n_characters = length;
+ nstr->normalized_length_in_bytes = (size_t)(d - (unsigned char *)nstr->normalized);
+ return NULL;
+}
+
+/* use cp1252 as latin1 */
+inline static grn_obj *
+latin1_normalize(grn_ctx *ctx, grn_string *nstr)
+{
+ int16_t *ch;
+ const unsigned char *s, *s_, *e;
+ unsigned char *d, *d0, *d_;
+ uint_least8_t *cp, *ctypes, ctype;
+ size_t size = nstr->original_length_in_bytes, length = 0;
+ int removeblankp = nstr->flags & GRN_STRING_REMOVE_BLANK;
+ if (!(nstr->normalized = GRN_MALLOC(size + 1))) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][latin1] failed to allocate normalized text space");
+ return NULL;
+ }
+ d0 = (unsigned char *) nstr->normalized;
+ if (nstr->flags & GRN_STRING_WITH_CHECKS) {
+ if (!(nstr->checks = GRN_MALLOC(size * sizeof(int16_t) + 1))) {
+ GRN_FREE(nstr->normalized);
+ nstr->normalized = NULL;
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][latin1] failed to allocate checks space");
+ return NULL;
+ }
+ }
+ ch = nstr->checks;
+ if (nstr->flags & GRN_STRING_WITH_TYPES) {
+ if (!(nstr->ctypes = GRN_MALLOC(size + 1))) {
+ GRN_FREE(nstr->checks);
+ GRN_FREE(nstr->normalized);
+ nstr->checks = NULL;
+ nstr->normalized = NULL;
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[normalizer][latin1] failed to allocate character types space");
+ return NULL;
+ }
+ }
+ cp = ctypes = nstr->ctypes;
+ e = (unsigned char *)nstr->original + size;
+ for (s = s_ = (unsigned char *) nstr->original, d = d_ = d0; s < e; s++) {
+ unsigned char c = *s;
+ switch (c >> 4) {
+ case 0 :
+ case 1 :
+ /* skip unprintable ascii */
+ if (cp > ctypes) { *(cp - 1) |= GRN_CHAR_BLANK; }
+ continue;
+ case 2 :
+ if (c == 0x20) {
+ if (removeblankp) {
+ if (cp > ctypes) { *(cp - 1) |= GRN_CHAR_BLANK; }
+ continue;
+ } else {
+ *d = ' ';
+ ctype = GRN_CHAR_BLANK|GRN_CHAR_SYMBOL;
+ }
+ } else {
+ *d = c;
+ ctype = GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 3 :
+ *d = c;
+ ctype = (c <= 0x39) ? GRN_CHAR_DIGIT : GRN_CHAR_SYMBOL;
+ break;
+ case 4 :
+ *d = ('A' <= c) ? c + 0x20 : c;
+ ctype = (c == 0x40) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 5 :
+ *d = (c <= 'Z') ? c + 0x20 : c;
+ ctype = (c <= 0x5a) ? GRN_CHAR_ALPHA : GRN_CHAR_SYMBOL;
+ break;
+ case 6 :
+ *d = c;
+ ctype = (c == 0x60) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 7 :
+ *d = c;
+ ctype = (c <= 0x7a) ? GRN_CHAR_ALPHA : (c == 0x7f ? GRN_CHAR_OTHERS : GRN_CHAR_SYMBOL);
+ break;
+ case 8 :
+ if (c == 0x8a || c == 0x8c || c == 0x8e) {
+ *d = c + 0x10;
+ ctype = GRN_CHAR_ALPHA;
+ } else {
+ *d = c;
+ ctype = GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 9 :
+ if (c == 0x9a || c == 0x9c || c == 0x9e || c == 0x9f) {
+ *d = (c == 0x9f) ? c + 0x60 : c;
+ ctype = GRN_CHAR_ALPHA;
+ } else {
+ *d = c;
+ ctype = GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 0x0c :
+ *d = c + 0x20;
+ ctype = GRN_CHAR_ALPHA;
+ break;
+ case 0x0d :
+ *d = (c == 0xd7 || c == 0xdf) ? c : c + 0x20;
+ ctype = (c == 0xd7) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 0x0e :
+ *d = c;
+ ctype = GRN_CHAR_ALPHA;
+ break;
+ case 0x0f :
+ *d = c;
+ ctype = (c == 0xf7) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ default :
+ *d = c;
+ ctype = GRN_CHAR_OTHERS;
+ break;
+ }
+ d++;
+ length++;
+ if (cp) { *cp++ = ctype; }
+ if (ch) {
+ *ch++ = (int16_t)(s + 1 - s_);
+ s_ = s + 1;
+ while (++d_ < d) { *ch++ = 0; }
+ }
+ }
+ if (cp) { *cp = GRN_CHAR_NULL; }
+ *d = '\0';
+ nstr->n_characters = length;
+ nstr->normalized_length_in_bytes = (size_t)(d - (unsigned char *)nstr->normalized);
+ return NULL;
+}
+
+inline static grn_obj *
+koi8r_normalize(grn_ctx *ctx, grn_string *nstr)
+{
+ int16_t *ch;
+ const unsigned char *s, *s_, *e;
+ unsigned char *d, *d0, *d_;
+ uint_least8_t *cp, *ctypes, ctype;
+ size_t size = nstr->original_length_in_bytes, length = 0;
+ int removeblankp = nstr->flags & GRN_STRING_REMOVE_BLANK;
+ if (!(nstr->normalized = GRN_MALLOC(size + 1))) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][koi8r] failed to allocate normalized text space");
+ return NULL;
+ }
+ d0 = (unsigned char *) nstr->normalized;
+ if (nstr->flags & GRN_STRING_WITH_CHECKS) {
+ if (!(nstr->checks = GRN_MALLOC(size * sizeof(int16_t) + 1))) {
+ GRN_FREE(nstr->normalized);
+ nstr->normalized = NULL;
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][koi8r] failed to allocate checks space");
+ return NULL;
+ }
+ }
+ ch = nstr->checks;
+ if (nstr->flags & GRN_STRING_WITH_TYPES) {
+ if (!(nstr->ctypes = GRN_MALLOC(size + 1))) {
+ GRN_FREE(nstr->checks);
+ GRN_FREE(nstr->normalized);
+ nstr->checks = NULL;
+ nstr->normalized = NULL;
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[string][koi8r] failed to allocate character types space");
+ return NULL;
+ }
+ }
+ cp = ctypes = nstr->ctypes;
+ e = (unsigned char *)nstr->original + size;
+ for (s = s_ = (unsigned char *) nstr->original, d = d_ = d0; s < e; s++) {
+ unsigned char c = *s;
+ switch (c >> 4) {
+ case 0 :
+ case 1 :
+ /* skip unprintable ascii */
+ if (cp > ctypes) { *(cp - 1) |= GRN_CHAR_BLANK; }
+ continue;
+ case 2 :
+ if (c == 0x20) {
+ if (removeblankp) {
+ if (cp > ctypes) { *(cp - 1) |= GRN_CHAR_BLANK; }
+ continue;
+ } else {
+ *d = ' ';
+ ctype = GRN_CHAR_BLANK|GRN_CHAR_SYMBOL;
+ }
+ } else {
+ *d = c;
+ ctype = GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 3 :
+ *d = c;
+ ctype = (c <= 0x39) ? GRN_CHAR_DIGIT : GRN_CHAR_SYMBOL;
+ break;
+ case 4 :
+ *d = ('A' <= c) ? c + 0x20 : c;
+ ctype = (c == 0x40) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 5 :
+ *d = (c <= 'Z') ? c + 0x20 : c;
+ ctype = (c <= 0x5a) ? GRN_CHAR_ALPHA : GRN_CHAR_SYMBOL;
+ break;
+ case 6 :
+ *d = c;
+ ctype = (c == 0x60) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 7 :
+ *d = c;
+ ctype = (c <= 0x7a) ? GRN_CHAR_ALPHA : (c == 0x7f ? GRN_CHAR_OTHERS : GRN_CHAR_SYMBOL);
+ break;
+ case 0x0a :
+ *d = c;
+ ctype = (c == 0xa3) ? GRN_CHAR_ALPHA : GRN_CHAR_OTHERS;
+ break;
+ case 0x0b :
+ if (c == 0xb3) {
+ *d = c - 0x10;
+ ctype = GRN_CHAR_ALPHA;
+ } else {
+ *d = c;
+ ctype = GRN_CHAR_OTHERS;
+ }
+ break;
+ case 0x0c :
+ case 0x0d :
+ *d = c;
+ ctype = GRN_CHAR_ALPHA;
+ break;
+ case 0x0e :
+ case 0x0f :
+ *d = c - 0x20;
+ ctype = GRN_CHAR_ALPHA;
+ break;
+ default :
+ *d = c;
+ ctype = GRN_CHAR_OTHERS;
+ break;
+ }
+ d++;
+ length++;
+ if (cp) { *cp++ = ctype; }
+ if (ch) {
+ *ch++ = (int16_t)(s + 1 - s_);
+ s_ = s + 1;
+ while (++d_ < d) { *ch++ = 0; }
+ }
+ }
+ if (cp) { *cp = GRN_CHAR_NULL; }
+ *d = '\0';
+ nstr->n_characters = length;
+ nstr->normalized_length_in_bytes = (size_t)(d - (unsigned char *)nstr->normalized);
+ return NULL;
+}
+
+static grn_obj *
+auto_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_string *string = (grn_string *)(args[0]);
+ switch (string->encoding) {
+ case GRN_ENC_EUC_JP :
+ eucjp_normalize(ctx, string);
+ break;
+ case GRN_ENC_UTF8 :
+#ifdef GRN_WITH_NFKC
+ utf8_normalize(ctx, string);
+#else /* GRN_WITH_NFKC */
+ ascii_normalize(ctx, string);
+#endif /* GRN_WITH_NFKC */
+ break;
+ case GRN_ENC_SJIS :
+ sjis_normalize(ctx, string);
+ break;
+ case GRN_ENC_LATIN1 :
+ latin1_normalize(ctx, string);
+ break;
+ case GRN_ENC_KOI8R :
+ koi8r_normalize(ctx, string);
+ break;
+ default :
+ ascii_normalize(ctx, string);
+ break;
+ }
+ return NULL;
+}
+
+#ifdef GRN_WITH_NFKC
+static grn_obj *
+nfkc51_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_string *string = (grn_string *)(args[0]);
+ utf8_normalize(ctx, string);
+ return NULL;
+}
+#endif /* GRN_WITH_NFKC */
+
+grn_rc
+grn_normalizer_normalize(grn_ctx *ctx, grn_obj *normalizer, grn_obj *string)
+{
+ grn_rc rc;
+ int nargs = 0;
+
+ grn_ctx_push(ctx, string);
+ nargs++;
+ rc = grn_proc_call(ctx, normalizer, nargs, NULL);
+ grn_ctx_pop(ctx);
+
+ return rc;
+}
+
+grn_rc
+grn_db_init_builtin_normalizers(grn_ctx *ctx)
+{
+ const char *normalizer_nfkc51_name = "NormalizerNFKC51";
+
+ grn_normalizer_register(ctx, GRN_NORMALIZER_AUTO_NAME, -1,
+ NULL, auto_next, NULL);
+
+#ifdef GRN_WITH_NFKC
+ grn_normalizer_register(ctx, normalizer_nfkc51_name, -1,
+ NULL, nfkc51_next, NULL);
+#else /* GRN_WITH_NFKC */
+ grn_normalizer_register(ctx, normalizer_nfkc51_name, -1,
+ NULL, NULL, NULL);
+#endif /* GRN_WITH_NFKC */
+/*
+ grn_normalizer_register(ctx, "NormalizerUCA", -1,
+ NULL, uca_next, NULL);
+*/
+
+ return GRN_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/obj.c b/storage/mroonga/vendor/groonga/lib/obj.c
new file mode 100644
index 00000000..8160daf5
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/obj.c
@@ -0,0 +1,689 @@
+/* -*- 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-1335 USA
+*/
+
+#include "grn.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)
+{
+ grn_id id;
+
+ if (!obj) { return GRN_FALSE; }
+
+ id = grn_obj_id(ctx, obj);
+ 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;
+ }
+
+ return GRN_TYPE_IS_TEXT_FAMILY(obj->header.domain);
+}
+
+grn_bool
+grn_obj_is_table(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_bool is_table = GRN_FALSE;
+
+ if (!obj) {
+ return GRN_FALSE;
+ }
+
+ switch (obj->header.type) {
+ case GRN_TABLE_NO_KEY :
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ is_table = GRN_TRUE;
+ default :
+ break;
+ }
+
+ return is_table;
+}
+
+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) {
+ return GRN_FALSE;
+ }
+
+ return obj->header.type == GRN_PROC;
+}
+
+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;
+
+ if (!grn_obj_is_proc(ctx, obj)) {
+ return GRN_FALSE;
+ }
+
+ proc = (grn_proc *)obj;
+ return proc->type == GRN_PROC_FUNCTION;
+}
+
+grn_bool
+grn_obj_is_selector_proc(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_proc *proc;
+
+ if (!grn_obj_is_function_proc(ctx, obj)) {
+ return GRN_FALSE;
+ }
+
+ proc = (grn_proc *)obj;
+ 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
+grn_obj_is_scorer_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_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
new file mode 100644
index 00000000..1d371fe4
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/operator.c
@@ -0,0 +1,1362 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#include "grn.h"
+#include "grn_db.h"
+#include "grn_str.h"
+#include "grn_normalizer.h"
+
+#include <string.h>
+
+#ifdef GRN_WITH_ONIGMO
+# define GRN_SUPPORT_REGEXP
+#endif
+
+#ifdef GRN_SUPPORT_REGEXP
+# include <onigmo.h>
+#endif
+
+static const char *operator_names[] = {
+ "push",
+ "pop",
+ "nop",
+ "call",
+ "intern",
+ "get_ref",
+ "get_value",
+ "and",
+ "and_not",
+ "or",
+ "assign",
+ "star_assign",
+ "slash_assign",
+ "mod_assign",
+ "plus_assign",
+ "minus_assign",
+ "shiftl_assign",
+ "shiftr_assign",
+ "shiftrr_assign",
+ "and_assign",
+ "xor_assign",
+ "or_assign",
+ "jump",
+ "cjump",
+ "comma",
+ "bitwise_or",
+ "bitwise_xor",
+ "bitwise_and",
+ "bitwise_not",
+ "equal",
+ "not_equal",
+ "less",
+ "greater",
+ "less_equal",
+ "greater_equal",
+ "in",
+ "match",
+ "near",
+ "near2",
+ "similar",
+ "term_extract",
+ "shiftl",
+ "shiftr",
+ "shiftrr",
+ "plus",
+ "minus",
+ "star",
+ "slash",
+ "mod",
+ "delete",
+ "incr",
+ "decr",
+ "incr_post",
+ "decr_post",
+ "not",
+ "adjust",
+ "exact",
+ "lcp",
+ "partial",
+ "unsplit",
+ "prefix",
+ "suffix",
+ "geo_distance1",
+ "geo_distance2",
+ "geo_distance3",
+ "geo_distance4",
+ "geo_withinp5",
+ "geo_withinp6",
+ "geo_withinp8",
+ "obj_search",
+ "expr_get_var",
+ "table_create",
+ "table_select",
+ "table_sort",
+ "table_group",
+ "json_put",
+ "get_member",
+ "regexp",
+ "fuzzy"
+};
+
+#define GRN_OP_LAST GRN_OP_FUZZY
+
+const char *
+grn_operator_to_string(grn_operator op)
+{
+ if (op <= GRN_OP_LAST) {
+ return operator_names[op];
+ } else {
+ return "unknown";
+ }
+}
+
+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 :\
+ r = (x_ == GRN_INT8_VALUE(y));\
+ break;\
+ case GRN_DB_UINT8 :\
+ r = (x_ == GRN_UINT8_VALUE(y));\
+ break;\
+ case GRN_DB_INT16 :\
+ r = (x_ == GRN_INT16_VALUE(y));\
+ break;\
+ case GRN_DB_UINT16 :\
+ r = (x_ == GRN_UINT16_VALUE(y));\
+ break;\
+ case GRN_DB_INT32 :\
+ r = (x_ == GRN_INT32_VALUE(y));\
+ break;\
+ case GRN_DB_UINT32 :\
+ r = (x_ == GRN_UINT32_VALUE(y));\
+ break;\
+ case GRN_DB_INT64 :\
+ r = (x_ == GRN_INT64_VALUE(y));\
+ break;\
+ case GRN_DB_TIME :\
+ r = (GRN_TIME_PACK(x_,0) == GRN_INT64_VALUE(y));\
+ break;\
+ case GRN_DB_UINT64 :\
+ r = (x_ == GRN_UINT64_VALUE(y));\
+ break;\
+ case GRN_DB_FLOAT :\
+ r = ((x_ <= GRN_FLOAT_VALUE(y)) && (x_ >= GRN_FLOAT_VALUE(y)));\
+ break;\
+ case GRN_DB_SHORT_TEXT :\
+ case GRN_DB_TEXT :\
+ case GRN_DB_LONG_TEXT :\
+ {\
+ const char *p_ = GRN_TEXT_VALUE(y);\
+ int i_ = grn_atoi(p_, p_ + GRN_TEXT_LEN(y), NULL);\
+ r = (x_ == i_);\
+ }\
+ break;\
+ default :\
+ r = GRN_FALSE;\
+ break;\
+ }\
+} while (0)
+
+#define DO_EQ(x,y,r) do {\
+ switch (x->header.domain) {\
+ case GRN_DB_VOID :\
+ r = GRN_FALSE;\
+ break;\
+ case GRN_DB_INT8 :\
+ {\
+ int8_t x_ = GRN_INT8_VALUE(x);\
+ DO_EQ_SUB;\
+ }\
+ break;\
+ case GRN_DB_UINT8 :\
+ {\
+ uint8_t x_ = GRN_UINT8_VALUE(x);\
+ DO_EQ_SUB;\
+ }\
+ break;\
+ case GRN_DB_INT16 :\
+ {\
+ int16_t x_ = GRN_INT16_VALUE(x);\
+ DO_EQ_SUB;\
+ }\
+ break;\
+ case GRN_DB_UINT16 :\
+ {\
+ uint16_t x_ = GRN_UINT16_VALUE(x);\
+ DO_EQ_SUB;\
+ }\
+ break;\
+ case GRN_DB_INT32 :\
+ {\
+ int32_t x_ = GRN_INT32_VALUE(x);\
+ DO_EQ_SUB;\
+ }\
+ break;\
+ case GRN_DB_UINT32 :\
+ {\
+ uint32_t x_ = GRN_UINT32_VALUE(x);\
+ DO_EQ_SUB;\
+ }\
+ break;\
+ case GRN_DB_INT64 :\
+ {\
+ int64_t x_ = GRN_INT64_VALUE(x);\
+ DO_EQ_SUB;\
+ }\
+ break;\
+ case GRN_DB_TIME :\
+ {\
+ int64_t x_ = GRN_INT64_VALUE(x);\
+ switch (y->header.domain) {\
+ case GRN_DB_INT32 :\
+ r = (x_ == GRN_TIME_PACK(GRN_INT32_VALUE(y), 0));\
+ break;\
+ case GRN_DB_UINT32 :\
+ r = (x_ == GRN_TIME_PACK(GRN_UINT32_VALUE(y), 0));\
+ break;\
+ case GRN_DB_INT64 :\
+ case GRN_DB_TIME :\
+ r = (x_ == GRN_INT64_VALUE(y));\
+ break;\
+ case GRN_DB_UINT64 :\
+ r = (x_ == GRN_UINT64_VALUE(y));\
+ break;\
+ case GRN_DB_FLOAT :\
+ r = (x_ == GRN_TIME_PACK(GRN_FLOAT_VALUE(y), 0));\
+ break;\
+ case GRN_DB_SHORT_TEXT :\
+ case GRN_DB_TEXT :\
+ case GRN_DB_LONG_TEXT :\
+ {\
+ grn_obj time_value_;\
+ GRN_TIME_INIT(&time_value_, 0);\
+ if (grn_obj_cast(ctx, y, &time_value_, GRN_FALSE) == GRN_SUCCESS) {\
+ r = (x_ == GRN_TIME_VALUE(&time_value_));\
+ } else {\
+ r = GRN_FALSE;\
+ }\
+ GRN_OBJ_FIN(ctx, &time_value_);\
+ }\
+ break;\
+ default :\
+ r = GRN_FALSE;\
+ break;\
+ }\
+ }\
+ break;\
+ case GRN_DB_UINT64 :\
+ {\
+ uint64_t x_ = GRN_UINT64_VALUE(x);\
+ DO_EQ_SUB;\
+ }\
+ break;\
+ case GRN_DB_FLOAT :\
+ {\
+ double x_ = GRN_FLOAT_VALUE(x);\
+ switch (y->header.domain) {\
+ case GRN_DB_INT32 :\
+ r = ((x_ <= GRN_INT32_VALUE(y)) && (x_ >= GRN_INT32_VALUE(y)));\
+ break;\
+ case GRN_DB_UINT32 :\
+ r = ((x_ <= GRN_UINT32_VALUE(y)) && (x_ >= GRN_UINT32_VALUE(y)));\
+ break;\
+ case GRN_DB_INT64 :\
+ case GRN_DB_TIME :\
+ r = ((x_ <= GRN_INT64_VALUE(y)) && (x_ >= GRN_INT64_VALUE(y)));\
+ break;\
+ case GRN_DB_UINT64 :\
+ r = ((x_ <= GRN_UINT64_VALUE(y)) && (x_ >= GRN_UINT64_VALUE(y)));\
+ break;\
+ case GRN_DB_FLOAT :\
+ r = ((x_ <= GRN_FLOAT_VALUE(y)) && (x_ >= GRN_FLOAT_VALUE(y)));\
+ break;\
+ case GRN_DB_SHORT_TEXT :\
+ case GRN_DB_TEXT :\
+ case GRN_DB_LONG_TEXT :\
+ {\
+ const char *p_ = GRN_TEXT_VALUE(y);\
+ int i_ = grn_atoi(p_, p_ + GRN_TEXT_LEN(y), NULL);\
+ r = (x_ <= i_ && x_ >= i_);\
+ }\
+ break;\
+ default :\
+ r = GRN_FALSE;\
+ break;\
+ }\
+ }\
+ break;\
+ case GRN_DB_SHORT_TEXT :\
+ case GRN_DB_TEXT :\
+ case GRN_DB_LONG_TEXT :\
+ if (GRN_DB_SHORT_TEXT <= y->header.domain && y->header.domain <= GRN_DB_LONG_TEXT) {\
+ uint32_t la = GRN_TEXT_LEN(x), lb = GRN_TEXT_LEN(y);\
+ r = (la == lb && !memcmp(GRN_TEXT_VALUE(x), GRN_TEXT_VALUE(y), lb));\
+ } else {\
+ const char *q_ = GRN_TEXT_VALUE(x);\
+ int x_ = grn_atoi(q_, q_ + GRN_TEXT_LEN(x), NULL);\
+ DO_EQ_SUB;\
+ }\
+ break;\
+ default :\
+ if ((x->header.domain == y->header.domain)) {\
+ r = (GRN_BULK_VSIZE(x) == GRN_BULK_VSIZE(y) &&\
+ !(memcmp(GRN_BULK_HEAD(x), GRN_BULK_HEAD(y), GRN_BULK_VSIZE(x))));\
+ } else {\
+ grn_obj dest;\
+ if (x->header.domain < y->header.domain) {\
+ GRN_OBJ_INIT(&dest, GRN_BULK, 0, y->header.domain);\
+ if (!grn_obj_cast(ctx, x, &dest, GRN_FALSE)) {\
+ r = (GRN_BULK_VSIZE(&dest) == GRN_BULK_VSIZE(y) &&\
+ !memcmp(GRN_BULK_HEAD(&dest), GRN_BULK_HEAD(y), GRN_BULK_VSIZE(y))); \
+ } else {\
+ r = GRN_FALSE;\
+ }\
+ } else {\
+ GRN_OBJ_INIT(&dest, GRN_BULK, 0, x->header.domain);\
+ if (!grn_obj_cast(ctx, y, &dest, GRN_FALSE)) {\
+ r = (GRN_BULK_VSIZE(&dest) == GRN_BULK_VSIZE(x) &&\
+ !memcmp(GRN_BULK_HEAD(&dest), GRN_BULK_HEAD(x), GRN_BULK_VSIZE(x))); \
+ } else {\
+ r = GRN_FALSE;\
+ }\
+ }\
+ GRN_OBJ_FIN(ctx, &dest);\
+ }\
+ break;\
+ }\
+} while (0)
+
+grn_bool
+grn_operator_exec_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y)
+{
+ grn_bool r = GRN_FALSE;
+ GRN_API_ENTER;
+ DO_EQ(x, y, r);
+ GRN_API_RETURN(r);
+}
+
+grn_bool
+grn_operator_exec_not_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y)
+{
+ grn_bool r = GRN_FALSE;
+ GRN_API_ENTER;
+ DO_EQ(x, y, r);
+ GRN_API_RETURN(!r);
+}
+
+#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;\
+ case GRN_DB_UINT8 :\
+ r = (x_ op GRN_UINT8_VALUE(y));\
+ break;\
+ case GRN_DB_INT16 :\
+ r = (x_ op GRN_INT16_VALUE(y));\
+ break;\
+ case GRN_DB_UINT16 :\
+ r = (x_ op GRN_UINT16_VALUE(y));\
+ break;\
+ case GRN_DB_INT32 :\
+ r = (x_ op GRN_INT32_VALUE(y));\
+ break;\
+ case GRN_DB_UINT32 :\
+ r = (x_ op GRN_UINT32_VALUE(y));\
+ break;\
+ case GRN_DB_INT64 :\
+ r = (x_ op GRN_INT64_VALUE(y));\
+ break;\
+ case GRN_DB_TIME :\
+ r = (GRN_TIME_PACK(x_,0) op GRN_INT64_VALUE(y));\
+ break;\
+ case GRN_DB_UINT64 :\
+ r = (x_ op GRN_UINT64_VALUE(y));\
+ break;\
+ case GRN_DB_FLOAT :\
+ r = (x_ op GRN_FLOAT_VALUE(y));\
+ break;\
+ default :\
+ r = GRN_FALSE;\
+ break;\
+ }\
+} while (0)
+
+#define DO_COMPARE_SCALAR_SUB_BUILTIN(op) do {\
+ switch (y->header.domain) {\
+ case GRN_DB_SHORT_TEXT :\
+ case GRN_DB_TEXT :\
+ case GRN_DB_LONG_TEXT :\
+ {\
+ grn_obj y_;\
+ GRN_OBJ_INIT(&y_, GRN_BULK, 0, x->header.domain);\
+ if (grn_obj_cast(ctx, y, &y_, GRN_FALSE)) {\
+ r = GRN_FALSE;\
+ } else {\
+ DO_COMPARE_SCALAR_SUB_NUMERIC(&y_, op);\
+ }\
+ GRN_OBJ_FIN(ctx, &y_);\
+ }\
+ break;\
+ default :\
+ DO_COMPARE_SCALAR_SUB_NUMERIC(y,op);\
+ break;\
+ }\
+} while (0)
+
+#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_SCALAR_SUB(op);\
+ }\
+ break;\
+ case GRN_DB_UINT8 :\
+ {\
+ uint8_t x_ = GRN_UINT8_VALUE(x);\
+ DO_COMPARE_SCALAR_SUB(op);\
+ }\
+ break;\
+ case GRN_DB_INT16 :\
+ {\
+ int16_t x_ = GRN_INT16_VALUE(x);\
+ DO_COMPARE_SCALAR_SUB(op);\
+ }\
+ break;\
+ case GRN_DB_UINT16 :\
+ {\
+ uint16_t x_ = GRN_UINT16_VALUE(x);\
+ DO_COMPARE_SCALAR_SUB(op);\
+ }\
+ break;\
+ case GRN_DB_INT32 :\
+ {\
+ int32_t x_ = GRN_INT32_VALUE(x);\
+ DO_COMPARE_SCALAR_SUB(op);\
+ }\
+ break;\
+ case GRN_DB_UINT32 :\
+ {\
+ uint32_t x_ = GRN_UINT32_VALUE(x);\
+ DO_COMPARE_SCALAR_SUB(op);\
+ }\
+ break;\
+ case GRN_DB_TIME :\
+ {\
+ int64_t x_ = GRN_INT64_VALUE(x);\
+ switch (y->header.domain) {\
+ case GRN_DB_INT32 :\
+ r = (x_ op GRN_TIME_PACK(GRN_INT32_VALUE(y), 0));\
+ break;\
+ case GRN_DB_UINT32 :\
+ r = (x_ op GRN_TIME_PACK(GRN_UINT32_VALUE(y), 0));\
+ break;\
+ case GRN_DB_INT64 :\
+ case GRN_DB_TIME :\
+ r = (x_ op GRN_INT64_VALUE(y));\
+ break;\
+ case GRN_DB_UINT64 :\
+ r = (x_ op GRN_UINT64_VALUE(y));\
+ break;\
+ case GRN_DB_FLOAT :\
+ r = (x_ op GRN_TIME_PACK(GRN_FLOAT_VALUE(y), 0));\
+ break;\
+ case GRN_DB_SHORT_TEXT :\
+ case GRN_DB_TEXT :\
+ case GRN_DB_LONG_TEXT :\
+ {\
+ grn_obj time_value_;\
+ GRN_TIME_INIT(&time_value_, 0);\
+ if (grn_obj_cast(ctx, y, &time_value_, GRN_FALSE) == GRN_SUCCESS) {\
+ r = (x_ op GRN_TIME_VALUE(&time_value_));\
+ } else {\
+ r = GRN_FALSE;\
+ }\
+ GRN_OBJ_FIN(ctx, &time_value_);\
+ }\
+ break;\
+ default :\
+ r = GRN_FALSE;\
+ break;\
+ }\
+ }\
+ break;\
+ case GRN_DB_INT64 :\
+ {\
+ int64_t x_ = GRN_INT64_VALUE(x);\
+ DO_COMPARE_SCALAR_SUB(op);\
+ }\
+ break;\
+ case GRN_DB_UINT64 :\
+ {\
+ uint64_t x_ = GRN_UINT64_VALUE(x);\
+ DO_COMPARE_SCALAR_SUB(op);\
+ }\
+ break;\
+ case GRN_DB_FLOAT :\
+ {\
+ double x_ = GRN_FLOAT_VALUE(x);\
+ DO_COMPARE_SCALAR_SUB(op);\
+ }\
+ break;\
+ case GRN_DB_SHORT_TEXT :\
+ case GRN_DB_TEXT :\
+ case GRN_DB_LONG_TEXT :\
+ if (GRN_DB_SHORT_TEXT <= y->header.domain && y->header.domain <= GRN_DB_LONG_TEXT) {\
+ int r_;\
+ uint32_t la = GRN_TEXT_LEN(x), lb = GRN_TEXT_LEN(y);\
+ if (la > lb) {\
+ if (!(r_ = memcmp(GRN_TEXT_VALUE(x), GRN_TEXT_VALUE(y), lb))) {\
+ r_ = 1;\
+ }\
+ } else {\
+ if (!(r_ = memcmp(GRN_TEXT_VALUE(x), GRN_TEXT_VALUE(y), la))) {\
+ r_ = la == lb ? 0 : -1;\
+ }\
+ }\
+ r = (r_ op 0);\
+ } else {\
+ const char *q_ = GRN_TEXT_VALUE(x);\
+ int x_ = grn_atoi(q_, q_ + GRN_TEXT_LEN(x), NULL);\
+ DO_COMPARE_SCALAR_SUB(op);\
+ }\
+ break;\
+ default :\
+ r = GRN_FALSE;\
+ break;\
+ }\
+} while (0)
+
+#define DO_COMPARE_SCALAR(x, y, r, op) do {\
+ if (x->header.domain >= GRN_N_RESERVED_TYPES) {\
+ 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 x_key;\
+ int length;\
+ 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 = &x_key;\
+ DO_COMPARE_SCALAR_BUILTIN((&x_key), y, r, op);\
+ x = x_original;\
+ } else {\
+ r = GRN_FALSE;\
+ }\
+ GRN_OBJ_FIN(ctx, &x_key);\
+ }\
+ break;\
+ default :\
+ r = GRN_FALSE;\
+ break;\
+ }\
+ grn_obj_unlink(ctx, x_table);\
+ } else {\
+ 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_FALSE;
+ GRN_API_ENTER;
+ DO_COMPARE(x, y, r, <);
+ GRN_API_RETURN(r);
+}
+
+grn_bool
+grn_operator_exec_greater(grn_ctx *ctx, grn_obj *x, grn_obj *y)
+{
+ grn_bool r = GRN_FALSE;
+ GRN_API_ENTER;
+ DO_COMPARE(x, y, r, >);
+ GRN_API_RETURN(r);
+}
+
+grn_bool
+grn_operator_exec_less_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y)
+{
+ grn_bool r = GRN_FALSE;
+ GRN_API_ENTER;
+ DO_COMPARE(x, y, r, <=);
+ GRN_API_RETURN(r);
+}
+
+grn_bool
+grn_operator_exec_greater_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y)
+{
+ grn_bool r = GRN_FALSE;
+ GRN_API_ENTER;
+ DO_COMPARE(x, y, r, >=);
+ GRN_API_RETURN(r);
+}
+
+static grn_bool
+exec_match_uvector_bulk(grn_ctx *ctx, grn_obj *uvector, grn_obj *query)
+{
+ grn_bool matched = GRN_FALSE;
+ unsigned int i, size;
+ grn_obj element;
+ unsigned int element_size;
+
+ size = grn_uvector_size(ctx, uvector);
+ element_size = grn_uvector_element_size(ctx, uvector);
+ GRN_VALUE_FIX_SIZE_INIT(&element, 0, uvector->header.domain);
+ for (i = 0; i < size; i++) {
+ GRN_BULK_REWIND(&element);
+ grn_bulk_write(ctx, &element,
+ GRN_BULK_HEAD(uvector) + (element_size * i),
+ element_size);
+ if (grn_operator_exec_equal(ctx, &element, query)) {
+ matched = GRN_TRUE;
+ break;
+ }
+ }
+ GRN_OBJ_FIN(ctx, &element);
+
+ return matched;
+}
+
+static grn_bool
+exec_match_vector_bulk(grn_ctx *ctx, grn_obj *vector, grn_obj *query)
+{
+ grn_bool matched = GRN_FALSE;
+ unsigned int i, size;
+ grn_obj element;
+
+ size = grn_vector_size(ctx, vector);
+ GRN_VOID_INIT(&element);
+ for (i = 0; i < size; i++) {
+ const char *content;
+ unsigned int content_size;
+ grn_id domain_id;
+
+ content_size = grn_vector_get_element(ctx, vector, i,
+ &content, NULL, &domain_id);
+ grn_obj_reinit(ctx, &element, domain_id, 0);
+ grn_bulk_write(ctx, &element, content, content_size);
+ if (grn_operator_exec_equal(ctx, &element, query)) {
+ matched = GRN_TRUE;
+ break;
+ }
+ }
+ GRN_OBJ_FIN(ctx, &element);
+
+ return matched;
+}
+
+#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 NULL;
+ }
+
+ 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 :
+ return NULL;
+ }
+
+ onig_result = onig_new(&regex,
+ pattern,
+ pattern + pattern_len,
+ ONIG_OPTION_ASCII_RANGE |
+ ONIG_OPTION_MULTILINE,
+ onig_encoding,
+ syntax,
+ &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,
+ "[operator][regexp] "
+ "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
+ {
+ 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 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;
+ }
+
+ matched = regexp_is_match(ctx, regex, target, target_len);
+ onig_free(regex);
+ return matched;
+#else /* GRN_SUPPORT_REGEXP */
+ return GRN_FALSE;
+#endif /* GRN_SUPPORT_REGEXP */
+}
+
+static grn_bool
+exec_text_operator(grn_ctx *ctx,
+ grn_operator op,
+ const char *target,
+ unsigned int target_len,
+ const char *query,
+ unsigned int query_len)
+{
+ 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);
+ break;
+ case GRN_OP_PREFIX :
+ matched = string_have_prefix(ctx, target, target_len, query, query_len);
+ break;
+ case GRN_OP_REGEXP :
+ matched = string_match_regexp(ctx, target, target_len, query, query_len);
+ break;
+ default :
+ matched = GRN_FALSE;
+ break;
+ }
+
+ return matched;
+}
+
+static grn_bool
+exec_text_operator_raw_text_raw_text(grn_ctx *ctx,
+ grn_operator op,
+ const char *target,
+ unsigned int target_len,
+ const char *query,
+ unsigned int query_len)
+{
+ grn_obj *normalizer;
+ grn_obj *norm_target;
+ grn_obj *norm_query;
+ const char *norm_target_raw;
+ const char *norm_query_raw;
+ unsigned int norm_target_raw_length_in_bytes;
+ unsigned int norm_query_raw_length_in_bytes;
+ grn_bool matched = GRN_FALSE;
+
+ if (target_len == 0 || query_len == 0) {
+ return GRN_FALSE;
+ }
+
+ normalizer = grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1);
+ norm_target = grn_string_open(ctx, target, target_len, normalizer, 0);
+ grn_string_get_normalized(ctx, norm_target,
+ &norm_target_raw,
+ &norm_target_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,
+ norm_target_raw_length_in_bytes,
+ norm_query_raw,
+ norm_query_raw_length_in_bytes);
+
+ grn_obj_close(ctx, norm_target);
+ if (norm_query) {
+ grn_obj_close(ctx, norm_query);
+ }
+ grn_obj_unlink(ctx, normalizer);
+
+ return matched;
+}
+
+static grn_bool
+exec_text_operator_record_text(grn_ctx *ctx,
+ grn_operator op,
+ grn_obj *record, grn_obj *table,
+ grn_obj *query)
+{
+ grn_obj *normalizer;
+ char record_key[GRN_TABLE_MAX_KEY_SIZE];
+ int record_key_len;
+ grn_bool matched = GRN_FALSE;
+
+ if (table->header.domain != GRN_DB_SHORT_TEXT) {
+ return GRN_FALSE;
+ }
+
+ if (GRN_TEXT_LEN(query) == 0) {
+ return GRN_FALSE;
+ }
+
+ 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) {
+ grn_obj *norm_query;
+ const char *norm_query_raw;
+ unsigned int norm_query_raw_length_in_bytes;
+
+ 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);
+ if (norm_query) {
+ grn_obj_close(ctx, norm_query);
+ }
+ } else {
+ matched = exec_text_operator_raw_text_raw_text(ctx,
+ op,
+ record_key,
+ record_key_len,
+ GRN_TEXT_VALUE(query),
+ GRN_TEXT_LEN(query));
+ }
+
+ return matched;
+}
+
+static grn_bool
+exec_text_operator_text_text(grn_ctx *ctx,
+ grn_operator op,
+ grn_obj *target,
+ grn_obj *query)
+{
+ return exec_text_operator_raw_text_raw_text(ctx,
+ op,
+ GRN_TEXT_VALUE(target),
+ GRN_TEXT_LEN(target),
+ GRN_TEXT_VALUE(query),
+ GRN_TEXT_LEN(query));
+}
+
+static grn_bool
+exec_text_operator_bulk_bulk(grn_ctx *ctx,
+ grn_operator op,
+ grn_obj *target,
+ grn_obj *query)
+{
+ switch (target->header.domain) {
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ switch (query->header.domain) {
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ return exec_text_operator_text_text(ctx, op, target, query);
+ default :
+ break;
+ }
+ return GRN_FALSE;
+ default:
+ {
+ grn_obj *domain;
+ domain = grn_ctx_at(ctx, target->header.domain);
+ if (GRN_OBJ_TABLEP(domain)) {
+ switch (query->header.domain) {
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ return exec_text_operator_record_text(ctx, op, target, domain, query);
+ default :
+ break;
+ }
+ }
+ }
+ return GRN_FALSE;
+ }
+}
+
+grn_bool
+grn_operator_exec_match(grn_ctx *ctx, grn_obj *target, grn_obj *sub_text)
+{
+ grn_bool matched;
+ GRN_API_ENTER;
+ switch (target->header.type) {
+ case GRN_UVECTOR :
+ matched = exec_match_uvector_bulk(ctx, target, sub_text);
+ break;
+ case GRN_VECTOR :
+ matched = exec_match_vector_bulk(ctx, target, sub_text);
+ break;
+ default :
+ matched = exec_text_operator_bulk_bulk(ctx, GRN_OP_MATCH, target, sub_text);
+ break;
+ }
+ GRN_API_RETURN(matched);
+}
+
+grn_bool
+grn_operator_exec_prefix(grn_ctx *ctx, grn_obj *target, grn_obj *prefix)
+{
+ grn_bool matched;
+ GRN_API_ENTER;
+ matched = exec_text_operator_bulk_bulk(ctx, GRN_OP_PREFIX, target, 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_FALSE;
+ GRN_API_ENTER;
+ 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
new file mode 100644
index 00000000..3c1fb21d
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/output.c
@@ -0,0 +1,2880 @@
+/* -*- 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-1335 USA
+*/
+
+#include "grn.h"
+
+#include <string.h>
+#include "grn_str.h"
+#include "grn_db.h"
+#include "grn_expr_code.h"
+#include "grn_util.h"
+#include "grn_output.h"
+
+#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)
+#define DECR_DEPTH (DEPTH ? grn_bulk_truncate(ctx, LEVELS, GRN_BULK_VSIZE(LEVELS) - sizeof(uint32_t)) : 0)
+#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) {
+ 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:
+ if (!DEPTH) { return; }
+ GRN_TEXT_PUTC(ctx, outbuf, '\n');
+ break;
+ case GRN_CONTENT_TSV:
+ if (level < 2) { return; }
+ if (DEPTH <= 2) {
+ GRN_TEXT_PUTC(ctx, outbuf, ((level & 3) == 3) ? '\t' : '\n');
+ } else {
+ GRN_TEXT_PUTC(ctx, outbuf, '\t');
+ }
+ case GRN_CONTENT_MSGPACK :
+ // do nothing
+ break;
+ case GRN_CONTENT_GROONGA_COMMAND_LIST :
+ break;
+ case GRN_CONTENT_NONE:
+ break;
+ }
+}
+
+void
+grn_output_array_open(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
+ const char *name, int nelements)
+{
+ put_delimiter(ctx, outbuf, output_type);
+ switch (output_type) {
+ case GRN_CONTENT_JSON:
+ GRN_TEXT_PUTC(ctx, outbuf, '[');
+ break;
+ case GRN_CONTENT_XML:
+ GRN_TEXT_PUTC(ctx, outbuf, '<');
+ GRN_TEXT_PUTS(ctx, outbuf, name);
+ GRN_TEXT_PUTC(ctx, outbuf, '>');
+ 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"); }
+ break;
+ case GRN_CONTENT_MSGPACK :
+#ifdef GRN_WITH_MESSAGE_PACK
+ if (nelements < 0) {
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
+ "grn_output_array_open nelements (%d) for <%s>",
+ nelements,
+ name);
+ }
+ msgpack_pack_array(&ctx->impl->output.msgpacker, nelements);
+#endif
+ break;
+ case GRN_CONTENT_GROONGA_COMMAND_LIST :
+ break;
+ case GRN_CONTENT_NONE:
+ break;
+ }
+ INCR_DEPTH(0);
+}
+
+void
+grn_output_array_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_PUTC(ctx, outbuf, ']');
+ break;
+ case GRN_CONTENT_TSV:
+ if (DEPTH > 3) {
+ if (CURR_LEVEL >= 2) { GRN_TEXT_PUTC(ctx, outbuf, '\t'); }
+ GRN_TEXT_PUTC(ctx, outbuf, ']');
+ }
+ break;
+ case GRN_CONTENT_XML:
+ {
+ const char *name;
+ 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, '>');
+ }
+ break;
+ case GRN_CONTENT_MSGPACK :
+ // do nothing
+ break;
+ case GRN_CONTENT_GROONGA_COMMAND_LIST :
+ break;
+ case GRN_CONTENT_NONE:
+ break;
+ }
+ DECR_DEPTH;
+ INCR_LENGTH;
+}
+
+void
+grn_output_map_open(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
+ const char *name, int nelements)
+{
+ put_delimiter(ctx, outbuf, output_type);
+ switch (output_type) {
+ case GRN_CONTENT_JSON:
+ GRN_TEXT_PUTS(ctx, outbuf, "{");
+ break;
+ case GRN_CONTENT_XML:
+ GRN_TEXT_PUTC(ctx, outbuf, '<');
+ GRN_TEXT_PUTS(ctx, outbuf, name);
+ GRN_TEXT_PUTC(ctx, outbuf, '>');
+ 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"); }
+ break;
+ case GRN_CONTENT_MSGPACK :
+#ifdef GRN_WITH_MESSAGE_PACK
+ if (nelements < 0) {
+ GRN_LOG(ctx, GRN_LOG_DEBUG,
+ "grn_output_map_open nelements (%d) for <%s>",
+ nelements,
+ name);
+ }
+ msgpack_pack_map(&ctx->impl->output.msgpacker, nelements);
+#endif
+ break;
+ case GRN_CONTENT_GROONGA_COMMAND_LIST :
+ break;
+ case GRN_CONTENT_NONE:
+ break;
+ }
+ INCR_DEPTH(1);
+}
+
+void
+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:
+ if (DEPTH > 3) {
+ if (CURR_LEVEL >= 2) { GRN_TEXT_PUTC(ctx, outbuf, '\t'); }
+ GRN_TEXT_PUTC(ctx, outbuf, '}');
+ }
+ break;
+ case GRN_CONTENT_XML:
+ {
+ const char *name;
+ 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, '>');
+ }
+ break;
+ case GRN_CONTENT_MSGPACK :
+ // do nothing
+ break;
+ case GRN_CONTENT_GROONGA_COMMAND_LIST :
+ break;
+ case GRN_CONTENT_NONE:
+ break;
+ }
+ DECR_DEPTH;
+ INCR_LENGTH;
+}
+
+void
+grn_output_int32(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, int value)
+{
+ put_delimiter(ctx, outbuf, output_type);
+ switch (output_type) {
+ case GRN_CONTENT_JSON:
+ grn_text_itoa(ctx, outbuf, value);
+ break;
+ case GRN_CONTENT_TSV:
+ grn_text_itoa(ctx, outbuf, value);
+ break;
+ case GRN_CONTENT_XML:
+ GRN_TEXT_PUTS(ctx, outbuf, "<INT>");
+ grn_text_itoa(ctx, outbuf, value);
+ GRN_TEXT_PUTS(ctx, outbuf, "</INT>");
+ break;
+ case GRN_CONTENT_MSGPACK :
+#ifdef GRN_WITH_MESSAGE_PACK
+ msgpack_pack_int32(&ctx->impl->output.msgpacker, value);
+#endif
+ break;
+ case GRN_CONTENT_GROONGA_COMMAND_LIST :
+ grn_text_itoa(ctx, outbuf, value);
+ break;
+ case GRN_CONTENT_NONE:
+ break;
+ }
+ INCR_LENGTH;
+}
+
+void
+grn_output_int64(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, int64_t value)
+{
+ put_delimiter(ctx, outbuf, output_type);
+ switch (output_type) {
+ case GRN_CONTENT_JSON:
+ grn_text_lltoa(ctx, outbuf, value);
+ break;
+ case GRN_CONTENT_TSV:
+ grn_text_lltoa(ctx, outbuf, value);
+ break;
+ case GRN_CONTENT_XML:
+ GRN_TEXT_PUTS(ctx, outbuf, "<INT>");
+ grn_text_lltoa(ctx, outbuf, value);
+ GRN_TEXT_PUTS(ctx, outbuf, "</INT>");
+ break;
+ case GRN_CONTENT_MSGPACK :
+#ifdef GRN_WITH_MESSAGE_PACK
+ msgpack_pack_int64(&ctx->impl->output.msgpacker, value);
+#endif
+ break;
+ case GRN_CONTENT_GROONGA_COMMAND_LIST :
+ grn_text_lltoa(ctx, outbuf, value);
+ break;
+ case GRN_CONTENT_NONE:
+ break;
+ }
+ INCR_LENGTH;
+}
+
+void
+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) {
+ case GRN_CONTENT_JSON:
+ grn_text_ulltoa(ctx, outbuf, value);
+ break;
+ case GRN_CONTENT_TSV:
+ grn_text_ulltoa(ctx, outbuf, value);
+ break;
+ case GRN_CONTENT_XML:
+ GRN_TEXT_PUTS(ctx, outbuf, "<INT>");
+ grn_text_ulltoa(ctx, outbuf, value);
+ GRN_TEXT_PUTS(ctx, outbuf, "</INT>");
+ break;
+ case GRN_CONTENT_MSGPACK :
+#ifdef GRN_WITH_MESSAGE_PACK
+ msgpack_pack_uint64(&ctx->impl->output.msgpacker, value);
+#endif
+ break;
+ case GRN_CONTENT_GROONGA_COMMAND_LIST :
+ grn_text_ulltoa(ctx, outbuf, value);
+ break;
+ case GRN_CONTENT_NONE:
+ break;
+ }
+ INCR_LENGTH;
+}
+
+void
+grn_output_float(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, double value)
+{
+ put_delimiter(ctx, outbuf, output_type);
+ switch (output_type) {
+ case GRN_CONTENT_JSON:
+ grn_text_ftoa(ctx, outbuf, value);
+ break;
+ case GRN_CONTENT_TSV:
+ grn_text_ftoa(ctx, outbuf, value);
+ break;
+ case GRN_CONTENT_XML:
+ GRN_TEXT_PUTS(ctx, outbuf, "<FLOAT>");
+ grn_text_ftoa(ctx, outbuf, value);
+ GRN_TEXT_PUTS(ctx, outbuf, "</FLOAT>");
+ break;
+ case GRN_CONTENT_MSGPACK :
+#ifdef GRN_WITH_MESSAGE_PACK
+ msgpack_pack_double(&ctx->impl->output.msgpacker, value);
+#endif
+ break;
+ case GRN_CONTENT_GROONGA_COMMAND_LIST :
+ grn_text_ftoa(ctx, outbuf, value);
+ break;
+ case GRN_CONTENT_NONE:
+ break;
+ }
+ INCR_LENGTH;
+}
+
+void
+grn_output_str(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
+ const char *value, size_t value_len)
+{
+ put_delimiter(ctx, outbuf, output_type);
+ switch (output_type) {
+ case GRN_CONTENT_JSON:
+ grn_text_esc(ctx, outbuf, value, value_len);
+ break;
+ case GRN_CONTENT_TSV:
+ grn_text_esc(ctx, outbuf, value, value_len);
+ break;
+ case GRN_CONTENT_XML:
+ GRN_TEXT_PUTS(ctx, outbuf, "<TEXT>");
+ grn_text_escape_xml(ctx, outbuf, value, value_len);
+ GRN_TEXT_PUTS(ctx, outbuf, "</TEXT>");
+ break;
+ case GRN_CONTENT_MSGPACK :
+#ifdef GRN_WITH_MESSAGE_PACK
+ 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 :
+ GRN_TEXT_PUT(ctx, outbuf, value, value_len);
+ break;
+ case GRN_CONTENT_NONE:
+ break;
+ }
+ INCR_LENGTH;
+}
+
+void
+grn_output_cstr(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
+ const char *value)
+{
+ grn_output_str(ctx, outbuf, output_type, value, strlen(value));
+}
+
+void
+grn_output_bool(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, grn_bool value)
+{
+ put_delimiter(ctx, outbuf, output_type);
+ switch (output_type) {
+ case GRN_CONTENT_JSON:
+ GRN_TEXT_PUTS(ctx, outbuf, value ? "true" : "false");
+ break;
+ case GRN_CONTENT_TSV:
+ GRN_TEXT_PUTS(ctx, outbuf, value ? "true" : "false");
+ break;
+ case GRN_CONTENT_XML:
+ GRN_TEXT_PUTS(ctx, outbuf, "<BOOL>");
+ GRN_TEXT_PUTS(ctx, outbuf, value ? "true" : "false");
+ GRN_TEXT_PUTS(ctx, outbuf, "</BOOL>");
+ break;
+ case GRN_CONTENT_MSGPACK :
+#ifdef GRN_WITH_MESSAGE_PACK
+ if (value) {
+ msgpack_pack_true(&ctx->impl->output.msgpacker);
+ } else {
+ msgpack_pack_false(&ctx->impl->output.msgpacker);
+ }
+#endif
+ break;
+ case GRN_CONTENT_GROONGA_COMMAND_LIST :
+ GRN_TEXT_PUTS(ctx, outbuf, value ? "true" : "false");
+ break;
+ case GRN_CONTENT_NONE:
+ break;
+ }
+ INCR_LENGTH;
+}
+
+void
+grn_output_null(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type)
+{
+ put_delimiter(ctx, outbuf, output_type);
+ switch (output_type) {
+ case GRN_CONTENT_JSON:
+ GRN_TEXT_PUTS(ctx, outbuf, "null");
+ break;
+ case GRN_CONTENT_TSV:
+ break;
+ case GRN_CONTENT_XML:
+ GRN_TEXT_PUTS(ctx, outbuf, "<NULL/>");
+ break;
+ case GRN_CONTENT_MSGPACK :
+#ifdef GRN_WITH_MESSAGE_PACK
+ msgpack_pack_nil(&ctx->impl->output.msgpacker);
+#endif
+ break;
+ case GRN_CONTENT_GROONGA_COMMAND_LIST :
+ break;
+ case GRN_CONTENT_NONE:
+ break;
+ }
+ INCR_LENGTH;
+}
+
+static inline void
+grn_output_bulk_void(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
+ const char *value, size_t value_len)
+{
+ if (value_len == sizeof(grn_id) && *(grn_id *)value == GRN_ID_NIL) {
+ grn_output_null(ctx, outbuf, output_type);
+ } else {
+ grn_output_str(ctx, outbuf, output_type, value, value_len);
+ }
+}
+
+void
+grn_output_time(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, int64_t value)
+{
+ double dv = value;
+ dv /= 1000000.0;
+ put_delimiter(ctx, outbuf, output_type);
+ switch (output_type) {
+ case GRN_CONTENT_JSON:
+ grn_text_ftoa(ctx, outbuf, dv);
+ break;
+ case GRN_CONTENT_TSV:
+ grn_text_ftoa(ctx, outbuf, dv);
+ break;
+ case GRN_CONTENT_XML:
+ GRN_TEXT_PUTS(ctx, outbuf, "<DATE>");
+ grn_text_ftoa(ctx, outbuf, dv);
+ GRN_TEXT_PUTS(ctx, outbuf, "</DATE>");
+ break;
+ case GRN_CONTENT_MSGPACK :
+#ifdef GRN_WITH_MESSAGE_PACK
+ msgpack_pack_double(&ctx->impl->output.msgpacker, dv);
+#endif
+ break;
+ case GRN_CONTENT_GROONGA_COMMAND_LIST :
+ grn_text_ftoa(ctx, outbuf, dv);
+ break;
+ case GRN_CONTENT_NONE:
+ break;
+ }
+ INCR_LENGTH;
+}
+
+void
+grn_output_geo_point(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
+ grn_geo_point *value)
+{
+ put_delimiter(ctx, outbuf, output_type);
+ switch (output_type) {
+ case GRN_CONTENT_JSON:
+ if (value) {
+ GRN_TEXT_PUTC(ctx, outbuf, '"');
+ grn_text_itoa(ctx, outbuf, value->latitude);
+ GRN_TEXT_PUTC(ctx, outbuf, 'x');
+ grn_text_itoa(ctx, outbuf, value->longitude);
+ GRN_TEXT_PUTC(ctx, outbuf, '"');
+ } else {
+ GRN_TEXT_PUTS(ctx, outbuf, "null");
+ }
+ break;
+ case GRN_CONTENT_TSV:
+ if (value) {
+ GRN_TEXT_PUTC(ctx, outbuf, '"');
+ grn_text_itoa(ctx, outbuf, value->latitude);
+ GRN_TEXT_PUTC(ctx, outbuf, 'x');
+ grn_text_itoa(ctx, outbuf, value->longitude);
+ GRN_TEXT_PUTC(ctx, outbuf, '"');
+ } else {
+ GRN_TEXT_PUTS(ctx, outbuf, "\"\"");
+ }
+ break;
+ case GRN_CONTENT_XML:
+ GRN_TEXT_PUTS(ctx, outbuf, "<GEO_POINT>");
+ if (value) {
+ grn_text_itoa(ctx, outbuf, value->latitude);
+ GRN_TEXT_PUTC(ctx, outbuf, 'x');
+ grn_text_itoa(ctx, outbuf, value->longitude);
+ }
+ GRN_TEXT_PUTS(ctx, outbuf, "</GEO_POINT>");
+ break;
+ case GRN_CONTENT_MSGPACK :
+#ifdef GRN_WITH_MESSAGE_PACK
+ if (value) {
+ grn_obj buf;
+ GRN_TEXT_INIT(&buf, 0);
+ 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->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->output.msgpacker);
+ }
+#endif
+ break;
+ case GRN_CONTENT_GROONGA_COMMAND_LIST :
+ if (value) {
+ GRN_TEXT_PUTC(ctx, outbuf, '"');
+ grn_text_itoa(ctx, outbuf, value->latitude);
+ GRN_TEXT_PUTC(ctx, outbuf, 'x');
+ grn_text_itoa(ctx, outbuf, value->longitude);
+ GRN_TEXT_PUTC(ctx, outbuf, '"');
+ } else {
+ GRN_TEXT_PUTS(ctx, outbuf, "\"\"");
+ }
+ break;
+ case GRN_CONTENT_NONE:
+ break;
+ }
+ INCR_LENGTH;
+}
+
+static void
+grn_text_atoj(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
+ grn_obj *obj, grn_id id)
+{
+ uint32_t vs;
+ grn_obj buf;
+ if (obj->header.type == GRN_ACCESSOR) {
+ grn_accessor *a = (grn_accessor *)obj;
+ GRN_TEXT_INIT(&buf, 0);
+ for (;;) {
+ buf.header.domain = grn_obj_get_range(ctx, obj);
+ GRN_BULK_REWIND(&buf);
+ switch (a->action) {
+ case GRN_ACCESSOR_GET_ID :
+ GRN_UINT32_PUT(ctx, &buf, id);
+ buf.header.domain = GRN_DB_UINT32;
+ break;
+ case GRN_ACCESSOR_GET_KEY :
+ grn_table_get_key2(ctx, a->obj, id, &buf);
+ buf.header.domain = DB_OBJ(a->obj)->header.domain;
+ break;
+ case GRN_ACCESSOR_GET_VALUE :
+ grn_obj_get_value(ctx, a->obj, id, &buf);
+ buf.header.domain = DB_OBJ(a->obj)->range;
+ break;
+ case GRN_ACCESSOR_GET_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;
+ }
+ }
+ break;
+ case GRN_ACCESSOR_GET_NSUBRECS :
+ {
+ grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs);
+ GRN_INT32_PUT(ctx, &buf, ri->n_subrecs);
+ }
+ buf.header.domain = GRN_DB_INT32;
+ break;
+ case GRN_ACCESSOR_GET_MAX :
+ {
+ grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs);
+ int64_t max;
+ max = grn_rset_recinfo_get_max(ctx, ri, a->obj);
+ GRN_INT64_PUT(ctx, &buf, max);
+ }
+ buf.header.domain = GRN_DB_INT64;
+ break;
+ case GRN_ACCESSOR_GET_MIN :
+ {
+ grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs);
+ int64_t min;
+ min = grn_rset_recinfo_get_min(ctx, ri, a->obj);
+ GRN_INT64_PUT(ctx, &buf, min);
+ }
+ buf.header.domain = GRN_DB_INT64;
+ break;
+ case GRN_ACCESSOR_GET_SUM :
+ {
+ grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs);
+ int64_t sum;
+ sum = grn_rset_recinfo_get_sum(ctx, ri, a->obj);
+ GRN_INT64_PUT(ctx, &buf, sum);
+ }
+ buf.header.domain = GRN_DB_INT64;
+ break;
+ case GRN_ACCESSOR_GET_AVG :
+ {
+ grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs);
+ double avg;
+ avg = grn_rset_recinfo_get_avg(ctx, ri, a->obj);
+ GRN_FLOAT_PUT(ctx, &buf, avg);
+ }
+ buf.header.domain = GRN_DB_FLOAT;
+ break;
+ case GRN_ACCESSOR_GET_COLUMN_VALUE :
+ if ((a->obj->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) == GRN_OBJ_COLUMN_VECTOR) {
+ if (a->next) {
+ grn_id *idp;
+ grn_obj_get_value(ctx, a->obj, id, &buf);
+ idp = (grn_id *)GRN_BULK_HEAD(&buf);
+ vs = GRN_BULK_VSIZE(&buf) / sizeof(grn_id);
+ grn_output_array_open(ctx, outbuf, output_type, "VECTOR", vs);
+ for (; vs--; idp++) {
+ grn_text_atoj(ctx, outbuf, output_type, (grn_obj *)a->next, *idp);
+ }
+ grn_output_array_close(ctx, outbuf, output_type);
+ } else {
+ grn_text_atoj(ctx, outbuf, output_type, a->obj, id);
+ }
+ goto exit;
+ } else {
+ grn_obj_get_value(ctx, a->obj, id, &buf);
+ }
+ break;
+ case GRN_ACCESSOR_GET_DB_OBJ :
+ /* todo */
+ break;
+ case GRN_ACCESSOR_LOOKUP :
+ /* todo */
+ break;
+ case GRN_ACCESSOR_FUNCALL :
+ /* todo */
+ break;
+ }
+ if (a->next) {
+ a = a->next;
+ if (GRN_BULK_VSIZE(&buf) >= sizeof(grn_id)) {
+ id = *((grn_id *)GRN_BULK_HEAD(&buf));
+ } else {
+ id = GRN_ID_NIL;
+ }
+ } else {
+ break;
+ }
+ }
+ grn_output_obj(ctx, outbuf, output_type, &buf, NULL);
+ } else {
+ grn_obj_format *format_argument = NULL;
+ grn_obj_format format;
+ GRN_OBJ_FORMAT_INIT(&format, 0, 0, 0, 0);
+ switch (obj->header.type) {
+ case GRN_COLUMN_FIX_SIZE :
+ GRN_VALUE_FIX_SIZE_INIT(&buf, 0, DB_OBJ(obj)->range);
+ break;
+ case GRN_COLUMN_VAR_SIZE :
+ if ((obj->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) == GRN_OBJ_COLUMN_VECTOR) {
+ grn_obj *range = grn_ctx_at(ctx, DB_OBJ(obj)->range);
+ if (GRN_OBJ_TABLEP(range) ||
+ (range->header.flags & GRN_OBJ_KEY_VAR_SIZE) == 0) {
+ GRN_VALUE_FIX_SIZE_INIT(&buf, GRN_OBJ_VECTOR, DB_OBJ(obj)->range);
+ } else {
+ GRN_VALUE_VAR_SIZE_INIT(&buf, GRN_OBJ_VECTOR, DB_OBJ(obj)->range);
+ }
+ if (obj->header.flags & GRN_OBJ_WITH_WEIGHT) {
+ format.flags |= GRN_OBJ_FORMAT_WITH_WEIGHT;
+ format_argument = &format;
+ }
+ } else {
+ GRN_VALUE_VAR_SIZE_INIT(&buf, 0, DB_OBJ(obj)->range);
+ }
+ break;
+ case GRN_COLUMN_INDEX :
+ GRN_UINT32_INIT(&buf, 0);
+ break;
+ default:
+ GRN_TEXT_INIT(&buf, 0);
+ break;
+ }
+ grn_obj_get_value(ctx, obj, id, &buf);
+ grn_output_obj(ctx, outbuf, output_type, &buf, format_argument);
+ }
+exit :
+ grn_obj_close(ctx, &buf);
+}
+
+static inline void
+grn_output_void(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
+ grn_obj *bulk, grn_obj_format *format)
+{
+ grn_output_null(ctx, outbuf, output_type);
+}
+
+static inline void
+grn_output_bulk(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
+ grn_obj *bulk, grn_obj_format *format)
+{
+ grn_obj buf;
+ GRN_TEXT_INIT(&buf, 0);
+ switch (bulk->header.domain) {
+ case GRN_DB_VOID :
+ grn_output_bulk_void(ctx, outbuf, output_type, GRN_BULK_HEAD(bulk), GRN_BULK_VSIZE(bulk));
+ break;
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ grn_output_str(ctx, outbuf, output_type, GRN_BULK_HEAD(bulk), GRN_BULK_VSIZE(bulk));
+ break;
+ case GRN_DB_BOOL :
+ grn_output_bool(ctx, outbuf, output_type,
+ GRN_BULK_VSIZE(bulk) ? GRN_UINT8_VALUE(bulk) : 0);
+ break;
+ case GRN_DB_INT8 :
+ grn_output_int32(ctx, outbuf, output_type,
+ GRN_BULK_VSIZE(bulk) ? GRN_INT8_VALUE(bulk) : 0);
+ break;
+ case GRN_DB_UINT8 :
+ grn_output_int32(ctx, outbuf, output_type,
+ GRN_BULK_VSIZE(bulk) ? GRN_UINT8_VALUE(bulk) : 0);
+ break;
+ case GRN_DB_INT16 :
+ grn_output_int32(ctx, outbuf, output_type,
+ GRN_BULK_VSIZE(bulk) ? GRN_INT16_VALUE(bulk) : 0);
+ break;
+ case GRN_DB_UINT16 :
+ grn_output_int32(ctx, outbuf, output_type,
+ GRN_BULK_VSIZE(bulk) ? GRN_UINT16_VALUE(bulk) : 0);
+ break;
+ case GRN_DB_INT32 :
+ grn_output_int32(ctx, outbuf, output_type,
+ GRN_BULK_VSIZE(bulk) ? GRN_INT32_VALUE(bulk) : 0);
+ break;
+ case GRN_DB_UINT32 :
+ grn_output_int64(ctx, outbuf, output_type,
+ GRN_BULK_VSIZE(bulk) ? GRN_UINT32_VALUE(bulk) : 0);
+ break;
+ case GRN_DB_INT64 :
+ grn_output_int64(ctx, outbuf, output_type,
+ GRN_BULK_VSIZE(bulk) ? GRN_INT64_VALUE(bulk) : 0);
+ break;
+ case GRN_DB_UINT64 :
+ grn_output_uint64(ctx, outbuf, output_type,
+ GRN_BULK_VSIZE(bulk) ? GRN_UINT64_VALUE(bulk) : 0);
+ break;
+ case GRN_DB_FLOAT :
+ grn_output_float(ctx, outbuf, output_type,
+ GRN_BULK_VSIZE(bulk) ? GRN_FLOAT_VALUE(bulk) : 0);
+ break;
+ case GRN_DB_TIME :
+ grn_output_time(ctx, outbuf, output_type,
+ GRN_BULK_VSIZE(bulk) ? GRN_INT64_VALUE(bulk) : 0);
+ break;
+ case GRN_DB_TOKYO_GEO_POINT :
+ case GRN_DB_WGS84_GEO_POINT :
+ grn_output_geo_point(ctx, outbuf, output_type,
+ GRN_BULK_VSIZE(bulk) ? (grn_geo_point *)GRN_BULK_HEAD(bulk) : NULL);
+ break;
+ default :
+ if (format) {
+ int j;
+ int ncolumns = GRN_BULK_VSIZE(&format->columns)/sizeof(grn_obj *);
+ grn_id id = GRN_RECORD_VALUE(bulk);
+ grn_obj **columns = (grn_obj **)GRN_BULK_HEAD(&format->columns);
+ if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) {
+ grn_output_array_open(ctx, outbuf, output_type, "COLUMNS", ncolumns);
+ for (j = 0; j < ncolumns; j++) {
+ grn_id range_id;
+ grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2);
+ GRN_BULK_REWIND(&buf);
+ grn_column_name_(ctx, columns[j], &buf);
+ grn_output_obj(ctx, outbuf, output_type, &buf, NULL);
+ /* column range */
+ range_id = grn_obj_get_range(ctx, columns[j]);
+ if (range_id == GRN_ID_NIL) {
+ GRN_TEXT_PUTS(ctx, outbuf, "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);
+ }
+ grn_output_array_close(ctx, outbuf, output_type);
+ }
+ grn_output_array_close(ctx, outbuf, output_type);
+ }
+ grn_output_array_open(ctx, outbuf, output_type, "HIT", ncolumns);
+ for (j = 0; j < ncolumns; j++) {
+ grn_text_atoj(ctx, outbuf, output_type, columns[j], id);
+ }
+ grn_output_array_close(ctx, outbuf, output_type);
+ } else {
+ grn_obj *table = grn_ctx_at(ctx, bulk->header.domain);
+ grn_id id = GRN_RECORD_VALUE(bulk);
+ if (table && table->header.type != GRN_TABLE_NO_KEY) {
+ grn_obj *accessor = grn_obj_column(ctx, table,
+ GRN_COLUMN_NAME_KEY,
+ GRN_COLUMN_NAME_KEY_LEN);
+ if (accessor) {
+ if (id == GRN_ID_NIL) {
+ grn_obj_reinit_for(ctx, &buf, accessor);
+ } else {
+ grn_obj_get_value(ctx, accessor, id, &buf);
+ }
+ grn_obj_unlink(ctx, accessor);
+ }
+ grn_output_obj(ctx, outbuf, output_type, &buf, format);
+ } else {
+ grn_output_int64(ctx, outbuf, output_type, id);
+ }
+ }
+ break;
+ }
+ GRN_OBJ_FIN(ctx, &buf);
+}
+
+static void
+grn_output_uvector_result_set(grn_ctx *ctx,
+ grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj *uvector,
+ grn_obj_format *format)
+{
+ unsigned int i_hit, n_hits;
+ unsigned int i_column, n_columns;
+ unsigned int n_elements;
+ grn_obj **columns;
+ grn_obj buf;
+ grn_bool with_column_names = GRN_FALSE;
+
+ n_hits = grn_vector_size(ctx, uvector);
+
+ n_columns = GRN_BULK_VSIZE(&format->columns) / sizeof(grn_obj *);
+ columns = (grn_obj **)GRN_BULK_HEAD(&format->columns);
+
+ GRN_TEXT_INIT(&buf, 0);
+
+ if (n_hits > 0 && format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) {
+ with_column_names = GRN_TRUE;
+ }
+
+ n_elements = 1; /* for NHITS */
+ if (with_column_names) {
+ n_elements += 1; /* for COLUMNS */
+ }
+ n_elements += n_hits; /* for HITS */
+ grn_output_array_open(ctx, outbuf, output_type, "RESULTSET", n_elements);
+
+ grn_output_array_open(ctx, outbuf, output_type, "NHITS", 1);
+ grn_text_itoa(ctx, outbuf, n_hits);
+ grn_output_array_close(ctx, outbuf, output_type);
+
+ if (with_column_names) {
+ grn_output_array_open(ctx, outbuf, output_type, "COLUMNS", n_columns);
+ for (i_column = 0; i_column < n_columns; i_column++) {
+ grn_id range_id;
+ grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2);
+
+ /* name */
+ GRN_BULK_REWIND(&buf);
+ grn_column_name_(ctx, columns[i_column], &buf);
+ grn_output_obj(ctx, outbuf, output_type, &buf, NULL);
+
+ /* type */
+ range_id = grn_obj_get_range(ctx, columns[i_column]);
+ if (range_id == GRN_ID_NIL) {
+ GRN_TEXT_PUTS(ctx, outbuf, "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);
+ }
+
+ grn_output_array_close(ctx, outbuf, output_type);
+ }
+ grn_output_array_close(ctx, outbuf, output_type);
+ }
+
+ for (i_hit = 0; i_hit < n_hits++; i_hit++) {
+ grn_id id;
+
+ id = grn_uvector_get_element(ctx, uvector, i_hit, NULL);
+ grn_output_array_open(ctx, outbuf, output_type, "HITS", n_columns);
+ for (i_column = 0; i_column < n_columns; i_column++) {
+ GRN_BULK_REWIND(&buf);
+ grn_obj_get_value(ctx, columns[i_column], id, &buf);
+ grn_output_obj(ctx, outbuf, output_type, &buf, NULL);
+ }
+ grn_output_array_close(ctx, outbuf, output_type);
+ }
+
+ grn_output_array_close(ctx, outbuf, output_type);
+
+ GRN_OBJ_FIN(ctx, &buf);
+}
+
+static inline void
+grn_output_uvector(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
+ grn_obj *uvector, grn_obj_format *format)
+{
+ grn_bool output_result_set = GRN_FALSE;
+ grn_bool with_weight = GRN_FALSE;
+ grn_obj *range;
+ grn_bool range_is_type;
+
+ if (format) {
+ if (GRN_BULK_VSIZE(&(format->columns)) > 0) {
+ output_result_set = GRN_TRUE;
+ }
+ if (format->flags & GRN_OBJ_FORMAT_WITH_WEIGHT) {
+ with_weight = GRN_TRUE;
+ }
+ }
+
+ if (output_result_set) {
+ grn_output_uvector_result_set(ctx, outbuf, output_type, uvector, format);
+ return;
+ }
+
+ range = grn_ctx_at(ctx, uvector->header.domain);
+ range_is_type = (range->header.type == GRN_TYPE);
+ if (range_is_type) {
+ unsigned int i, n;
+ char *raw_elements;
+ unsigned int element_size;
+ grn_obj element;
+
+ raw_elements = GRN_BULK_HEAD(uvector);
+ element_size = GRN_TYPE_SIZE(DB_OBJ(range));
+ n = GRN_BULK_VSIZE(uvector) / element_size;
+
+ grn_output_array_open(ctx, outbuf, output_type, "VECTOR", n);
+ GRN_OBJ_INIT(&element, GRN_BULK, 0, uvector->header.domain);
+ for (i = 0; i < n; i++) {
+ GRN_BULK_REWIND(&element);
+ grn_bulk_write_from(ctx, &element, raw_elements + (element_size * i),
+ 0, element_size);
+ grn_output_obj(ctx, outbuf, output_type, &element, NULL);
+ }
+ GRN_OBJ_FIN(ctx, &element);
+ grn_output_array_close(ctx, outbuf, output_type);
+ } else {
+ unsigned int i, n;
+ grn_obj id_value;
+ grn_obj key_value;
+
+ GRN_UINT32_INIT(&id_value, 0);
+ GRN_OBJ_INIT(&key_value, GRN_BULK, 0, range->header.domain);
+
+ n = grn_vector_size(ctx, uvector);
+ if (with_weight) {
+ grn_output_map_open(ctx, outbuf, output_type, "WEIGHT_VECTOR", n);
+ } else {
+ grn_output_array_open(ctx, outbuf, output_type, "VECTOR", n);
+ }
+
+ for (i = 0; i < n; i++) {
+ grn_id id;
+ unsigned int weight;
+
+ id = grn_uvector_get_element(ctx, uvector, i, &weight);
+ if (range->header.type == GRN_TABLE_NO_KEY) {
+ GRN_UINT32_SET(ctx, &id_value, id);
+ grn_output_obj(ctx, outbuf, output_type, &id_value, NULL);
+ } else {
+ GRN_BULK_REWIND(&key_value);
+ grn_table_get_key2(ctx, range, id, &key_value);
+ grn_output_obj(ctx, outbuf, output_type, &key_value, NULL);
+ }
+
+ if (with_weight) {
+ grn_output_uint64(ctx, outbuf, output_type, weight);
+ }
+ }
+
+ if (with_weight) {
+ grn_output_map_close(ctx, outbuf, output_type);
+ } else {
+ grn_output_array_close(ctx, outbuf, output_type);
+ }
+
+ GRN_OBJ_FIN(ctx, &id_value);
+ GRN_OBJ_FIN(ctx, &key_value);
+ }
+ grn_obj_unlink(ctx, range);
+}
+
+static inline void
+grn_output_vector(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
+ grn_obj *vector, grn_obj_format *format)
+{
+ grn_bool with_weight = GRN_FALSE;
+
+ if (vector->header.domain == GRN_DB_VOID) {
+ ERR(GRN_INVALID_ARGUMENT, "invalid obj->header.domain");
+ return;
+ }
+
+ if (format) {
+ if (format->flags & GRN_OBJ_FORMAT_WITH_WEIGHT) {
+ with_weight = GRN_TRUE;
+ }
+ }
+
+ if (with_weight) {
+ unsigned int i, n;
+ grn_obj value;
+
+ GRN_VOID_INIT(&value);
+ n = grn_vector_size(ctx, vector);
+ grn_output_map_open(ctx, outbuf, output_type, "WEIGHT_VECTOR", n);
+ for (i = 0; i < n; i++) {
+ const char *_value;
+ unsigned int weight, length;
+ grn_id domain;
+
+ length = grn_vector_get_element(ctx, vector, i,
+ &_value, &weight, &domain);
+ if (domain != GRN_DB_VOID) {
+ grn_obj_reinit(ctx, &value, domain, 0);
+ } else {
+ grn_obj_reinit(ctx, &value, vector->header.domain, 0);
+ }
+ grn_bulk_write(ctx, &value, _value, length);
+ grn_output_obj(ctx, outbuf, output_type, &value, NULL);
+ grn_output_uint64(ctx, outbuf, output_type, weight);
+ }
+ grn_output_map_close(ctx, outbuf, output_type);
+ GRN_OBJ_FIN(ctx, &value);
+ } else {
+ unsigned int i, n;
+ grn_obj value;
+ GRN_VOID_INIT(&value);
+ n = grn_vector_size(ctx, vector);
+ grn_output_array_open(ctx, outbuf, output_type, "VECTOR", n);
+ for (i = 0; i < n; i++) {
+ const char *_value;
+ unsigned int weight, length;
+ grn_id domain;
+
+ length = grn_vector_get_element(ctx, vector, i,
+ &_value, &weight, &domain);
+ if (domain != GRN_DB_VOID) {
+ grn_obj_reinit(ctx, &value, domain, 0);
+ } else {
+ grn_obj_reinit(ctx, &value, vector->header.domain, 0);
+ }
+ grn_bulk_write(ctx, &value, _value, length);
+ grn_output_obj(ctx, outbuf, output_type, &value, NULL);
+ }
+ grn_output_array_close(ctx, outbuf, output_type);
+ GRN_OBJ_FIN(ctx, &value);
+ }
+}
+
+static inline void
+grn_output_pvector(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
+ grn_obj *pvector, grn_obj_format *format)
+{
+ if (format) {
+ ERR(GRN_FUNCTION_NOT_IMPLEMENTED,
+ "cannot print GRN_PVECTOR using grn_obj_format");
+ } else {
+ unsigned int i, n;
+ grn_output_array_open(ctx, outbuf, output_type, "VECTOR", -1);
+ n = GRN_BULK_VSIZE(pvector) / sizeof(grn_obj *);
+ for (i = 0; i < n; i++) {
+ grn_obj *value;
+
+ value = GRN_PTR_VALUE_AT(pvector, i);
+ grn_output_obj(ctx, outbuf, output_type, value, NULL);
+ }
+ grn_output_array_close(ctx, outbuf, output_type);
+ }
+}
+
+static inline void
+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 (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_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);
+ }
+}
+
+static inline int
+count_n_elements_in_expression(grn_ctx *ctx, grn_obj *expression)
+{
+ int n_elements = 0;
+ grn_bool is_first_comma = GRN_TRUE;
+ grn_expr *expr = (grn_expr *)expression;
+ grn_expr_code *code;
+ grn_expr_code *code_end = expr->codes + expr->codes_curr;
+
+ for (code = expr->codes; code < code_end; code++) {
+ if (code->op == GRN_OP_COMMA) {
+ n_elements++;
+ if (is_first_comma) {
+ n_elements++;
+ is_first_comma = GRN_FALSE;
+ }
+ }
+ }
+
+ return n_elements;
+}
+
+static grn_bool
+is_score_accessor(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_accessor *a;
+
+ if (obj->header.type != GRN_ACCESSOR) {
+ return GRN_FALSE;
+ }
+
+ for (a = (grn_accessor *)obj; a->next; a = a->next) {
+ }
+ return a->action == GRN_ACCESSOR_GET_SCORE;
+}
+
+static inline void
+grn_output_table_column(grn_ctx *ctx, grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj *column, grn_obj *buf)
+{
+ 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;
+ } else {
+ 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_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);
+ }
+}
+
+static inline void
+grn_output_table_column_by_expression(grn_ctx *ctx, grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_expr_code *code,
+ grn_expr_code *code_end,
+ grn_obj *buf)
+{
+ if (code_end <= code) {
+ 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_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_table_column_info(ctx,
+ outbuf,
+ output_type,
+ GRN_TEXT_VALUE(buf),
+ NULL);
+ } else {
+ grn_output_table_column(ctx, outbuf, output_type, code->value, buf);
+ }
+ break;
+ default :
+ grn_output_table_column(ctx, outbuf, output_type, code->value, buf);
+ break;
+ }
+}
+
+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,
+ grn_obj *buf)
+{
+ int n_elements;
+ int previous_comma_offset = -1;
+ grn_bool is_first_comma = GRN_TRUE;
+ grn_bool have_comma = GRN_FALSE;
+ grn_expr *expr = (grn_expr *)format->expression;
+ grn_expr_code *code;
+ grn_expr_code *code_end = expr->codes + expr->codes_curr;
+
+ n_elements = count_n_elements_in_expression(ctx, format->expression);
+
+ grn_output_table_columns_open(ctx, outbuf, output_type, n_elements);
+
+ for (code = expr->codes; code < code_end; code++) {
+ int code_start_offset;
+
+ if (code->op != GRN_OP_COMMA) {
+ continue;
+ }
+
+ have_comma = GRN_TRUE;
+ if (is_first_comma) {
+ unsigned int n_used_codes;
+ int code_end_offset;
+
+ n_used_codes = grn_expr_code_n_used_codes(ctx, expr->codes, code - 1);
+ code_end_offset = code - expr->codes - n_used_codes;
+
+ grn_output_table_column_by_expression(ctx, outbuf, output_type,
+ expr->codes,
+ expr->codes + code_end_offset,
+ buf);
+ code_start_offset = code_end_offset;
+ is_first_comma = GRN_FALSE;
+ } else {
+ code_start_offset = previous_comma_offset + 1;
+ }
+
+ grn_output_table_column_by_expression(ctx, outbuf, output_type,
+ expr->codes + code_start_offset,
+ code,
+ buf);
+ previous_comma_offset = code - expr->codes;
+ }
+
+ if (!have_comma && expr->codes_curr > 0) {
+ grn_output_table_column_by_expression(ctx, outbuf, output_type,
+ expr->codes,
+ code_end,
+ buf);
+ }
+
+ grn_output_table_columns_close(ctx, outbuf, output_type);
+}
+
+static inline void
+grn_output_table_columns_by_columns(grn_ctx *ctx, grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj *table, grn_obj_format *format,
+ grn_obj *buf)
+{
+ int i;
+ int ncolumns = GRN_BULK_VSIZE(&format->columns)/sizeof(grn_obj *);
+ grn_obj **columns = (grn_obj **)GRN_BULK_HEAD(&format->columns);
+
+ 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_table_columns_close(ctx, outbuf, output_type);
+}
+
+void
+grn_output_table_columns(grn_ctx *ctx, grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_obj *table, grn_obj_format *format)
+{
+ grn_obj buf;
+
+ GRN_TEXT_INIT(&buf, 0);
+ if (format->expression) {
+ grn_output_table_columns_by_expression(ctx, outbuf, output_type,
+ table, format, &buf);
+ } else {
+ grn_output_table_columns_by_columns(ctx, outbuf, output_type,
+ table, format, &buf);
+ }
+ GRN_OBJ_FIN(ctx, &buf);
+}
+
+static inline void
+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 *record)
+{
+ 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_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);
+ }
+ }
+}
+
+static inline void
+grn_output_table_records_by_expression(grn_ctx *ctx, grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_table_cursor *tc,
+ grn_obj_format *format)
+{
+ int n_elements = 0;
+ grn_id id;
+ grn_obj *record;
+ grn_expr *expr = (grn_expr *)format->expression;
+ grn_expr_code *code;
+ grn_expr_code *code_end = expr->codes + expr->codes_curr;
+
+ n_elements = count_n_elements_in_expression(ctx, format->expression);
+ record = grn_expr_get_var_by_offset(ctx, format->expression, 0);
+ while ((id = grn_table_cursor_next(ctx, tc)) != GRN_ID_NIL) {
+ int previous_comma_offset = -1;
+ grn_bool is_first_comma = GRN_TRUE;
+ grn_bool have_comma = GRN_FALSE;
+ GRN_RECORD_SET(ctx, record, id);
+ 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;
+ int code_end_offset;
+ int original_codes_curr = expr->codes_curr;
+
+ have_comma = GRN_TRUE;
+ if (is_first_comma) {
+ int second_code_offset;
+ unsigned int second_code_n_used_codes;
+ second_code_offset = code - expr->codes - 1;
+ second_code_n_used_codes =
+ grn_expr_code_n_used_codes(ctx,
+ 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,
+ 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,
+ record);
+ expr->codes -= code_start_offset;
+ expr->codes_curr = original_codes_curr;
+ previous_comma_offset = code - expr->codes;
+ }
+ }
+
+ if (!have_comma && expr->codes_curr > 0) {
+ grn_output_table_record_by_expression(ctx,
+ outbuf,
+ output_type,
+ format->expression,
+ record);
+ }
+
+ grn_output_table_record_close(ctx, outbuf, output_type);
+ }
+}
+
+static inline void
+grn_output_table_records_by_columns(grn_ctx *ctx, grn_obj *outbuf,
+ grn_content_type output_type,
+ grn_table_cursor *tc,
+ grn_obj_format *format)
+{
+ int i;
+ grn_id id;
+ 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_table_record_open(ctx, outbuf, output_type, ncolumns);
+ for (i = 0; i < ncolumns; i++) {
+ 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);
+ }
+}
+
+void
+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_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,
+ tc, format);
+ } else {
+ grn_output_table_records_by_columns(ctx, outbuf, output_type,
+ tc, format);
+ }
+ grn_table_cursor_close(ctx, tc);
+ } else {
+ ERRCLR(ctx);
+ }
+ grn_output_table_records_close(ctx, outbuf, output_type);
+}
+
+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);
+ if (format) {
+ int resultset_size = 1;
+ /* resultset: [NHITS, (COLUMNS), (HITS)] */
+ if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) {
+ resultset_size++;
+ }
+ resultset_size += format->limit;
+ resultset_size += n_additional_elements;
+ grn_output_array_open(ctx, outbuf, output_type, "RESULTSET", resultset_size);
+ 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);
+ } else {
+ int i;
+ grn_obj *column = grn_obj_column(ctx, table,
+ GRN_COLUMN_NAME_KEY,
+ GRN_COLUMN_NAME_KEY_LEN);
+ grn_table_cursor *tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0,
+ 0, -1, GRN_CURSOR_ASCENDING);
+ grn_output_array_open(ctx, outbuf, output_type, "HIT", -1);
+ if (tc) {
+ grn_id id;
+ for (i = 0; (id = grn_table_cursor_next(ctx, tc)) != GRN_ID_NIL; i++) {
+ 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_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)
+{
+ grn_obj buf;
+ GRN_TEXT_INIT(&buf, 0);
+ switch (obj->header.type) {
+ case GRN_VOID :
+ grn_output_void(ctx, outbuf, output_type, obj, format);
+ break;
+ case GRN_BULK :
+ grn_output_bulk(ctx, outbuf, output_type, obj, format);
+ break;
+ case GRN_UVECTOR :
+ grn_output_uvector(ctx, outbuf, output_type, obj, format);
+ break;
+ case GRN_VECTOR :
+ grn_output_vector(ctx, outbuf, output_type, obj, format);
+ break;
+ case GRN_PVECTOR :
+ grn_output_pvector(ctx, outbuf, output_type, obj, format);
+ break;
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ /* Deprecated. Use grn_output_result_set() directly. */
+ grn_output_result_set(ctx, outbuf, output_type, obj, format);
+ break;
+ }
+ GRN_OBJ_FIN(ctx, &buf);
+}
+
+typedef enum {
+ XML_START,
+ XML_START_ELEMENT,
+ XML_END_ELEMENT,
+ XML_TEXT
+} xml_status;
+
+typedef enum {
+ XML_PLACE_NONE,
+ XML_PLACE_COLUMN,
+ XML_PLACE_HIT
+} xml_place;
+
+static char *
+transform_xml_next_column(grn_obj *columns, int n)
+{
+ char *column = GRN_TEXT_VALUE(columns);
+ while (n--) {
+ while (*column) {
+ column++;
+ }
+ column++;
+ }
+ return column;
+}
+
+static void
+transform_xml(grn_ctx *ctx, grn_obj *output, grn_obj *transformed)
+{
+ char *s, *e;
+ xml_status status = XML_START;
+ xml_place place = XML_PLACE_NONE;
+ grn_obj buf, name, columns, *expr;
+ unsigned int len;
+ int offset = 0, limit = 0, record_n = 0;
+ int column_n = 0, column_text_n = 0, result_set_n = -1;
+ grn_bool in_vector = GRN_FALSE;
+ unsigned int vector_element_n = 0;
+ grn_bool in_weight_vector = GRN_FALSE;
+ unsigned int weight_vector_item_n = 0;
+
+ s = GRN_TEXT_VALUE(output);
+ e = GRN_BULK_CURR(output);
+ GRN_TEXT_INIT(&buf, 0);
+ GRN_TEXT_INIT(&name, 0);
+ GRN_TEXT_INIT(&columns, 0);
+
+ expr = ctx->impl->curr_expr;
+
+#define EQUAL_NAME_P(_name) \
+ (GRN_TEXT_LEN(&name) == strlen(_name) && \
+ !memcmp(GRN_TEXT_VALUE(&name), _name, strlen(_name)))
+
+ while (s < e) {
+ switch (*s) {
+ case '<' :
+ s++;
+ switch (*s) {
+ case '/' :
+ status = XML_END_ELEMENT;
+ s++;
+ break;
+ default :
+ status = XML_START_ELEMENT;
+ break;
+ }
+ GRN_BULK_REWIND(&name);
+ break;
+ case '>' :
+ switch (status) {
+ case XML_START_ELEMENT :
+ if (EQUAL_NAME_P("COLUMN")) {
+ place = XML_PLACE_COLUMN;
+ column_text_n = 0;
+ } else if (EQUAL_NAME_P("HIT")) {
+ place = XML_PLACE_HIT;
+ column_n = 0;
+ if (result_set_n == 0) {
+ GRN_TEXT_PUTS(ctx, transformed, "<HIT NO=\"");
+ grn_text_itoa(ctx, transformed, record_n++);
+ GRN_TEXT_PUTS(ctx, transformed, "\">\n");
+ } else {
+ GRN_TEXT_PUTS(ctx, transformed, "<NAVIGATIONELEMENT ");
+ }
+ } else if (EQUAL_NAME_P("RESULTSET")) {
+ GRN_BULK_REWIND(&columns);
+ result_set_n++;
+ if (result_set_n == 0) {
+ } else {
+ GRN_TEXT_PUTS(ctx, transformed, "<NAVIGATIONENTRY>\n");
+ }
+ } else if (EQUAL_NAME_P("VECTOR")) {
+ char *c = transform_xml_next_column(&columns, column_n++);
+ in_vector = GRN_TRUE;
+ vector_element_n = 0;
+ GRN_TEXT_PUTS(ctx, transformed, "<FIELD NAME=\"");
+ GRN_TEXT_PUTS(ctx, transformed, c);
+ GRN_TEXT_PUTS(ctx, transformed, "\">");
+ } else if (EQUAL_NAME_P("WEIGHT_VECTOR")) {
+ char *c = transform_xml_next_column(&columns, column_n++);
+ in_weight_vector = GRN_TRUE;
+ weight_vector_item_n = 0;
+ GRN_TEXT_PUTS(ctx, transformed, "<FIELD NAME=\"");
+ GRN_TEXT_PUTS(ctx, transformed, c);
+ GRN_TEXT_PUTS(ctx, transformed, "\">");
+ }
+ break;
+ case XML_END_ELEMENT :
+ if (EQUAL_NAME_P("HIT")) {
+ place = XML_PLACE_NONE;
+ if (result_set_n == 0) {
+ GRN_TEXT_PUTS(ctx, transformed, "</HIT>\n");
+ } else {
+ GRN_TEXT_PUTS(ctx, transformed, "/>\n");
+ }
+ } else if (EQUAL_NAME_P("RESULTSET")) {
+ place = XML_PLACE_NONE;
+ if (result_set_n == 0) {
+ GRN_TEXT_PUTS(ctx, transformed, "</RESULTSET>\n");
+ } else {
+ GRN_TEXT_PUTS(ctx, transformed,
+ "</NAVIGATIONELEMENTS>\n"
+ "</NAVIGATIONENTRY>\n");
+ }
+ } else if (EQUAL_NAME_P("RESULT")) {
+ GRN_TEXT_PUTS(ctx, transformed,
+ "</RESULTPAGE>\n"
+ "</SEGMENT>\n"
+ "</SEGMENTS>\n");
+ } else if (EQUAL_NAME_P("VECTOR")) {
+ in_vector = GRN_FALSE;
+ GRN_TEXT_PUTS(ctx, transformed, "</FIELD>\n");
+ } else if (EQUAL_NAME_P("WEIGHT_VECTOR")) {
+ in_weight_vector = GRN_FALSE;
+ GRN_TEXT_PUTS(ctx, transformed, "</FIELD>\n");
+ } else {
+ switch (place) {
+ case XML_PLACE_HIT :
+ if (result_set_n == 0) {
+ if (in_vector) {
+ if (vector_element_n > 0) {
+ GRN_TEXT_PUTS(ctx, transformed, ", ");
+ }
+ GRN_TEXT_PUT(ctx, transformed,
+ GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf));
+ vector_element_n++;
+ } else if (in_weight_vector) {
+ grn_bool is_key;
+ is_key = ((weight_vector_item_n % 2) == 0);
+ if (is_key) {
+ unsigned int weight_vector_key_n;
+ weight_vector_key_n = weight_vector_item_n / 2;
+ if (weight_vector_key_n > 0) {
+ GRN_TEXT_PUTS(ctx, transformed, ", ");
+ }
+ } else {
+ GRN_TEXT_PUTS(ctx, transformed, ":");
+ }
+ GRN_TEXT_PUT(ctx, transformed,
+ GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf));
+ weight_vector_item_n++;
+ } else {
+ char *c = transform_xml_next_column(&columns, column_n++);
+ GRN_TEXT_PUTS(ctx, transformed, "<FIELD NAME=\"");
+ GRN_TEXT_PUTS(ctx, transformed, c);
+ GRN_TEXT_PUTS(ctx, transformed, "\">");
+ GRN_TEXT_PUT(ctx, transformed,
+ GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf));
+ GRN_TEXT_PUTS(ctx, transformed, "</FIELD>\n");
+ }
+ } else {
+ char *c = transform_xml_next_column(&columns, column_n++);
+ GRN_TEXT_PUTS(ctx, transformed, c);
+ GRN_TEXT_PUTS(ctx, transformed, "=\"");
+ GRN_TEXT_PUT(ctx, transformed,
+ GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf));
+ GRN_TEXT_PUTS(ctx, transformed, "\" ");
+ }
+ break;
+ default :
+ if (EQUAL_NAME_P("NHITS")) {
+ if (result_set_n == 0) {
+ uint32_t nhits;
+ grn_obj *offset_value, *limit_value;
+
+ nhits = grn_atoui(GRN_TEXT_VALUE(&buf), GRN_BULK_CURR(&buf),
+ NULL);
+ offset_value = grn_expr_get_var(ctx, expr,
+ "offset", strlen("offset"));
+ limit_value = grn_expr_get_var(ctx, expr,
+ "limit", strlen("limit"));
+ if (GRN_TEXT_LEN(offset_value)) {
+ offset = grn_atoi(GRN_TEXT_VALUE(offset_value),
+ GRN_BULK_CURR(offset_value),
+ NULL);
+ } else {
+ offset = 0;
+ }
+ if (GRN_TEXT_LEN(limit_value)) {
+ limit = grn_atoi(GRN_TEXT_VALUE(limit_value),
+ GRN_BULK_CURR(limit_value),
+ NULL);
+ } else {
+#define DEFAULT_LIMIT 10
+ limit = DEFAULT_LIMIT;
+#undef DEFAULT_LIMIT
+ }
+ grn_normalize_offset_and_limit(ctx, nhits, &offset, &limit);
+ record_n = offset + 1;
+ GRN_TEXT_PUTS(ctx, transformed,
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<SEGMENTS>\n"
+ "<SEGMENT>\n"
+ "<RESULTPAGE>\n"
+ "<RESULTSET OFFSET=\"");
+ grn_text_lltoa(ctx, transformed, offset);
+ GRN_TEXT_PUTS(ctx, transformed, "\" LIMIT=\"");
+ grn_text_lltoa(ctx, transformed, limit);
+ GRN_TEXT_PUTS(ctx, transformed, "\" NHITS=\"");
+ grn_text_lltoa(ctx, transformed, nhits);
+ GRN_TEXT_PUTS(ctx, transformed, "\">\n");
+ } else {
+ GRN_TEXT_PUTS(ctx, transformed,
+ "<NAVIGATIONELEMENTS COUNT=\"");
+ GRN_TEXT_PUT(ctx, transformed,
+ GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf));
+ GRN_TEXT_PUTS(ctx, transformed,
+ "\">\n");
+ }
+ } else if (EQUAL_NAME_P("TEXT")) {
+ switch (place) {
+ case XML_PLACE_COLUMN :
+ if (column_text_n == 0) {
+ GRN_TEXT_PUT(ctx, &columns,
+ GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf));
+ GRN_TEXT_PUTC(ctx, &columns, '\0');
+ }
+ column_text_n++;
+ break;
+ default :
+ break;
+ }
+ }
+ }
+ }
+ default :
+ break;
+ }
+ s++;
+ GRN_BULK_REWIND(&buf);
+ status = XML_TEXT;
+ break;
+ default :
+ len = grn_charlen(ctx, s, e);
+ switch (status) {
+ case XML_START_ELEMENT :
+ case XML_END_ELEMENT :
+ GRN_TEXT_PUT(ctx, &name, s, len);
+ break;
+ default :
+ GRN_TEXT_PUT(ctx, &buf, s, len);
+ break;
+ }
+ s += len;
+ break;
+ }
+ }
+#undef EQUAL_NAME_P
+
+ GRN_OBJ_FIN(ctx, &buf);
+ GRN_OBJ_FIN(ctx, &name);
+ GRN_OBJ_FIN(ctx, &columns);
+}
+
+#ifdef GRN_WITH_MESSAGE_PACK
+typedef struct {
+ grn_ctx *ctx;
+ grn_obj *buffer;
+} msgpack_writer_ctx;
+
+static inline int
+msgpack_buffer_writer(void* data, const char* buf, msgpack_size_t len)
+{
+ msgpack_writer_ctx *writer_ctx = (msgpack_writer_ctx *)data;
+ return grn_bulk_write(writer_ctx->ctx, writer_ctx->buffer, buf, len);
+}
+#endif
+
+#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,
+ grn_obj *head,
+ grn_obj *body,
+ grn_obj *foot,
+ const char *file,
+ int line)
+{
+ double started, finished, elapsed;
+
+ grn_timeval tv_now;
+ grn_timeval_now(ctx, &tv_now);
+ started = ctx->impl->tv.tv_sec;
+ started += ctx->impl->tv.tv_nsec / GRN_TIME_NSEC_PER_SEC_F;
+ finished = tv_now.tv_sec;
+ finished += tv_now.tv_nsec / GRN_TIME_NSEC_PER_SEC_F;
+ elapsed = finished - started;
+
+ switch (ctx->impl->output.type) {
+ case GRN_CONTENT_JSON:
+ {
+ 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, ");");
+ }
+ }
+ break;
+ case GRN_CONTENT_TSV:
+ grn_text_itoa(ctx, head, rc);
+ GRN_TEXT_PUTC(ctx, head, '\t');
+ grn_text_ftoa(ctx, head, started);
+ GRN_TEXT_PUTC(ctx, head, '\t');
+ grn_text_ftoa(ctx, head, elapsed);
+ if (rc != GRN_SUCCESS) {
+ GRN_TEXT_PUTC(ctx, head, '\t');
+ grn_text_esc(ctx, head, ctx->errbuf, strlen(ctx->errbuf));
+ if (ctx->errfunc && ctx->errfile) {
+ /* TODO: output backtrace */
+ GRN_TEXT_PUTC(ctx, head, '\t');
+ grn_text_esc(ctx, head, ctx->errfunc, strlen(ctx->errfunc));
+ GRN_TEXT_PUTC(ctx, head, '\t');
+ grn_text_esc(ctx, head, ctx->errfile, strlen(ctx->errfile));
+ GRN_TEXT_PUTC(ctx, head, '\t');
+ grn_text_itoa(ctx, head, ctx->errline);
+ }
+ }
+ GRN_TEXT_PUTS(ctx, head, "\n");
+ GRN_TEXT_PUTS(ctx, foot, "\nEND");
+ break;
+ case GRN_CONTENT_XML:
+ {
+ char buf[GRN_TABLE_MAX_KEY_SIZE];
+ int is_select = 0;
+ if (!rc && ctx->impl->curr_expr) {
+ int len = grn_obj_name(ctx, ctx->impl->curr_expr,
+ buf, GRN_TABLE_MAX_KEY_SIZE);
+ buf[len] = '\0';
+ is_select = strcmp(buf, "select") == 0;
+ }
+ if (is_select) {
+ grn_obj transformed;
+ GRN_TEXT_INIT(&transformed, 0);
+ transform_xml(ctx, body, &transformed);
+ GRN_TEXT_SET(ctx, body,
+ GRN_TEXT_VALUE(&transformed), GRN_TEXT_LEN(&transformed));
+ GRN_OBJ_FIN(ctx, &transformed);
+ } else {
+ GRN_TEXT_PUTS(ctx, head, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RESULT CODE=\"");
+ grn_text_itoa(ctx, head, rc);
+ GRN_TEXT_PUTS(ctx, head, "\" UP=\"");
+ grn_text_ftoa(ctx, head, started);
+ GRN_TEXT_PUTS(ctx, head, "\" ELAPSED=\"");
+ grn_text_ftoa(ctx, head, elapsed);
+ GRN_TEXT_PUTS(ctx, head, "\">\n");
+ if (rc != GRN_SUCCESS) {
+ GRN_TEXT_PUTS(ctx, head, "<ERROR>");
+ grn_text_escape_xml(ctx, head, ctx->errbuf, strlen(ctx->errbuf));
+ if (ctx->errfunc && ctx->errfile) {
+ /* TODO: output backtrace */
+ GRN_TEXT_PUTS(ctx, head, "<INFO FUNC=\"");
+ grn_text_escape_xml(ctx, head, ctx->errfunc, strlen(ctx->errfunc));
+ GRN_TEXT_PUTS(ctx, head, "\" FILE=\"");
+ grn_text_escape_xml(ctx, head, ctx->errfile, strlen(ctx->errfile));
+ GRN_TEXT_PUTS(ctx, head, "\" LINE=\"");
+ grn_text_itoa(ctx, head, ctx->errline);
+ GRN_TEXT_PUTS(ctx, head, "\"/>");
+ }
+ GRN_TEXT_PUTS(ctx, head, "</ERROR>");
+ }
+ GRN_TEXT_PUTS(ctx, foot, "\n</RESULT>");
+ }
+ }
+ break;
+ case GRN_CONTENT_MSGPACK:
+#ifdef GRN_WITH_MESSAGE_PACK
+ 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 /* GRN_WITH_MESSAGE_PACK */
+ break;
+ case GRN_CONTENT_GROONGA_COMMAND_LIST :
+ break;
+ case GRN_CONTENT_NONE:
+ break;
+ }
+}
+
+static inline grn_bool
+is_output_columns_format_v1(grn_ctx *ctx,
+ const char *output_columns,
+ unsigned int output_columns_len)
+{
+ const char *current;
+ const char *end;
+ grn_bool in_identifier = GRN_FALSE;
+
+ current = output_columns;
+ end = current + output_columns_len;
+ while (current < end) {
+ int char_length;
+
+ char_length = grn_charlen(ctx, current, end);
+ if (char_length != 1) {
+ return GRN_FALSE;
+ }
+
+ 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;
+}
+
+grn_rc
+grn_output_format_set_columns(grn_ctx *ctx, grn_obj_format *format,
+ grn_obj *table,
+ const char *columns, int columns_len)
+{
+ grn_rc rc;
+
+ if (is_output_columns_format_v1(ctx, columns, columns_len)) {
+ rc = grn_obj_columns(ctx, table, columns, columns_len, &(format->columns));
+ } else {
+ grn_obj *variable;
+ GRN_EXPR_CREATE_FOR_QUERY(ctx, table, format->expression, variable);
+ rc = grn_expr_parse(ctx, format->expression,
+ columns, columns_len, NULL,
+ GRN_OP_MATCH, GRN_OP_AND,
+ GRN_EXPR_SYNTAX_OUTPUT_COLUMNS);
+ }
+
+ return rc;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/pat.c b/storage/mroonga/vendor/groonga/lib/pat.c
new file mode 100644
index 00000000..01f6108f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/pat.c
@@ -0,0 +1,3674 @@
+/* -*- 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-1335 USA
+*/
+#include "grn.h"
+#include <string.h>
+#include <limits.h>
+#include "grn_pat.h"
+#include "grn_output.h"
+#include "grn_util.h"
+#include "grn_normalizer.h"
+
+#define GRN_PAT_DELETED (GRN_ID_MAX + 1)
+
+#define GRN_PAT_SEGMENT_SIZE 0x400000
+#define W_OF_KEY_IN_A_SEGMENT 22
+#define W_OF_PAT_IN_A_SEGMENT 18
+#define W_OF_SIS_IN_A_SEGMENT 19
+#define KEY_MASK_IN_A_SEGMENT 0x3fffff
+#define PAT_MASK_IN_A_SEGMENT 0x3ffff
+#define SIS_MASK_IN_A_SEGMENT 0x7ffff
+#define SEG_NOT_ASSIGNED 0xffff
+#define GRN_PAT_MAX_SEGMENT 0x1000
+#define GRN_PAT_MDELINFOS (GRN_PAT_NDELINFOS - 1)
+
+#define GRN_PAT_BIN_KEY 0x70000
+
+typedef struct {
+ grn_id lr[2];
+ /*
+ lr[0]: the left node.
+ lr[1]: the right node.
+
+ The left node has 0 at the nth bit at the nth byte.
+ The right node has 1 at the nth bit at the nth byte.
+ 'check' value indicate 'at the nth bit at the nth byte'.
+
+ The both available nodes has larger check value rather
+ than the current node.
+
+ The first node (PAT_AT(pat, GRN_ID_NIL, node)) has only
+ the right node and the node is the start point.
+ */
+ uint32_t key;
+ /*
+ PAT_IMD(node) == 0: key bytes offset in memory map.
+ PAT_IMD(node) == 1: the key bytes.
+ */
+ uint16_t check;
+ /*
+ nth byte: 12, nth bit: 3, terminated: 1
+
+ nth byte is different in key bytes: (check >> 4): max == 4095
+ the left most byte is the 0th byte and the right most byte is the 11th byte.
+
+ nth bit is different in nth byte: ((check >> 1) & 0b111)
+ the left most bit is the 0th bit and the right most bit is the 7th bit.
+
+ terminated: (check & 0b1)
+ terminated == 1: key is terminated.
+ */
+ uint16_t bits;
+ /* length: 13, immediate: 1, deleting: 1 */
+} pat_node;
+
+#define PAT_DELETING (1<<1)
+#define PAT_IMMEDIATE (1<<2)
+
+#define PAT_DEL(x) ((x)->bits & PAT_DELETING)
+#define PAT_IMD(x) ((x)->bits & PAT_IMMEDIATE)
+#define PAT_LEN(x) (((x)->bits >> 3) + 1)
+#define PAT_CHK(x) ((x)->check)
+#define PAT_DEL_ON(x) ((x)->bits |= PAT_DELETING)
+#define PAT_IMD_ON(x) ((x)->bits |= PAT_IMMEDIATE)
+#define PAT_DEL_OFF(x) ((x)->bits &= ~PAT_DELETING)
+#define PAT_IMD_OFF(x) ((x)->bits &= ~PAT_IMMEDIATE)
+#define PAT_LEN_SET(x,v) ((x)->bits = ((x)->bits & ((1<<3) - 1))|(((v) - 1) << 3))
+#define PAT_CHK_SET(x,v) ((x)->check = (v))
+
+typedef struct {
+ grn_id children;
+ grn_id sibling;
+} sis_node;
+
+enum {
+ segment_key = 0,
+ segment_pat = 1,
+ 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)
+
+/* segment operation */
+
+/* patricia array operation */
+
+#define PAT_AT(pat,id,n) do {\
+ int flags = 0;\
+ GRN_IO_ARRAY_AT(pat->io, segment_pat, id, &flags, n);\
+} while (0)
+
+inline static pat_node *
+pat_get(grn_ctx *ctx, grn_pat *pat, grn_id id)
+{
+ pat_node *res;
+ int flags = GRN_TABLE_ADD;
+ if (id > GRN_ID_MAX) { return NULL; }
+ GRN_IO_ARRAY_AT(pat->io, segment_pat, id, &flags, res);
+ return res;
+}
+
+/* sis operation */
+
+inline static sis_node *
+sis_at(grn_ctx *ctx, grn_pat *pat, grn_id id)
+{
+ sis_node *res;
+ int flags = 0;
+ if (id > GRN_ID_MAX) { return NULL; }
+ GRN_IO_ARRAY_AT(pat->io, segment_sis, id, &flags, res);
+ return res;
+}
+
+inline static sis_node *
+sis_get(grn_ctx *ctx, grn_pat *pat, grn_id id)
+{
+ sis_node *res;
+ int flags = GRN_TABLE_ADD;
+ if (id > GRN_ID_MAX) { return NULL; }
+ GRN_IO_ARRAY_AT(pat->io, segment_sis, id, &flags, res);
+ return res;
+}
+
+#define MAX_LEVEL 16
+
+static void
+sis_collect(grn_ctx *ctx, grn_pat *pat, grn_hash *h, grn_id id, uint32_t level)
+{
+ uint32_t *offset;
+ sis_node *sl = sis_at(ctx, pat, id);
+ if (sl) {
+ grn_id sid = sl->children;
+ while (sid && sid != id) {
+ if (grn_hash_add(ctx, h, &sid, sizeof(grn_id), (void **) &offset, NULL)) {
+ *offset = level;
+ if (level < MAX_LEVEL) { sis_collect(ctx, pat, h, sid, level + 1); }
+ if (!(sl = sis_at(ctx, pat, sid))) { break; }
+ sid = sl->sibling;
+ } else {
+ /* todo : must be handled */
+ }
+ }
+ }
+}
+
+/* key operation */
+
+#define KEY_AT(pat,pos,ptr,addp) do {\
+ int flags = addp;\
+ GRN_IO_ARRAY_AT(pat->io, segment_key, pos, &flags, ptr);\
+} while (0)
+
+inline static uint32_t
+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;
+ }
+ {
+ uint8_t *dest;
+ KEY_AT(pat, res, dest, GRN_TABLE_ADD);
+ 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;
+ return res;
+}
+
+inline static uint8_t *
+pat_node_get_key(grn_ctx *ctx, grn_pat *pat, pat_node *n)
+{
+ if (PAT_IMD(n)) {
+ return (uint8_t *) &n->key;
+ } else {
+ uint8_t *res;
+ KEY_AT(pat, n->key, res, 0);
+ return res;
+ }
+}
+
+inline static grn_rc
+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 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
+};
+
+inline static grn_pat_delinfo *
+delinfo_search(grn_pat *pat, grn_id id)
+{
+ int i;
+ grn_pat_delinfo *di;
+ for (i = (pat->header->curr_del2) & GRN_PAT_MDELINFOS;
+ i != pat->header->curr_del;
+ i = (i + 1) & GRN_PAT_MDELINFOS) {
+ di = &pat->header->delinfos[i];
+ if (di->stat != DL_PHASE1) { continue; }
+ if (di->ld == id) { return di; }
+ if (di->d == id) { return di; }
+ }
+ return NULL;
+}
+
+inline static grn_rc
+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;
+ }
+ PAT_AT(pat, di->ld, ln);
+ 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;
+ }
+ PAT_DEL_OFF(ln);
+ PAT_DEL_OFF(dn);
+ {
+ 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;
+ }
+ PAT_AT(pat, 0, rn);
+ p0 = &rn->lr[1];
+ 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;
+ }
+ c = PAT_CHK(rn);
+ if (c <= c0 || len <= c) {
+ break;
+ }
+ if (c & 1) {
+ p0 = (c + 1 < len) ? &rn->lr[1] : &rn->lr[0];
+ } else {
+ p0 = &rn->lr[nth_bit((uint8_t *)key, c, len)];
+ }
+ c0 = c;
+ }
+ }
+ if (p) {
+ PAT_CHK_SET(ln, PAT_CHK(dn));
+ ln->lr[1] = dn->lr[1];
+ ln->lr[0] = dn->lr[0];
+ *p = di->ld;
+ } else {
+ /* debug */
+ int j;
+ grn_id dd;
+ grn_pat_delinfo *ddi;
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "failed to find d=%d", d);
+ for (j = (pat->header->curr_del2 + 1) & GRN_PAT_MDELINFOS;
+ j != pat->header->curr_del;
+ j = (j + 1) & GRN_PAT_MDELINFOS) {
+ ddi = &pat->header->delinfos[j];
+ if (ddi->stat != DL_PHASE1) { continue; }
+ PAT_AT(pat, ddi->ld, ln);
+ if (!ln) { continue; }
+ if (!(dd = ddi->d)) { continue; }
+ if (d == ddi->ld) {
+ GRN_LOG(ctx, GRN_LOG_DEBUG, "found!!!, d(%d) become ld of (%d)", d, dd);
+ }
+ }
+ /* debug */
+ }
+ di->stat = DL_PHASE2;
+ di->d = d;
+ // grn_log("delinfo_turn_2< di->d=%d di->ld=%d", di->d, di->ld);
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+delinfo_turn_3(grn_ctx *ctx, grn_pat *pat, grn_pat_delinfo *di)
+{
+ pat_node *dn;
+ uint32_t size;
+ if (di->stat != DL_PHASE2) { return GRN_SUCCESS; }
+ PAT_AT(pat, di->d, dn);
+ if (!dn) { return GRN_INVALID_ARGUMENT; }
+ if (di->shared) {
+ PAT_IMD_ON(dn);
+ size = 0;
+ } else {
+ if (PAT_IMD(dn)) {
+ size = 0;
+ } else {
+ size = PAT_LEN(dn);
+ }
+ }
+ di->stat = DL_EMPTY;
+ // dn->lr[1] = GRN_PAT_DELETED;
+ dn->lr[0] = pat->header->garbages[size];
+ pat->header->garbages[size] = di->d;
+ return GRN_SUCCESS;
+}
+
+inline static grn_pat_delinfo *
+delinfo_new(grn_ctx *ctx, grn_pat *pat)
+{
+ grn_pat_delinfo *res = &pat->header->delinfos[pat->header->curr_del];
+ uint32_t n = (pat->header->curr_del + 1) & GRN_PAT_MDELINFOS;
+ int gap = ((n + GRN_PAT_NDELINFOS - pat->header->curr_del2) & GRN_PAT_MDELINFOS)
+ - (GRN_PAT_NDELINFOS / 2);
+ while (gap-- > 0) {
+ if (delinfo_turn_2(ctx, pat, &pat->header->delinfos[pat->header->curr_del2])) {
+ GRN_LOG(ctx, GRN_LOG_CRIT, "d2 failed: %d", pat->header->delinfos[pat->header->curr_del2].ld);
+ }
+ pat->header->curr_del2 = (pat->header->curr_del2 + 1) & GRN_PAT_MDELINFOS;
+ }
+ if (n == pat->header->curr_del3) {
+ if (delinfo_turn_3(ctx, pat, &pat->header->delinfos[pat->header->curr_del3])) {
+ GRN_LOG(ctx, GRN_LOG_CRIT, "d3 failed: %d", pat->header->delinfos[pat->header->curr_del3].ld);
+ }
+ pat->header->curr_del3 = (pat->header->curr_del3 + 1) & GRN_PAT_MDELINFOS;
+ }
+ pat->header->curr_del = n;
+ return res;
+}
+
+/* pat operation */
+
+inline static grn_pat *
+_grn_pat_create(grn_ctx *ctx, grn_pat *pat,
+ const char *path, uint32_t key_size,
+ uint32_t value_size, uint32_t flags) {
+ grn_io *io;
+ pat_node *node0;
+ struct grn_pat_header *header;
+ uint32_t entry_size, w_of_element;
+ grn_encoding encoding = ctx->encoding;
+ if (flags & GRN_OBJ_KEY_WITH_SIS) {
+ entry_size = sizeof(sis_node) + value_size;
+ } else {
+ entry_size = value_size;
+ }
+ for (w_of_element = 0; (1 << w_of_element) < entry_size; w_of_element++) {
+ /* nop */
+ }
+ {
+ grn_io_array_spec array_spec[3];
+ array_spec[segment_key].w_of_element = 0;
+ array_spec[segment_key].max_n_segments = 0x400;
+ array_spec[segment_pat].w_of_element = 4;
+ array_spec[segment_pat].max_n_segments = 1 << (30 - (22 - 4));
+ array_spec[segment_sis].w_of_element = w_of_element;
+ array_spec[segment_sis].max_n_segments = 1 << (30 - (22 - w_of_element));
+ io = grn_io_create_with_array(ctx, path, sizeof(struct grn_pat_header),
+ GRN_PAT_SEGMENT_SIZE, grn_io_auto, 3, array_spec);
+ }
+ if (!io) { return NULL; }
+ if (encoding == GRN_ENC_DEFAULT) { encoding = grn_gctx.encoding; }
+ header = grn_io_header(io);
+ grn_io_set_type(io, GRN_TABLE_PAT_KEY);
+ header->flags = flags;
+ header->encoding = encoding;
+ header->key_size = key_size;
+ header->value_size = value_size;
+ header->n_entries = 0;
+ header->curr_rec = 0;
+ header->curr_key = 0;
+ header->curr_del = 0;
+ header->curr_del2 = 0;
+ header->curr_del3 = 0;
+ header->n_garbages = 0;
+ header->tokenizer = GRN_ID_NIL;
+ if (header->flags & GRN_OBJ_KEY_NORMALIZE) {
+ header->flags &= ~GRN_OBJ_KEY_NORMALIZE;
+ pat->normalizer = grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1);
+ header->normalizer = grn_obj_id(ctx, pat->normalizer);
+ } else {
+ 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;
+ pat->key_size = key_size;
+ pat->value_size = value_size;
+ pat->tokenizer = NULL;
+ pat->encoding = encoding;
+ pat->obj.header.flags = header->flags;
+ if (!(node0 = pat_get(ctx, pat, 0))) {
+ grn_io_close(ctx, io);
+ return NULL;
+ }
+ node0->lr[1] = 0;
+ node0->lr[0] = 0;
+ node0->key = 0;
+ return pat;
+}
+
+grn_pat *
+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_CALLOC(sizeof(grn_pat)))) {
+ return NULL;
+ }
+ GRN_DB_OBJ_SET_TYPE(pat, GRN_TABLE_PAT_KEY);
+ if (!_grn_pat_create(ctx, pat, path, key_size, value_size, flags)) {
+ 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_cache_enable() and grn_pat_cache_disable() are not thread-safe.
+ So far, they can be used only from single threaded programs.
+ */
+
+grn_rc
+grn_pat_cache_enable(grn_ctx *ctx, grn_pat *pat, uint32_t cache_size)
+{
+ if (pat->cache || pat->cache_size) {
+ ERR(GRN_INVALID_ARGUMENT, "cache is already enabled");
+ return ctx->rc;
+ }
+ if (cache_size & (cache_size - 1)) {
+ ERR(GRN_INVALID_ARGUMENT, "cache_size(%u) must be a power of two", cache_size);
+ return ctx->rc;
+ }
+ if (!(pat->cache = GRN_CALLOC(cache_size * sizeof(grn_id)))) {
+ return ctx->rc;
+ }
+ pat->cache_size = cache_size;
+ return GRN_SUCCESS;
+}
+
+void
+grn_pat_cache_disable(grn_ctx *ctx, grn_pat *pat)
+{
+ if (pat->cache) {
+ GRN_FREE(pat->cache);
+ pat->cache_size = 0;
+ pat->cache = NULL;
+ }
+}
+
+grn_pat *
+grn_pat_open(grn_ctx *ctx, const char *path)
+{
+ grn_io *io;
+ 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);
+ 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;
+ }
+ if (!(pat = GRN_MALLOC(sizeof(grn_pat)))) {
+ grn_io_close(ctx, io);
+ return NULL;
+ }
+ GRN_DB_OBJ_SET_TYPE(pat, GRN_TABLE_PAT_KEY);
+ pat->io = io;
+ pat->header = header;
+ pat->key_size = header->key_size;
+ pat->value_size = header->value_size;
+ pat->encoding = header->encoding;
+ pat->tokenizer = grn_ctx_at(ctx, header->tokenizer);
+ if (header->flags & GRN_OBJ_KEY_NORMALIZE) {
+ header->flags &= ~GRN_OBJ_KEY_NORMALIZE;
+ pat->normalizer = grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1);
+ header->normalizer = grn_obj_id(ctx, pat->normalizer);
+ } else {
+ pat->normalizer = grn_ctx_at(ctx, header->normalizer);
+ }
+ GRN_PTR_INIT(&(pat->token_filters), GRN_OBJ_VECTOR, GRN_ID_NIL);
+ pat->obj.header.flags = header->flags;
+ PAT_AT(pat, 0, node0);
+ if (!node0) {
+ grn_io_close(ctx, io);
+ 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_pvector_fin(ctx, &pat->token_filters);
+ if (pat->cache) { grn_pat_cache_disable(ctx, pat); }
+ GRN_FREE(pat);
+ }
+
+ return rc;
+}
+
+grn_rc
+grn_pat_remove(grn_ctx *ctx, const char *path)
+{
+ if (!path) {
+ ERR(GRN_INVALID_ARGUMENT, "path is null");
+ return GRN_INVALID_ARGUMENT;
+ }
+ return grn_io_remove(ctx, path);
+}
+
+grn_rc
+grn_pat_truncate(grn_ctx *ctx, grn_pat *pat)
+{
+ grn_rc rc;
+ const char *io_path;
+ 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);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ } else {
+ path = NULL;
+ }
+ 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)) {
+ rc = GRN_UNKNOWN_ERROR;
+ }
+ if (pat->cache && pat->cache_size) {
+ memset(pat->cache, 0, pat->cache_size * sizeof(grn_id));
+ }
+exit:
+ if (path) { GRN_FREE(path); }
+ return rc;
+}
+
+inline static grn_id
+_grn_pat_add(grn_ctx *ctx, grn_pat *pat, const uint8_t *key, uint32_t size, uint32_t *new, uint32_t *lkey)
+{
+ 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;
+ for (cache_id = 0; length--; p++) { cache_id = (cache_id * 37) + *p; }
+ cache_id &= (pat->cache_size - 1);
+ if (pat->cache[cache_id]) {
+ PAT_AT(pat, pat->cache[cache_id], rn);
+ if (rn) {
+ const uint8_t *k = pat_node_get_key(ctx, pat, rn);
+ if (k && size == PAT_LEN(rn) && !memcmp(k, key, size)) {
+ return pat->cache[cache_id];
+ }
+ }
+ }
+ }
+
+ len = (int)size * 16;
+ PAT_AT(pat, 0, rn0);
+ p0 = &rn0->lr[1];
+ if (*p0) {
+ uint32_t size2;
+ int xor, mask;
+ const uint8_t *s, *d;
+ for (;;) {
+ if (!(r0 = *p0)) {
+ if (!(s = pat_node_get_key(ctx, pat, rn0))) { return GRN_ID_NIL; }
+ size2 = PAT_LEN(rn0);
+ break;
+ }
+ PAT_AT(pat, r0, rn0);
+ if (!rn0) { return GRN_ID_NIL; }
+ if (c0 < rn0->check && rn0->check < len) {
+ c1 = c0; c0 = rn0->check;
+ p1 = p0;
+ if (c0 & 1) {
+ p0 = (c0 + 1 < len) ? &rn0->lr[1] : &rn0->lr[0];
+ } else {
+ p0 = &rn0->lr[nth_bit(key, c0, len)];
+ }
+ } else {
+ 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; }
+ return r0;
+ }
+ break;
+ }
+ }
+ {
+ uint32_t min = size > size2 ? size2 : size;
+ for (c = 0, d = key; min && *s == *d; c += 16, s++, d++, min--);
+ if (min) {
+ for (xor = *s ^ *d, mask = 0x80; !(xor & mask); mask >>= 1, c += 2);
+ } else {
+ c--;
+ }
+ }
+ if (c == c0 && !*p0) {
+ if (c < len - 2) { c += 2; }
+ } else {
+ if (c < c0) {
+ if (c > c1) {
+ p0 = p1;
+ } else {
+ PAT_AT(pat, 0, rn0);
+ p0 = &rn0->lr[1];
+ while ((r0 = *p0)) {
+ PAT_AT(pat, r0, rn0);
+ if (!rn0) { return GRN_ID_NIL; }
+ c0 = PAT_CHK(rn0);
+ if (c < c0) { break; }
+ if (c0 & 1) {
+ p0 = (c0 + 1 < len) ? &rn0->lr[1] : &rn0->lr[0];
+ } else {
+ p0 = &rn0->lr[nth_bit(key, c0, len)];
+ }
+ }
+ }
+ }
+ }
+ if (c >= len) { return GRN_ID_NIL; }
+ } else {
+ c = len - 2;
+ }
+ {
+ uint32_t size2 = size > sizeof(uint32_t) ? size : 0;
+ 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->header->garbages[0] = rn->lr[0];
+ } else {
+ 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);
+ rn->key = *lkey;
+ } else {
+ 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->header->garbages[size2] = rn->lr[0];
+ PAT_LEN_SET(rn, size);
+ grn_memcpy(keybuf, key, size);
+ } else {
+ 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;
+ }
+ }
+ PAT_CHK_SET(rn, c);
+ PAT_DEL_OFF(rn);
+ if ((c & 1) ? (c + 1 < len) : nth_bit(key, c, len)) {
+ rn->lr[1] = r;
+ rn->lr[0] = *p0;
+ } else {
+ rn->lr[1] = *p0;
+ rn->lr[0] = r;
+ }
+ // smp_wmb();
+ *p0 = r;
+ *new = 1;
+ if (pat->cache) { pat->cache[cache_id] = r; }
+ return r;
+}
+
+inline static grn_bool
+chop(grn_ctx *ctx, grn_pat *pat, const char **key, const char *end, uint32_t *lkey)
+{
+ size_t len = grn_charlen(ctx, *key, end);
+ if (len) {
+ *lkey += len;
+ *key += len;
+ return (end - *key) > 0;
+ } else {
+ return GRN_FALSE;
+ }
+}
+
+#define MAX_FIXED_KEY_SIZE (sizeof(int64_t))
+
+#define KEY_NEEDS_CONVERT(pat,size) \
+ (!((pat)->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) && (size) <= MAX_FIXED_KEY_SIZE)
+
+#define KEY_ENC(pat,keybuf,key,size) do {\
+ switch ((pat)->obj.header.flags & GRN_OBJ_KEY_MASK) {\
+ case GRN_OBJ_KEY_UINT :\
+ if (((pat)->obj.header.domain != GRN_DB_TOKYO_GEO_POINT) &&\
+ ((pat)->obj.header.domain != GRN_DB_WGS84_GEO_POINT)) {\
+ grn_hton((keybuf), (key), (size));\
+ break;\
+ }\
+ case GRN_OBJ_KEY_GEO_POINT :\
+ grn_gton((keybuf), (key), (size));\
+ break;\
+ case GRN_OBJ_KEY_INT :\
+ grn_hton((keybuf), (key), (size));\
+ *((uint8_t *)(keybuf)) ^= 0x80;\
+ break;\
+ case GRN_OBJ_KEY_FLOAT :\
+ if ((size) == sizeof(int64_t)) {\
+ int64_t v = *(int64_t *)(key);\
+ v ^= ((v >> 63)|(1ULL << 63));\
+ grn_hton((keybuf), &v, (size));\
+ }\
+ break;\
+ }\
+} while (0)
+
+#define KEY_DEC(pat,keybuf,key,size) do {\
+ switch ((pat)->obj.header.flags & GRN_OBJ_KEY_MASK) {\
+ case GRN_OBJ_KEY_UINT :\
+ if (((pat)->obj.header.domain != GRN_DB_TOKYO_GEO_POINT) &&\
+ ((pat)->obj.header.domain != GRN_DB_WGS84_GEO_POINT)) {\
+ grn_ntoh((keybuf), (key), (size));\
+ break;\
+ }\
+ case GRN_OBJ_KEY_GEO_POINT :\
+ grn_ntog((keybuf), (key), (size));\
+ break;\
+ case GRN_OBJ_KEY_INT :\
+ grn_ntohi((keybuf), (key), (size));\
+ break;\
+ case GRN_OBJ_KEY_FLOAT :\
+ if ((size) == sizeof(int64_t)) {\
+ int64_t v;\
+ grn_hton(&v, (key), (size));\
+ *((int64_t *)(keybuf)) = v ^ ((((int64_t)(v^(1ULL<<63)))>> 63)|(1ULL<<63)); \
+ }\
+ break;\
+ }\
+} while (0)
+
+#define KEY_ENCODE(pat,keybuf,key,size) do {\
+ if (KEY_NEEDS_CONVERT(pat,size)) {\
+ KEY_ENC((pat), (keybuf), (key), (size));\
+ (key) = (keybuf);\
+ }\
+} while (0)
+
+grn_id
+grn_pat_add(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_size,
+ void **value, int *added)
+{
+ 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);
+ return GRN_ID_NIL;
+ }
+ 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!!
+ sis_node *sl, *sr;
+ grn_id l = r0, r;
+ if (new && (sl = sis_get(ctx, pat, l))) {
+ const char *sis = key, *end = sis + key_size;
+ sl->children = l;
+ sl->sibling = 0;
+ while (chop(ctx, pat, &sis, end, &lkey)) {
+ if (!(*sis & 0x80)) { break; }
+ if (!(r = _grn_pat_add(ctx, pat, (uint8_t *)sis, end - sis, &new, &lkey))) {
+ break;
+ }
+ if (!(sr = sis_get(ctx, pat, r))) { break; }
+ if (new) {
+ sl->sibling = r;
+ sr->children = l;
+ sr->sibling = 0;
+ } else {
+ sl->sibling = sr->children;
+ sr->children = l;
+ break;
+ }
+ l = r;
+ sl = sr;
+ }
+ }
+ }
+ if (r0 && value) {
+ byte *v = (byte *)sis_get(ctx, pat, r0);
+ if (pat->obj.header.flags & GRN_OBJ_KEY_WITH_SIS) {
+ *value = v + sizeof(sis_node);
+ } else {
+ *value = v;
+ }
+ }
+ return r0;
+}
+
+inline static grn_id
+_grn_pat_get(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_size, void **value)
+{
+ grn_id r;
+ pat_node *rn;
+ int c0 = -1, c;
+ uint32_t len = key_size * 16;
+ PAT_AT(pat, 0, rn);
+ for (r = rn->lr[1]; r;) {
+ PAT_AT(pat, r, rn);
+ if (!rn) { break; /* corrupt? */ }
+ c = PAT_CHK(rn);
+ if (len <= c) { break; }
+ if (c <= c0) {
+ const uint8_t *k = pat_node_get_key(ctx, pat, rn);
+ if (k && key_size == PAT_LEN(rn) && !memcmp(k, key, key_size)) {
+ if (value) {
+ byte *v = (byte *)sis_get(ctx, pat, r);
+ if (pat->obj.header.flags & GRN_OBJ_KEY_WITH_SIS) {
+ *value = v + sizeof(sis_node);
+ } else {
+ *value = v;
+ }
+ }
+ return r;
+ }
+ break;
+ }
+ 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;
+ }
+ return GRN_ID_NIL;
+}
+
+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);
+}
+
+grn_id
+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;
+ }
+ }
+ return r;
+}
+
+static void
+get_tc(grn_ctx *ctx, grn_pat *pat, grn_hash *h, pat_node *rn)
+{
+ grn_id id;
+ pat_node *node;
+ id = rn->lr[1];
+ if (id) {
+ PAT_AT(pat, id, node);
+ if (node) {
+ if (PAT_CHK(node) > PAT_CHK(rn)) {
+ get_tc(ctx, pat, h, node);
+ } else {
+ grn_hash_add(ctx, h, &id, sizeof(grn_id), NULL, NULL);
+ }
+ }
+ }
+ id = rn->lr[0];
+ if (id) {
+ PAT_AT(pat, id, node);
+ if (node) {
+ if (PAT_CHK(node) > PAT_CHK(rn)) {
+ get_tc(ctx, pat, h, node);
+ } else {
+ grn_hash_add(ctx, h, &id, sizeof(grn_id), NULL, NULL);
+ }
+ }
+ }
+}
+
+grn_rc
+grn_pat_prefix_search(grn_ctx *ctx, grn_pat *pat,
+ const void *key, uint32_t key_size, grn_hash *h)
+{
+ 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];
+ 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];
+ while (r) {
+ PAT_AT(pat, r, rn);
+ if (!rn) { return GRN_FILE_CORRUPT; }
+ 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)) {
+ if (c >= len - 1) {
+ get_tc(ctx, pat, h, rn);
+ } else {
+ grn_hash_add(ctx, h, &r, sizeof(grn_id), NULL, NULL);
+ }
+ return GRN_SUCCESS;
+ }
+ break;
+ }
+ return GRN_END_OF_DATA;
+}
+
+grn_hash *
+grn_pat_prefix_search2(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_size)
+{
+ grn_hash *h;
+ if (!pat || !key) { return NULL; }
+ if ((h = grn_hash_create(ctx, NULL, sizeof(grn_id), 0, 0))) {
+ if (grn_pat_prefix_search(ctx, pat, key, key_size, h)) {
+ grn_hash_close(ctx, h);
+ h = NULL;
+ }
+ }
+ return h;
+}
+
+grn_rc
+grn_pat_suffix_search(grn_ctx *ctx, grn_pat *pat,
+ const void *key, uint32_t key_size, grn_hash *h)
+{
+ grn_id r;
+ if ((r = grn_pat_get(ctx, pat, key, key_size, NULL))) {
+ uint32_t *offset;
+ if (grn_hash_add(ctx, h, &r, sizeof(grn_id), (void **) &offset, NULL)) {
+ *offset = 0;
+ if (pat->obj.header.flags & GRN_OBJ_KEY_WITH_SIS) { sis_collect(ctx, pat, h, r, 1); }
+ return GRN_SUCCESS;
+ }
+ }
+ return GRN_END_OF_DATA;
+}
+
+grn_hash *
+grn_pat_suffix_search2(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_size)
+{
+ grn_hash *h;
+ if (!pat || !key) { return NULL; }
+ if ((h = grn_hash_create(ctx, NULL, sizeof(grn_id), sizeof(uint32_t), 0))) {
+ if (grn_pat_suffix_search(ctx, pat, key, key_size, h)) {
+ grn_hash_close(ctx, h);
+ h = NULL;
+ }
+ }
+ return h;
+}
+
+grn_id
+grn_pat_lcp_search(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_size)
+{
+ pat_node *rn;
+ grn_id r, r2 = GRN_ID_NIL;
+ uint32_t len = key_size * 16;
+ int c0 = -1, c;
+ 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);
+ if (!rn) { break; /* corrupt? */ }
+ c = PAT_CHK(rn);
+ if (c <= c0) {
+ if (PAT_LEN(rn) <= key_size) {
+ uint8_t *p = pat_node_get_key(ctx, pat, rn);
+ if (!p) { break; }
+ if (!memcmp(p, key, PAT_LEN(rn))) { return r; }
+ }
+ break;
+ }
+ if (len <= c) { break; }
+ if (c & 1) {
+ uint8_t *p;
+ pat_node *rn0;
+ grn_id r0 = rn->lr[0];
+ PAT_AT(pat, r0, rn0);
+ if (!rn0) { break; /* corrupt? */ }
+ p = pat_node_get_key(ctx, pat, rn0);
+ if (!p) { break; }
+ if (PAT_LEN(rn0) <= key_size && !memcmp(p, key, PAT_LEN(rn0))) { r2 = r0; }
+ r = (c + 1 < len) ? rn->lr[1] : rn->lr[0];
+ } else {
+ r = rn->lr[nth_bit((uint8_t *)key, c, len)];
+ }
+ c0 = c;
+ }
+ 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;
+ 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;
+
+ /* 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);
+ proot = p = &rn->lr[1];
+ for (;;) {
+ r = *p;
+ if (!r) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ PAT_AT(pat, r, rn);
+ if (!rn) {
+ return GRN_FILE_CORRUPT;
+ }
+ ch = PAT_CHK(rn);
+ 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)) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ /* Given key found. */
+ break;
+ }
+ c0 = c;
+ p0 = p;
+ 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)];
+ }
+ rn0 = rn;
+ }
+ if (optarg && optarg->func &&
+ !optarg->func(ctx, (grn_obj *)pat, r, optarg->func_arg)) {
+ return GRN_SUCCESS;
+ }
+ 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 (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);
+ }
+ 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 (ldi) {
+ PAT_DEL_OFF(rn);
+ di->stat = DL_PHASE2;
+ if (ddi) {
+ PAT_DEL_OFF(rn0);
+ ddi->stat = DL_PHASE2;
+ if (ddi == ldi) {
+ if (r != ddi->ld) {
+ GRN_LOG(ctx, GRN_LOG_ERROR, "r(%d) != ddi->ld(%d)", r, ddi->ld);
+ }
+ di->d = r;
+ } else {
+ ldi->ld = ddi->ld;
+ di->d = r;
+ }
+ } else {
+ PAT_DEL_ON(rn0);
+ ldi->ld = *p0;
+ di->d = r;
+ }
+ } else {
+ PAT_DEL_ON(rn);
+ if (ddi) {
+ if (ddi->d != *p0) {
+ GRN_LOG(ctx, GRN_LOG_ERROR, "ddi->d(%d) != *p0(%d)", ddi->d, *p0);
+ }
+ PAT_DEL_OFF(rn0);
+ ddi->stat = DL_PHASE2;
+ di->stat = DL_PHASE1;
+ di->ld = ddi->ld;
+ di->d = r;
+ /*
+ PAT_DEL_OFF(rn0);
+ ddi->d = r;
+ di->stat = DL_PHASE2;
+ di->d = *p0;
+ */
+ } else {
+ PAT_DEL_ON(rn0);
+ di->stat = DL_PHASE1;
+ di->ld = *p0;
+ di->d = r;
+ // grn_log("pat_del d=%d ld=%d stat=%d", r, *p0, DL_PHASE1);
+ }
+ }
+ if (*p0 == 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 (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);
+ }
+ 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;
+ }
+ }
+ pat->header->n_entries--;
+ pat->header->n_garbages++;
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+_grn_pat_delete(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_size,
+ grn_table_delete_optarg *optarg)
+{
+ if (pat->obj.header.flags & GRN_OBJ_KEY_WITH_SIS) {
+ grn_id id = grn_pat_get(ctx, pat, key, key_size, NULL);
+ if (id && grn_pat_delete_with_sis(ctx, pat, id, optarg)) {
+ return GRN_SUCCESS;
+ }
+ return GRN_INVALID_ARGUMENT;
+ }
+ return _grn_pat_del(ctx, pat, key, key_size, 0, optarg);
+}
+
+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);
+}
+
+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;
+}
+
+const char *
+_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;
+ return NULL;
+ }
+ key = pat_node_get_key(ctx, pat, node);
+ if (key) {
+ *key_size = PAT_LEN(node);
+ } else {
+ *key_size = 0;
+ }
+ return (const char *)key;
+}
+
+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);
+ return _grn_pat_delete(ctx, pat, key, key_size, optarg);
+ }
+}
+
+int
+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 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; }
+ len = PAT_LEN(node);
+ if (keybuf && bufsize >= len) {
+ if (KEY_NEEDS_CONVERT(pat, len)) {
+ KEY_DEC(pat, keybuf, key, len);
+ } else {
+ grn_memcpy(keybuf, key, len);
+ }
+ }
+ return len;
+}
+
+int
+grn_pat_get_key2(grn_ctx *ctx, grn_pat *pat, grn_id id, grn_obj *bulk)
+{
+ uint32_t len;
+ 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; }
+ len = PAT_LEN(node);
+ if (KEY_NEEDS_CONVERT(pat, len)) {
+ if (bulk->header.impl_flags & GRN_OBJ_REFER) {
+ GRN_TEXT_INIT(bulk, 0);
+ }
+ if (!grn_bulk_reserve(ctx, bulk, len)) {
+ char *curr = GRN_BULK_CURR(bulk);
+ KEY_DEC(pat, curr, key, len);
+ grn_bulk_truncate(ctx, bulk, GRN_BULK_VSIZE(bulk) + len);
+ }
+ } else {
+ if (bulk->header.impl_flags & GRN_OBJ_REFER) {
+ bulk->u.b.head = (char *)key;
+ bulk->u.b.curr = (char *)key + len;
+ } else {
+ grn_bulk_write(ctx, bulk, (char *)key, len);
+ }
+ }
+ return len;
+}
+
+int
+grn_pat_get_value(grn_ctx *ctx, grn_pat *pat, grn_id id, void *valuebuf)
+{
+ 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) {
+ if (valuebuf) {
+ if (pat->obj.header.flags & GRN_OBJ_KEY_WITH_SIS) {
+ grn_memcpy(valuebuf, v + sizeof(sis_node), value_size);
+ } else {
+ grn_memcpy(valuebuf, v, value_size);
+ }
+ }
+ return value_size;
+ }
+ }
+ return 0;
+}
+
+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)) {
+ value += sizeof(sis_node);
+ }
+ }
+ return value;
+}
+
+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) {
+ byte *v = (byte *)sis_get(ctx, pat, id);
+ if (v) {
+ if (pat->obj.header.flags & GRN_OBJ_KEY_WITH_SIS) { v += sizeof(sis_node); }
+ switch ((flags & GRN_OBJ_SET_MASK)) {
+ case GRN_OBJ_SET :
+ grn_memcpy(v, value, value_size);
+ return GRN_SUCCESS;
+ case GRN_OBJ_INCR :
+ switch (value_size) {
+ case sizeof(int32_t) :
+ *((int32_t *)v) += *((int32_t *)value);
+ return GRN_SUCCESS;
+ case sizeof(int64_t) :
+ *((int64_t *)v) += *((int64_t *)value);
+ return GRN_SUCCESS;
+ default :
+ return GRN_INVALID_ARGUMENT;
+ }
+ break;
+ case GRN_OBJ_DECR :
+ switch (value_size) {
+ case sizeof(int32_t) :
+ *((int32_t *)v) -= *((int32_t *)value);
+ return GRN_SUCCESS;
+ case sizeof(int64_t) :
+ *((int64_t *)v) -= *((int64_t *)value);
+ return GRN_SUCCESS;
+ default :
+ return GRN_INVALID_ARGUMENT;
+ }
+ break;
+ default :
+ // todo : support other types.
+ return GRN_INVALID_ARGUMENT;
+ }
+ } else {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ }
+ return GRN_INVALID_ARGUMENT;
+}
+
+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) {
+ uint64_t tmp = 0;
+ if ((rc = grn_io_size(ctx, pat->io, &tmp))) {
+ return rc;
+ }
+ *file_size = (unsigned int) tmp; /* FIXME: inappropriate cast */
+ }
+ return GRN_SUCCESS;
+}
+
+int
+grn_pat_delete_with_sis(grn_ctx *ctx, grn_pat *pat, grn_id id,
+ grn_table_delete_optarg *optarg)
+{
+ int level = 0, shared;
+ const char *key = NULL, *_key;
+ 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;
+ if ((si && si->children && si->children != id) ||
+ (optarg && optarg->func &&
+ !optarg->func(ctx, (grn_obj *)pat, id, optarg->func_arg))) {
+ break;
+ }
+ PAT_AT(pat, id, rn);
+ if (!(_key = (char *)pat_node_get_key(ctx, pat, rn))) { return 0; }
+ if (_key == key) {
+ shared = 1;
+ } else {
+ key = _key;
+ shared = 0;
+ }
+ key_size = PAT_LEN(rn);
+ if (key && key_size) { _grn_pat_del(ctx, pat, key, key_size, shared, NULL); }
+ if (si) {
+ grn_id *p, sid;
+ uint32_t lkey = 0;
+ if ((*key & 0x80) && chop(ctx, pat, &key, key + key_size, &lkey)) {
+ if ((sid = grn_pat_get(ctx, pat, key, key_size - lkey, NULL)) &&
+ (ss = sis_at(ctx, pat, sid))) {
+ for (p = &ss->children; *p && *p != sid; p = &sp->sibling) {
+ if (*p == id) {
+ *p = si->sibling;
+ break;
+ }
+ if (!(sp = sis_at(ctx, pat, *p))) { break; }
+ }
+ }
+ } else {
+ sid = GRN_ID_NIL;
+ }
+ si->sibling = 0;
+ si->children = 0;
+ id = sid;
+ si = ss;
+ } else {
+ id = GRN_ID_NIL;
+ }
+ level++;
+ }
+ if (level) {
+ uint32_t lkey = 0;
+ while (id && key) {
+ uint32_t key_size;
+ if (_grn_pat_key(ctx, pat, id, &key_size) != key) { break; }
+ {
+ pat_node *rn;
+ PAT_AT(pat, id, rn);
+ if (!rn) { break; }
+ if (lkey) {
+ rn->key = lkey;
+ } else {
+ pat_node_set_key(ctx, pat, rn, (uint8_t *)key, key_size);
+ lkey = rn->key;
+ }
+ }
+ {
+ const char *end = key + key_size;
+ if (!((*key & 0x80) && chop(ctx, pat, &key, end, &lkey))) { break; }
+ id = grn_pat_get(ctx, pat, key, end - key, NULL);
+ }
+ }
+ }
+ return level;
+}
+
+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);
+ if (id == grn_pat_get(ctx, pat, key, key_size, NULL)) {
+ return id;
+ }
+ }
+ return GRN_ID_NIL;
+}
+
+grn_id
+grn_pat_at(grn_ctx *ctx, grn_pat *pat, grn_id id)
+{
+ uint32_t key_size;
+ const char *key = _grn_pat_key(ctx, pat, id, &key_size);
+ if (key && (id == _grn_pat_get(ctx, pat, key, key_size, NULL))) { return id; }
+ return GRN_ID_NIL;
+}
+
+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;
+}
+
+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)
+{
+ 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, 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;
+ grn_string_get_normalized(ctx, nstr, &sp, &normalized_length_in_bytes,
+ NULL);
+ 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;
+ int first_key_char_len;
+ key = _grn_pat_key(ctx, pat, tid, &len);
+ sh[n].id = tid;
+ sh[n].offset = (*cp > 0) ? offset : offset0;
+ 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++;
+ }
+ }
+ } else {
+ if (*cp > 0) { offset0 = offset; offset += *cp; tp++; }
+ do {
+ sp++; cp++;
+ } while (sp < se && !*cp);
+ }
+ if (se <= sp) { offset = str_len; break; }
+ }
+ if (rest) {
+ grn_string_get_original(ctx, nstr, rest, NULL);
+ *rest += offset;
+ }
+ grn_obj_close(ctx, nstr);
+ } else {
+ n = -1;
+ if (rest) { *rest = str; }
+ }
+ } else {
+ uint32_t len;
+ const char *sp, *se = str + str_len;
+ for (sp = str; sp < se && n < sh_size; sp += len) {
+ if ((tid = grn_pat_lcp_search(ctx, pat, sp, se - sp))) {
+ _grn_pat_key(ctx, pat, tid, &len);
+ sh[n].id = tid;
+ sh[n].offset = sp - str;
+ sh[n].length = len;
+ n++;
+ } else {
+ len = grn_charlen(ctx, sp, se);
+ }
+ if (!len) { break; }
+ }
+ if (rest) { *rest = sp; }
+ }
+ return n;
+}
+
+#define INITIAL_SIZE 512
+
+inline static void
+push(grn_pat_cursor *c, grn_id id, uint16_t check)
+{
+ grn_ctx *ctx = c->ctx;
+ grn_pat_cursor_entry *se;
+ if (c->size <= c->sp) {
+ if (c->ss) {
+ uint32_t size = c->size * 4;
+ grn_pat_cursor_entry *ss = GRN_REALLOC(c->ss, size);
+ if (!ss) { return; /* give up */ }
+ c->ss = ss;
+ c->size = size;
+ } else {
+ if (!(c->ss = GRN_MALLOC(sizeof(grn_pat_cursor_entry) * INITIAL_SIZE))) {
+ return; /* give up */
+ }
+ c->size = INITIAL_SIZE;
+ }
+ }
+ se = &c->ss[c->sp++];
+ se->id = id;
+ se->check = check;
+}
+
+inline static grn_pat_cursor_entry *
+pop(grn_pat_cursor *c)
+{
+ return c->sp ? &c->ss[--c->sp] : NULL;
+}
+
+static grn_id
+grn_pat_cursor_next_by_id(grn_ctx *ctx, grn_pat_cursor *c)
+{
+ grn_pat *pat = c->pat;
+ int dir = (c->obj.header.flags & GRN_CURSOR_DESCENDING) ? -1 : 1;
+ while (c->curr_rec != c->tail) {
+ c->curr_rec += dir;
+ if (pat->header->n_garbages) {
+ uint32_t key_size;
+ const void *key = _grn_pat_key(ctx, pat, c->curr_rec, &key_size);
+ if (_grn_pat_get(ctx, pat, key, key_size, NULL) != c->curr_rec) {
+ continue;
+ }
+ }
+ c->rest--;
+ return c->curr_rec;
+ }
+ return GRN_ID_NIL;
+}
+
+grn_id
+grn_pat_cursor_next(grn_ctx *ctx, grn_pat_cursor *c)
+{
+ pat_node *node;
+ grn_pat_cursor_entry *se;
+ if (!c->rest) { return GRN_ID_NIL; }
+ if ((c->obj.header.flags & GRN_CURSOR_BY_ID)) {
+ return grn_pat_cursor_next_by_id(ctx, c);
+ }
+ while ((se = pop(c))) {
+ grn_id id = se->id;
+ int check = se->check, ch;
+ 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) {
+ 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;
+ }
+ }
+ }
+ c->curr_rec = id;
+ c->rest--;
+ return id;
+ }
+ }
+ }
+ return GRN_ID_NIL;
+}
+
+void
+grn_pat_cursor_close(grn_ctx *ctx, grn_pat_cursor *c)
+{
+ GRN_ASSERT(c->ctx == ctx);
+ if (c->ss) { GRN_FREE(c->ss); }
+ GRN_FREE(c);
+}
+
+inline static int
+bitcmp(const void *s1, const void *s2, int offset, int length)
+{
+ int r, rest = length + (offset & 7) - 8, bl = offset >> 3, mask = 0xff >> (offset & 7);
+ unsigned char *a = (unsigned char *)s1 + bl, *b = (unsigned char *)s2 + bl;
+ if (rest <= 0) {
+ mask &= 0xff << -rest;
+ return (*a & mask) - (*b & mask);
+ }
+ if ((r = (*a & mask) - (*b & mask))) { return r; }
+ a++; b++;
+ if ((bl = rest >> 3)) {
+ if ((r = memcmp(a, b, bl))) { return r; }
+ a += bl; b += bl;
+ }
+ mask = 0xff << (8 - (rest & 7));
+ return (*a & mask) - (*b & mask);
+}
+
+inline static grn_rc
+set_cursor_prefix(grn_ctx *ctx, grn_pat *pat, grn_pat_cursor *c,
+ const void *key, uint32_t key_size, int flags)
+{
+ int c0 = -1, ch;
+ const uint8_t *k;
+ uint32_t len, byte_len;
+ grn_id id;
+ pat_node *node;
+ uint8_t keybuf[MAX_FIXED_KEY_SIZE];
+ if (flags & GRN_CURSOR_SIZE_BY_BIT) {
+ len = key_size * 2;
+ byte_len = key_size >> 3;
+ } else {
+ len = key_size * 16;
+ byte_len = key_size;
+ }
+ KEY_ENCODE(pat, keybuf, key, byte_len);
+ PAT_AT(pat, 0, node);
+ id = node->lr[1];
+ while (id) {
+ PAT_AT(pat, id, node);
+ if (!node) { return GRN_FILE_CORRUPT; }
+ ch = PAT_CHK(node);
+ if (c0 < ch && ch < len - 1) {
+ if (ch & 1) {
+ id = (ch + 1 < len) ? node->lr[1] : node->lr[0];
+ } else {
+ id = node->lr[nth_bit((uint8_t *)key, ch, len)];
+ }
+ c0 = ch;
+ continue;
+ }
+ if (!(k = pat_node_get_key(ctx, pat, node))) { break; }
+ if (PAT_LEN(node) < byte_len) { break; }
+ if ((flags & GRN_CURSOR_SIZE_BY_BIT)
+ ? !bitcmp(k, key, 0, key_size)
+ : !memcmp(k, key, key_size)) {
+ if (c0 < ch) {
+ if (flags & GRN_CURSOR_DESCENDING) {
+ if ((ch > len - 1) || !(flags & GRN_CURSOR_GT)) {
+ push(c, node->lr[0], ch);
+ }
+ push(c, node->lr[1], ch);
+ } else {
+ push(c, node->lr[1], ch);
+ if ((ch > len - 1) || !(flags & GRN_CURSOR_GT)) {
+ push(c, node->lr[0], ch);
+ }
+ }
+ } else {
+ if (PAT_LEN(node) * 16 > len || !(flags & GRN_CURSOR_GT)) {
+ push(c, id, ch);
+ }
+ }
+ }
+ break;
+ }
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+set_cursor_near(grn_ctx *ctx, grn_pat *pat, grn_pat_cursor *c,
+ uint32_t min_size, const void *key, int flags)
+{
+ grn_id id;
+ pat_node *node;
+ const uint8_t *k;
+ int r, check = -1, ch;
+ uint32_t min = min_size * 16;
+ uint8_t keybuf[MAX_FIXED_KEY_SIZE];
+ KEY_ENCODE(pat, keybuf, key, pat->key_size);
+ PAT_AT(pat, 0, node);
+ for (id = node->lr[1]; id;) {
+ PAT_AT(pat, id, node);
+ if (!node) { return GRN_FILE_CORRUPT; }
+ ch = PAT_CHK(node);
+ if (ch <= check) {
+ if (check >= min) { push(c, id, check); }
+ break;
+ }
+ if ((check += 2) < ch) {
+ if (!(k = pat_node_get_key(ctx, pat, node))) { return GRN_FILE_CORRUPT; }
+ if ((r = bitcmp(key, k, check >> 1, (ch - check) >> 1))) {
+ if (ch >= min) {
+ push(c, node->lr[1], ch);
+ push(c, node->lr[0], ch);
+ }
+ break;
+ }
+ }
+ check = ch;
+ if (nth_bit((uint8_t *)key, check, pat->key_size)) {
+ if (check >= min) { push(c, node->lr[0], check); }
+ id = node->lr[1];
+ } else {
+ if (check >= min) { push(c, node->lr[1], check); }
+ id = node->lr[0];
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+set_cursor_common_prefix(grn_ctx *ctx, grn_pat *pat, grn_pat_cursor *c,
+ uint32_t min_size, const void *key, uint32_t key_size, int flags)
+{
+ grn_id id;
+ pat_node *node;
+ const uint8_t *k;
+ int check = -1, ch;
+ uint32_t len = key_size * 16;
+ uint8_t keybuf[MAX_FIXED_KEY_SIZE];
+ KEY_ENCODE(pat, keybuf, key, key_size);
+ PAT_AT(pat, 0, node);
+ for (id = node->lr[1]; id;) {
+ PAT_AT(pat, id, node);
+ if (!node) { return GRN_FILE_CORRUPT; }
+ ch = PAT_CHK(node);
+ if (ch <= check) {
+ if (!(k = pat_node_get_key(ctx, pat, node))) { return GRN_FILE_CORRUPT; }
+ {
+ uint32_t l = PAT_LEN(node);
+ if (min_size <= l && l <= key_size) {
+ if (!memcmp(key, k, l)) { push(c, id, check); }
+ }
+ }
+ break;
+ }
+ check = ch;
+ if (len <= check) { break; }
+ if (check & 1) {
+ grn_id id0 = node->lr[0];
+ pat_node *node0;
+ PAT_AT(pat, id0, node0);
+ if (!node0) { return GRN_FILE_CORRUPT; }
+ if (!(k = pat_node_get_key(ctx, pat, node0))) { return GRN_FILE_CORRUPT; }
+ {
+ uint32_t l = PAT_LEN(node0);
+ if (memcmp(key, k, l)) { break; }
+ if (min_size <= l) {
+ push(c, id0, check);
+ }
+ }
+ id = node->lr[1];
+ } else {
+ id = node->lr[nth_bit((uint8_t *)key, check, len)];
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+set_cursor_ascend(grn_ctx *ctx, grn_pat *pat, grn_pat_cursor *c,
+ const void *key, uint32_t key_size, int flags)
+{
+ grn_id id;
+ pat_node *node;
+ const uint8_t *k;
+ int r, check = -1, ch, c2;
+ uint32_t len = key_size * 16;
+ uint8_t keybuf[MAX_FIXED_KEY_SIZE];
+ KEY_ENCODE(pat, keybuf, key, key_size);
+ PAT_AT(pat, 0, node);
+ for (id = node->lr[1]; id;) {
+ PAT_AT(pat, id, node);
+ if (!node) { return GRN_FILE_CORRUPT; }
+ ch = PAT_CHK(node);
+ if (ch <= check) {
+ if (!(k = pat_node_get_key(ctx, pat, node))) { return GRN_FILE_CORRUPT; }
+ {
+ uint32_t l = PAT_LEN(node);
+ if (l == key_size) {
+ if (flags & GRN_CURSOR_GT) {
+ if (memcmp(key, k, l) < 0) { push(c, id, check); }
+ } else {
+ if (memcmp(key, k, l) <= 0) { push(c, id, check); }
+ }
+ } else if (l < key_size) {
+ if (memcmp(key, k, l) < 0) { push(c, id, check); }
+ } else {
+ if (memcmp(key, k, key_size) <= 0) { push(c, id, check); }
+ }
+ }
+ break;
+ }
+ c2 = len < ch ? len : ch;
+ if ((check += 2) < c2) {
+ if (!(k = pat_node_get_key(ctx, pat, node))) { return GRN_FILE_CORRUPT; }
+ if ((r = bitcmp(key, k, check >> 1, ((c2 + 1) >> 1) - (check >> 1)))) {
+ if (r < 0) {
+ push(c, node->lr[1], ch);
+ push(c, node->lr[0], ch);
+ }
+ break;
+ }
+ }
+ check = ch;
+ if (len <= check) {
+ push(c, node->lr[1], ch);
+ push(c, node->lr[0], ch);
+ break;
+ }
+ if (check & 1) {
+ if (check + 1 < len) {
+ id = node->lr[1];
+ } else {
+ push(c, node->lr[1], check);
+ id = node->lr[0];
+ }
+ } else {
+ if (nth_bit((uint8_t *)key, check, len)) {
+ id = node->lr[1];
+ } else {
+ push(c, node->lr[1], check);
+ id = node->lr[0];
+ }
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+set_cursor_descend(grn_ctx *ctx, grn_pat *pat, grn_pat_cursor *c,
+ const void *key, uint32_t key_size, int flags)
+{
+ grn_id id;
+ pat_node *node;
+ const uint8_t *k;
+ int r, check = -1, ch, c2;
+ uint32_t len = key_size * 16;
+ uint8_t keybuf[MAX_FIXED_KEY_SIZE];
+ KEY_ENCODE(pat, keybuf, key, key_size);
+ PAT_AT(pat, 0, node);
+ for (id = node->lr[1]; id;) {
+ PAT_AT(pat, id, node);
+ if (!node) { return GRN_FILE_CORRUPT; }
+ ch = PAT_CHK(node);
+ if (ch <= check) {
+ if (!(k = pat_node_get_key(ctx, pat, node))) { return GRN_FILE_CORRUPT; }
+ {
+ uint32_t l = PAT_LEN(node);
+ if (l <= key_size) {
+ if ((flags & GRN_CURSOR_LT) && l == key_size) {
+ if (memcmp(key, k, l) > 0) { push(c, id, check); }
+ } else {
+ if (memcmp(key, k, l) >= 0) { push(c, id, check); }
+ }
+ } else {
+ if (memcmp(key, k, key_size) > 0) { push(c, id, check); }
+ }
+ }
+ break;
+ }
+ c2 = len < ch ? len : ch;
+ if ((check += 2) < c2) {
+ if (!(k = pat_node_get_key(ctx, pat, node))) { return GRN_FILE_CORRUPT; }
+ if ((r = bitcmp(key, k, check >> 1, ((c2 + 1) >> 1) - (check >> 1)))) {
+ if (r >= 0) {
+ push(c, node->lr[0], ch);
+ push(c, node->lr[1], ch);
+ }
+ break;
+ }
+ }
+ check = ch;
+ if (len <= check) { break; }
+ if (check & 1) {
+ if (check + 1 < len) {
+ push(c, node->lr[0], check);
+ id = node->lr[1];
+ } else {
+ id = node->lr[0];
+ }
+ } else {
+ if (nth_bit((uint8_t *)key, check, len)) {
+ push(c, node->lr[0], check);
+ id = node->lr[1];
+ } else {
+ id = node->lr[0];
+ }
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+static grn_pat_cursor *
+grn_pat_cursor_open_by_id(grn_ctx *ctx, grn_pat *pat,
+ const void *min, uint32_t min_size,
+ const void *max, uint32_t max_size,
+ int offset, int limit, int flags)
+{
+ int dir;
+ grn_pat_cursor *c;
+ if (!pat || !ctx) { return NULL; }
+ if (!(c = GRN_MALLOCN(grn_pat_cursor, 1))) { return NULL; }
+ GRN_DB_OBJ_SET_TYPE(c, GRN_CURSOR_TABLE_PAT_KEY);
+ c->pat = pat;
+ c->ctx = ctx;
+ c->obj.header.flags = flags;
+ c->obj.header.domain = GRN_ID_NIL;
+ c->size = 0;
+ c->sp = 0;
+ c->ss = NULL;
+ c->tail = 0;
+ if (flags & GRN_CURSOR_DESCENDING) {
+ dir = -1;
+ if (max) {
+ if (!(c->curr_rec = grn_pat_get(ctx, pat, max, max_size, NULL))) {
+ c->tail = GRN_ID_NIL;
+ goto exit;
+ }
+ if (!(flags & GRN_CURSOR_LT)) { c->curr_rec++; }
+ } else {
+ c->curr_rec = pat->header->curr_rec + 1;
+ }
+ if (min) {
+ if (!(c->tail = grn_pat_get(ctx, pat, min, min_size, NULL))) {
+ c->curr_rec = GRN_ID_NIL;
+ goto exit;
+ }
+ if ((flags & GRN_CURSOR_GT)) { c->tail++; }
+ } else {
+ c->tail = GRN_ID_NIL + 1;
+ }
+ if (c->curr_rec < c->tail) { c->tail = c->curr_rec; }
+ } else {
+ dir = 1;
+ if (min) {
+ if (!(c->curr_rec = grn_pat_get(ctx, pat, min, min_size, NULL))) {
+ c->tail = GRN_ID_NIL;
+ goto exit;
+ }
+ if (!(flags & GRN_CURSOR_GT)) { c->curr_rec--; }
+ } else {
+ c->curr_rec = GRN_ID_NIL;
+ }
+ if (max) {
+ if (!(c->tail = grn_pat_get(ctx, pat, max, max_size, NULL))) {
+ c->curr_rec = GRN_ID_NIL;
+ goto exit;
+ }
+ if ((flags & GRN_CURSOR_LT)) { c->tail--; }
+ } else {
+ c->tail = pat->header->curr_rec;
+ }
+ if (c->tail < c->curr_rec) { c->tail = c->curr_rec; }
+ }
+ if (pat->header->n_garbages) {
+ while (offset && c->curr_rec != c->tail) {
+ uint32_t key_size;
+ const void *key;
+ c->curr_rec += dir;
+ key = _grn_pat_key(ctx, pat, c->curr_rec, &key_size);
+ if (_grn_pat_get(ctx, pat, key, key_size, NULL) == c->curr_rec) {
+ offset--;
+ }
+ }
+ } else {
+ if ((dir * (c->tail - c->curr_rec)) < offset) {
+ c->curr_rec = c->tail;
+ } else {
+ c->curr_rec += dir * offset;
+ }
+ }
+ c->rest = (limit < 0) ? GRN_ID_MAX : limit;
+exit :
+ return c;
+}
+
+static grn_rc set_cursor_rk(grn_ctx *ctx, grn_pat *pat, grn_pat_cursor *c,
+ const void *key, uint32_t key_size, int flags);
+
+grn_pat_cursor *
+grn_pat_cursor_open(grn_ctx *ctx, grn_pat *pat,
+ const void *min, uint32_t min_size,
+ const void *max, uint32_t max_size,
+ int offset, int limit, int flags)
+{
+ grn_id id;
+ 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);
+ }
+ if (!(c = GRN_MALLOCN(grn_pat_cursor, 1))) { return NULL; }
+ GRN_DB_OBJ_SET_TYPE(c, GRN_CURSOR_TABLE_PAT_KEY);
+ c->pat = pat;
+ c->ctx = ctx;
+ c->size = 0;
+ c->sp = 0;
+ c->ss = NULL;
+ c->tail = 0;
+ c->rest = GRN_ID_MAX;
+ c->curr_rec = GRN_ID_NIL;
+ c->obj.header.domain = GRN_ID_NIL;
+ if (flags & GRN_CURSOR_PREFIX) {
+ if (max && max_size) {
+ if ((pat->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE)) {
+ set_cursor_common_prefix(ctx, pat, c, min_size, max, max_size, flags);
+ } else {
+ set_cursor_near(ctx, pat, c, min_size, max, flags);
+ }
+ goto exit;
+ } else {
+ if (min && min_size) {
+ if (flags & GRN_CURSOR_RK) {
+ set_cursor_rk(ctx, pat, c, min, min_size, flags);
+ } else {
+ set_cursor_prefix(ctx, pat, c, min, min_size, flags);
+ }
+ goto exit;
+ }
+ }
+ }
+ if (flags & GRN_CURSOR_DESCENDING) {
+ if (min && min_size) {
+ set_cursor_ascend(ctx, pat, c, min, min_size, flags);
+ c->obj.header.flags = GRN_CURSOR_ASCENDING;
+ c->tail = grn_pat_cursor_next(ctx, c);
+ c->sp = 0;
+ if (!c->tail) { goto exit; }
+ }
+ if (max && max_size) {
+ set_cursor_descend(ctx, pat, c, max, max_size, flags);
+ } else {
+ PAT_AT(pat, 0, node);
+ if (!node) {
+ grn_pat_cursor_close(ctx, c);
+ return NULL;
+ }
+ if ((id = node->lr[1])) {
+ PAT_AT(pat, id, node);
+ if (node) {
+ int ch = PAT_CHK(node);
+ push(c, node->lr[0], ch);
+ push(c, node->lr[1], ch);
+ }
+ }
+ }
+ } else {
+ if (max && max_size) {
+ set_cursor_descend(ctx, pat, c, max, max_size, flags);
+ c->obj.header.flags = GRN_CURSOR_DESCENDING;
+ c->tail = grn_pat_cursor_next(ctx, c);
+ c->sp = 0;
+ if (!c->tail) { goto exit; }
+ }
+ if (min && min_size) {
+ set_cursor_ascend(ctx, pat, c, min, min_size, flags);
+ } else {
+ PAT_AT(pat, 0, node);
+ if (!node) {
+ grn_pat_cursor_close(ctx, c);
+ return NULL;
+ }
+ if ((id = node->lr[1])) {
+ PAT_AT(pat, id, node);
+ if (node) {
+ int ch = PAT_CHK(node);
+ push(c, node->lr[1], ch);
+ push(c, node->lr[0], ch);
+ }
+ }
+ }
+ }
+exit :
+ c->obj.header.flags = flags;
+ c->curr_rec = GRN_ID_NIL;
+ while (offset--) { grn_pat_cursor_next(ctx, c); }
+ c->rest = (limit < 0) ? GRN_ID_MAX : limit;
+ return c;
+}
+
+int
+grn_pat_cursor_get_key(grn_ctx *ctx, grn_pat_cursor *c, void **key)
+{
+ *key = c->curr_key;
+ return grn_pat_get_key(ctx, c->pat, c->curr_rec, *key, GRN_TABLE_MAX_KEY_SIZE);
+}
+
+int
+grn_pat_cursor_get_value(grn_ctx *ctx, grn_pat_cursor *c, void **value)
+{
+ int value_size = (int)c->pat->value_size;
+ if (value_size) {
+ byte *v = (byte *)sis_at(ctx, c->pat, c->curr_rec);
+ if (v) {
+ if (c->pat->obj.header.flags & GRN_OBJ_KEY_WITH_SIS) {
+ *value = v + sizeof(sis_node);
+ } else {
+ *value = v;
+ }
+ } else {
+ *value = NULL;
+ }
+ }
+ return value_size;
+}
+
+int
+grn_pat_cursor_get_key_value(grn_ctx *ctx, grn_pat_cursor *c,
+ void **key, uint32_t *key_size, void **value)
+{
+ int value_size = (int)c->pat->value_size;
+ if (key_size) {
+ *key_size = (uint32_t) grn_pat_get_key(ctx, c->pat, c->curr_rec, c->curr_key,
+ GRN_TABLE_MAX_KEY_SIZE);
+ if (key) { *key = c->curr_key; }
+ }
+ if (value && value_size) {
+ byte *v = (byte *)sis_at(ctx, c->pat, c->curr_rec);
+ if (v) {
+ if (c->pat->obj.header.flags & GRN_OBJ_KEY_WITH_SIS) {
+ *value = v + sizeof(sis_node);
+ } else {
+ *value = v;
+ }
+ } else {
+ *value = NULL;
+ }
+ }
+ return value_size;
+}
+
+grn_rc
+grn_pat_cursor_set_value(grn_ctx *ctx, grn_pat_cursor *c,
+ const void *value, int flags)
+{
+ return grn_pat_set_value(ctx, c->pat, c->curr_rec, value, flags);
+}
+
+grn_rc
+grn_pat_cursor_delete(grn_ctx *ctx, grn_pat_cursor *c,
+ grn_table_delete_optarg *optarg)
+{
+ return grn_pat_delete_by_id(ctx, c->pat, c->curr_rec, optarg);
+}
+
+void
+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");
+ grn_itoh(h->flags, buf, 8);
+ GRN_OUTPUT_STR(buf, 8);
+ GRN_OUTPUT_CSTR("key size");
+ GRN_OUTPUT_INT64(h->key_size);
+ GRN_OUTPUT_CSTR("value_size");
+ GRN_OUTPUT_INT64(h->value_size);
+ GRN_OUTPUT_CSTR("tokenizer");
+ GRN_OUTPUT_INT64(h->tokenizer);
+ GRN_OUTPUT_CSTR("normalizer");
+ GRN_OUTPUT_INT64(h->normalizer);
+ GRN_OUTPUT_CSTR("n_entries");
+ GRN_OUTPUT_INT64(h->n_entries);
+ 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_del");
+ GRN_OUTPUT_INT64(h->curr_del);
+ GRN_OUTPUT_CSTR("curr_del2");
+ GRN_OUTPUT_INT64(h->curr_del2);
+ GRN_OUTPUT_CSTR("curr_del3");
+ GRN_OUTPUT_INT64(h->curr_del3);
+ GRN_OUTPUT_CSTR("n_garbages");
+ GRN_OUTPUT_INT64(h->n_garbages);
+ GRN_OUTPUT_MAP_CLOSE();
+ 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)
+{
+ GRN_TEXT_PUTS(ctx, buf, "{");
+ grn_text_lltoa(ctx, buf, check >> 4);
+ GRN_TEXT_PUTS(ctx, buf, ",");
+ grn_text_lltoa(ctx, buf, (check >> 1) & 7);
+ GRN_TEXT_PUTS(ctx, buf, ",");
+ grn_text_lltoa(ctx, buf, check & 1);
+ GRN_TEXT_PUTS(ctx, buf, "}");
+}
+
+static void
+grn_pat_inspect_node(grn_ctx *ctx, grn_pat *pat, grn_id id, int check,
+ grn_obj *key_buf, int indent, const char *prefix,
+ grn_obj *buf)
+{
+ pat_node *node = NULL;
+ int i, c;
+
+ PAT_AT(pat, id, node);
+ c = PAT_CHK(node);
+
+ for (i = 0; i < indent; i++) {
+ GRN_TEXT_PUTC(ctx, buf, ' ');
+ }
+ 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;
+
+ key_size = PAT_LEN(node);
+ GRN_BULK_REWIND(key_buf);
+ grn_bulk_space(ctx, key_buf, key_size);
+ grn_pat_get_key(ctx, pat, id, GRN_BULK_HEAD(key_buf), key_size);
+ GRN_TEXT_PUTS(ctx, buf, "(");
+ grn_inspect(ctx, buf, key_buf);
+ GRN_TEXT_PUTS(ctx, buf, ")");
+
+ GRN_TEXT_PUTS(ctx, buf, "[");
+ key = pat_node_get_key(ctx, pat, node);
+ for (i = 0; i < key_size; i++) {
+ int j;
+ uint8_t byte = key[i];
+ if (i != 0) {
+ GRN_TEXT_PUTS(ctx, buf, " ");
+ }
+ for (j = 0; j < 8; j++) {
+ grn_text_lltoa(ctx, buf, (byte >> (7 - j)) & 1);
+ }
+ }
+ GRN_TEXT_PUTS(ctx, buf, "]");
+ }
+}
+
+void
+grn_pat_inspect_nodes(grn_ctx *ctx, grn_pat *pat, grn_obj *buf)
+{
+ pat_node *node;
+ grn_obj key_buf;
+
+ GRN_TEXT_PUTS(ctx, buf, "{");
+ PAT_AT(pat, GRN_ID_NIL, node);
+ if (node->lr[1]) {
+ GRN_TEXT_PUTS(ctx, buf, "\n");
+ GRN_OBJ_INIT(&key_buf, GRN_BULK, 0, pat->obj.header.domain);
+ grn_pat_inspect_node(ctx, pat, node->lr[1], -1, &key_buf, 0, "", buf);
+ GRN_OBJ_FIN(ctx, &key_buf);
+ GRN_TEXT_PUTS(ctx, buf, "\n");
+ }
+ GRN_TEXT_PUTS(ctx, buf, "}");
+}
+
+static void
+grn_pat_cursor_inspect_entries(grn_ctx *ctx, grn_pat_cursor *c, grn_obj *buf)
+{
+ int i;
+ GRN_TEXT_PUTS(ctx, buf, "[");
+ for (i = 0; i < c->sp; i++) {
+ grn_pat_cursor_entry *e = c->ss + i;
+ if (i != 0) {
+ GRN_TEXT_PUTS(ctx, buf, ", ");
+ }
+ GRN_TEXT_PUTS(ctx, buf, "[");
+ grn_text_lltoa(ctx, buf, e->id);
+ GRN_TEXT_PUTS(ctx, buf, ",");
+ grn_pat_inspect_check(ctx, buf, e->check);
+ GRN_TEXT_PUTS(ctx, buf, "]");
+ }
+ GRN_TEXT_PUTS(ctx, buf, "]");
+}
+
+void
+grn_pat_cursor_inspect(grn_ctx *ctx, grn_pat_cursor *c, grn_obj *buf)
+{
+ GRN_TEXT_PUTS(ctx, buf, "#<cursor:pat:");
+ grn_inspect_name(ctx, buf, (grn_obj *)(c->pat));
+
+ GRN_TEXT_PUTS(ctx, buf, " ");
+ GRN_TEXT_PUTS(ctx, buf, "current:");
+ grn_text_lltoa(ctx, buf, c->curr_rec);
+
+ GRN_TEXT_PUTS(ctx, buf, " ");
+ GRN_TEXT_PUTS(ctx, buf, "tail:");
+ grn_text_lltoa(ctx, buf, c->tail);
+
+ GRN_TEXT_PUTS(ctx, buf, " ");
+ GRN_TEXT_PUTS(ctx, buf, "flags:");
+ if (c->obj.header.flags & GRN_CURSOR_PREFIX) {
+ GRN_TEXT_PUTS(ctx, buf, "prefix");
+ } else {
+ if (c->obj.header.flags & GRN_CURSOR_DESCENDING) {
+ GRN_TEXT_PUTS(ctx, buf, "descending");
+ } else {
+ GRN_TEXT_PUTS(ctx, buf, "ascending");
+ }
+ GRN_TEXT_PUTS(ctx, buf, "|");
+ if (c->obj.header.flags & GRN_CURSOR_GT) {
+ GRN_TEXT_PUTS(ctx, buf, "greater-than");
+ } else {
+ GRN_TEXT_PUTS(ctx, buf, "greater");
+ }
+ GRN_TEXT_PUTS(ctx, buf, "|");
+ if (c->obj.header.flags & GRN_CURSOR_LT) {
+ GRN_TEXT_PUTS(ctx, buf, "less-than");
+ } else {
+ GRN_TEXT_PUTS(ctx, buf, "less");
+ }
+ if (c->obj.header.flags & GRN_CURSOR_BY_ID) {
+ GRN_TEXT_PUTS(ctx, buf, "|by-id");
+ }
+ if (c->obj.header.flags & GRN_CURSOR_BY_KEY) {
+ GRN_TEXT_PUTS(ctx, buf, "|by-key");
+ }
+ }
+
+ GRN_TEXT_PUTS(ctx, buf, " ");
+ GRN_TEXT_PUTS(ctx, buf, "rest:");
+ grn_text_lltoa(ctx, buf, c->rest);
+
+ GRN_TEXT_PUTS(ctx, buf, " ");
+ GRN_TEXT_PUTS(ctx, buf, "entries:");
+ grn_pat_cursor_inspect_entries(ctx, c, buf);
+
+ GRN_TEXT_PUTS(ctx, buf, ">");
+}
+
+typedef struct {
+ uint8_t code;
+ uint8_t next;
+ uint8_t emit;
+ uint8_t attr;
+} rk_tree_node;
+
+static uint16_t rk_str_idx[] = {
+ 0x0003, 0x0006, 0x0009, 0x000c, 0x0012, 0x0015, 0x0018, 0x001e, 0x0024, 0x002a,
+ 0x0030, 0x0036, 0x003c, 0x0042, 0x0048, 0x004e, 0x0054, 0x005a, 0x0060, 0x0066,
+ 0x006c, 0x0072, 0x0078, 0x007e, 0x0084, 0x008a, 0x0090, 0x0096, 0x009c, 0x00a2,
+ 0x00a8, 0x00ae, 0x00b4, 0x00ba, 0x00c0, 0x00c3, 0x00c6, 0x00c9, 0x00cc, 0x00cf,
+ 0x00d2, 0x00d5, 0x00db, 0x00e1, 0x00e7, 0x00ea, 0x00f0, 0x00f6, 0x00fc, 0x00ff,
+ 0x0105, 0x0108, 0x010e, 0x0111, 0x0114, 0x0117, 0x011a, 0x011d, 0x0120, 0x0123,
+ 0x0129, 0x012f, 0x0135, 0x013b, 0x013e, 0x0144, 0x014a, 0x0150, 0x0156, 0x0159,
+ 0x015c, 0x015f, 0x0162, 0x0165, 0x0168, 0x016b, 0x016e, 0x0171, 0x0177, 0x017d,
+ 0x0183, 0x0189, 0x018c, 0x0192, 0x0198, 0x019e, 0x01a1, 0x01a4, 0x01aa, 0x01b0,
+ 0x01b6, 0x01bc, 0x01bf, 0x01c2, 0x01c8, 0x01ce, 0x01d1, 0x01d7, 0x01dd, 0x01e0,
+ 0x01e6, 0x01e9, 0x01ef, 0x01f2, 0x01f5, 0x01fb, 0x0201, 0x0207, 0x020d, 0x0213,
+ 0x0216, 0x0219, 0x021c, 0x021f, 0x0222, 0x0225, 0x0228, 0x022e, 0x0234, 0x023a,
+ 0x023d, 0x0243, 0x0249, 0x024f, 0x0252, 0x0258, 0x025e, 0x0264, 0x0267, 0x026d,
+ 0x0273, 0x0279, 0x027f, 0x0285, 0x0288, 0x028b, 0x028e, 0x0291, 0x0294, 0x0297,
+ 0x029a, 0x029d, 0x02a0, 0x02a3, 0x02a9, 0x02af, 0x02b5, 0x02b8, 0x02bb, 0x02be,
+ 0x02c1, 0x02c4, 0x02c7, 0x02ca, 0x02cd, 0x02d0, 0x02d3, 0x02d6, 0x02dc, 0x02e2,
+ 0x02e8, 0x02eb, 0x02ee, 0x02f1, 0x02f4, 0x02f7, 0x02fa, 0x02fd, 0x0300, 0x0303,
+ 0x0309, 0x030c, 0x0312, 0x0318, 0x031e, 0x0324, 0x0327, 0x032a, 0x032d
+};
+static char rk_str[] = {
+ 0xe3, 0x82, 0xa1, 0xe3, 0x82, 0xa2, 0xe3, 0x82, 0xa3, 0xe3, 0x82, 0xa4, 0xe3,
+ 0x82, 0xa4, 0xe3, 0x82, 0xa7, 0xe3, 0x82, 0xa5, 0xe3, 0x82, 0xa6, 0xe3, 0x82,
+ 0xa6, 0xe3, 0x82, 0xa2, 0xe3, 0x82, 0xa6, 0xe3, 0x82, 0xa3, 0xe3, 0x82, 0xa6,
+ 0xe3, 0x82, 0xa4, 0xe3, 0x82, 0xa6, 0xe3, 0x82, 0xa6, 0xe3, 0x82, 0xa6, 0xe3,
+ 0x82, 0xa7, 0xe3, 0x82, 0xa6, 0xe3, 0x82, 0xa8, 0xe3, 0x82, 0xa6, 0xe3, 0x82,
+ 0xaa, 0xe3, 0x82, 0xa6, 0xe3, 0x83, 0xa0, 0xe3, 0x82, 0xa6, 0xe3, 0x83, 0xa1,
+ 0xe3, 0x82, 0xa6, 0xe3, 0x83, 0xa2, 0xe3, 0x82, 0xa6, 0xe3, 0x83, 0xa3, 0xe3,
+ 0x82, 0xa6, 0xe3, 0x83, 0xa4, 0xe3, 0x82, 0xa6, 0xe3, 0x83, 0xa5, 0xe3, 0x82,
+ 0xa6, 0xe3, 0x83, 0xa6, 0xe3, 0x82, 0xa6, 0xe3, 0x83, 0xa7, 0xe3, 0x82, 0xa6,
+ 0xe3, 0x83, 0xa8, 0xe3, 0x82, 0xa6, 0xe3, 0x83, 0xa9, 0xe3, 0x82, 0xa6, 0xe3,
+ 0x83, 0xaa, 0xe3, 0x82, 0xa6, 0xe3, 0x83, 0xab, 0xe3, 0x82, 0xa6, 0xe3, 0x83,
+ 0xac, 0xe3, 0x82, 0xa6, 0xe3, 0x83, 0xad, 0xe3, 0x82, 0xa6, 0xe3, 0x83, 0xae,
+ 0xe3, 0x82, 0xa6, 0xe3, 0x83, 0xaf, 0xe3, 0x82, 0xa6, 0xe3, 0x83, 0xb0, 0xe3,
+ 0x82, 0xa6, 0xe3, 0x83, 0xb1, 0xe3, 0x82, 0xa6, 0xe3, 0x83, 0xb2, 0xe3, 0x82,
+ 0xa6, 0xe3, 0x83, 0xb3, 0xe3, 0x82, 0xa6, 0xe3, 0x83, 0xbc, 0xe3, 0x82, 0xa7,
+ 0xe3, 0x82, 0xa8, 0xe3, 0x82, 0xa9, 0xe3, 0x82, 0xaa, 0xe3, 0x82, 0xab, 0xe3,
+ 0x82, 0xac, 0xe3, 0x82, 0xad, 0xe3, 0x82, 0xad, 0xe3, 0x83, 0xa3, 0xe3, 0x82,
+ 0xad, 0xe3, 0x83, 0xa5, 0xe3, 0x82, 0xad, 0xe3, 0x83, 0xa7, 0xe3, 0x82, 0xae,
+ 0xe3, 0x82, 0xae, 0xe3, 0x83, 0xa3, 0xe3, 0x82, 0xae, 0xe3, 0x83, 0xa5, 0xe3,
+ 0x82, 0xae, 0xe3, 0x83, 0xa7, 0xe3, 0x82, 0xaf, 0xe3, 0x82, 0xaf, 0xe3, 0x82,
+ 0xa1, 0xe3, 0x82, 0xb0, 0xe3, 0x82, 0xb0, 0xe3, 0x82, 0xa1, 0xe3, 0x82, 0xb1,
+ 0xe3, 0x82, 0xb2, 0xe3, 0x82, 0xb3, 0xe3, 0x82, 0xb4, 0xe3, 0x82, 0xb5, 0xe3,
+ 0x82, 0xb6, 0xe3, 0x82, 0xb7, 0xe3, 0x82, 0xb7, 0xe3, 0x82, 0xa7, 0xe3, 0x82,
+ 0xb7, 0xe3, 0x83, 0xa3, 0xe3, 0x82, 0xb7, 0xe3, 0x83, 0xa5, 0xe3, 0x82, 0xb7,
+ 0xe3, 0x83, 0xa7, 0xe3, 0x82, 0xb8, 0xe3, 0x82, 0xb8, 0xe3, 0x82, 0xa7, 0xe3,
+ 0x82, 0xb8, 0xe3, 0x83, 0xa3, 0xe3, 0x82, 0xb8, 0xe3, 0x83, 0xa5, 0xe3, 0x82,
+ 0xb8, 0xe3, 0x83, 0xa7, 0xe3, 0x82, 0xb9, 0xe3, 0x82, 0xba, 0xe3, 0x82, 0xbb,
+ 0xe3, 0x82, 0xbc, 0xe3, 0x82, 0xbd, 0xe3, 0x82, 0xbe, 0xe3, 0x82, 0xbf, 0xe3,
+ 0x83, 0x80, 0xe3, 0x83, 0x81, 0xe3, 0x83, 0x81, 0xe3, 0x82, 0xa7, 0xe3, 0x83,
+ 0x81, 0xe3, 0x83, 0xa3, 0xe3, 0x83, 0x81, 0xe3, 0x83, 0xa5, 0xe3, 0x83, 0x81,
+ 0xe3, 0x83, 0xa7, 0xe3, 0x83, 0x82, 0xe3, 0x83, 0x82, 0xe3, 0x83, 0xa3, 0xe3,
+ 0x83, 0x82, 0xe3, 0x83, 0xa5, 0xe3, 0x83, 0x82, 0xe3, 0x83, 0xa7, 0xe3, 0x83,
+ 0x83, 0xe3, 0x83, 0x84, 0xe3, 0x83, 0x84, 0xe3, 0x82, 0xa1, 0xe3, 0x83, 0x84,
+ 0xe3, 0x82, 0xa3, 0xe3, 0x83, 0x84, 0xe3, 0x82, 0xa7, 0xe3, 0x83, 0x84, 0xe3,
+ 0x82, 0xa9, 0xe3, 0x83, 0x85, 0xe3, 0x83, 0x86, 0xe3, 0x83, 0x86, 0xe3, 0x82,
+ 0xa3, 0xe3, 0x83, 0x86, 0xe3, 0x83, 0xa5, 0xe3, 0x83, 0x87, 0xe3, 0x83, 0x87,
+ 0xe3, 0x82, 0xa3, 0xe3, 0x83, 0x87, 0xe3, 0x83, 0xa5, 0xe3, 0x83, 0x88, 0xe3,
+ 0x83, 0x88, 0xe3, 0x82, 0xa5, 0xe3, 0x83, 0x89, 0xe3, 0x83, 0x89, 0xe3, 0x82,
+ 0xa5, 0xe3, 0x83, 0x8a, 0xe3, 0x83, 0x8b, 0xe3, 0x83, 0x8b, 0xe3, 0x82, 0xa3,
+ 0xe3, 0x83, 0x8b, 0xe3, 0x82, 0xa7, 0xe3, 0x83, 0x8b, 0xe3, 0x83, 0xa3, 0xe3,
+ 0x83, 0x8b, 0xe3, 0x83, 0xa5, 0xe3, 0x83, 0x8b, 0xe3, 0x83, 0xa7, 0xe3, 0x83,
+ 0x8c, 0xe3, 0x83, 0x8d, 0xe3, 0x83, 0x8e, 0xe3, 0x83, 0x8f, 0xe3, 0x83, 0x90,
+ 0xe3, 0x83, 0x91, 0xe3, 0x83, 0x92, 0xe3, 0x83, 0x92, 0xe3, 0x83, 0xa3, 0xe3,
+ 0x83, 0x92, 0xe3, 0x83, 0xa5, 0xe3, 0x83, 0x92, 0xe3, 0x83, 0xa7, 0xe3, 0x83,
+ 0x93, 0xe3, 0x83, 0x93, 0xe3, 0x83, 0xa3, 0xe3, 0x83, 0x93, 0xe3, 0x83, 0xa5,
+ 0xe3, 0x83, 0x93, 0xe3, 0x83, 0xa7, 0xe3, 0x83, 0x94, 0xe3, 0x83, 0x94, 0xe3,
+ 0x83, 0xa3, 0xe3, 0x83, 0x94, 0xe3, 0x83, 0xa5, 0xe3, 0x83, 0x94, 0xe3, 0x83,
+ 0xa7, 0xe3, 0x83, 0x95, 0xe3, 0x83, 0x95, 0xe3, 0x82, 0xa1, 0xe3, 0x83, 0x95,
+ 0xe3, 0x82, 0xa3, 0xe3, 0x83, 0x95, 0xe3, 0x82, 0xa7, 0xe3, 0x83, 0x95, 0xe3,
+ 0x82, 0xa9, 0xe3, 0x83, 0x95, 0xe3, 0x83, 0xa5, 0xe3, 0x83, 0x96, 0xe3, 0x83,
+ 0x97, 0xe3, 0x83, 0x98, 0xe3, 0x83, 0x99, 0xe3, 0x83, 0x9a, 0xe3, 0x83, 0x9b,
+ 0xe3, 0x83, 0x9c, 0xe3, 0x83, 0x9d, 0xe3, 0x83, 0x9e, 0xe3, 0x83, 0x9f, 0xe3,
+ 0x83, 0x9f, 0xe3, 0x83, 0xa3, 0xe3, 0x83, 0x9f, 0xe3, 0x83, 0xa5, 0xe3, 0x83,
+ 0x9f, 0xe3, 0x83, 0xa7, 0xe3, 0x83, 0xa0, 0xe3, 0x83, 0xa1, 0xe3, 0x83, 0xa2,
+ 0xe3, 0x83, 0xa3, 0xe3, 0x83, 0xa4, 0xe3, 0x83, 0xa5, 0xe3, 0x83, 0xa6, 0xe3,
+ 0x83, 0xa7, 0xe3, 0x83, 0xa8, 0xe3, 0x83, 0xa9, 0xe3, 0x83, 0xaa, 0xe3, 0x83,
+ 0xaa, 0xe3, 0x83, 0xa3, 0xe3, 0x83, 0xaa, 0xe3, 0x83, 0xa5, 0xe3, 0x83, 0xaa,
+ 0xe3, 0x83, 0xa7, 0xe3, 0x83, 0xab, 0xe3, 0x83, 0xac, 0xe3, 0x83, 0xad, 0xe3,
+ 0x83, 0xae, 0xe3, 0x83, 0xaf, 0xe3, 0x83, 0xb0, 0xe3, 0x83, 0xb1, 0xe3, 0x83,
+ 0xb2, 0xe3, 0x83, 0xb3, 0xe3, 0x83, 0xb3, 0xe3, 0x83, 0xbc, 0xe3, 0x83, 0xb4,
+ 0xe3, 0x83, 0xb4, 0xe3, 0x82, 0xa1, 0xe3, 0x83, 0xb4, 0xe3, 0x82, 0xa3, 0xe3,
+ 0x83, 0xb4, 0xe3, 0x82, 0xa7, 0xe3, 0x83, 0xb4, 0xe3, 0x82, 0xa9, 0xe3, 0x83,
+ 0xb5, 0xe3, 0x83, 0xb6, 0xe3, 0x83, 0xbc
+};
+static uint16_t rk_tree_idx[] = {
+ 0x001b, 0x0022, 0x0025, 0x0028, 0x002d, 0x0030, 0x0039, 0x003b, 0x003c, 0x003f,
+ 0x0046, 0x0047, 0x004f, 0x0050, 0x0053, 0x005a, 0x005d, 0x0064, 0x0067, 0x006f,
+ 0x0070, 0x0073, 0x007d, 0x007f, 0x0081, 0x0082, 0x0083, 0x0088, 0x008f, 0x0092,
+ 0x00af, 0x00b5, 0x00bc, 0x00bf, 0x00c6, 0x00c9, 0x00d1, 0x00d6, 0x00da, 0x00e4,
+ 0x00e6, 0x00eb, 0x00ec, 0x00f0, 0x00f6, 0x00fc, 0x00fe, 0x0108, 0x010a, 0x010c,
+ 0x010d, 0x010e, 0x0113, 0x0118, 0x011f, 0x0123, 0x0125, 0x0164, 0x0180, 0x0183,
+ 0x0199, 0x01ad
+};
+static rk_tree_node rk_tree[] = {
+ {0x2d, 0x00, 0xb2, 0x01}, {0x61, 0x00, 0x01, 0x01}, {0x62, 0x01, 0xff, 0x01},
+ {0x63, 0x03, 0xff, 0x01}, {0x64, 0x06, 0xff, 0x01}, {0x65, 0x00, 0x24, 0x01},
+ {0x66, 0x0a, 0xff, 0x01}, {0x67, 0x0c, 0xff, 0x01}, {0x68, 0x0f, 0xff, 0x01},
+ {0x69, 0x00, 0x03, 0x01}, {0x6a, 0x11, 0xff, 0x01}, {0x6b, 0x13, 0xff, 0x01},
+ {0x6c, 0x16, 0xff, 0x01}, {0x6d, 0x1c, 0xff, 0x01}, {0x6e, 0x1e, 0xff, 0x01},
+ {0x6f, 0x00, 0x26, 0x01}, {0x70, 0x20, 0xff, 0x01}, {0x72, 0x22, 0xff, 0x01},
+ {0x73, 0x24, 0xff, 0x01}, {0x74, 0x27, 0xff, 0x01}, {0x75, 0x00, 0x06, 0x01},
+ {0x76, 0x2c, 0xff, 0x01}, {0x77, 0x2d, 0xff, 0x01}, {0x78, 0x2f, 0xff, 0x01},
+ {0x79, 0x35, 0xff, 0x01}, {0x7a, 0x36, 0xff, 0x01}, {0xe3, 0x38, 0xff, 0x01},
+ {0x61, 0x00, 0x72, 0x01}, {0x62, 0x01, 0x56, 0x01}, {0x65, 0x00, 0x89, 0x01},
+ {0x69, 0x00, 0x78, 0x01}, {0x6f, 0x00, 0x8c, 0x01}, {0x75, 0x00, 0x86, 0x01},
+ {0x79, 0x02, 0xff, 0x00}, {0x61, 0x00, 0x79, 0x01}, {0x6f, 0x00, 0x7b, 0x01},
+ {0x75, 0x00, 0x7a, 0x01}, {0x63, 0x03, 0x56, 0x01}, {0x68, 0x04, 0xff, 0x01},
+ {0x79, 0x05, 0xff, 0x01}, {0x61, 0x00, 0x4f, 0x00}, {0x65, 0x00, 0x4e, 0x00},
+ {0x69, 0x00, 0x4d, 0x01}, {0x6f, 0x00, 0x51, 0x00}, {0x75, 0x00, 0x50, 0x00},
+ {0x61, 0x00, 0x4f, 0x01}, {0x6f, 0x00, 0x51, 0x01}, {0x75, 0x00, 0x50, 0x01},
+ {0x61, 0x00, 0x4c, 0x01}, {0x64, 0x06, 0x56, 0x01}, {0x65, 0x00, 0x60, 0x01},
+ {0x68, 0x07, 0xff, 0x00}, {0x69, 0x00, 0x61, 0x00}, {0x6f, 0x00, 0x65, 0x01},
+ {0x75, 0x00, 0x5c, 0x01}, {0x77, 0x08, 0xff, 0x00}, {0x79, 0x09, 0xff, 0x01},
+ {0x69, 0x00, 0x61, 0x01}, {0x75, 0x00, 0x62, 0x01}, {0x75, 0x00, 0x66, 0x01},
+ {0x61, 0x00, 0x53, 0x01}, {0x6f, 0x00, 0x55, 0x01}, {0x75, 0x00, 0x54, 0x01},
+ {0x61, 0x00, 0x81, 0x00}, {0x65, 0x00, 0x83, 0x00}, {0x66, 0x0a, 0x56, 0x01},
+ {0x69, 0x00, 0x82, 0x00}, {0x6f, 0x00, 0x84, 0x00}, {0x75, 0x00, 0x80, 0x01},
+ {0x79, 0x0b, 0xff, 0x00}, {0x75, 0x00, 0x85, 0x01}, {0x61, 0x00, 0x28, 0x01},
+ {0x65, 0x00, 0x36, 0x01}, {0x67, 0x0c, 0x56, 0x01}, {0x69, 0x00, 0x2d, 0x01},
+ {0x6f, 0x00, 0x38, 0x01}, {0x75, 0x00, 0x33, 0x01}, {0x77, 0x0d, 0xff, 0x00},
+ {0x79, 0x0e, 0xff, 0x00}, {0x61, 0x00, 0x34, 0x01}, {0x61, 0x00, 0x2e, 0x01},
+ {0x6f, 0x00, 0x30, 0x01}, {0x75, 0x00, 0x2f, 0x01}, {0x61, 0x00, 0x71, 0x01},
+ {0x65, 0x00, 0x88, 0x01}, {0x68, 0x0f, 0x56, 0x01}, {0x69, 0x00, 0x74, 0x01},
+ {0x6f, 0x00, 0x8b, 0x01}, {0x75, 0x00, 0x80, 0x01}, {0x79, 0x10, 0xff, 0x00},
+ {0x61, 0x00, 0x75, 0x01}, {0x6f, 0x00, 0x77, 0x01}, {0x75, 0x00, 0x76, 0x01},
+ {0x61, 0x00, 0x42, 0x00}, {0x65, 0x00, 0x41, 0x00}, {0x69, 0x00, 0x40, 0x01},
+ {0x6a, 0x11, 0x56, 0x01}, {0x6f, 0x00, 0x44, 0x00}, {0x75, 0x00, 0x43, 0x00},
+ {0x79, 0x12, 0xff, 0x00}, {0x61, 0x00, 0x42, 0x01}, {0x6f, 0x00, 0x44, 0x01},
+ {0x75, 0x00, 0x43, 0x01}, {0x61, 0x00, 0x27, 0x01}, {0x65, 0x00, 0x35, 0x01},
+ {0x69, 0x00, 0x29, 0x01}, {0x6b, 0x13, 0x56, 0x01}, {0x6f, 0x00, 0x37, 0x01},
+ {0x75, 0x00, 0x31, 0x01}, {0x77, 0x14, 0xff, 0x00}, {0x79, 0x15, 0xff, 0x00},
+ {0x61, 0x00, 0x32, 0x01}, {0x61, 0x00, 0x2a, 0x01}, {0x6f, 0x00, 0x2c, 0x01},
+ {0x75, 0x00, 0x2b, 0x01}, {0x61, 0x00, 0x00, 0x01}, {0x65, 0x00, 0x23, 0x01},
+ {0x69, 0x00, 0x02, 0x01}, {0x6b, 0x17, 0xff, 0x01}, {0x6c, 0x16, 0x56, 0x01},
+ {0x6f, 0x00, 0x25, 0x01}, {0x74, 0x18, 0xff, 0x01}, {0x75, 0x00, 0x05, 0x01},
+ {0x77, 0x1a, 0xff, 0x01}, {0x79, 0x1b, 0xff, 0x01}, {0x61, 0x00, 0xb0, 0x01},
+ {0x65, 0x00, 0xb1, 0x01}, {0x73, 0x19, 0xff, 0x00}, {0x75, 0x00, 0x56, 0x01},
+ {0x75, 0x00, 0x56, 0x01}, {0x61, 0x00, 0xa4, 0x01}, {0x61, 0x00, 0x96, 0x01},
+ {0x65, 0x00, 0x23, 0x01}, {0x69, 0x00, 0x02, 0x01}, {0x6f, 0x00, 0x9a, 0x01},
+ {0x75, 0x00, 0x98, 0x01}, {0x61, 0x00, 0x8e, 0x01}, {0x65, 0x00, 0x94, 0x01},
+ {0x69, 0x00, 0x8f, 0x01}, {0x6d, 0x1c, 0x56, 0x01}, {0x6f, 0x00, 0x95, 0x01},
+ {0x75, 0x00, 0x93, 0x01}, {0x79, 0x1d, 0xff, 0x00}, {0x61, 0x00, 0x90, 0x01},
+ {0x6f, 0x00, 0x92, 0x01}, {0x75, 0x00, 0x91, 0x01}, {0x00, 0x00, 0xa9, 0x01},
+ {0x27, 0x00, 0xa9, 0x00}, {0x2d, 0x00, 0xaa, 0x00}, {0x61, 0x00, 0x67, 0x01},
+ {0x62, 0x01, 0xa9, 0x00}, {0x63, 0x03, 0xa9, 0x00}, {0x64, 0x06, 0xa9, 0x00},
+ {0x65, 0x00, 0x6f, 0x01}, {0x66, 0x0a, 0xa9, 0x00}, {0x67, 0x0c, 0xa9, 0x00},
+ {0x68, 0x0f, 0xa9, 0x00}, {0x69, 0x00, 0x68, 0x01}, {0x6a, 0x11, 0xa9, 0x00},
+ {0x6b, 0x13, 0xa9, 0x00}, {0x6c, 0x16, 0xa9, 0x00}, {0x6d, 0x1c, 0xa9, 0x00},
+ {0x6e, 0x00, 0xa9, 0x00}, {0x6f, 0x00, 0x70, 0x01}, {0x70, 0x20, 0xa9, 0x00},
+ {0x72, 0x22, 0xa9, 0x00}, {0x73, 0x24, 0xa9, 0x00}, {0x74, 0x27, 0xa9, 0x00},
+ {0x75, 0x00, 0x6e, 0x01}, {0x76, 0x2c, 0xa9, 0x00}, {0x77, 0x2d, 0xa9, 0x00},
+ {0x78, 0x2f, 0xa9, 0x00}, {0x79, 0x1f, 0xff, 0x00}, {0x7a, 0x36, 0xa9, 0x00},
+ {0xe3, 0x38, 0xa9, 0x00}, {0x00, 0x00, 0xa9, 0x01}, {0x61, 0x00, 0x6b, 0x01},
+ {0x65, 0x00, 0x6a, 0x01}, {0x69, 0x00, 0x69, 0x01}, {0x6f, 0x00, 0x6d, 0x01},
+ {0x75, 0x00, 0x6c, 0x01}, {0x61, 0x00, 0x73, 0x01}, {0x65, 0x00, 0x8a, 0x01},
+ {0x69, 0x00, 0x7c, 0x01}, {0x6f, 0x00, 0x8d, 0x01}, {0x70, 0x20, 0x56, 0x01},
+ {0x75, 0x00, 0x87, 0x01}, {0x79, 0x21, 0xff, 0x00}, {0x61, 0x00, 0x7d, 0x01},
+ {0x6f, 0x00, 0x7f, 0x01}, {0x75, 0x00, 0x7e, 0x01}, {0x61, 0x00, 0x9c, 0x01},
+ {0x65, 0x00, 0xa2, 0x01}, {0x69, 0x00, 0x9d, 0x01}, {0x6f, 0x00, 0xa3, 0x01},
+ {0x72, 0x22, 0x56, 0x01}, {0x75, 0x00, 0xa1, 0x01}, {0x79, 0x23, 0xff, 0x00},
+ {0x61, 0x00, 0x9e, 0x01}, {0x6f, 0x00, 0xa0, 0x01}, {0x75, 0x00, 0x9f, 0x01},
+ {0x61, 0x00, 0x39, 0x01}, {0x65, 0x00, 0x47, 0x01}, {0x68, 0x25, 0xff, 0x00},
+ {0x69, 0x00, 0x3b, 0x01}, {0x6f, 0x00, 0x49, 0x01}, {0x73, 0x24, 0x56, 0x01},
+ {0x75, 0x00, 0x45, 0x01}, {0x79, 0x26, 0xff, 0x00}, {0x61, 0x00, 0x3d, 0x00},
+ {0x65, 0x00, 0x3c, 0x00}, {0x69, 0x00, 0x3b, 0x01}, {0x6f, 0x00, 0x3f, 0x00},
+ {0x75, 0x00, 0x3e, 0x00}, {0x61, 0x00, 0x3d, 0x01}, {0x65, 0x00, 0x3c, 0x01},
+ {0x6f, 0x00, 0x3f, 0x01}, {0x75, 0x00, 0x3e, 0x01}, {0x61, 0x00, 0x4b, 0x01},
+ {0x65, 0x00, 0x5d, 0x01}, {0x68, 0x28, 0xff, 0x00}, {0x69, 0x00, 0x4d, 0x01},
+ {0x6f, 0x00, 0x63, 0x01}, {0x73, 0x29, 0xff, 0x00}, {0x74, 0x27, 0x56, 0x01},
+ {0x75, 0x00, 0x57, 0x01}, {0x77, 0x2a, 0xff, 0x00}, {0x79, 0x2b, 0xff, 0x00},
+ {0x69, 0x00, 0x5e, 0x01}, {0x75, 0x00, 0x5f, 0x01}, {0x61, 0x00, 0x58, 0x00},
+ {0x65, 0x00, 0x5a, 0x00}, {0x69, 0x00, 0x59, 0x00}, {0x6f, 0x00, 0x5b, 0x00},
+ {0x75, 0x00, 0x57, 0x01}, {0x75, 0x00, 0x64, 0x01}, {0x61, 0x00, 0x4f, 0x01},
+ {0x65, 0x00, 0x4e, 0x01}, {0x6f, 0x00, 0x51, 0x01}, {0x75, 0x00, 0x50, 0x01},
+ {0x61, 0x00, 0xac, 0x00}, {0x65, 0x00, 0xae, 0x00}, {0x69, 0x00, 0xad, 0x00},
+ {0x6f, 0x00, 0xaf, 0x00}, {0x75, 0x00, 0xab, 0x01}, {0x76, 0x2c, 0x56, 0x01},
+ {0x61, 0x00, 0xa5, 0x01}, {0x65, 0x00, 0x0b, 0x01}, {0x69, 0x00, 0x08, 0x01},
+ {0x6f, 0x00, 0xa8, 0x01}, {0x77, 0x2d, 0x56, 0x01}, {0x79, 0x2e, 0xff, 0x01},
+ {0x65, 0x00, 0xa7, 0x01}, {0x69, 0x00, 0xa6, 0x01}, {0x61, 0x00, 0x00, 0x01},
+ {0x65, 0x00, 0x23, 0x01}, {0x69, 0x00, 0x02, 0x01}, {0x6b, 0x30, 0xff, 0x01},
+ {0x6f, 0x00, 0x25, 0x01}, {0x74, 0x31, 0xff, 0x01}, {0x75, 0x00, 0x05, 0x01},
+ {0x77, 0x33, 0xff, 0x01}, {0x78, 0x2f, 0x56, 0x01}, {0x79, 0x34, 0xff, 0x01},
+ {0x61, 0x00, 0xb0, 0x01}, {0x65, 0x00, 0xb1, 0x01}, {0x73, 0x32, 0xff, 0x00},
+ {0x75, 0x00, 0x56, 0x01}, {0x75, 0x00, 0x56, 0x01}, {0x61, 0x00, 0xa4, 0x01},
+ {0x61, 0x00, 0x96, 0x01}, {0x65, 0x00, 0x23, 0x01}, {0x69, 0x00, 0x02, 0x01},
+ {0x6f, 0x00, 0x9a, 0x01}, {0x75, 0x00, 0x98, 0x01}, {0x61, 0x00, 0x97, 0x01},
+ {0x65, 0x00, 0x04, 0x01}, {0x6f, 0x00, 0x9b, 0x01}, {0x75, 0x00, 0x99, 0x01},
+ {0x79, 0x35, 0x56, 0x01}, {0x61, 0x00, 0x3a, 0x01}, {0x65, 0x00, 0x48, 0x01},
+ {0x69, 0x00, 0x40, 0x01}, {0x6f, 0x00, 0x4a, 0x01}, {0x75, 0x00, 0x46, 0x01},
+ {0x79, 0x37, 0xff, 0x00}, {0x7a, 0x36, 0x56, 0x01}, {0x61, 0x00, 0x42, 0x01},
+ {0x65, 0x00, 0x41, 0x01}, {0x6f, 0x00, 0x44, 0x01}, {0x75, 0x00, 0x43, 0x01},
+ {0x81, 0x39, 0xff, 0x01}, {0x82, 0x3d, 0xff, 0x01}, {0x81, 0x00, 0x00, 0x01},
+ {0x82, 0x00, 0x01, 0x01}, {0x83, 0x00, 0x02, 0x01}, {0x84, 0x00, 0x03, 0x01},
+ {0x85, 0x00, 0x05, 0x01}, {0x86, 0x3a, 0xff, 0x01}, {0x87, 0x00, 0x23, 0x01},
+ {0x88, 0x00, 0x24, 0x01}, {0x89, 0x00, 0x25, 0x01}, {0x8a, 0x00, 0x26, 0x01},
+ {0x8b, 0x00, 0x27, 0x01}, {0x8c, 0x00, 0x28, 0x01}, {0x8d, 0x00, 0x29, 0x01},
+ {0x8e, 0x00, 0x2d, 0x01}, {0x8f, 0x00, 0x31, 0x01}, {0x90, 0x00, 0x33, 0x01},
+ {0x91, 0x00, 0x35, 0x01}, {0x92, 0x00, 0x36, 0x01}, {0x93, 0x00, 0x37, 0x01},
+ {0x94, 0x00, 0x38, 0x01}, {0x95, 0x00, 0x39, 0x01}, {0x96, 0x00, 0x3a, 0x01},
+ {0x97, 0x00, 0x3b, 0x01}, {0x98, 0x00, 0x40, 0x01}, {0x99, 0x00, 0x45, 0x01},
+ {0x9a, 0x00, 0x46, 0x01}, {0x9b, 0x00, 0x47, 0x01}, {0x9c, 0x00, 0x48, 0x01},
+ {0x9d, 0x00, 0x49, 0x01}, {0x9e, 0x00, 0x4a, 0x01}, {0x9f, 0x00, 0x4b, 0x01},
+ {0xa0, 0x00, 0x4c, 0x01}, {0xa1, 0x00, 0x4d, 0x01}, {0xa2, 0x00, 0x52, 0x01},
+ {0xa3, 0x00, 0x56, 0x01}, {0xa4, 0x00, 0x57, 0x01}, {0xa5, 0x00, 0x5c, 0x01},
+ {0xa6, 0x00, 0x5d, 0x01}, {0xa7, 0x00, 0x60, 0x01}, {0xa8, 0x00, 0x63, 0x01},
+ {0xa9, 0x00, 0x65, 0x01}, {0xaa, 0x00, 0x67, 0x01}, {0xab, 0x00, 0x68, 0x01},
+ {0xac, 0x00, 0x6e, 0x01}, {0xad, 0x00, 0x6f, 0x01}, {0xae, 0x00, 0x70, 0x01},
+ {0xaf, 0x00, 0x71, 0x01}, {0xb0, 0x00, 0x72, 0x01}, {0xb1, 0x00, 0x73, 0x01},
+ {0xb2, 0x00, 0x74, 0x01}, {0xb3, 0x00, 0x78, 0x01}, {0xb4, 0x00, 0x7c, 0x01},
+ {0xb5, 0x00, 0x80, 0x01}, {0xb6, 0x00, 0x86, 0x01}, {0xb7, 0x00, 0x87, 0x01},
+ {0xb8, 0x00, 0x88, 0x01}, {0xb9, 0x00, 0x89, 0x01}, {0xba, 0x00, 0x8a, 0x01},
+ {0xbb, 0x00, 0x8b, 0x01}, {0xbc, 0x00, 0x8c, 0x01}, {0xbd, 0x00, 0x8d, 0x01},
+ {0xbe, 0x00, 0x8e, 0x01}, {0xbf, 0x00, 0x8f, 0x01}, {0x00, 0x00, 0x06, 0x00},
+ {0x2d, 0x00, 0x22, 0x00}, {0x61, 0x00, 0x07, 0x00}, {0x62, 0x01, 0x06, 0x00},
+ {0x63, 0x03, 0x06, 0x00}, {0x64, 0x06, 0x06, 0x00}, {0x65, 0x00, 0x0c, 0x00},
+ {0x66, 0x0a, 0x06, 0x00}, {0x67, 0x0c, 0x06, 0x00}, {0x68, 0x0f, 0x06, 0x00},
+ {0x69, 0x00, 0x09, 0x00}, {0x6a, 0x11, 0x06, 0x00}, {0x6b, 0x13, 0x06, 0x00},
+ {0x6c, 0x16, 0x06, 0x00}, {0x6d, 0x1c, 0x06, 0x00}, {0x6e, 0x1e, 0x06, 0x00},
+ {0x6f, 0x00, 0x0d, 0x00}, {0x70, 0x20, 0x06, 0x00}, {0x72, 0x22, 0x06, 0x00},
+ {0x73, 0x24, 0x06, 0x00}, {0x74, 0x27, 0x06, 0x00}, {0x75, 0x00, 0x0a, 0x00},
+ {0x76, 0x2c, 0x06, 0x00}, {0x77, 0x2d, 0x06, 0x00}, {0x78, 0x2f, 0x06, 0x00},
+ {0x79, 0x35, 0x06, 0x00}, {0x7a, 0x36, 0x06, 0x00}, {0xe3, 0x3b, 0xff, 0x01},
+ {0x00, 0x00, 0x06, 0x00}, {0x81, 0x39, 0x06, 0x00}, {0x82, 0x3c, 0xff, 0x01},
+ {0x00, 0x00, 0x06, 0x01}, {0x80, 0x00, 0x0e, 0x00}, {0x81, 0x00, 0x0f, 0x00},
+ {0x82, 0x00, 0x10, 0x00}, {0x83, 0x00, 0x11, 0x00}, {0x84, 0x00, 0x12, 0x00},
+ {0x85, 0x00, 0x13, 0x00}, {0x86, 0x00, 0x14, 0x00}, {0x87, 0x00, 0x15, 0x00},
+ {0x88, 0x00, 0x16, 0x00}, {0x89, 0x00, 0x17, 0x00}, {0x8a, 0x00, 0x18, 0x00},
+ {0x8b, 0x00, 0x19, 0x00}, {0x8c, 0x00, 0x1a, 0x00}, {0x8d, 0x00, 0x1b, 0x00},
+ {0x8e, 0x00, 0x1c, 0x00}, {0x8f, 0x00, 0x1d, 0x00}, {0x90, 0x00, 0x1e, 0x00},
+ {0x91, 0x00, 0x1f, 0x00}, {0x92, 0x00, 0x20, 0x00}, {0x93, 0x00, 0x21, 0x00},
+ {0x9b, 0x00, 0xab, 0x01}, {0x80, 0x00, 0x93, 0x01}, {0x81, 0x00, 0x94, 0x01},
+ {0x82, 0x00, 0x95, 0x01}, {0x83, 0x00, 0x96, 0x01}, {0x84, 0x00, 0x97, 0x01},
+ {0x85, 0x00, 0x98, 0x01}, {0x86, 0x00, 0x99, 0x01}, {0x87, 0x00, 0x9a, 0x01},
+ {0x88, 0x00, 0x9b, 0x01}, {0x89, 0x00, 0x9c, 0x01}, {0x8a, 0x00, 0x9d, 0x01},
+ {0x8b, 0x00, 0xa1, 0x01}, {0x8c, 0x00, 0xa2, 0x01}, {0x8d, 0x00, 0xa3, 0x01},
+ {0x8e, 0x00, 0xa4, 0x01}, {0x8f, 0x00, 0xa5, 0x01}, {0x90, 0x00, 0xa6, 0x01},
+ {0x91, 0x00, 0xa7, 0x01}, {0x92, 0x00, 0xa8, 0x01}, {0x93, 0x00, 0xa9, 0x01}
+};
+
+static rk_tree_node *
+rk_lookup(uint8_t state, uint8_t code)
+{
+ if (state < sizeof(rk_tree_idx)/sizeof(uint16_t)) {
+ uint16_t ns = state ? rk_tree_idx[state - 1] : 0;
+ uint16_t ne = rk_tree_idx[state];
+ while (ns < ne) {
+ uint16_t m = (ns + ne)>>1;
+ rk_tree_node *rn = &rk_tree[m];
+ if (rn->code == code) { return rn; }
+ if (rn->code < code) {
+ ns = m + 1;
+ } else {
+ ne = m;
+ }
+ }
+ }
+ return NULL;
+}
+
+static uint32_t
+rk_emit(rk_tree_node *rn, char **str)
+{
+ if (rn && rn->emit != 0xff) {
+ uint16_t pos = rn->emit ? rk_str_idx[rn->emit - 1] : 0;
+ *str = &rk_str[pos];
+ return (uint32_t)(rk_str_idx[rn->emit] - pos);
+ } else {
+ *str = NULL;
+ return 0;
+ }
+}
+
+#define RK_OUTPUT(e,l) do {\
+ if (oc < oe) {\
+ uint32_t l_ = (oc + (l) < oe) ? (l) : (oe - oc);\
+ grn_memcpy(oc, (e), l_);\
+ oc += l_;\
+ ic_ = ic;\
+ }\
+} while (0)
+
+static uint32_t
+rk_conv(const char *str, uint32_t str_len, uint8_t *buf, uint32_t buf_size, uint8_t *statep)
+{
+ uint32_t l;
+ uint8_t state = 0;
+ rk_tree_node *rn;
+ char *e;
+ uint8_t *oc = buf, *oe = oc + buf_size;
+ const uint8_t *ic = (uint8_t *)str, *ic_ = ic, *ie = ic + str_len;
+ while (ic < ie) {
+ if ((rn = rk_lookup(state, *ic))) {
+ ic++;
+ if ((l = rk_emit(rn, &e))) { RK_OUTPUT(e, l); }
+ state = rn->next;
+ } else {
+ if (!state) { ic++; }
+ if (ic_ < ic) { RK_OUTPUT(ic_, ic - ic_); }
+ state = 0;
+ }
+ }
+#ifdef FLUSH_UNRESOLVED_INPUT
+ if ((rn = rk_lookup(state, 0))) {
+ if ((l = rk_emit(rn, &e))) { RK_OUTPUT(e, l); }
+ state = rn->next;
+ } else {
+ if (ic_ < ic) { RK_OUTPUT(ic_, ic - ic_); }
+ }
+#endif /* FLUSH_UNRESOLVED_INPUT */
+ *statep = state;
+ return oc - buf;
+}
+
+static grn_id
+sub_search(grn_ctx *ctx, grn_pat *pat, grn_id id,
+ int *c0, uint8_t *key, uint32_t key_len)
+{
+ pat_node *pn;
+ uint32_t len = key_len * 16;
+ if (!key_len) { return id; }
+ PAT_AT(pat, id, pn);
+ while (pn) {
+ int ch;
+ ch = PAT_CHK(pn);
+ if (*c0 < ch && ch < len - 1) {
+ if (ch & 1) {
+ id = (ch + 1 < len) ? pn->lr[1] : pn->lr[0];
+ } else {
+ id = pn->lr[nth_bit(key, ch, len)];
+ }
+ *c0 = ch;
+ PAT_AT(pat, id, pn);
+ } else {
+ const uint8_t *k = pat_node_get_key(ctx, pat, pn);
+ return (k && key_len <= PAT_LEN(pn) && !memcmp(k, key, key_len)) ? id : GRN_ID_NIL;
+ }
+ }
+ return GRN_ID_NIL;
+}
+
+static void
+search_push(grn_ctx *ctx, grn_pat *pat, grn_pat_cursor *c,
+ uint8_t *key, uint32_t key_len, uint8_t state, grn_id id, int c0, int flags)
+{
+ if (state) {
+ int step;
+ uint16_t ns, ne;
+ if (flags & GRN_CURSOR_DESCENDING) {
+ ns = rk_tree_idx[state - 1];
+ ne = rk_tree_idx[state];
+ step = 1;
+ } else {
+ ns = rk_tree_idx[state] - 1;
+ ne = rk_tree_idx[state - 1] - 1;
+ step = -1;
+ }
+ for (; ns != ne; ns += step) {
+ rk_tree_node *rn = &rk_tree[ns];
+ if (rn->attr) {
+ char *e;
+ uint32_t l = rk_emit(rn, &e);
+ if (l) {
+ if (l + key_len <= GRN_TABLE_MAX_KEY_SIZE) {
+ int ch = c0;
+ grn_id i;
+ grn_memcpy(key + key_len, e, l);
+ if ((i = sub_search(ctx, pat, id, &ch, key, key_len + l))) {
+ search_push(ctx, pat, c, key, key_len + l, rn->next, i, ch, flags);
+ }
+ }
+ } else {
+ search_push(ctx, pat, c, key, key_len, rn->next, id, c0, flags);
+ }
+ }
+ }
+ } else {
+ pat_node *pn;
+ PAT_AT(pat, id, pn);
+ if (pn) {
+ int ch = PAT_CHK(pn);
+ uint32_t len = key_len * 16;
+ if (c0 < ch) {
+ if (flags & GRN_CURSOR_DESCENDING) {
+ if ((ch > len - 1) || !(flags & GRN_CURSOR_GT)) { push(c, pn->lr[0], ch); }
+ push(c, pn->lr[1], ch);
+ } else {
+ push(c, pn->lr[1], ch);
+ if ((ch > len - 1) || !(flags & GRN_CURSOR_GT)) { push(c, pn->lr[0], ch); }
+ }
+ } else {
+ if (PAT_LEN(pn) * 16 > len || !(flags & GRN_CURSOR_GT)) { push(c, id, ch); }
+ }
+ }
+ }
+}
+
+static grn_rc
+set_cursor_rk(grn_ctx *ctx, grn_pat *pat, grn_pat_cursor *c,
+ const void *key, uint32_t key_len, int flags)
+{
+ grn_id id;
+ uint8_t state;
+ pat_node *pn;
+ int c0 = -1;
+ uint32_t len, byte_len;
+ uint8_t keybuf[GRN_TABLE_MAX_KEY_SIZE];
+ if (flags & GRN_CURSOR_SIZE_BY_BIT) { return GRN_OPERATION_NOT_SUPPORTED; }
+ byte_len = rk_conv(key, key_len, keybuf, GRN_TABLE_MAX_KEY_SIZE, &state);
+ len = byte_len * 16;
+ PAT_AT(pat, 0, pn);
+ id = pn->lr[1];
+ if ((id = sub_search(ctx, pat, id, &c0, keybuf, byte_len))) {
+ search_push(ctx, pat, c, keybuf, byte_len, state, id, c0, flags);
+ }
+ 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
new file mode 100644
index 00000000..ce4e3347
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/plugin.c
@@ -0,0 +1,1396 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+#include "grn.h"
+#include "grn_ctx_impl_mrb.h"
+#include "grn_proc.h"
+#include <groonga/plugin.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <sys/stat.h>
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+#endif /* HAVE_DIRENT_H */
+
+#ifndef S_ISREG
+# ifdef _S_IFREG
+# define S_ISREG(mode) (mode & _S_IFREG)
+# endif /* _S_IFREG */
+#endif /* !S_ISREG */
+
+#include "grn_db.h"
+#include "grn_plugin.h"
+#include "grn_ctx_impl.h"
+#include "grn_util.h"
+
+#ifdef GRN_WITH_MRUBY
+# include <mruby.h>
+#endif /* GRN_WITH_MRUBY */
+
+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>
+# define grn_dl_open(filename) dlopen(filename, RTLD_LAZY | RTLD_LOCAL)
+# define grn_dl_open_error_label() dlerror()
+# define grn_dl_close(dl) (dlclose(dl) == 0)
+# define grn_dl_close_error_label() dlerror()
+# define grn_dl_sym(dl, symbol) dlsym(dl, symbol)
+# define grn_dl_sym_error_label() dlerror()
+# define grn_dl_clear_error() dlerror()
+#else
+# define grn_dl_open(filename) LoadLibrary(filename)
+# define grn_dl_open_error_label() "LoadLibrary"
+# define grn_dl_close(dl) (FreeLibrary(dl) != 0)
+# define grn_dl_close_error_label() "FreeLibrary"
+# define grn_dl_sym(dl, symbol) ((void *)GetProcAddress(dl, symbol))
+# define grn_dl_sym_error_label() "GetProcAddress"
+# define grn_dl_clear_error()
+#endif
+
+#define GRN_PLUGIN_KEY_SIZE(filename) (strlen((filename)) + 1)
+
+static char grn_plugins_dir[GRN_ENV_BUFFER_SIZE];
+
+void
+grn_plugin_init_from_env(void)
+{
+ grn_getenv("GRN_PLUGINS_DIR",
+ grn_plugins_dir,
+ GRN_ENV_BUFFER_SIZE);
+}
+
+static int
+compute_name_size(const char *name, int name_size)
+{
+ if (name_size < 0) {
+ if (name) {
+ name_size = strlen(name);
+ } else {
+ name_size = 0;
+ }
+ }
+ return name_size;
+}
+
+grn_id
+grn_plugin_reference(grn_ctx *ctx, const char *filename)
+{
+ grn_id id;
+ grn_plugin **plugin = NULL;
+
+ CRITICAL_SECTION_ENTER(grn_plugins_lock);
+ id = grn_hash_get(&grn_plugins_ctx, grn_plugins,
+ filename, GRN_PLUGIN_KEY_SIZE(filename),
+ (void **)&plugin);
+ if (plugin) {
+ (*plugin)->refcount++;
+ }
+ CRITICAL_SECTION_LEAVE(grn_plugins_lock);
+
+ return id;
+}
+
+const char *
+grn_plugin_path(grn_ctx *ctx, grn_id id)
+{
+ const char *path;
+ grn_plugin *plugin;
+ int value_size;
+ const char *system_plugins_dir;
+ size_t system_plugins_dir_size;
+
+ if (id == GRN_ID_NIL) {
+ return NULL;
+ }
+
+ CRITICAL_SECTION_ENTER(grn_plugins_lock);
+ value_size = grn_hash_get_value(&grn_plugins_ctx, grn_plugins, id, &plugin);
+ CRITICAL_SECTION_LEAVE(grn_plugins_lock);
+
+ if (!plugin) {
+ return NULL;
+ }
+
+ path = plugin->path;
+ system_plugins_dir = grn_plugin_get_system_plugins_dir();
+ system_plugins_dir_size = strlen(system_plugins_dir);
+ if (strncmp(system_plugins_dir, path, system_plugins_dir_size) == 0) {
+ const char *plugin_name = path + system_plugins_dir_size;
+ while (plugin_name[0] == '/') {
+ plugin_name++;
+ }
+ /* TODO: remove suffix too? */
+ return plugin_name;
+ } else {
+ return path;
+ }
+}
+
+#define GRN_PLUGIN_FUNC_PREFIX "grn_plugin_impl_"
+
+static grn_rc
+grn_plugin_call_init(grn_ctx *ctx, grn_id id)
+{
+ grn_plugin *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;
+}
+
+#ifdef GRN_WITH_MRUBY
+static grn_rc
+grn_plugin_call_register_mrb(grn_ctx *ctx, grn_id id, grn_plugin *plugin)
+{
+ 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,
+ &id, sizeof(grn_id), NULL, &added);
+ if (!added) {
+ return ctx->rc;
+ }
+ }
+
+ arena_index = mrb_gc_arena_save(mrb);
+ plugin_loader_class = mrb_class_get_under(mrb, module, "PluginLoader");
+ mrb_funcall(mrb, mrb_obj_value(plugin_loader_class),
+ "load_file", 1, mrb_str_new_cstr(mrb, ctx->impl->plugin_path));
+ mrb_gc_arena_restore(mrb, arena_index);
+ return ctx->rc;
+}
+#endif /*GRN_WITH_MRUBY */
+
+static grn_rc
+grn_plugin_call_register(grn_ctx *ctx, grn_id id)
+{
+ grn_plugin *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;
+}
+
+static grn_rc
+grn_plugin_call_fin(grn_ctx *ctx, grn_id id)
+{
+ grn_plugin *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;
+}
+
+static grn_rc
+grn_plugin_initialize(grn_ctx *ctx, grn_plugin *plugin,
+ grn_dl dl, grn_id id, const char *path)
+{
+ plugin->dl = dl;
+
+#define GET_SYMBOL(type) do { \
+ grn_dl_clear_error(); \
+ plugin->type ## _func = grn_dl_sym(dl, GRN_PLUGIN_FUNC_PREFIX #type); \
+ if (!plugin->type ## _func) { \
+ const char *label; \
+ label = grn_dl_sym_error_label(); \
+ SERR("%s", label); \
+ } \
+} while (0)
+
+ GET_SYMBOL(init);
+ GET_SYMBOL(register);
+ GET_SYMBOL(fin);
+
+#undef GET_SYMBOL
+
+ if (!plugin->init_func || !plugin->register_func || !plugin->fin_func) {
+ ERR(GRN_INVALID_FORMAT,
+ "init func (%s) %sfound, "
+ "register func (%s) %sfound and "
+ "fin func (%s) %sfound",
+ GRN_PLUGIN_FUNC_PREFIX "init", plugin->init_func ? "" : "not ",
+ GRN_PLUGIN_FUNC_PREFIX "register", plugin->register_func ? "" : "not ",
+ GRN_PLUGIN_FUNC_PREFIX "fin", plugin->fin_func ? "" : "not ");
+ }
+
+ if (!ctx->rc) {
+ ctx->impl->plugin_path = path;
+ grn_plugin_call_init(ctx, id);
+ ctx->impl->plugin_path = NULL;
+ }
+
+ return ctx->rc;
+}
+
+#ifdef GRN_WITH_MRUBY
+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(plugins_ctx, grn_plugins, filename, filename_size,
+ (void **)&plugin, NULL);
+ if (!id) {
+ return id;
+ }
+
+ {
+ grn_ctx *ctx = plugins_ctx;
+ *plugin = GRN_MALLOCN(grn_plugin, 1);
+ }
+ if (!*plugin) {
+ grn_hash_delete_by_id(plugins_ctx, grn_plugins, id, NULL);
+ return GRN_ID_NIL;
+ }
+
+ grn_memcpy((*plugin)->path, filename, filename_size);
+ (*plugin)->dl = NULL;
+ (*plugin)->init_func = NULL;
+ (*plugin)->register_func = NULL;
+ (*plugin)->fin_func = NULL;
+ (*plugin)->refcount = 1;
+
+ return id;
+}
+#endif /* GRN_WITH_MRUBY */
+
+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;
+ size_t filename_size;
+
+ filename_size = GRN_PLUGIN_KEY_SIZE(filename);
+
+ CRITICAL_SECTION_ENTER(grn_plugins_lock);
+ if ((id = grn_hash_get(plugins_ctx, grn_plugins, filename, filename_size,
+ (void **)&plugin))) {
+ (*plugin)->refcount++;
+ goto exit;
+ }
+
+#ifdef GRN_WITH_MRUBY
+ {
+ const char *mrb_suffix;
+ mrb_suffix = grn_plugin_get_ruby_suffix();
+ if (filename_size > strlen(mrb_suffix) &&
+ strcmp(filename + (strlen(filename) - strlen(mrb_suffix)),
+ mrb_suffix) == 0) {
+ id = grn_plugin_open_mrb(ctx, filename, filename_size);
+ goto exit;
+ }
+ }
+#endif /* GRN_WITH_MRUBY */
+
+ if ((dl = grn_dl_open(filename))) {
+ if ((id = grn_hash_add(plugins_ctx, grn_plugins, filename, filename_size,
+ (void **)&plugin, NULL))) {
+ {
+ 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_ctx *ctx = plugins_ctx;
+ GRN_FREE(*plugin);
+ }
+ *plugin = NULL;
+ }
+ }
+ if (!*plugin) {
+ 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;
+ ctx->errfile = NULL;
+ } else {
+ const char *label;
+ label = grn_dl_close_error_label();
+ SERR("%s", label);
+ }
+ id = GRN_ID_NIL;
+ } else {
+ (*plugin)->refcount = 1;
+ }
+ } else {
+ if (!grn_dl_close(dl)) {
+ const char *label;
+ label = grn_dl_close_error_label();
+ SERR("%s", label);
+ }
+ }
+ } else {
+ const char *label;
+ label = grn_dl_open_error_label();
+ SERR("%s", label);
+ }
+
+exit:
+ CRITICAL_SECTION_LEAVE(grn_plugins_lock);
+
+ return id;
+}
+
+grn_rc
+grn_plugin_close(grn_ctx *ctx, grn_id id)
+{
+ grn_ctx *plugins_ctx = &grn_plugins_ctx;
+ grn_rc rc;
+ grn_plugin *plugin;
+
+ if (id == GRN_ID_NIL) {
+ return GRN_INVALID_ARGUMENT;
+ }
+
+ CRITICAL_SECTION_ENTER(grn_plugins_lock);
+ if (!grn_hash_get_value(plugins_ctx, grn_plugins, id, &plugin)) {
+ rc = GRN_INVALID_ARGUMENT;
+ goto exit;
+ }
+ if (--plugin->refcount) {
+ rc = GRN_SUCCESS;
+ goto exit;
+ }
+ if (plugin->dl) {
+ grn_plugin_call_fin(ctx, id);
+ if (!grn_dl_close(plugin->dl)) {
+ const char *label;
+ label = grn_dl_close_error_label();
+ SERR("%s", label);
+ }
+ }
+ {
+ 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);
+
+ return rc;
+}
+
+void *
+grn_plugin_sym(grn_ctx *ctx, grn_id id, const char *symbol)
+{
+ grn_plugin *plugin;
+ grn_dl_symbol func;
+
+ if (id == GRN_ID_NIL) {
+ return NULL;
+ }
+
+ CRITICAL_SECTION_ENTER(grn_plugins_lock);
+ if (!grn_hash_get_value(&grn_plugins_ctx, grn_plugins, id, &plugin)) {
+ func = NULL;
+ goto exit;
+ }
+ grn_dl_clear_error();
+ if (!(func = grn_dl_sym(plugin->dl, symbol))) {
+ const char *label;
+ label = grn_dl_sym_error_label();
+ SERR("%s", label);
+ }
+
+exit:
+ CRITICAL_SECTION_LEAVE(grn_plugins_lock);
+
+ return func;
+}
+
+grn_rc
+grn_plugins_init(void)
+{
+ CRITICAL_SECTION_INIT(grn_plugins_lock);
+ 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) {
+ grn_ctx_fin(&grn_plugins_ctx);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_plugins_fin(void)
+{
+ grn_rc rc;
+ if (!grn_plugins) { return GRN_INVALID_ARGUMENT; }
+ GRN_HASH_EACH(&grn_plugins_ctx, grn_plugins, id, NULL, NULL, NULL, {
+ grn_plugin_close(&grn_plugins_ctx, id);
+ });
+ rc = grn_hash_close(&grn_plugins_ctx, grn_plugins);
+ grn_ctx_fin(&grn_plugins_ctx);
+ CRITICAL_SECTION_FIN(grn_plugins_lock);
+ return rc;
+}
+
+const char *
+grn_plugin_get_suffix(void)
+{
+ return GRN_PLUGIN_SUFFIX;
+}
+
+const char *
+grn_plugin_get_ruby_suffix(void)
+{
+ return ".rb";
+}
+
+grn_rc
+grn_plugin_register_by_path(grn_ctx *ctx, const char *path)
+{
+ grn_obj *db;
+ if (!ctx || !ctx->impl || !(db = ctx->impl->db)) {
+ ERR(GRN_INVALID_ARGUMENT, "db not initialized");
+ return ctx->rc;
+ }
+ GRN_API_ENTER;
+ if (GRN_DB_P(db)) {
+ grn_id id;
+ id = grn_plugin_open(ctx, path);
+ if (id) {
+ ctx->impl->plugin_path = path;
+ ctx->rc = grn_plugin_call_register(ctx, id);
+ ctx->impl->plugin_path = NULL;
+ grn_plugin_close(ctx, id);
+ }
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "invalid db assigned");
+ }
+ GRN_API_RETURN(ctx->rc);
+}
+
+#ifdef WIN32
+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 (!windows_plugins_dir) {
+ const char *base_dir;
+ const char *relative_path = GRN_RELATIVE_PLUGINS_DIR;
+ size_t base_dir_length;
+
+ base_dir = grn_windows_base_dir();
+ base_dir_length = strlen(base_dir);
+ 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 windows_plugins_dir;
+}
+
+#else /* WIN32 */
+static const char *
+grn_plugin_get_default_system_plugins_dir(void)
+{
+ return GRN_PLUGINS_DIR;
+}
+#endif /* WIN32 */
+
+const char *
+grn_plugin_get_system_plugins_dir(void)
+{
+ if (grn_plugins_dir[0]) {
+ return grn_plugins_dir;
+ } else {
+ return grn_plugin_get_default_system_plugins_dir();
+ }
+}
+
+static char *
+grn_plugin_find_path_raw(grn_ctx *ctx, const char *path)
+{
+ struct stat path_stat;
+
+ if (stat(path, &path_stat) != 0) {
+ return NULL;
+ }
+
+ if (!S_ISREG(path_stat.st_mode)) {
+ return NULL;
+ }
+
+ return GRN_STRDUP(path);
+}
+
+#ifdef GRN_WITH_MRUBY
+static char *
+grn_plugin_find_path_mrb(grn_ctx *ctx, const char *path, size_t path_len)
+{
+ char mrb_path[PATH_MAX];
+ const char *mrb_suffix;
+ size_t mrb_path_len;
+
+ 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,
+ "too long plugin path: <%s%s>",
+ path, mrb_suffix);
+ return NULL;
+ }
+
+ grn_strcpy(mrb_path, PATH_MAX, path);
+ grn_strcat(mrb_path, PATH_MAX, mrb_suffix);
+ return grn_plugin_find_path_raw(ctx, mrb_path);
+}
+#else /* GRN_WITH_MRUBY */
+static char *
+grn_plugin_find_path_mrb(grn_ctx *ctx, const char *path, size_t path_len)
+{
+ return NULL;
+}
+#endif /* GRN_WITH_MRUBY */
+
+static char *
+grn_plugin_find_path_so(grn_ctx *ctx, const char *path, size_t path_len)
+{
+ char so_path[PATH_MAX];
+ const char *so_suffix;
+ size_t so_path_len;
+
+ so_suffix = grn_plugin_get_suffix();
+ so_path_len = path_len + strlen(so_suffix);
+ if (so_path_len >= PATH_MAX) {
+ ERR(GRN_FILENAME_TOO_LONG,
+ "too long plugin path: <%s%s>",
+ path, so_suffix);
+ return NULL;
+ }
+
+ grn_strcpy(so_path, PATH_MAX, path);
+ grn_strcat(so_path, PATH_MAX, so_suffix);
+ return grn_plugin_find_path_raw(ctx, so_path);
+}
+
+static char *
+grn_plugin_find_path_libs_so(grn_ctx *ctx, const char *path, size_t path_len)
+{
+ char libs_so_path[PATH_MAX];
+ const char *base_name;
+ const char *so_suffix;
+ const char *libs_path = "/.libs";
+ size_t libs_so_path_len;
+
+ base_name = strrchr(path, '/');
+ if (!base_name) {
+ return NULL;
+ }
+
+ so_suffix = grn_plugin_get_suffix();
+ libs_so_path_len =
+ base_name - path +
+ strlen(libs_path) +
+ strlen(base_name) +
+ strlen(so_suffix);
+ if (libs_so_path_len >= PATH_MAX) {
+ ERR(GRN_FILENAME_TOO_LONG,
+ "too long plugin path: <%.*s/.libs%s%s>",
+ (int)(base_name - path), path, base_name, so_suffix);
+ return NULL;
+ }
+
+ libs_so_path[0] = '\0';
+ grn_strncat(libs_so_path, PATH_MAX, path, base_name - path);
+ grn_strcat(libs_so_path, PATH_MAX, libs_path);
+ grn_strcat(libs_so_path, PATH_MAX, base_name);
+ grn_strcat(libs_so_path, PATH_MAX, so_suffix);
+ return grn_plugin_find_path_raw(ctx, libs_so_path);
+}
+
+char *
+grn_plugin_find_path(grn_ctx *ctx, const char *name)
+{
+ const char *plugins_dir;
+ char dir_last_char;
+ char path[PATH_MAX];
+ int name_length, max_name_length;
+ char *found_path = NULL;
+ size_t path_len;
+
+ GRN_API_ENTER;
+ if (name[0] == '/') {
+ path[0] = '\0';
+ } else {
+ plugins_dir = grn_plugin_get_system_plugins_dir();
+ grn_strcpy(path, PATH_MAX, plugins_dir);
+
+ dir_last_char = plugins_dir[strlen(path) - 1];
+ if (dir_last_char != '/') {
+ grn_strcat(path, PATH_MAX, "/");
+ }
+ }
+
+ name_length = strlen(name);
+ max_name_length = PATH_MAX - strlen(path) - 1;
+ if (name_length > max_name_length) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "plugin name is too long: %d (max: %d) <%s%s>",
+ name_length, max_name_length,
+ path, name);
+ goto exit;
+ }
+ grn_strcat(path, PATH_MAX, name);
+
+ found_path = grn_plugin_find_path_raw(ctx, path);
+ if (found_path) {
+ goto exit;
+ }
+
+ path_len = strlen(path);
+
+ found_path = grn_plugin_find_path_so(ctx, path, path_len);
+ if (found_path) {
+ goto exit;
+ }
+ if (ctx->rc) {
+ goto exit;
+ }
+
+ found_path = grn_plugin_find_path_libs_so(ctx, path, path_len);
+ if (found_path) {
+ goto exit;
+ }
+ if (ctx->rc) {
+ goto exit;
+ }
+
+ found_path = grn_plugin_find_path_mrb(ctx, path, path_len);
+ if (found_path) {
+ goto exit;
+ }
+ if (ctx->rc) {
+ goto exit;
+ }
+
+exit :
+ GRN_API_RETURN(found_path);
+}
+
+static void
+grn_plugin_set_name_resolve_error(grn_ctx *ctx, const char *name,
+ const char *tag)
+{
+ const char *prefix, *prefix_separator, *suffix;
+
+ if (name[0] == '/') {
+ prefix = "";
+ prefix_separator = "";
+ suffix = "";
+ } else {
+ prefix = grn_plugin_get_system_plugins_dir();
+ if (prefix[strlen(prefix) - 1] != '/') {
+ prefix_separator = "/";
+ } else {
+ prefix_separator = "";
+ }
+ suffix = grn_plugin_get_suffix();
+ }
+ ERR(GRN_NO_SUCH_FILE_OR_DIRECTORY,
+ "%s cannot find plugin file: <%s%s%s%s>",
+ tag, prefix, prefix_separator, name, suffix);
+}
+
+grn_rc
+grn_plugin_register(grn_ctx *ctx, const char *name)
+{
+ grn_rc rc;
+ char *path;
+
+ GRN_API_ENTER;
+ path = grn_plugin_find_path(ctx, name);
+ if (path) {
+ rc = grn_plugin_register_by_path(ctx, path);
+ GRN_FREE(path);
+ } else {
+ if (ctx->rc == GRN_SUCCESS) {
+ grn_plugin_set_name_resolve_error(ctx, name, "[plugin][register]");
+ }
+ rc = ctx->rc;
+ }
+ GRN_API_RETURN(rc);
+}
+
+grn_rc
+grn_plugin_unregister_by_path(grn_ctx *ctx, const char *path)
+{
+ grn_obj *db;
+ grn_id plugin_id;
+
+ if (!ctx || !ctx->impl) {
+ ERR(GRN_INVALID_ARGUMENT, "[plugin][unregister] ctx isn't initialized");
+ return ctx->rc;
+ }
+
+ db = ctx->impl->db;
+ if (!db) {
+ ERR(GRN_INVALID_ARGUMENT, "[plugin][unregister] DB isn't initialized");
+ return ctx->rc;
+ }
+
+ GRN_API_ENTER;
+
+ CRITICAL_SECTION_ENTER(grn_plugins_lock);
+ plugin_id = grn_hash_get(&grn_plugins_ctx, grn_plugins,
+ path, GRN_PLUGIN_KEY_SIZE(path),
+ NULL);
+ CRITICAL_SECTION_LEAVE(grn_plugins_lock);
+
+ if (plugin_id == GRN_ID_NIL) {
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ {
+ 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) {
+ GRN_API_RETURN(ctx->rc);
+ }
+
+ while ((id = grn_table_cursor_next(ctx, cursor))) {
+ grn_obj *obj;
+ obj = grn_ctx_at(ctx, id);
+ if (!obj) {
+ continue;
+ }
+ if (obj->header.type == GRN_PROC && DB_OBJ(obj)->range == plugin_id) {
+ grn_obj_remove(ctx, obj);
+ } else {
+ grn_obj_unlink(ctx, obj);
+ }
+ }
+ grn_table_cursor_close(ctx, cursor);
+ }
+
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_rc
+grn_plugin_unregister(grn_ctx *ctx, const char *name)
+{
+ grn_rc rc;
+ char *path;
+
+ GRN_API_ENTER;
+ path = grn_plugin_find_path(ctx, name);
+ if (path) {
+ rc = grn_plugin_unregister_by_path(ctx, path);
+ GRN_FREE(path);
+ } else {
+ if (ctx->rc == GRN_SUCCESS) {
+ grn_plugin_set_name_resolve_error(ctx, name, "[plugin][unregister]");
+ }
+ rc = ctx->rc;
+ }
+ GRN_API_RETURN(rc);
+}
+
+void
+grn_plugin_ensure_registered(grn_ctx *ctx, grn_obj *proc)
+{
+#ifdef GRN_WITH_MRUBY
+ grn_id plugin_id;
+ grn_plugin *plugin = NULL;
+
+ if (!(proc->header.flags & GRN_OBJ_CUSTOM_NAME)) {
+ return;
+ }
+
+ 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;
+ }
+
+ {
+ grn_id id;
+ int added;
+ id = DB_OBJ(proc)->id;
+ grn_hash_add(ctx, ctx->impl->mrb.checked_procs,
+ &id, sizeof(grn_id), NULL, &added);
+ if (!added) {
+ return;
+ }
+ }
+
+ 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);
+ }
+
+ if (grn_thread_get_limit() == 1) {
+ is_close_opened_object_mode = GRN_TRUE;
+ }
+
+ 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);
+ }
+
+ 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 *
+grn_plugin_malloc(grn_ctx *ctx, size_t size, const char *file, int line,
+ const char *func)
+{
+ return grn_malloc(ctx, size, file, line, func);
+}
+
+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)
+{
+ return grn_realloc(ctx, ptr, size, file, line, func);
+}
+
+void
+grn_plugin_free(grn_ctx *ctx, void *ptr, const char *file, int line,
+ const char *func)
+{
+ grn_free(ctx, ptr, file, line, func);
+}
+
+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_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
+grn_plugin_backtrace(grn_ctx *ctx)
+{
+ BACKTRACE(ctx);
+}
+
+void
+grn_plugin_logtrace(grn_ctx *ctx, grn_log_level level)
+{
+ if (level <= GRN_LOG_ERROR) {
+ grn_plugin_backtrace(ctx);
+ LOGTRACE(ctx, level);
+ }
+}
+
+struct _grn_plugin_mutex {
+ grn_critical_section critical_section;
+};
+
+grn_plugin_mutex *
+grn_plugin_mutex_open(grn_ctx *ctx)
+{
+ grn_plugin_mutex * const mutex =
+ GRN_PLUGIN_MALLOC(ctx, sizeof(grn_plugin_mutex));
+ if (mutex != NULL) {
+ CRITICAL_SECTION_INIT(mutex->critical_section);
+ }
+ return mutex;
+}
+
+grn_plugin_mutex *
+grn_plugin_mutex_create(grn_ctx *ctx)
+{
+ return grn_plugin_mutex_open(ctx);
+}
+
+void
+grn_plugin_mutex_close(grn_ctx *ctx, grn_plugin_mutex *mutex)
+{
+ if (mutex != NULL) {
+ CRITICAL_SECTION_FIN(mutex->critical_section);
+ GRN_PLUGIN_FREE(ctx, mutex);
+ }
+}
+
+void
+grn_plugin_mutex_destroy(grn_ctx *ctx, grn_plugin_mutex *mutex)
+{
+ grn_plugin_mutex_close(ctx, mutex);
+}
+
+void
+grn_plugin_mutex_lock(grn_ctx *ctx, grn_plugin_mutex *mutex)
+{
+ if (mutex != NULL) {
+ CRITICAL_SECTION_ENTER(mutex->critical_section);
+ }
+}
+
+void
+grn_plugin_mutex_unlock(grn_ctx *ctx, grn_plugin_mutex *mutex)
+{
+ if (mutex != NULL) {
+ CRITICAL_SECTION_LEAVE(mutex->critical_section);
+ }
+}
+
+grn_obj *
+grn_plugin_proc_alloc(grn_ctx *ctx, grn_user_data *user_data,
+ grn_id domain, unsigned char flags)
+{
+ return grn_proc_alloc(ctx, user_data, domain, flags);
+}
+
+grn_obj *
+grn_plugin_proc_get_vars(grn_ctx *ctx, grn_user_data *user_data)
+{
+ return grn_proc_get_vars(ctx, user_data);
+}
+
+grn_obj *
+grn_plugin_proc_get_var(grn_ctx *ctx, grn_user_data *user_data,
+ const char *name, int name_size)
+{
+ name_size = compute_name_size(name, name_size);
+ 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)
+{
+ 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_windows_base_dir();
+#else /* WIN32 */
+ return NULL;
+#endif /* WIN32 */
+}
+
+/*
+ grn_plugin_charlen() takes the length of a string, unlike grn_charlen_().
+ */
+int
+grn_plugin_charlen(grn_ctx *ctx, const char *str_ptr,
+ unsigned int str_length, grn_encoding encoding)
+{
+ return grn_charlen_(ctx, str_ptr, str_ptr + str_length, encoding);
+}
+
+/*
+ grn_plugin_isspace() takes the length of a string, unlike grn_isspace().
+ */
+int
+grn_plugin_isspace(grn_ctx *ctx, const char *str_ptr,
+ unsigned int str_length, grn_encoding encoding)
+{
+ if ((str_ptr == NULL) || (str_length == 0)) {
+ return 0;
+ }
+ switch ((unsigned char)str_ptr[0]) {
+ case ' ' :
+ case '\f' :
+ case '\n' :
+ case '\r' :
+ case '\t' :
+ case '\v' :
+ return 1;
+ case 0x81 :
+ if ((encoding == GRN_ENC_SJIS) && (str_length >= 2) &&
+ ((unsigned char)str_ptr[1] == 0x40)) {
+ return 2;
+ }
+ break;
+ case 0xA1 :
+ if ((encoding == GRN_ENC_EUC_JP) && (str_length >= 2) &&
+ ((unsigned char)str_ptr[1] == 0xA1)) {
+ return 2;
+ }
+ break;
+ case 0xE3 :
+ if ((encoding == GRN_ENC_UTF8) && (str_length >= 3) &&
+ ((unsigned char)str_ptr[1] == 0x80) &&
+ ((unsigned char)str_ptr[2] == 0x80)) {
+ return 3;
+ }
+ break;
+ default :
+ break;
+ }
+ return 0;
+}
+
+grn_rc
+grn_plugin_expr_var_init(grn_ctx *ctx,
+ grn_expr_var *var,
+ const char *name,
+ int name_size)
+{
+ var->name = name;
+ var->name_size = compute_name_size(name, name_size);
+ GRN_TEXT_INIT(&var->value, 0);
+ return GRN_SUCCESS;
+}
+
+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_obj *proc;
+ name_size = compute_name_size(name, name_size);
+ proc = grn_proc_create(ctx, name, name_size, GRN_PROC_COMMAND,
+ func, NULL, NULL, n_vars, vars);
+ return proc;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/proc.c b/storage/mroonga/vendor/groonga/lib/proc.c
new file mode 100644
index 00000000..8ed39961
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc.c
@@ -0,0 +1,4211 @@
+/* -*- 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-1335 USA
+*/
+
+#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_expr.h"
+#include "grn_cache.h"
+#include "grn_load.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#ifdef WIN32
+# include <io.h>
+# include <share.h>
+#endif /* WIN32 */
+
+#ifndef O_NOFOLLOW
+#define O_NOFOLLOW 0
+#endif
+
+/**** globals for procs ****/
+const char *grn_document_root = NULL;
+
+#define VAR GRN_PROC_GET_VAR_BY_OFFSET
+
+static double grn_between_too_many_index_match_ratio = 0.01;
+static double grn_in_values_too_many_index_match_ratio = 0.01;
+
+void
+grn_proc_init_from_env(void)
+{
+ {
+ char grn_between_too_many_index_match_ratio_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_BETWEEN_TOO_MANY_INDEX_MATCH_RATIO",
+ grn_between_too_many_index_match_ratio_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_between_too_many_index_match_ratio_env[0]) {
+ grn_between_too_many_index_match_ratio =
+ atof(grn_between_too_many_index_match_ratio_env);
+ }
+ }
+
+ {
+ char grn_in_values_too_many_index_match_ratio_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_IN_VALUES_TOO_MANY_INDEX_MATCH_RATIO",
+ grn_in_values_too_many_index_match_ratio_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_in_values_too_many_index_match_ratio_env[0]) {
+ grn_in_values_too_many_index_match_ratio =
+ atof(grn_in_values_too_many_index_match_ratio_env);
+ }
+ }
+}
+
+/* bulk must be initialized grn_bulk or grn_msg */
+static int
+grn_bulk_put_from_file(grn_ctx *ctx, grn_obj *bulk, const char *path)
+{
+ /* FIXME: implement more smartly with grn_bulk */
+ int fd, ret = 0;
+ struct stat stat;
+ grn_open(fd, path, O_RDONLY|O_NOFOLLOW|GRN_OPEN_FLAG_BINARY);
+ if (fd == -1) {
+ switch (errno) {
+ case EACCES :
+ ERR(GRN_OPERATION_NOT_PERMITTED, "request is not allowed: <%s>", path);
+ break;
+ case ENOENT :
+ ERR(GRN_NO_SUCH_FILE_OR_DIRECTORY, "no such file: <%s>", path);
+ break;
+#ifndef WIN32
+ case ELOOP :
+ ERR(GRN_NO_SUCH_FILE_OR_DIRECTORY,
+ "symbolic link is not allowed: <%s>", path);
+ break;
+#endif /* WIN32 */
+ default :
+ ERRNO_ERR("failed to open file: <%s>", path);
+ break;
+ }
+ return 0;
+ }
+ if (fstat(fd, &stat) != -1) {
+ char *buf, *bp;
+ off_t rest = stat.st_size;
+ if ((buf = GRN_MALLOC(rest))) {
+ ssize_t ss;
+ for (bp = buf; rest; rest -= ss, bp += ss) {
+ if ((ss = grn_read(fd, bp, rest)) == -1) { goto exit; }
+ }
+ GRN_TEXT_PUT(ctx, bulk, buf, stat.st_size);
+ ret = 1;
+ }
+ GRN_FREE(buf);
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "cannot stat file: <%s>", path);
+ }
+exit :
+ grn_close(fd);
+ return ret;
+}
+
+#ifdef stat
+# undef stat
+#endif /* stat */
+
+/**** procs ****/
+
+static grn_obj *
+proc_load(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ 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 {
+ 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++;
+ }
+ if (ctx->impl->loader.output_errors) {
+ n_elements++;
+ }
+ 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_OUTPUT_ARRAY_CLOSE();
+ }
+ 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_OUTPUT_MAP_CLOSE();
+ }
+ GRN_OUTPUT_ARRAY_CLOSE();
+ }
+ GRN_OUTPUT_MAP_CLOSE();
+ } else {
+ GRN_OUTPUT_INT64(ctx->impl->loader.nrecords);
+ }
+ if (ctx->impl->loader.table) {
+ grn_db_touch(ctx, DB_OBJ(ctx->impl->loader.table)->db);
+ }
+ grn_ctx_loader_clear(ctx);
+ }
+ return NULL;
+}
+
+static grn_obj *
+proc_status(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_timeval now;
+ grn_cache *cache;
+ grn_cache_statistics statistics;
+
+ grn_timeval_now(ctx, &now);
+ cache = grn_cache_current_get(ctx);
+ grn_cache_get_statistics(ctx, cache, &statistics);
+ 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");
+ GRN_OUTPUT_CSTR(grn_get_version());
+ GRN_OUTPUT_CSTR("n_queries");
+ GRN_OUTPUT_INT64(statistics.nfetches);
+ GRN_OUTPUT_CSTR("cache_hit_rate");
+ if (statistics.nfetches == 0) {
+ GRN_OUTPUT_FLOAT(0.0);
+ } else {
+ double cache_hit_rate;
+ cache_hit_rate = (double)statistics.nhits / (double)statistics.nfetches;
+ GRN_OUTPUT_FLOAT(cache_hit_rate * 100.0);
+ }
+ GRN_OUTPUT_CSTR("command_version");
+ GRN_OUTPUT_INT32(grn_ctx_get_command_version(ctx));
+ GRN_OUTPUT_CSTR("default_command_version");
+ GRN_OUTPUT_INT32(grn_get_default_command_version());
+ GRN_OUTPUT_CSTR("max_command_version");
+ GRN_OUTPUT_INT32(GRN_COMMAND_VERSION_MAX);
+ GRN_OUTPUT_MAP_CLOSE();
+
+#ifdef USE_MEMORY_DEBUG
+ grn_alloc_info_dump(&grn_gctx);
+#endif /* USE_MEMORY_DEBUG */
+
+ return NULL;
+}
+
+#define GRN_STRLEN(s) ((s) ? strlen(s) : 0)
+
+void
+grn_proc_output_object_name(grn_ctx *ctx, grn_obj *obj)
+{
+ grn_obj bulk;
+ int name_len;
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+
+ if (obj) {
+ GRN_TEXT_INIT(&bulk, GRN_OBJ_DO_SHALLOW_COPY);
+ name_len = grn_obj_name(ctx, obj, name, GRN_TABLE_MAX_KEY_SIZE);
+ GRN_TEXT_SET(ctx, &bulk, name, name_len);
+ } else {
+ GRN_VOID_INIT(&bulk);
+ }
+
+ GRN_OUTPUT_OBJ(&bulk, NULL);
+ GRN_OBJ_FIN(ctx, &bulk);
+}
+
+void
+grn_proc_output_object_id_name(grn_ctx *ctx, grn_id id)
+{
+ grn_obj *obj = NULL;
+
+ if (id != GRN_ID_NIL) {
+ obj = grn_ctx_at(ctx, id);
+ }
+
+ 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->output.buf;
+ static int grn_document_root_len = -1;
+ if (!grn_document_root) { return NULL; }
+ if (grn_document_root_len < 0) {
+ size_t l;
+ if ((l = strlen(grn_document_root)) > PATH_MAX) {
+ return NULL;
+ }
+ grn_document_root_len = (int)l;
+ if (l > 0 && grn_document_root[l - 1] == '/') { grn_document_root_len--; }
+ }
+ if ((plen = GRN_TEXT_LEN(VAR(0))) + grn_document_root_len < PATH_MAX) {
+ char path[PATH_MAX];
+ grn_memcpy(path, grn_document_root, grn_document_root_len);
+ path[grn_document_root_len] = '/';
+ grn_str_url_path_normalize(ctx,
+ GRN_TEXT_VALUE(VAR(0)),
+ GRN_TEXT_LEN(VAR(0)),
+ path + grn_document_root_len + 1,
+ PATH_MAX - grn_document_root_len - 1);
+ grn_bulk_put_from_file(ctx, outbuf, path);
+ } else {
+ uint32_t abbrlen = 32;
+ ERR(GRN_INVALID_ARGUMENT,
+ "too long path name: <%s/%.*s...> %u(%u)",
+ grn_document_root,
+ abbrlen < plen ? abbrlen : plen, GRN_TEXT_VALUE(VAR(0)),
+ plen + grn_document_root_len, PATH_MAX);
+ }
+ return NULL;
+}
+
+static grn_obj *
+proc_quit(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ ctx->stat = GRN_CTX_QUITTING;
+ GRN_OUTPUT_BOOL(!ctx->rc);
+ return NULL;
+}
+
+static grn_obj *
+proc_shutdown(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ const char *mode;
+ size_t mode_size;
+
+ 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 {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[shutdown] mode must be <graceful> or <immediate>: <%.*s>",
+ (int)mode_size, mode);
+ }
+#undef MODE_EQUAL
+
+ if (ctx->rc == GRN_SUCCESS) {
+ grn_gctx.stat = GRN_CTX_QUIT;
+ ctx->stat = GRN_CTX_QUITTING;
+ }
+
+ GRN_OUTPUT_BOOL(!ctx->rc);
+
+ return NULL;
+}
+
+static grn_obj *
+proc_defrag(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_obj *obj;
+ int olen, threshold;
+ olen = GRN_TEXT_LEN(VAR(0));
+
+ if (olen) {
+ obj = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(0)), olen);
+ } else {
+ obj = ctx->impl->db;
+ }
+
+ threshold = GRN_TEXT_LEN(VAR(1))
+ ? grn_atoi(GRN_TEXT_VALUE(VAR(1)), GRN_BULK_CURR(VAR(1)), NULL)
+ : 0;
+
+ if (obj) {
+ grn_obj_defrag(ctx, obj, threshold);
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "defrag object not found");
+ }
+ GRN_OUTPUT_BOOL(!ctx->rc);
+ return NULL;
+}
+
+static grn_obj *
+proc_log_level(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ 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, "log level is missing");
+ }
+ GRN_OUTPUT_BOOL(!ctx->rc);
+ return NULL;
+}
+
+static grn_obj *
+proc_log_put(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ 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, "log level is missing");
+ }
+ GRN_OUTPUT_BOOL(!ctx->rc);
+ return NULL;
+}
+
+static grn_obj *
+proc_log_reopen(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_log_reopen(ctx);
+ GRN_OUTPUT_BOOL(!ctx->rc);
+ return NULL;
+}
+
+static grn_rc
+proc_delete_validate_selector(grn_ctx *ctx, grn_obj *table, grn_obj *table_name,
+ grn_obj *key, grn_obj *id, grn_obj *filter)
+{
+ grn_rc rc = GRN_SUCCESS;
+
+ if (!table) {
+ rc = GRN_INVALID_ARGUMENT;
+ ERR(rc,
+ "[table][record][delete] table doesn't exist: <%.*s>",
+ (int)GRN_TEXT_LEN(table_name), GRN_TEXT_VALUE(table_name));
+ return rc;
+ }
+
+ if (GRN_TEXT_LEN(key) == 0 &&
+ GRN_TEXT_LEN(id) == 0 &&
+ GRN_TEXT_LEN(filter) == 0) {
+ rc = GRN_INVALID_ARGUMENT;
+ ERR(rc,
+ "[table][record][delete] either key, id or filter must be specified: "
+ "table: <%.*s>",
+ (int)GRN_TEXT_LEN(table_name), GRN_TEXT_VALUE(table_name));
+ return rc;
+ }
+
+ if (GRN_TEXT_LEN(key) && GRN_TEXT_LEN(id) && GRN_TEXT_LEN(filter)) {
+ rc = GRN_INVALID_ARGUMENT;
+ ERR(rc,
+ "[table][record][delete] "
+ "record selector must be one of key, id and filter: "
+ "table: <%.*s>, key: <%.*s>, id: <%.*s>, filter: <%.*s>",
+ (int)GRN_TEXT_LEN(table_name), GRN_TEXT_VALUE(table_name),
+ (int)GRN_TEXT_LEN(key), GRN_TEXT_VALUE(key),
+ (int)GRN_TEXT_LEN(id), GRN_TEXT_VALUE(id),
+ (int)GRN_TEXT_LEN(filter), GRN_TEXT_VALUE(filter));
+ return rc;
+ }
+
+ if (GRN_TEXT_LEN(key) && GRN_TEXT_LEN(id) && GRN_TEXT_LEN(filter) == 0) {
+ rc = GRN_INVALID_ARGUMENT;
+ ERR(rc,
+ "[table][record][delete] "
+ "can't use both key and id: table: <%.*s>, key: <%.*s>, id: <%.*s>",
+ (int)GRN_TEXT_LEN(table_name), GRN_TEXT_VALUE(table_name),
+ (int)GRN_TEXT_LEN(key), GRN_TEXT_VALUE(key),
+ (int)GRN_TEXT_LEN(id), GRN_TEXT_VALUE(id));
+ return rc;
+ }
+
+ if (GRN_TEXT_LEN(key) && GRN_TEXT_LEN(id) == 0 && GRN_TEXT_LEN(filter)) {
+ rc = GRN_INVALID_ARGUMENT;
+ ERR(rc,
+ "[table][record][delete] "
+ "can't use both key and filter: "
+ "table: <%.*s>, key: <%.*s>, filter: <%.*s>",
+ (int)GRN_TEXT_LEN(table_name), GRN_TEXT_VALUE(table_name),
+ (int)GRN_TEXT_LEN(key), GRN_TEXT_VALUE(key),
+ (int)GRN_TEXT_LEN(filter), GRN_TEXT_VALUE(filter));
+ return rc;
+ }
+
+ if (GRN_TEXT_LEN(key) == 0 && GRN_TEXT_LEN(id) && GRN_TEXT_LEN(filter)) {
+ rc = GRN_INVALID_ARGUMENT;
+ ERR(rc,
+ "[table][record][delete] "
+ "can't use both id and filter: "
+ "table: <%.*s>, id: <%.*s>, filter: <%.*s>",
+ (int)GRN_TEXT_LEN(table_name), GRN_TEXT_VALUE(table_name),
+ (int)GRN_TEXT_LEN(id), GRN_TEXT_VALUE(id),
+ (int)GRN_TEXT_LEN(filter), GRN_TEXT_VALUE(filter));
+ return rc;
+ }
+
+ return rc;
+}
+
+static grn_obj *
+proc_delete(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ grn_obj *table_name = VAR(0);
+ grn_obj *key = VAR(1);
+ grn_obj *id = VAR(2);
+ grn_obj *filter = VAR(3);
+ grn_obj *table = NULL;
+
+ if (GRN_TEXT_LEN(table_name) == 0) {
+ rc = GRN_INVALID_ARGUMENT;
+ ERR(rc, "[table][record][delete] table name isn't specified");
+ goto exit;
+ }
+
+ table = grn_ctx_get(ctx,
+ GRN_TEXT_VALUE(table_name),
+ GRN_TEXT_LEN(table_name));
+ rc = proc_delete_validate_selector(ctx, table, table_name, key, id, filter);
+ if (rc != GRN_SUCCESS) { goto exit; }
+
+ if (GRN_TEXT_LEN(key)) {
+ grn_obj casted_key;
+ if (key->header.domain != table->header.domain) {
+ GRN_OBJ_INIT(&casted_key, GRN_BULK, 0, table->header.domain);
+ grn_obj_cast(ctx, key, &casted_key, GRN_FALSE);
+ key = &casted_key;
+ }
+ if (ctx->rc) {
+ rc = ctx->rc;
+ } else {
+ rc = grn_table_delete(ctx, table, GRN_BULK_HEAD(key), GRN_BULK_VSIZE(key));
+ if (key == &casted_key) {
+ GRN_OBJ_FIN(ctx, &casted_key);
+ }
+ }
+ } else if (GRN_TEXT_LEN(id)) {
+ const char *end;
+ grn_id parsed_id = grn_atoui(GRN_TEXT_VALUE(id), GRN_BULK_CURR(id), &end);
+ if (end == GRN_BULK_CURR(id)) {
+ rc = grn_table_delete_by_id(ctx, table, parsed_id);
+ } else {
+ rc = GRN_INVALID_ARGUMENT;
+ ERR(rc,
+ "[table][record][delete] id should be number: "
+ "table: <%.*s>, id: <%.*s>, detail: <%.*s|%c|%.*s>",
+ (int)GRN_TEXT_LEN(table_name), GRN_TEXT_VALUE(table_name),
+ (int)GRN_TEXT_LEN(id), GRN_TEXT_VALUE(id),
+ (int)(end - GRN_TEXT_VALUE(id)), GRN_TEXT_VALUE(id),
+ end[0],
+ (int)(GRN_TEXT_VALUE(id) - end - 1), end + 1);
+ }
+ } else if (GRN_TEXT_LEN(filter)) {
+ grn_obj *cond, *v;
+
+ GRN_EXPR_CREATE_FOR_QUERY(ctx, table, cond, v);
+ grn_expr_parse(ctx, cond,
+ GRN_TEXT_VALUE(filter),
+ GRN_TEXT_LEN(filter),
+ NULL, GRN_OP_MATCH, GRN_OP_AND,
+ GRN_EXPR_SYNTAX_SCRIPT);
+ if (ctx->rc) {
+ 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),
+ ctx->errbuf);
+ } else {
+ grn_obj *records;
+
+ records = grn_table_select(ctx, table, cond, NULL, GRN_OP_OR);
+ if (records) {
+ 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);
+ }
+ }
+ grn_obj_unlink(ctx, cond);
+ }
+
+exit :
+ if (table) {
+ grn_obj_unlink(ctx, table);
+ }
+ GRN_OUTPUT_BOOL(rc == GRN_SUCCESS);
+ return NULL;
+}
+
+grn_bool
+grn_proc_option_value_bool(grn_ctx *ctx,
+ grn_obj *option,
+ grn_bool default_value)
+{
+ const char *value;
+ size_t value_length;
+
+ if (!option) {
+ return default_value;
+ }
+
+ value = GRN_TEXT_VALUE(option);
+ value_length = GRN_TEXT_LEN(option);
+
+ if (value_length == 0) {
+ return default_value;
+ }
+
+ 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;
+ } else {
+ return default_value;
+ }
+}
+
+int32_t
+grn_proc_option_value_int32(grn_ctx *ctx,
+ grn_obj *option,
+ int32_t default_value)
+{
+ const char *value;
+ size_t value_length;
+ int32_t int32_value;
+ const char *rest;
+
+ if (!option) {
+ return default_value;
+ }
+
+ value = GRN_TEXT_VALUE(option);
+ value_length = GRN_TEXT_LEN(option);
+
+ if (value_length == 0) {
+ return default_value;
+ }
+
+ int32_value = grn_atoi(value, value + value_length, &rest);
+ if (rest == value + value_length) {
+ return int32_value;
+ } else {
+ return default_value;
+ }
+}
+
+const char *
+grn_proc_option_value_string(grn_ctx *ctx,
+ grn_obj *option,
+ size_t *size)
+{
+ const char *value;
+ size_t value_length;
+
+ if (!option) {
+ if (size) {
+ *size = 0;
+ }
+ return NULL;
+ }
+
+ value = GRN_TEXT_VALUE(option);
+ value_length = GRN_TEXT_LEN(option);
+
+ if (size) {
+ *size = value_length;
+ }
+
+ if (value_length == 0) {
+ return NULL;
+ } else {
+ return value;
+ }
+}
+
+grn_content_type
+grn_proc_option_value_content_type(grn_ctx *ctx,
+ grn_obj *option,
+ grn_content_type default_value)
+{
+ if (!option) {
+ return default_value;
+ }
+
+ return grn_content_type_parse(ctx, option, default_value);
+}
+
+static grn_obj *
+proc_cache_limit(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_cache *cache;
+ unsigned int current_max_n_entries;
+
+ cache = grn_cache_current_get(ctx);
+ current_max_n_entries = grn_cache_get_max_n_entries(ctx, cache);
+ if (GRN_TEXT_LEN(VAR(0))) {
+ const char *rest;
+ uint32_t max = grn_atoui(GRN_TEXT_VALUE(VAR(0)),
+ GRN_BULK_CURR(VAR(0)), &rest);
+ if (GRN_BULK_CURR(VAR(0)) == rest) {
+ grn_cache_set_max_n_entries(ctx, cache, max);
+ } else {
+ ERR(GRN_INVALID_ARGUMENT,
+ "max value is invalid unsigned integer format: <%.*s>",
+ (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)));
+ }
+ }
+ if (ctx->rc == GRN_SUCCESS) {
+ GRN_OUTPUT_INT64(current_max_n_entries);
+ }
+ return NULL;
+}
+
+static grn_obj *
+proc_register(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ if (GRN_TEXT_LEN(VAR(0))) {
+ const char *name;
+ GRN_TEXT_PUTC(ctx, VAR(0), '\0');
+ name = GRN_TEXT_VALUE(VAR(0));
+ grn_plugin_register(ctx, name);
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "path is required");
+ }
+ GRN_OUTPUT_BOOL(!ctx->rc);
+ return NULL;
+}
+
+void grn_ii_buffer_check(grn_ctx *ctx, grn_ii *ii, uint32_t seg);
+
+static grn_obj *
+proc_check(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_obj *obj = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(0)), GRN_TEXT_LEN(VAR(0)));
+ if (!obj) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "no such object: <%.*s>", (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)));
+ GRN_OUTPUT_BOOL(!ctx->rc);
+ } else {
+ switch (obj->header.type) {
+ case GRN_DB :
+ GRN_OUTPUT_BOOL(!ctx->rc);
+ break;
+ case GRN_TABLE_PAT_KEY :
+ grn_pat_check(ctx, (grn_pat *)obj);
+ break;
+ case GRN_TABLE_HASH_KEY :
+ grn_hash_check(ctx, (grn_hash *)obj);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ case GRN_COLUMN_FIX_SIZE :
+ GRN_OUTPUT_BOOL(!ctx->rc);
+ break;
+ case GRN_COLUMN_VAR_SIZE :
+ grn_ja_check(ctx, (grn_ja *)obj);
+ break;
+ case GRN_COLUMN_INDEX :
+ {
+ grn_ii *ii = (grn_ii *)obj;
+ struct grn_ii_header *h = ii->header;
+ char buf[8];
+ GRN_OUTPUT_ARRAY_OPEN("RESULT", 8);
+ {
+ uint32_t i, j, g =0, a = 0, b = 0;
+ uint32_t max = 0;
+ for (i = h->bgqtail; i != h->bgqhead; i = ((i + 1) & (GRN_II_BGQSIZE - 1))) {
+ j = h->bgqbody[i];
+ g++;
+ if (j > max) { max = j; }
+ }
+ for (i = 0; i < GRN_II_MAX_LSEG; i++) {
+ j = h->binfo[i];
+ 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 != GRN_II_PSEG_NOT_ASSIGNED) {
+ if (j > max) { max = j; }
+ a++;
+ }
+ }
+ GRN_OUTPUT_MAP_OPEN("SUMMARY", 12);
+ GRN_OUTPUT_CSTR("flags");
+ grn_itoh(h->flags, buf, 8);
+ GRN_OUTPUT_STR(buf, 8);
+ GRN_OUTPUT_CSTR("max sid");
+ GRN_OUTPUT_INT64(h->smax);
+ GRN_OUTPUT_CSTR("number of garbage segments");
+ GRN_OUTPUT_INT64(g);
+ GRN_OUTPUT_CSTR("number of array segments");
+ GRN_OUTPUT_INT64(a);
+ GRN_OUTPUT_CSTR("max id of array segment");
+ GRN_OUTPUT_INT64(h->amax);
+ GRN_OUTPUT_CSTR("number of buffer segments");
+ GRN_OUTPUT_INT64(b);
+ GRN_OUTPUT_CSTR("max id of buffer segment");
+ GRN_OUTPUT_INT64(h->bmax);
+ GRN_OUTPUT_CSTR("max id of physical segment in use");
+ GRN_OUTPUT_INT64(max);
+ GRN_OUTPUT_CSTR("number of unmanaged segments");
+ GRN_OUTPUT_INT64(h->pnext - a - b - g);
+ GRN_OUTPUT_CSTR("total chunk size");
+ GRN_OUTPUT_INT64(h->total_chunk_size);
+ for (max = 0, i = 0; i < (GRN_II_MAX_CHUNK >> 3); i++) {
+ if ((j = h->chunks[i])) {
+ int k;
+ for (k = 0; k < 8; k++) {
+ if ((j & (1 << k))) { max = (i << 3) + j; }
+ }
+ }
+ }
+ GRN_OUTPUT_CSTR("max id of chunk segments in use");
+ GRN_OUTPUT_INT64(max);
+ GRN_OUTPUT_CSTR("number of garbage chunk");
+ GRN_OUTPUT_ARRAY_OPEN("NGARBAGES", GRN_II_N_CHUNK_VARIATION);
+ for (i = 0; i <= GRN_II_N_CHUNK_VARIATION; i++) {
+ GRN_OUTPUT_INT64(h->ngarbages[i]);
+ }
+ GRN_OUTPUT_ARRAY_CLOSE();
+ GRN_OUTPUT_MAP_CLOSE();
+ for (i = 0; i < GRN_II_MAX_LSEG; i++) {
+ if (h->binfo[i] < 0x20000) { grn_ii_buffer_check(ctx, ii, i); }
+ }
+ }
+ GRN_OUTPUT_ARRAY_CLOSE();
+ }
+ break;
+ }
+ }
+ return NULL;
+}
+
+static grn_obj *
+proc_truncate(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ const char *target_name;
+ int target_name_len;
+
+ target_name_len = GRN_TEXT_LEN(VAR(0));
+ if (target_name_len > 0) {
+ target_name = GRN_TEXT_VALUE(VAR(0));
+ } else {
+ target_name_len = GRN_TEXT_LEN(VAR(1));
+ if (target_name_len == 0) {
+ ERR(GRN_INVALID_ARGUMENT, "[truncate] table name is missing");
+ goto exit;
+ }
+ target_name = GRN_TEXT_VALUE(VAR(1));
+ }
+
+ {
+ grn_obj *target = grn_ctx_get(ctx, target_name, target_name_len);
+ if (!target) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[truncate] no such target: <%.*s>", target_name_len, target_name);
+ goto exit;
+ }
+
+ switch (target->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ grn_table_truncate(ctx, target);
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ case GRN_COLUMN_INDEX :
+ grn_column_truncate(ctx, target);
+ break;
+ default:
+ {
+ grn_obj buffer;
+ GRN_TEXT_INIT(&buffer, 0);
+ grn_inspect(ctx, &buffer, target);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[truncate] not a table nor column object: <%.*s>",
+ (int)GRN_TEXT_LEN(&buffer), GRN_TEXT_VALUE(&buffer));
+ GRN_OBJ_FIN(ctx, &buffer);
+ }
+ break;
+ }
+ }
+
+exit :
+ GRN_OUTPUT_BOOL(!ctx->rc);
+ return NULL;
+}
+
+static int
+parse_normalize_flags(grn_ctx *ctx, grn_obj *flag_names)
+{
+ 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 (((unsigned long) (names_end - names) >= (unsigned long) (sizeof(#name) - 1)) && \
+ (!memcmp(names, #name, sizeof(#name) - 1))) {\
+ flags |= GRN_STRING_ ## name;\
+ names += sizeof(#name) - 1;\
+ continue;\
+ }
+
+ CHECK_FLAG(REMOVE_BLANK);
+ CHECK_FLAG(WITH_TYPES);
+ CHECK_FLAG(WITH_CHECKS);
+ CHECK_FLAG(REMOVE_TOKENIZED_DELIMITER);
+
+#define GRN_STRING_NONE 0
+ CHECK_FLAG(NONE);
+#undef GRN_STRING_NONE
+
+ ERR(GRN_INVALID_ARGUMENT, "[normalize] invalid flag: <%.*s>",
+ (int)(names_end - names), names);
+ return 0;
+#undef CHECK_FLAG
+ }
+
+ return flags;
+}
+
+static grn_bool
+is_normalizer(grn_ctx *ctx, grn_obj *object)
+{
+ if (object->header.type != GRN_PROC) {
+ return GRN_FALSE;
+ }
+
+ if (grn_proc_get_type(ctx, object) != GRN_PROC_NORMALIZER) {
+ return GRN_FALSE;
+ }
+
+ return GRN_TRUE;
+}
+
+static const char *
+char_type_name(grn_char_type type)
+{
+ const char *name = "unknown";
+
+#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 :
+ CHAR_TYPE_NAME_WITH_BLANK("null");
+ break;
+ case GRN_CHAR_ALPHA :
+ CHAR_TYPE_NAME_WITH_BLANK("alpha");
+ break;
+ case GRN_CHAR_DIGIT :
+ CHAR_TYPE_NAME_WITH_BLANK("digit");
+ break;
+ case GRN_CHAR_SYMBOL :
+ CHAR_TYPE_NAME_WITH_BLANK("symbol");
+ break;
+ case GRN_CHAR_HIRAGANA :
+ CHAR_TYPE_NAME_WITH_BLANK("hiragana");
+ break;
+ case GRN_CHAR_KATAKANA :
+ CHAR_TYPE_NAME_WITH_BLANK("katakana");
+ break;
+ case GRN_CHAR_KANJI :
+ CHAR_TYPE_NAME_WITH_BLANK("kanji");
+ break;
+ case GRN_CHAR_OTHERS :
+ CHAR_TYPE_NAME_WITH_BLANK("others");
+ break;
+ default :
+ CHAR_TYPE_NAME_WITH_BLANK("unknown");
+ break;
+ }
+
+#undef CHAR_TYPE_NAME_WITH_BLANK
+
+ return name;
+}
+
+static grn_obj *
+proc_normalize(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_obj *normalizer_name;
+ grn_obj *string;
+ grn_obj *flag_names;
+
+ normalizer_name = VAR(0);
+ string = VAR(1);
+ flag_names = VAR(2);
+ if (GRN_TEXT_LEN(normalizer_name) == 0) {
+ ERR(GRN_INVALID_ARGUMENT, "normalizer name is missing");
+ return NULL;
+ }
+
+ {
+ grn_obj *normalizer;
+ grn_obj *grn_string;
+ int flags;
+ unsigned int normalized_length_in_bytes;
+ unsigned int normalized_n_characters;
+
+ flags = parse_normalize_flags(ctx, flag_names);
+ normalizer = grn_ctx_get(ctx,
+ GRN_TEXT_VALUE(normalizer_name),
+ GRN_TEXT_LEN(normalizer_name));
+ if (!normalizer) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[normalize] 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_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, normalizer);
+ ERR(GRN_INVALID_ARGUMENT,
+ "[normalize] not normalizer: %.*s",
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ grn_obj_unlink(ctx, normalizer);
+ return NULL;
+ }
+
+ grn_string = grn_string_open(ctx,
+ GRN_TEXT_VALUE(string), GRN_TEXT_LEN(string),
+ normalizer, flags);
+ grn_obj_unlink(ctx, normalizer);
+
+ GRN_OUTPUT_MAP_OPEN("RESULT", 3);
+ {
+ const char *normalized;
+
+ grn_string_get_normalized(ctx, grn_string,
+ &normalized,
+ &normalized_length_in_bytes,
+ &normalized_n_characters);
+ GRN_OUTPUT_CSTR("normalized");
+ GRN_OUTPUT_STR(normalized, normalized_length_in_bytes);
+ }
+ {
+ const unsigned char *types;
+
+ types = grn_string_get_types(ctx, grn_string);
+ GRN_OUTPUT_CSTR("types");
+ if (types) {
+ unsigned int i;
+ GRN_OUTPUT_ARRAY_OPEN("types", normalized_n_characters);
+ for (i = 0; i < normalized_n_characters; i++) {
+ GRN_OUTPUT_CSTR(char_type_name(types[i]));
+ }
+ GRN_OUTPUT_ARRAY_CLOSE();
+ } else {
+ GRN_OUTPUT_ARRAY_OPEN("types", 0);
+ GRN_OUTPUT_ARRAY_CLOSE();
+ }
+ }
+ {
+ const short *checks;
+
+ checks = grn_string_get_checks(ctx, grn_string);
+ GRN_OUTPUT_CSTR("checks");
+ if (checks) {
+ unsigned int i;
+ GRN_OUTPUT_ARRAY_OPEN("checks", normalized_length_in_bytes);
+ for (i = 0; i < normalized_length_in_bytes; i++) {
+ GRN_OUTPUT_INT32(checks[i]);
+ }
+ GRN_OUTPUT_ARRAY_CLOSE();
+ } else {
+ GRN_OUTPUT_ARRAY_OPEN("checks", 0);
+ GRN_OUTPUT_ARRAY_CLOSE();
+ }
+ }
+ GRN_OUTPUT_MAP_CLOSE();
+
+ grn_obj_unlink(ctx, grn_string);
+ }
+
+ return NULL;
+}
+
+static void
+list_proc(grn_ctx *ctx, grn_proc_type target_proc_type,
+ const char *name, const char *plural_name)
+{
+ grn_obj *db;
+ grn_table_cursor *cursor;
+ grn_obj target_procs;
+
+ db = grn_ctx_db(ctx);
+ cursor = grn_table_cursor_open(ctx, db, NULL, 0, NULL, 0, 0, -1,
+ GRN_CURSOR_BY_ID);
+ if (!cursor) {
+ return;
+ }
+
+ GRN_PTR_INIT(&target_procs, GRN_OBJ_VECTOR, GRN_ID_NIL);
+ {
+ grn_id id;
+
+ while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
+ grn_obj *obj;
+ grn_proc_type proc_type;
+
+ obj = grn_ctx_at(ctx, id);
+ if (!obj) {
+ continue;
+ }
+
+ if (obj->header.type != GRN_PROC) {
+ grn_obj_unlink(ctx, obj);
+ continue;
+ }
+
+ proc_type = grn_proc_get_type(ctx, obj);
+ if (proc_type != target_proc_type) {
+ grn_obj_unlink(ctx, obj);
+ continue;
+ }
+
+ GRN_PTR_PUT(ctx, &target_procs, obj);
+ }
+ grn_table_cursor_close(ctx, cursor);
+
+ {
+ int i, n_procs;
+
+ n_procs = GRN_BULK_VSIZE(&target_procs) / sizeof(grn_obj *);
+ GRN_OUTPUT_ARRAY_OPEN(plural_name, n_procs);
+ for (i = 0; i < n_procs; i++) {
+ grn_obj *proc;
+ char name[GRN_TABLE_MAX_KEY_SIZE];
+ int name_size;
+
+ proc = GRN_PTR_VALUE_AT(&target_procs, i);
+ name_size = grn_obj_name(ctx, proc, name, GRN_TABLE_MAX_KEY_SIZE);
+ GRN_OUTPUT_MAP_OPEN(name, 1);
+ GRN_OUTPUT_CSTR("name");
+ GRN_OUTPUT_STR(name, name_size);
+ GRN_OUTPUT_MAP_CLOSE();
+
+ grn_obj_unlink(ctx, proc);
+ }
+ GRN_OUTPUT_ARRAY_CLOSE();
+ }
+
+ grn_obj_unlink(ctx, &target_procs);
+ }
+}
+
+static grn_obj *
+proc_tokenizer_list(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ list_proc(ctx, GRN_PROC_TOKENIZER, "tokenizer", "tokenizers");
+ return NULL;
+}
+
+static grn_obj *
+proc_normalizer_list(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ list_proc(ctx, GRN_PROC_NORMALIZER, "normalizer", "normalizers");
+ return NULL;
+}
+
+static grn_obj *
+func_rand(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ int val;
+ grn_obj *obj;
+ if (nargs > 0) {
+ int max = GRN_INT32_VALUE(args[0]);
+ val = (int) (1.0 * max * rand() / (RAND_MAX + 1.0));
+ } else {
+ val = rand();
+ }
+ if ((obj = GRN_PROC_ALLOC(GRN_DB_INT32, 0))) {
+ GRN_INT32_SET(ctx, obj, val);
+ }
+ return obj;
+}
+
+static grn_obj *
+func_now(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_obj *obj;
+ if ((obj = GRN_PROC_ALLOC(GRN_DB_TIME, 0))) {
+ GRN_TIME_NOW(ctx, obj);
+ }
+ return obj;
+}
+
+static inline grn_bool
+is_comparable_number_type(grn_id type)
+{
+ return GRN_DB_INT8 <= type && type <= GRN_DB_TIME;
+}
+
+static inline grn_id
+larger_number_type(grn_id type1, grn_id type2)
+{
+ if (type1 == type2) {
+ return type1;
+ }
+
+ switch (type1) {
+ case GRN_DB_FLOAT :
+ return type1;
+ case GRN_DB_TIME :
+ if (type2 == GRN_DB_FLOAT) {
+ return type2;
+ } else {
+ return type1;
+ }
+ default :
+ if (type2 > type1) {
+ return type2;
+ } else {
+ return type1;
+ }
+ }
+}
+
+static inline grn_id
+smaller_number_type(grn_id type1, grn_id type2)
+{
+ if (type1 == type2) {
+ return type1;
+ }
+
+ switch (type1) {
+ case GRN_DB_FLOAT :
+ return type1;
+ case GRN_DB_TIME :
+ if (type2 == GRN_DB_FLOAT) {
+ return type2;
+ } else {
+ return type1;
+ }
+ default :
+ {
+ grn_id smaller_number_type;
+ if (type2 > type1) {
+ smaller_number_type = type2;
+ } else {
+ smaller_number_type = type1;
+ }
+ switch (smaller_number_type) {
+ case GRN_DB_UINT8 :
+ return GRN_DB_INT8;
+ case GRN_DB_UINT16 :
+ return GRN_DB_INT16;
+ case GRN_DB_UINT32 :
+ return GRN_DB_INT32;
+ case GRN_DB_UINT64 :
+ return GRN_DB_INT64;
+ default :
+ return smaller_number_type;
+ }
+ }
+ }
+}
+
+static inline grn_bool
+is_negative_value(grn_obj *number)
+{
+ switch (number->header.domain) {
+ case GRN_DB_INT8 :
+ return GRN_INT8_VALUE(number) < 0;
+ case GRN_DB_INT16 :
+ return GRN_INT16_VALUE(number) < 0;
+ case GRN_DB_INT32 :
+ return GRN_INT32_VALUE(number) < 0;
+ case GRN_DB_INT64 :
+ return GRN_INT64_VALUE(number) < 0;
+ case GRN_DB_TIME :
+ return GRN_TIME_VALUE(number) < 0;
+ case GRN_DB_FLOAT :
+ return GRN_FLOAT_VALUE(number) < 0;
+ default :
+ return GRN_FALSE;
+ }
+}
+
+static inline grn_bool
+number_safe_cast(grn_ctx *ctx, grn_obj *src, grn_obj *dest, grn_id type)
+{
+ grn_obj_reinit(ctx, dest, type, 0);
+ if (src->header.domain == type) {
+ GRN_TEXT_SET(ctx, dest, GRN_TEXT_VALUE(src), GRN_TEXT_LEN(src));
+ return GRN_TRUE;
+ }
+
+ switch (type) {
+ case GRN_DB_UINT8 :
+ if (is_negative_value(src)) {
+ 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;
+ }
+ break;
+ }
+ return grn_obj_cast(ctx, src, dest, GRN_FALSE) == GRN_SUCCESS;
+}
+
+static inline int
+compare_number(grn_ctx *ctx, grn_obj *number1, grn_obj *number2, grn_id type)
+{
+#define COMPARE_AND_RETURN(type, value1, value2)\
+ {\
+ type computed_value1 = value1;\
+ type computed_value2 = value2;\
+ if (computed_value1 > computed_value2) {\
+ return 1;\
+ } else if (computed_value1 < computed_value2) {\
+ return -1;\
+ } else {\
+ return 0;\
+ }\
+ }
+
+ switch (type) {
+ case GRN_DB_INT8 :
+ COMPARE_AND_RETURN(int8_t,
+ GRN_INT8_VALUE(number1),
+ GRN_INT8_VALUE(number2));
+ case GRN_DB_UINT8 :
+ COMPARE_AND_RETURN(uint8_t,
+ GRN_UINT8_VALUE(number1),
+ GRN_UINT8_VALUE(number2));
+ case GRN_DB_INT16 :
+ COMPARE_AND_RETURN(int16_t,
+ GRN_INT16_VALUE(number1),
+ GRN_INT16_VALUE(number2));
+ case GRN_DB_UINT16 :
+ COMPARE_AND_RETURN(uint16_t,
+ GRN_UINT16_VALUE(number1),
+ GRN_UINT16_VALUE(number2));
+ case GRN_DB_INT32 :
+ COMPARE_AND_RETURN(int32_t,
+ GRN_INT32_VALUE(number1),
+ GRN_INT32_VALUE(number2));
+ case GRN_DB_UINT32 :
+ COMPARE_AND_RETURN(uint32_t,
+ GRN_UINT32_VALUE(number1),
+ GRN_UINT32_VALUE(number2));
+ case GRN_DB_INT64 :
+ COMPARE_AND_RETURN(int64_t,
+ GRN_INT64_VALUE(number1),
+ GRN_INT64_VALUE(number2));
+ case GRN_DB_UINT64 :
+ COMPARE_AND_RETURN(uint64_t,
+ GRN_UINT64_VALUE(number1),
+ GRN_UINT64_VALUE(number2));
+ case GRN_DB_FLOAT :
+ COMPARE_AND_RETURN(double,
+ GRN_FLOAT_VALUE(number1),
+ GRN_FLOAT_VALUE(number2));
+ case GRN_DB_TIME :
+ COMPARE_AND_RETURN(int64_t,
+ GRN_TIME_VALUE(number1),
+ GRN_TIME_VALUE(number2));
+ default :
+ return 0;
+ }
+
+#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)
+{
+ grn_obj *max;
+ grn_id cast_type = GRN_DB_INT8;
+ grn_obj casted_max, casted_number;
+ int i;
+
+ max = GRN_PROC_ALLOC(GRN_DB_VOID, 0);
+ if (!max) {
+ return max;
+ }
+
+ GRN_VOID_INIT(&casted_max);
+ GRN_VOID_INIT(&casted_number);
+
+ 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);
+ }
+ break;
+ default :
+ continue;
+ }
+ }
+ GRN_OBJ_FIN(ctx, &casted_max);
+ GRN_OBJ_FIN(ctx, &casted_number);
+
+ 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)
+{
+ grn_obj *min;
+ grn_id cast_type = GRN_DB_INT8;
+ grn_obj casted_min, casted_number;
+ int i;
+
+ min = GRN_PROC_ALLOC(GRN_DB_VOID, 0);
+ if (!min) {
+ return min;
+ }
+
+ GRN_VOID_INIT(&casted_min);
+ GRN_VOID_INIT(&casted_number);
+ for (i = 0; i < nargs; i++) {
+ 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);
+ }
+ break;
+ default :
+ continue;
+ }
+ }
+ GRN_OBJ_FIN(ctx, &casted_min);
+ GRN_OBJ_FIN(ctx, &casted_number);
+
+ return min;
+}
+
+static grn_obj *
+func_geo_in_circle(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_obj *obj;
+ grn_bool r = GRN_FALSE;
+ grn_geo_approximate_type type = GRN_GEO_APPROXIMATE_RECTANGLE;
+ switch (nargs) {
+ case 4 :
+ if (grn_geo_resolve_approximate_type(ctx, args[3], &type) != GRN_SUCCESS) {
+ break;
+ }
+ /* fallthru */
+ case 3 :
+ r = grn_geo_in_circle(ctx, args[0], args[1], args[2], type);
+ break;
+ default :
+ break;
+ }
+ if ((obj = GRN_PROC_ALLOC(GRN_DB_BOOL, 0))) {
+ GRN_BOOL_SET(ctx, obj, r);
+ }
+ return obj;
+}
+
+static grn_obj *
+func_geo_in_rectangle(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_obj *obj;
+ 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_BOOL, 0))) {
+ GRN_BOOL_SET(ctx, obj, r);
+ }
+ return obj;
+}
+
+static grn_obj *
+func_geo_distance(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_obj *obj;
+ double d = 0.0;
+ grn_geo_approximate_type type = GRN_GEO_APPROXIMATE_RECTANGLE;
+ switch (nargs) {
+ case 3 :
+ if (grn_geo_resolve_approximate_type(ctx, args[2], &type) != GRN_SUCCESS) {
+ break;
+ }
+ /* fallthru */
+ case 2 :
+ d = grn_geo_distance(ctx, args[0], args[1], type);
+ break;
+ default:
+ break;
+ }
+ if ((obj = GRN_PROC_ALLOC(GRN_DB_FLOAT, 0))) {
+ GRN_FLOAT_SET(ctx, obj, d);
+ }
+ return obj;
+}
+
+/* deprecated. */
+static grn_obj *
+func_geo_distance2(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_obj *obj;
+ double d = 0;
+ if (nargs == 2) {
+ d = grn_geo_distance_sphere(ctx, args[0], args[1]);
+ }
+ if ((obj = GRN_PROC_ALLOC(GRN_DB_FLOAT, 0))) {
+ GRN_FLOAT_SET(ctx, obj, d);
+ }
+ return obj;
+}
+
+/* deprecated. */
+static grn_obj *
+func_geo_distance3(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_obj *obj;
+ double d = 0;
+ if (nargs == 2) {
+ d = grn_geo_distance_ellipsoid(ctx, args[0], args[1]);
+ }
+ if ((obj = GRN_PROC_ALLOC(GRN_DB_FLOAT, 0))) {
+ GRN_FLOAT_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)
+{
+ grn_obj *true_value;
+ if ((true_value = GRN_PROC_ALLOC(GRN_DB_BOOL, 0))) {
+ GRN_BOOL_SET(ctx, true_value, GRN_TRUE);
+ }
+ return true_value;
+}
+
+static grn_rc
+selector_all_records(grn_ctx *ctx, grn_obj *table, grn_obj *index,
+ int nargs, grn_obj **args,
+ grn_obj *res, grn_operator op)
+{
+ grn_posting 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);
+ });
+
+ return ctx->rc;
+}
+
+typedef struct {
+ grn_obj *found;
+ grn_obj *table;
+ grn_obj *records;
+} selector_to_function_data;
+
+static grn_bool
+selector_to_function_data_init(grn_ctx *ctx,
+ selector_to_function_data *data,
+ grn_user_data *user_data)
+{
+ grn_obj *condition = NULL;
+ grn_obj *variable;
+
+ data->table = NULL;
+ data->records = NULL;
+
+ data->found = GRN_PROC_ALLOC(GRN_DB_BOOL, 0);
+ if (!data->found) {
+ return GRN_FALSE;
+ }
+ GRN_BOOL_SET(ctx, data->found, GRN_FALSE);
+
+ grn_proc_get_info(ctx, user_data, NULL, NULL, &condition);
+ if (!condition) {
+ return GRN_FALSE;
+ }
+
+ variable = grn_expr_get_var_by_offset(ctx, condition, 0);
+ if (!variable) {
+ return GRN_FALSE;
+ }
+
+ data->table = grn_ctx_at(ctx, variable->header.domain);
+ if (!data->table) {
+ return GRN_FALSE;
+ }
+
+ data->records = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
+ data->table, NULL);
+ if (!data->records) {
+ return GRN_FALSE;
+ }
+
+ {
+ grn_rset_posinfo pi;
+ unsigned int key_size;
+ memset(&pi, 0, sizeof(grn_rset_posinfo));
+ pi.rid = GRN_RECORD_VALUE(variable);
+ key_size = ((grn_hash *)(data->records))->key_size;
+ if (grn_table_add(ctx, data->records, &pi, key_size, NULL) == GRN_ID_NIL) {
+ return GRN_FALSE;
+ }
+ }
+
+ return GRN_TRUE;
+}
+
+static void
+selector_to_function_data_selected(grn_ctx *ctx,
+ selector_to_function_data *data)
+{
+ GRN_BOOL_SET(ctx, data->found, grn_table_size(ctx, data->records) > 0);
+}
+
+static void
+selector_to_function_data_fin(grn_ctx *ctx,
+ selector_to_function_data *data)
+{
+ if (data->records) {
+ grn_obj_unlink(ctx, data->records);
+ }
+}
+
+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
+run_query(grn_ctx *ctx, grn_obj *table,
+ int nargs, grn_obj **args,
+ grn_obj *res, grn_operator op)
+{
+ grn_rc rc = GRN_SUCCESS;
+ 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;
+
+ if (!(2 <= nargs && nargs <= 3)) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "query(): wrong number of arguments (%d for 2..3)", nargs);
+ rc = ctx->rc;
+ goto exit;
+ }
+
+ match_columns_string = args[0];
+ query = args[1];
+ if (nargs > 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 &&
+ GRN_TEXT_LEN(match_columns_string) > 0) {
+ GRN_EXPR_CREATE_FOR_QUERY(ctx, table, match_columns, dummy_variable);
+ if (!match_columns) {
+ rc = ctx->rc;
+ goto exit;
+ }
+
+ grn_expr_parse(ctx, match_columns,
+ GRN_TEXT_VALUE(match_columns_string),
+ GRN_TEXT_LEN(match_columns_string),
+ NULL, GRN_OP_MATCH, GRN_OP_AND,
+ GRN_EXPR_SYNTAX_SCRIPT);
+ if (ctx->rc != GRN_SUCCESS) {
+ rc = ctx->rc;
+ goto exit;
+ }
+ }
+
+ if (query->header.domain == GRN_DB_TEXT && GRN_TEXT_LEN(query) > 0) {
+ const char *query_string;
+ unsigned int query_string_len;
+ grn_obj expanded_query;
+
+ GRN_EXPR_CREATE_FOR_QUERY(ctx, table, condition, dummy_variable);
+ if (!condition) {
+ rc = ctx->rc;
+ goto exit;
+ }
+
+ query_string = GRN_TEXT_VALUE(query);
+ query_string_len = GRN_TEXT_LEN(query);
+
+ GRN_TEXT_INIT(&expanded_query, 0);
+ if (query_expander_name &&
+ query_expander_name->header.domain == GRN_DB_TEXT &&
+ GRN_TEXT_LEN(query_expander_name) > 0) {
+ 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;
+ }
+ query_string = GRN_TEXT_VALUE(&expanded_query);
+ query_string_len = GRN_TEXT_LEN(&expanded_query);
+ }
+ grn_expr_parse(ctx, condition,
+ query_string,
+ query_string_len,
+ match_columns, default_mode, GRN_OP_AND, flags);
+ rc = ctx->rc;
+ GRN_OBJ_FIN(ctx, &expanded_query);
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+ grn_table_select(ctx, table, condition, res, op);
+ rc = ctx->rc;
+ }
+
+exit :
+ if (match_columns) {
+ grn_obj_unlink(ctx, match_columns);
+ }
+ if (condition) {
+ grn_obj_unlink(ctx, condition);
+ }
+
+ return rc;
+}
+
+static grn_obj *
+func_query(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_query(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_query(grn_ctx *ctx, grn_obj *table, grn_obj *index,
+ int nargs, grn_obj **args,
+ grn_obj *res, grn_operator op)
+{
+ return run_query(ctx, table, nargs - 1, args + 1, res, op);
+}
+
+static grn_rc
+run_sub_filter(grn_ctx *ctx, grn_obj *table,
+ int nargs, grn_obj **args,
+ grn_obj *res, grn_operator op)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *scope;
+ grn_obj *sub_filter_string;
+ grn_obj *scope_domain = NULL;
+ grn_obj *sub_filter = NULL;
+ grn_obj *dummy_variable = NULL;
+
+ if (nargs != 2) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "sub_filter(): wrong number of arguments (%d for 2)", nargs);
+ rc = ctx->rc;
+ goto exit;
+ }
+
+ scope = args[0];
+ sub_filter_string = args[1];
+
+ switch (scope->header.type) {
+ case GRN_ACCESSOR :
+ case GRN_COLUMN_FIX_SIZE :
+ case GRN_COLUMN_VAR_SIZE :
+ case GRN_COLUMN_INDEX :
+ break;
+ default :
+ /* TODO: put inspected the 1st argument to message */
+ ERR(GRN_INVALID_ARGUMENT,
+ "sub_filter(): the 1st argument must be column or accessor");
+ rc = ctx->rc;
+ goto exit;
+ break;
+ }
+
+ scope_domain = grn_ctx_at(ctx, grn_obj_get_range(ctx, scope));
+
+ if (sub_filter_string->header.domain != GRN_DB_TEXT) {
+ /* TODO: put inspected the 2nd argument to message */
+ ERR(GRN_INVALID_ARGUMENT,
+ "sub_filter(): the 2nd argument must be String");
+ rc = ctx->rc;
+ goto exit;
+ }
+ if (GRN_TEXT_LEN(sub_filter_string) == 0) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "sub_filter(): the 2nd argument must not be empty String");
+ rc = ctx->rc;
+ goto exit;
+ }
+
+ GRN_EXPR_CREATE_FOR_QUERY(ctx, scope_domain, sub_filter, dummy_variable);
+ if (!sub_filter) {
+ rc = ctx->rc;
+ goto exit;
+ }
+
+ grn_expr_parse(ctx, sub_filter,
+ GRN_TEXT_VALUE(sub_filter_string),
+ GRN_TEXT_LEN(sub_filter_string),
+ NULL, GRN_OP_MATCH, GRN_OP_AND,
+ GRN_EXPR_SYNTAX_SCRIPT);
+ if (ctx->rc != GRN_SUCCESS) {
+ rc = ctx->rc;
+ goto exit;
+ }
+
+ {
+ grn_obj *base_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, res, op);
+ } else {
+ grn_accessor accessor;
+ accessor.header.type = GRN_ACCESSOR;
+ accessor.obj = scope;
+ accessor.action = GRN_ACCESSOR_GET_COLUMN_VALUE;
+ accessor.next = NULL;
+ rc = grn_accessor_resolve(ctx, (grn_obj *)&accessor, -1, base_res,
+ res, op);
+ }
+ grn_obj_unlink(ctx, base_res);
+ }
+
+exit :
+ if (scope_domain) {
+ grn_obj_unlink(ctx, scope_domain);
+ }
+ if (sub_filter) {
+ grn_obj_unlink(ctx, sub_filter);
+ }
+
+ return rc;
+}
+
+static grn_rc
+selector_sub_filter(grn_ctx *ctx, grn_obj *table, grn_obj *index,
+ int nargs, grn_obj **args,
+ grn_obj *res, grn_operator op)
+{
+ return run_sub_filter(ctx, table, nargs - 1, args + 1, res, op);
+}
+
+static grn_obj *
+func_html_untag(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *html_arg;
+ int html_arg_domain;
+ grn_obj html;
+ grn_obj *text;
+ const char *html_raw;
+ int i, length;
+ grn_bool in_tag = GRN_FALSE;
+
+ if (nargs != 1) {
+ ERR(GRN_INVALID_ARGUMENT, "HTML is missing");
+ return NULL;
+ }
+
+ html_arg = args[0];
+ html_arg_domain = html_arg->header.domain;
+ switch (html_arg_domain) {
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ GRN_VALUE_VAR_SIZE_INIT(&html, GRN_OBJ_DO_SHALLOW_COPY, html_arg_domain);
+ GRN_TEXT_SET(ctx, &html, GRN_TEXT_VALUE(html_arg), GRN_TEXT_LEN(html_arg));
+ break;
+ default :
+ GRN_TEXT_INIT(&html, 0);
+ if (grn_obj_cast(ctx, html_arg, &html, GRN_FALSE)) {
+ grn_obj inspected;
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, html_arg);
+ ERR(GRN_INVALID_ARGUMENT, "failed to cast to text: <%.*s>",
+ (int)GRN_TEXT_LEN(&inspected), GRN_TEXT_VALUE(&inspected));
+ GRN_OBJ_FIN(ctx, &inspected);
+ GRN_OBJ_FIN(ctx, &html);
+ return NULL;
+ }
+ break;
+ }
+
+ text = GRN_PROC_ALLOC(html.header.domain, 0);
+ if (!text) {
+ GRN_OBJ_FIN(ctx, &html);
+ return NULL;
+ }
+
+ html_raw = GRN_TEXT_VALUE(&html);
+ length = GRN_TEXT_LEN(&html);
+ for (i = 0; i < length; i++) {
+ switch (html_raw[i]) {
+ case '<' :
+ in_tag = GRN_TRUE;
+ break;
+ case '>' :
+ if (in_tag) {
+ in_tag = GRN_FALSE;
+ } else {
+ GRN_TEXT_PUTC(ctx, text, html_raw[i]);
+ }
+ break;
+ default :
+ if (!in_tag) {
+ GRN_TEXT_PUTC(ctx, text, html_raw[i]);
+ }
+ break;
+ }
+ }
+
+ GRN_OBJ_FIN(ctx, &html);
+
+ return text;
+}
+
+static grn_bool
+grn_text_equal_cstr(grn_ctx *ctx, grn_obj *text, const char *cstr)
+{
+ int cstr_len;
+
+ cstr_len = strlen(cstr);
+ return (GRN_TEXT_LEN(text) == cstr_len &&
+ strncmp(GRN_TEXT_VALUE(text), cstr, cstr_len) == 0);
+}
+
+typedef enum {
+ BETWEEN_BORDER_INVALID,
+ BETWEEN_BORDER_INCLUDE,
+ BETWEEN_BORDER_EXCLUDE
+} between_border_type;
+
+typedef struct {
+ grn_obj *value;
+ grn_obj *min;
+ grn_obj casted_min;
+ between_border_type min_border_type;
+ grn_obj *max;
+ grn_obj casted_max;
+ between_border_type max_border_type;
+} between_data;
+
+static void
+between_data_init(grn_ctx *ctx, between_data *data)
+{
+ GRN_VOID_INIT(&(data->casted_min));
+ GRN_VOID_INIT(&(data->casted_max));
+}
+
+static void
+between_data_fin(grn_ctx *ctx, between_data *data)
+{
+ GRN_OBJ_FIN(ctx, &(data->casted_min));
+ GRN_OBJ_FIN(ctx, &(data->casted_max));
+}
+
+static between_border_type
+between_parse_border(grn_ctx *ctx, grn_obj *border,
+ const char *argument_description)
+{
+ grn_obj inspected;
+
+ /* TODO: support other text types */
+ if (border->header.domain == GRN_DB_TEXT) {
+ if (grn_text_equal_cstr(ctx, border, "include")) {
+ return BETWEEN_BORDER_INCLUDE;
+ } else if (grn_text_equal_cstr(ctx, border, "exclude")) {
+ return BETWEEN_BORDER_EXCLUDE;
+ }
+ }
+
+ GRN_TEXT_INIT(&inspected, 0);
+ grn_inspect(ctx, &inspected, border);
+ ERR(GRN_INVALID_ARGUMENT,
+ "between(): %s must be \"include\" or \"exclude\": <%.*s>",
+ argument_description,
+ (int)GRN_TEXT_LEN(&inspected),
+ GRN_TEXT_VALUE(&inspected));
+ grn_obj_unlink(ctx, &inspected);
+
+ return BETWEEN_BORDER_INVALID;
+}
+
+static grn_rc
+between_cast(grn_ctx *ctx, grn_obj *source, grn_obj *destination, grn_id domain,
+ const char *target_argument_name)
+{
+ grn_rc rc;
+
+ GRN_OBJ_INIT(destination, GRN_BULK, 0, domain);
+ rc = grn_obj_cast(ctx, source, destination, GRN_FALSE);
+ if (rc != GRN_SUCCESS) {
+ grn_obj inspected_source;
+ grn_obj *domain_object;
+ char domain_name[GRN_TABLE_MAX_KEY_SIZE];
+ int domain_name_length;
+
+ GRN_TEXT_INIT(&inspected_source, 0);
+ grn_inspect(ctx, &inspected_source, source);
+
+ domain_object = grn_ctx_at(ctx, domain);
+ domain_name_length =
+ grn_obj_name(ctx, domain_object, domain_name, GRN_TABLE_MAX_KEY_SIZE);
+
+ ERR(rc, "between(): failed to cast %s: <%.*s> -> <%.*s>",
+ target_argument_name,
+ (int)GRN_TEXT_LEN(&inspected_source),
+ GRN_TEXT_VALUE(&inspected_source),
+ domain_name_length,
+ domain_name);
+
+ grn_obj_unlink(ctx, &inspected_source);
+ grn_obj_unlink(ctx, domain_object);
+ }
+
+ return rc;
+}
+
+static grn_rc
+between_parse_args(grn_ctx *ctx, int nargs, grn_obj **args, between_data *data)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *min_border;
+ grn_obj *max_border;
+
+ if (nargs != 5) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "between(): wrong number of arguments (%d for 5)", nargs);
+ rc = ctx->rc;
+ goto exit;
+ }
+
+ data->value = args[0];
+ data->min = args[1];
+ min_border = args[2];
+ data->max = args[3];
+ max_border = args[4];
+
+ data->min_border_type =
+ between_parse_border(ctx, min_border, "the 3rd argument (min_border)");
+ if (data->min_border_type == BETWEEN_BORDER_INVALID) {
+ rc = ctx->rc;
+ goto exit;
+ }
+
+ data->max_border_type =
+ between_parse_border(ctx, max_border, "the 5th argument (max_border)");
+ if (data->max_border_type == BETWEEN_BORDER_INVALID) {
+ rc = ctx->rc;
+ goto exit;
+ }
+
+ {
+ grn_id value_type;
+ switch (data->value->header.type) {
+ case GRN_BULK :
+ value_type = data->value->header.domain;
+ 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");
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+ data->min = &(data->casted_min);
+ }
+
+ if (value_type != data->max->header.domain) {
+ rc = between_cast(ctx, data->max, &data->casted_max, value_type, "max");
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+ data->max = &(data->casted_max);
+ }
+ }
+
+exit :
+ return rc;
+}
+
+static grn_bool
+between_create_expr(grn_ctx *ctx, grn_obj *table, between_data *data,
+ grn_obj **expr, grn_obj **variable)
+{
+ GRN_EXPR_CREATE_FOR_QUERY(ctx, table, *expr, *variable);
+ if (!*expr) {
+ return GRN_FALSE;
+ }
+
+ if (data->value->header.type == GRN_BULK) {
+ grn_expr_append_obj(ctx, *expr, data->value, GRN_OP_PUSH, 1);
+ } else {
+ grn_expr_append_obj(ctx, *expr, data->value, GRN_OP_GET_VALUE, 1);
+ }
+ grn_expr_append_obj(ctx, *expr, data->min, GRN_OP_PUSH, 1);
+ if (data->min_border_type == BETWEEN_BORDER_INCLUDE) {
+ grn_expr_append_op(ctx, *expr, GRN_OP_GREATER_EQUAL, 2);
+ } else {
+ grn_expr_append_op(ctx, *expr, GRN_OP_GREATER, 2);
+ }
+
+ if (data->value->header.type == GRN_BULK) {
+ grn_expr_append_obj(ctx, *expr, data->value, GRN_OP_PUSH, 1);
+ } else {
+ grn_expr_append_obj(ctx, *expr, data->value, GRN_OP_GET_VALUE, 1);
+ }
+ grn_expr_append_obj(ctx, *expr, data->max, GRN_OP_PUSH, 1);
+ if (data->max_border_type == BETWEEN_BORDER_INCLUDE) {
+ grn_expr_append_op(ctx, *expr, GRN_OP_LESS_EQUAL, 2);
+ } else {
+ grn_expr_append_op(ctx, *expr, GRN_OP_LESS, 2);
+ }
+
+ grn_expr_append_op(ctx, *expr, GRN_OP_AND, 2);
+
+ return GRN_TRUE;
+}
+
+static grn_obj *
+func_between(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *found;
+ between_data data;
+ grn_obj *condition = NULL;
+ grn_obj *variable;
+ grn_obj *table = NULL;
+ grn_obj *between_expr;
+ grn_obj *between_variable;
+ grn_obj *result;
+
+ found = GRN_PROC_ALLOC(GRN_DB_BOOL, 0);
+ if (!found) {
+ return NULL;
+ }
+ GRN_BOOL_SET(ctx, found, GRN_FALSE);
+
+ grn_proc_get_info(ctx, user_data, NULL, NULL, &condition);
+ if (!condition) {
+ return found;
+ }
+
+ variable = grn_expr_get_var_by_offset(ctx, condition, 0);
+ if (!variable) {
+ return found;
+ }
+
+ between_data_init(ctx, &data);
+ rc = between_parse_args(ctx, nargs, args, &data);
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+
+ table = grn_ctx_at(ctx, variable->header.domain);
+ if (!table) {
+ goto exit;
+ }
+ if (!between_create_expr(ctx, table, &data, &between_expr, &between_variable)) {
+ goto exit;
+ }
+
+ GRN_RECORD_SET(ctx, between_variable, GRN_RECORD_VALUE(variable));
+ result = grn_expr_exec(ctx, between_expr, 0);
+ if (grn_obj_is_true(ctx, result)) {
+ GRN_BOOL_SET(ctx, found, GRN_TRUE);
+ }
+
+ grn_obj_unlink(ctx, between_expr);
+ grn_obj_unlink(ctx, table);
+
+exit :
+ between_data_fin(ctx, &data);
+ if (table) {
+ grn_obj_unlink(ctx, table);
+ }
+
+ return found;
+}
+
+static grn_bool
+selector_between_sequential_search_should_use(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *index,
+ grn_obj *index_table,
+ between_data *data,
+ grn_obj *res,
+ grn_operator op,
+ double too_many_index_match_ratio)
+{
+ int n_index_keys;
+
+ if (too_many_index_match_ratio < 0.0) {
+ return GRN_FALSE;
+ }
+
+ if (op != GRN_OP_AND) {
+ 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;
+ }
+
+ switch (index_table->header.domain) {
+ /* TODO: */
+ /* case GRN_DB_INT8 : */
+ /* case GRN_DB_UINT8 : */
+ /* case GRN_DB_INT16 : */
+ /* case GRN_DB_UINT16 : */
+ /* case GRN_DB_INT32 : */
+ /* case GRN_DB_UINT32 : */
+ /* case GRN_DB_INT64 : */
+ /* case GRN_DB_UINT64 : */
+ /* case GRN_DB_FLOAT : */
+ case GRN_DB_TIME :
+ break;
+ default :
+ return GRN_FALSE;
+ }
+
+ {
+ grn_table_cursor *cursor;
+ long long int all_min;
+ long long int all_max;
+ cursor = grn_table_cursor_open(ctx, index_table,
+ NULL, -1,
+ NULL, -1,
+ 0, 1,
+ GRN_CURSOR_BY_KEY | GRN_CURSOR_ASCENDING);
+ if (!cursor) {
+ return GRN_FALSE;
+ }
+ if (grn_table_cursor_next(ctx, cursor) == GRN_ID_NIL) {
+ grn_table_cursor_close(ctx, cursor);
+ return GRN_FALSE;
+ }
+ {
+ long long int *key;
+ grn_table_cursor_get_key(ctx, cursor, (void **)&key);
+ all_min = *key;
+ }
+ grn_table_cursor_close(ctx, cursor);
+
+ cursor = grn_table_cursor_open(ctx, index_table,
+ NULL, 0, NULL, 0,
+ 0, 1,
+ GRN_CURSOR_BY_KEY | GRN_CURSOR_DESCENDING);
+ if (!cursor) {
+ return GRN_FALSE;
+ }
+ if (grn_table_cursor_next(ctx, cursor) == GRN_ID_NIL) {
+ grn_table_cursor_close(ctx, cursor);
+ return GRN_FALSE;
+ }
+ {
+ long long int *key;
+ grn_table_cursor_get_key(ctx, cursor, (void **)&key);
+ all_max = *key;
+ }
+ grn_table_cursor_close(ctx, cursor);
+
+ /*
+ * We assume the following:
+ * * homogeneous index key distribution.
+ * * each index key matches only 1 record.
+ * TODO: Improve me.
+ */
+ {
+ int n_existing_records;
+ int n_indexed_records;
+ long long int all_difference;
+ long long int argument_difference;
+
+ n_existing_records = grn_table_size(ctx, res);
+
+ all_difference = all_max - all_min;
+ if (all_difference <= 0) {
+ return GRN_FALSE;
+ }
+ argument_difference =
+ GRN_TIME_VALUE(data->max) - GRN_TIME_VALUE(data->min);
+ if (argument_difference <= 0) {
+ return GRN_FALSE;
+ }
+ n_indexed_records =
+ n_index_keys * ((double)argument_difference / (double)all_difference);
+
+ /*
+ * Same as:
+ * ((n_existing_record / n_indexed_records) > too_many_index_match_ratio)
+ */
+ if (n_existing_records > (n_indexed_records * too_many_index_match_ratio)) {
+ return GRN_FALSE;
+ }
+ }
+ }
+
+ return GRN_TRUE;
+}
+
+static grn_rc
+selector_between_sequential_search(grn_ctx *ctx,
+ grn_obj *table,
+ between_data *data,
+ grn_obj *res,
+ grn_operator op)
+{
+ {
+ 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_id id;
+ grn_obj value;
+
+ if (op == GRN_OP_AND) {
+ target_table = res;
+ } else {
+ target_table = table;
+ }
+ cursor = grn_table_cursor_open(ctx, target_table,
+ NULL, 0,
+ NULL, 0,
+ offset, limit, flags);
+ if (!cursor) {
+ 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;
+
+ if (target_table == res) {
+ grn_id *key;
+ grn_table_cursor_get_key(ctx, cursor, (void **)&key);
+ record_id = *key;
+ } else {
+ record_id = id;
+ }
+
+ 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_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_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)
+{
+ 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;
+
+ between_data_init(ctx, &data);
+ rc = between_parse_args(ctx, nargs - 1, args + 1, &data);
+ if (rc != GRN_SUCCESS) {
+ goto exit;
+ }
+
+ if (data.min_border_type == BETWEEN_BORDER_EXCLUDE) {
+ flags |= GRN_CURSOR_GT;
+ }
+ if (data.max_border_type == BETWEEN_BORDER_EXCLUDE) {
+ flags |= GRN_CURSOR_LT;
+ }
+
+ 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;
+ }
+
+ cursor = grn_table_cursor_open(ctx, index_table,
+ GRN_BULK_HEAD(data.min),
+ GRN_BULK_VSIZE(data.min),
+ GRN_BULK_HEAD(data.max),
+ GRN_BULK_VSIZE(data.max),
+ offset, limit, flags);
+ if (!cursor) {
+ rc = ctx->rc;
+ goto exit;
+ }
+
+ 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);
+
+ return rc;
+}
+
+static grn_obj *
+func_in_values(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_obj *found;
+ grn_obj *target_value;
+ int i;
+
+ found = GRN_PROC_ALLOC(GRN_DB_BOOL, 0);
+ if (!found) {
+ return NULL;
+ }
+ GRN_BOOL_SET(ctx, found, GRN_FALSE);
+
+ if (nargs < 1) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "in_values(): wrong number of arguments (%d for 1..)", nargs);
+ return found;
+ }
+
+ target_value = args[0];
+ for (i = 1; i < nargs; i++) {
+ grn_obj *value = args[i];
+ grn_bool result;
+
+ result = grn_operator_exec_equal(ctx, target_value, value);
+ if (ctx->rc) {
+ break;
+ }
+
+ if (result) {
+ GRN_BOOL_SET(ctx, found, GRN_TRUE);
+ break;
+ }
+ }
+
+ return found;
+}
+
+static grn_bool
+is_reference_type_column(grn_ctx *ctx, grn_obj *column)
+{
+ grn_bool is_reference_type;
+ grn_obj *range;
+
+ range = grn_ctx_at(ctx, grn_obj_get_range(ctx, column));
+ switch (range->header.type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ is_reference_type = GRN_TRUE;
+ break;
+ default :
+ is_reference_type = GRN_FALSE;
+ break;
+ }
+ grn_obj_unlink(ctx, range);
+
+ return is_reference_type;
+}
+
+static grn_obj *
+selector_in_values_find_source(grn_ctx *ctx, grn_obj *index, grn_obj *res)
+{
+ grn_id source_id = GRN_ID_NIL;
+ grn_obj source_ids;
+ unsigned int n_source_ids;
+
+ GRN_UINT32_INIT(&source_ids, GRN_OBJ_VECTOR);
+ grn_obj_get_info(ctx, index, GRN_INFO_SOURCE, &source_ids);
+ n_source_ids = GRN_BULK_VSIZE(&source_ids) / sizeof(grn_id);
+ if (n_source_ids == 1) {
+ source_id = GRN_UINT32_VALUE_AT(&source_ids, 0);
+ }
+ GRN_OBJ_FIN(ctx, &source_ids);
+
+ if (source_id == GRN_ID_NIL) {
+ return NULL;
+ } else {
+ return grn_ctx_at(ctx, source_id);
+ }
+}
+
+static grn_bool
+selector_in_values_sequential_search(grn_ctx *ctx,
+ grn_obj *table,
+ grn_obj *index,
+ int n_values,
+ grn_obj **values,
+ grn_obj *res,
+ grn_operator op)
+{
+ grn_obj *source;
+ int n_existing_records;
+
+ if (grn_in_values_too_many_index_match_ratio < 0.0) {
+ return GRN_FALSE;
+ }
+
+ if (op != GRN_OP_AND) {
+ return GRN_FALSE;
+ }
+
+ if (index->header.flags & GRN_OBJ_WITH_WEIGHT) {
+ return GRN_FALSE;
+ }
+
+ n_existing_records = grn_table_size(ctx, res);
+ if (n_existing_records == 0) {
+ return GRN_TRUE;
+ }
+
+ source = selector_in_values_find_source(ctx, index, res);
+ if (!source) {
+ return GRN_FALSE;
+ }
+
+ if (!is_reference_type_column(ctx, source)) {
+ grn_obj_unlink(ctx, source);
+ return GRN_FALSE;
+ }
+
+ {
+ grn_obj value_ids;
+ int i, n_value_ids;
+ int n_indexed_records = 0;
+
+ {
+ grn_id range_id;
+ grn_obj *range;
+
+ range_id = grn_obj_get_range(ctx, source);
+ range = grn_ctx_at(ctx, range_id);
+ if (!range) {
+ grn_obj_unlink(ctx, source);
+ return GRN_FALSE;
+ }
+
+ GRN_RECORD_INIT(&value_ids, GRN_OBJ_VECTOR, range_id);
+ for (i = 0; i < n_values; i++) {
+ grn_obj *value = values[i];
+ grn_id value_id;
+
+ value_id = grn_table_get(ctx, range,
+ GRN_TEXT_VALUE(value), GRN_TEXT_LEN(value));
+ if (value_id == GRN_ID_NIL) {
+ continue;
+ }
+ GRN_RECORD_PUT(ctx, &value_ids, value_id);
+ }
+ grn_obj_unlink(ctx, range);
+ }
+
+ n_value_ids = GRN_BULK_VSIZE(&value_ids) / sizeof(grn_id);
+ for (i = 0; i < n_value_ids; i++) {
+ grn_id value_id = GRN_RECORD_VALUE_AT(&value_ids, i);
+ n_indexed_records += grn_ii_estimate_size(ctx, (grn_ii *)index, value_id);
+ }
+
+ /*
+ * Same as:
+ * ((n_existing_record / n_indexed_records) >
+ * grn_in_values_too_many_index_match_ratio)
+ */
+ if (n_existing_records >
+ (n_indexed_records * grn_in_values_too_many_index_match_ratio)) {
+ grn_obj_unlink(ctx, &value_ids);
+ grn_obj_unlink(ctx, source);
+ return GRN_FALSE;
+ }
+
+ {
+ grn_obj *accessor;
+ char local_source_name[GRN_TABLE_MAX_KEY_SIZE];
+ int local_source_name_length;
+
+ local_source_name_length = grn_column_name(ctx, source,
+ local_source_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ grn_obj_unlink(ctx, source);
+ accessor = grn_obj_column(ctx, res,
+ local_source_name,
+ local_source_name_length);
+ {
+ grn_table_cursor *cursor;
+ grn_id id;
+ grn_obj record_value;
+
+ GRN_VOID_INIT(&record_value);
+ cursor = grn_table_cursor_open(ctx, res,
+ NULL, 0, NULL, 0,
+ 0, -1, GRN_CURSOR_ASCENDING);
+ 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, id, &record_value);
+ for (i = 0; i < n_value_ids; i++) {
+ grn_id value_id = GRN_RECORD_VALUE_AT(&value_ids, i);
+ 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;
+ }
+ }
+ }
+ grn_table_cursor_close(ctx, cursor);
+ grn_ii_resolve_sel_and(ctx, (grn_hash *)res, op);
+ GRN_OBJ_FIN(ctx, &record_value);
+ }
+ grn_obj_unlink(ctx, accessor);
+ }
+ grn_obj_unlink(ctx, &value_ids);
+ }
+ grn_obj_unlink(ctx, source);
+
+ return GRN_TRUE;
+}
+
+static grn_rc
+selector_in_values(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 i, n_values;
+ grn_obj **values;
+
+ if (!index) {
+ return GRN_INVALID_ARGUMENT;
+ }
+
+ if (nargs < 2) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "in_values(): wrong number of arguments (%d for 1..)", nargs);
+ return ctx->rc;
+ }
+
+ n_values = nargs - 2;
+ values = args + 2;
+
+ if (n_values == 0) {
+ return rc;
+ }
+
+ if (selector_in_values_sequential_search(ctx, table, index,
+ n_values, values,
+ res, op)) {
+ return ctx->rc;
+ }
+
+ ctx->flags |= GRN_CTX_TEMPORARY_DISABLE_II_RESOLVE_SEL_AND;
+ for (i = 0; i < n_values; i++) {
+ grn_obj *value = values[i];
+ grn_search_optarg search_options;
+ memset(&search_options, 0, sizeof(grn_search_optarg));
+ search_options.mode = GRN_OP_EXACT;
+ search_options.similarity_threshold = 0;
+ search_options.max_interval = 0;
+ search_options.weight_vector = NULL;
+ search_options.vector_size = 0;
+ search_options.proc = NULL;
+ search_options.max_size = 0;
+ search_options.scorer = NULL;
+ if (i == n_values - 1) {
+ ctx->flags &= ~GRN_CTX_TEMPORARY_DISABLE_II_RESOLVE_SEL_AND;
+ }
+ rc = grn_obj_search(ctx, index, value, res, op, &search_options);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+
+ return rc;
+}
+
+static grn_obj *
+proc_range_filter(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *table_name = VAR(0);
+ grn_obj *column_name = VAR(1);
+ grn_obj *min = VAR(2);
+ grn_obj *min_border = VAR(3);
+ grn_obj *max = VAR(4);
+ grn_obj *max_border = VAR(5);
+ grn_obj *offset = VAR(6);
+ grn_obj *limit = VAR(7);
+ grn_obj *filter = VAR(8);
+ grn_obj *output_columns = VAR(9);
+ grn_obj *table;
+ grn_obj *res = NULL;
+ grn_obj *filter_expr = NULL;
+ grn_obj *filter_variable = NULL;
+ int real_offset;
+ int real_limit;
+
+ table = grn_ctx_get(ctx, GRN_TEXT_VALUE(table_name), GRN_TEXT_LEN(table_name));
+ if (!table) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[range_filter] nonexistent table <%.*s>",
+ (int)GRN_TEXT_LEN(table_name), GRN_TEXT_VALUE(table_name));
+ return NULL;
+ }
+
+ if (GRN_TEXT_LEN(filter) > 0) {
+ GRN_EXPR_CREATE_FOR_QUERY(ctx, table, filter_expr, filter_variable);
+ if (!filter_expr) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[range_filter] failed to create expression");
+ goto exit;
+ }
+
+ grn_expr_parse(ctx, filter_expr,
+ GRN_TEXT_VALUE(filter), GRN_TEXT_LEN(filter),
+ NULL, GRN_OP_MATCH, GRN_OP_AND, GRN_EXPR_SYNTAX_SCRIPT);
+ if (ctx->rc != GRN_SUCCESS) {
+ goto exit;
+ }
+ }
+
+ res = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
+ table, NULL);
+ if (!res) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[range_filter] failed to result table");
+ goto exit;
+ }
+
+ {
+ grn_obj int32_value;
+
+ GRN_INT32_INIT(&int32_value, 0);
+
+ if (GRN_TEXT_LEN(offset) > 0) {
+ if (grn_obj_cast(ctx, offset, &int32_value, GRN_FALSE) != GRN_SUCCESS) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[range_filter] invalid offset format: <%.*s>",
+ (int)GRN_TEXT_LEN(offset), GRN_TEXT_VALUE(offset));
+ GRN_OBJ_FIN(ctx, &int32_value);
+ goto exit;
+ }
+ real_offset = GRN_INT32_VALUE(&int32_value);
+ } else {
+ real_offset = 0;
+ }
+
+ GRN_BULK_REWIND(&int32_value);
+
+ if (GRN_TEXT_LEN(limit) > 0) {
+ if (grn_obj_cast(ctx, limit, &int32_value, GRN_FALSE) != GRN_SUCCESS) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[range_filter] invalid limit format: <%.*s>",
+ (int)GRN_TEXT_LEN(limit), GRN_TEXT_VALUE(limit));
+ GRN_OBJ_FIN(ctx, &int32_value);
+ goto exit;
+ }
+ real_limit = GRN_INT32_VALUE(&int32_value);
+ } else {
+ real_limit = GRN_SELECT_DEFAULT_LIMIT;
+ }
+
+ GRN_OBJ_FIN(ctx, &int32_value);
+ }
+ {
+ grn_rc rc;
+ int original_offset = real_offset;
+ int original_limit = real_limit;
+ rc = grn_normalize_offset_and_limit(ctx, grn_table_size(ctx, table),
+ &real_offset, &real_limit);
+ switch (rc) {
+ case GRN_TOO_SMALL_OFFSET :
+ ERR(GRN_INVALID_ARGUMENT,
+ "[range_filter] too small offset: <%d>", original_offset);
+ goto exit;
+ case GRN_TOO_LARGE_OFFSET :
+ ERR(GRN_INVALID_ARGUMENT,
+ "[range_filter] too large offset: <%d>", original_offset);
+ goto exit;
+ case GRN_TOO_SMALL_LIMIT :
+ ERR(GRN_INVALID_ARGUMENT,
+ "[range_filter] too small limit: <%d>", original_limit);
+ goto exit;
+ default :
+ break;
+ }
+ }
+
+ if (real_limit != 0) {
+ grn_table_sort_key *sort_keys;
+ unsigned int n_sort_keys;
+ sort_keys = grn_table_sort_key_from_str(ctx,
+ GRN_TEXT_VALUE(column_name),
+ GRN_TEXT_LEN(column_name),
+ table,
+ &n_sort_keys);
+ if (n_sort_keys == 1) {
+ grn_table_sort_key *sort_key;
+ grn_obj *index;
+ int n_indexes;
+ grn_operator op = GRN_OP_OR;
+
+ sort_key = &(sort_keys[0]);
+ n_indexes = grn_column_index(ctx, sort_key->key, GRN_OP_LESS,
+ &index, 1, NULL);
+ if (n_indexes > 0) {
+ grn_obj *lexicon;
+ grn_table_cursor *table_cursor;
+ int table_cursor_flags = 0;
+ between_border_type min_border_type;
+ between_border_type max_border_type;
+ grn_obj real_min;
+ grn_obj real_max;
+ int n_records = 0;
+ grn_obj *index_cursor;
+ int index_cursor_flags = 0;
+ grn_posting *posting;
+
+ lexicon = grn_ctx_at(ctx, index->header.domain);
+ if (sort_key->flags & GRN_TABLE_SORT_DESC) {
+ table_cursor_flags |= GRN_CURSOR_DESCENDING;
+ } else {
+ table_cursor_flags |= GRN_CURSOR_ASCENDING;
+ }
+ if (GRN_TEXT_LEN(min_border) > 0) {
+ min_border_type = between_parse_border(ctx, min_border, "min_border");
+ } else {
+ min_border_type = BETWEEN_BORDER_INCLUDE;
+ }
+ if (GRN_TEXT_LEN(max_border) > 0) {
+ max_border_type = between_parse_border(ctx, max_border, "max_border");
+ } else {
+ max_border_type = BETWEEN_BORDER_INCLUDE;
+ }
+ if (min_border_type == BETWEEN_BORDER_EXCLUDE) {
+ table_cursor_flags |= GRN_CURSOR_GT;
+ }
+ if (max_border_type == BETWEEN_BORDER_EXCLUDE) {
+ table_cursor_flags |= GRN_CURSOR_LT;
+ }
+ GRN_OBJ_INIT(&real_min, GRN_BULK, 0, lexicon->header.domain);
+ GRN_OBJ_INIT(&real_max, GRN_BULK, 0, lexicon->header.domain);
+ if (GRN_TEXT_LEN(min) > 0) {
+ grn_obj_cast(ctx, min, &real_min, GRN_FALSE);
+ }
+ if (GRN_TEXT_LEN(max) > 0) {
+ grn_obj_cast(ctx, max, &real_max, GRN_FALSE);
+ }
+ table_cursor = grn_table_cursor_open(ctx, lexicon,
+ GRN_BULK_HEAD(&real_min),
+ GRN_BULK_VSIZE(&real_min),
+ GRN_BULK_HEAD(&real_max),
+ GRN_BULK_VSIZE(&real_max),
+ 0, -1, table_cursor_flags);
+ index_cursor = grn_index_cursor_open(ctx, table_cursor,
+ index, GRN_ID_NIL, GRN_ID_NIL,
+ index_cursor_flags);
+ while ((posting = grn_index_cursor_next(ctx, index_cursor, NULL))) {
+ grn_bool result_boolean = GRN_FALSE;
+
+ if (filter_expr) {
+ grn_obj *result;
+ GRN_RECORD_SET(ctx, filter_variable, posting->rid);
+ result = grn_expr_exec(ctx, filter_expr, 0);
+ if (ctx->rc) {
+ break;
+ }
+ result_boolean = grn_obj_is_true(ctx, result);
+ } else {
+ result_boolean = GRN_TRUE;
+ }
+
+ if (result_boolean) {
+ if (n_records >= real_offset) {
+ grn_ii_posting_add(ctx, posting, (grn_hash *)res, op);
+ }
+ n_records++;
+ if (n_records == real_limit) {
+ break;
+ }
+ }
+ }
+ grn_obj_unlink(ctx, index_cursor);
+ grn_table_cursor_close(ctx, table_cursor);
+
+ GRN_OBJ_FIN(ctx, &real_min);
+ GRN_OBJ_FIN(ctx, &real_max);
+ }
+ grn_ii_resolve_sel_and(ctx, (grn_hash *)res, op);
+ }
+ grn_table_sort_key_close(ctx, sort_keys, n_sort_keys);
+ }
+
+ if (ctx->rc == GRN_SUCCESS) {
+ const char *raw_output_columns;
+ int raw_output_columns_len;
+
+ 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 = GRN_SELECT_DEFAULT_OUTPUT_COLUMNS;
+ raw_output_columns_len = strlen(raw_output_columns);
+ }
+ grn_proc_select_output_columns(ctx, res, -1, real_offset, real_limit,
+ raw_output_columns,
+ raw_output_columns_len,
+ filter_expr);
+ }
+
+exit :
+ if (filter_expr) {
+ grn_obj_unlink(ctx, filter_expr);
+ }
+ if (res) {
+ grn_obj_unlink(ctx, res);
+ }
+
+ return NULL;
+}
+
+static grn_obj *
+proc_request_cancel(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ grn_obj *id = VAR(0);
+ grn_bool canceled;
+
+ if (GRN_TEXT_LEN(id) == 0) {
+ ERR(GRN_INVALID_ARGUMENT, "[request_cancel] ID is missing");
+ return NULL;
+ }
+
+ canceled = grn_request_canceler_cancel(GRN_TEXT_VALUE(id), GRN_TEXT_LEN(id));
+
+ GRN_OUTPUT_MAP_OPEN("result", 2);
+ GRN_OUTPUT_CSTR("id");
+ GRN_OUTPUT_STR(GRN_TEXT_VALUE(id), GRN_TEXT_LEN(id));
+ GRN_OUTPUT_CSTR("canceled");
+ GRN_OUTPUT_BOOL(canceled);
+ GRN_OUTPUT_MAP_CLOSE();
+
+ return NULL;
+}
+
+static grn_obj *
+proc_plugin_register(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ if (GRN_TEXT_LEN(VAR(0))) {
+ const char *name;
+ GRN_TEXT_PUTC(ctx, VAR(0), '\0');
+ name = GRN_TEXT_VALUE(VAR(0));
+ grn_plugin_register(ctx, name);
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "[plugin_register] name is missing");
+ }
+ GRN_OUTPUT_BOOL(!ctx->rc);
+ return NULL;
+}
+
+static grn_obj *
+proc_plugin_unregister(grn_ctx *ctx, int nargs, grn_obj **args,
+ grn_user_data *user_data)
+{
+ if (GRN_TEXT_LEN(VAR(0))) {
+ const char *name;
+ GRN_TEXT_PUTC(ctx, VAR(0), '\0');
+ name = GRN_TEXT_VALUE(VAR(0));
+ grn_plugin_unregister(ctx, name);
+ } else {
+ ERR(GRN_INVALID_ARGUMENT, "[plugin_unregister] name is missing");
+ }
+ GRN_OUTPUT_BOOL(!ctx->rc);
+ return NULL;
+}
+
+static grn_obj *
+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,
+ GRN_TEXT_VALUE(target_name),
+ GRN_TEXT_LEN(target_name));
+ if (!target) {
+ ERR(GRN_INVALID_ARGUMENT, "[io_flush] unknown target: <%.*s>",
+ (int)GRN_TEXT_LEN(target_name),
+ GRN_TEXT_VALUE(target_name));
+ GRN_OUTPUT_BOOL(GRN_FALSE);
+ return NULL;
+ }
+ } else {
+ target = grn_ctx_db(ctx);
+ }
+
+ 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 (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);\
+ GRN_TEXT_INIT(&(v).value, 0);\
+} while (0)
+
+#define DEF_COMMAND(name, func, nvars, vars)\
+ (grn_proc_create(ctx, (name), (sizeof(name) - 1),\
+ GRN_PROC_COMMAND, (func), NULL, NULL, (nvars), (vars)))
+
+void
+grn_db_init_builtin_commands(grn_ctx *ctx)
+{
+ grn_expr_var vars[10];
+
+ grn_proc_init_define_selector(ctx);
+ grn_proc_init_select(ctx);
+
+ DEF_VAR(vars[0], "values");
+ DEF_VAR(vars[1], "table");
+ DEF_VAR(vars[2], "columns");
+ DEF_VAR(vars[3], "ifexists");
+ DEF_VAR(vars[4], "input_type");
+ DEF_VAR(vars[5], "each");
+ 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);
+
+ grn_proc_init_table_list(ctx);
+
+ grn_proc_init_column_list(ctx);
+
+ grn_proc_init_table_create(ctx);
+
+ grn_proc_init_table_remove(ctx);
+
+ grn_proc_init_table_rename(ctx);
+
+ grn_proc_init_column_create(ctx);
+
+ grn_proc_init_column_remove(ctx);
+
+ 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_VAR(vars[0], "mode");
+ DEF_COMMAND("shutdown", proc_shutdown, 1, vars);
+
+ grn_proc_init_clearlock(ctx);
+ grn_proc_init_lock_clear(ctx);
+
+ DEF_VAR(vars[0], "target_name");
+ DEF_VAR(vars[1], "threshold");
+ DEF_COMMAND("defrag", proc_defrag, 2, vars);
+
+ DEF_VAR(vars[0], "level");
+ DEF_COMMAND("log_level", proc_log_level, 1, vars);
+
+ DEF_VAR(vars[0], "level");
+ DEF_VAR(vars[1], "message");
+ DEF_COMMAND("log_put", proc_log_put, 2, vars);
+
+ DEF_COMMAND("log_reopen", proc_log_reopen, 0, vars);
+
+ DEF_VAR(vars[0], "table");
+ DEF_VAR(vars[1], "key");
+ DEF_VAR(vars[2], "id");
+ DEF_VAR(vars[3], "filter");
+ DEF_COMMAND("delete", proc_delete, 4, vars);
+
+ DEF_VAR(vars[0], "max");
+ DEF_COMMAND("cache_limit", proc_cache_limit, 1, vars);
+
+ grn_proc_init_dump(ctx);
+
+ /* Deprecated. Use "plugin_register" instead. */
+ DEF_VAR(vars[0], "path");
+ DEF_COMMAND("register", proc_register, 1, vars);
+
+ DEF_VAR(vars[0], "obj");
+ DEF_COMMAND("check", proc_check, 1, vars);
+
+ DEF_VAR(vars[0], "target_name");
+ DEF_VAR(vars[1], "table");
+ DEF_COMMAND("truncate", proc_truncate, 2, vars);
+
+ DEF_VAR(vars[0], "normalizer");
+ DEF_VAR(vars[1], "string");
+ DEF_VAR(vars[2], "flags");
+ DEF_COMMAND("normalize", proc_normalize, 3, 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);
+
+ {
+ 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_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, NULL);
+ grn_proc_create(ctx, "min", -1, GRN_PROC_FUNCTION, func_min,
+ NULL, NULL, 0, NULL);
+
+ {
+ grn_obj *selector_proc;
+
+ 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,
+ func_geo_distance, NULL, NULL, 0, NULL);
+
+ /* deprecated. */
+ grn_proc_create(ctx, "geo_distance2", -1, GRN_PROC_FUNCTION,
+ func_geo_distance2, NULL, NULL, 0, NULL);
+
+ /* deprecated. */
+ grn_proc_create(ctx, "geo_distance3", -1, GRN_PROC_FUNCTION,
+ func_geo_distance3, NULL, NULL, 0, NULL);
+
+ grn_proc_init_edit_distance(ctx);
+
+ {
+ grn_obj *selector_proc;
+
+ 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_init_snippet_html(ctx);
+
+ {
+ grn_obj *selector_proc;
+
+ 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,
+ 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,
+ func_html_untag, NULL, NULL, 0, NULL);
+
+ {
+ grn_obj *selector_proc;
+
+ 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_init_highlight_html(ctx);
+ grn_proc_init_highlight_full(ctx);
+
+ {
+ grn_obj *selector_proc;
+
+ 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");
+ DEF_VAR(vars[1], "column");
+ DEF_VAR(vars[2], "min");
+ DEF_VAR(vars[3], "min_border");
+ DEF_VAR(vars[4], "max");
+ DEF_VAR(vars[5], "max_border");
+ DEF_VAR(vars[6], "offset");
+ DEF_VAR(vars[7], "limit");
+ DEF_VAR(vars[8], "filter");
+ DEF_VAR(vars[9], "output_columns");
+ DEF_COMMAND("range_filter", proc_range_filter, 10, vars);
+
+ DEF_VAR(vars[0], "id");
+ DEF_COMMAND("request_cancel", proc_request_cancel, 1, vars);
+
+ DEF_VAR(vars[0], "name");
+ DEF_COMMAND("plugin_register", proc_plugin_register, 1, vars);
+
+ DEF_VAR(vars[0], "name");
+ DEF_COMMAND("plugin_unregister", proc_plugin_unregister, 1, vars);
+
+ DEF_VAR(vars[0], "target_name");
+ DEF_VAR(vars[1], "recursive");
+ 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 00000000..e4284dc2
--- /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 00000000..74d0d7a9
--- /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-1335 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 ((unsigned long) (end - text) >= (unsigned long) 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 00000000..61a1c5a8
--- /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-1335 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 00000000..391925d8
--- /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-1335 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 ((size_t) 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 00000000..952fdbb1
--- /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-1335 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 >= (int) 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 >= (int) 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 && (uint32_t) 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 00000000..80551a10
--- /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-1335 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 00000000..e3b8a7e3
--- /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-1335 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 00000000..9eaf808a
--- /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-1335 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 00000000..380e6553
--- /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-1335 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 00000000..eaa6ec4b
--- /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-1335 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 00000000..adb4c91b
--- /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-1335 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 00000000..6dcf63e1
--- /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-1335 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 00000000..b05d1abf
--- /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-1335 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 00000000..061c145a
--- /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-1335 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 00000000..a665b1cc
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_select.c
@@ -0,0 +1,3809 @@
+/* -*- 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-1335 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 (((unsigned long) (calc_types_end - calc_types) >= (unsigned long) (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;
+ unsigned 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 (((unsigned long) (query_flags_end - query_flags) >= (unsigned long) (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) \
+ if ((string).value) \
+ 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 00000000..0c6ea681
--- /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-1335 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 00000000..3c40992d
--- /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-1335 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 ((unsigned long) (end - nptr) >= (unsigned long) 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 00000000..206ebf58
--- /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-1335 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 (((unsigned long) (names_end - names) >= (unsigned long) (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 00000000..a945320f
--- /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 00000000..794450f8
--- /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-1335 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 00000000..c16e6e68
--- /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-1335 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
new file mode 100644
index 00000000..c5aedf3e
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/request_canceler.c
@@ -0,0 +1,176 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#include "grn_ctx.h"
+#include "grn_ctx_impl.h"
+#include "grn_request_canceler.h"
+
+typedef struct _grn_request_canceler grn_request_canceler;
+struct _grn_request_canceler {
+ grn_hash *entries;
+ grn_mutex mutex;
+};
+
+typedef struct _grn_request_canceler_entry grn_request_canceler_entry;
+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_the_request_canceler_ctx;
+
+ grn_ctx_init(ctx, 0);
+
+ grn_the_request_canceler = GRN_MALLOC(sizeof(grn_request_canceler));
+ if (!grn_the_request_canceler) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[request-canceler] failed to allocate the global request canceler");
+ return GRN_FALSE;
+ }
+
+ grn_the_request_canceler->entries =
+ grn_hash_create(ctx, NULL, GRN_TABLE_MAX_KEY_SIZE,
+ sizeof(grn_request_canceler_entry), GRN_OBJ_KEY_VAR_SIZE);
+ if (!grn_the_request_canceler->entries) {
+ return GRN_FALSE;
+ }
+ MUTEX_INIT(grn_the_request_canceler->mutex);
+
+ return GRN_TRUE;
+}
+
+void
+grn_request_canceler_register(grn_ctx *ctx,
+ const char *request_id, unsigned int size)
+{
+ MUTEX_LOCK(grn_the_request_canceler->mutex);
+ {
+ grn_hash *entries = grn_the_request_canceler->entries;
+ grn_id id;
+ void *value;
+ 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;
+ }
+ }
+ MUTEX_UNLOCK(grn_the_request_canceler->mutex);
+}
+
+void
+grn_request_canceler_unregister(grn_ctx *ctx,
+ const char *request_id, unsigned int size)
+{
+ MUTEX_LOCK(grn_the_request_canceler->mutex);
+ {
+ grn_hash *entries = grn_the_request_canceler->entries;
+ grn_hash_delete(&grn_the_request_canceler_ctx,
+ entries, request_id, size, NULL);
+ }
+ MUTEX_UNLOCK(grn_the_request_canceler->mutex);
+
+ 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(ctx, entries, request_id, size, &value)) {
+ grn_request_canceler_entry *entry = value;
+ if (grn_request_canceler_cancel_entry(entry)) {
+ canceled = GRN_TRUE;
+ }
+ }
+ }
+ MUTEX_UNLOCK(grn_the_request_canceler->mutex);
+ 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_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 00000000..23a0c644
--- /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-1335 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/rset.c b/storage/mroonga/vendor/groonga/lib/rset.c
new file mode 100644
index 00000000..f7b50039
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/rset.c
@@ -0,0 +1,324 @@
+/* -*- 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-1335 USA
+*/
+#include "grn_db.h"
+
+uint32_t
+grn_rset_recinfo_calc_values_size(grn_ctx *ctx, grn_table_group_flags flags)
+{
+ uint32_t size = 0;
+
+ if (flags & GRN_TABLE_GROUP_CALC_MAX) {
+ size += GRN_RSET_MAX_SIZE;
+ }
+ if (flags & GRN_TABLE_GROUP_CALC_MIN) {
+ size += GRN_RSET_MIN_SIZE;
+ }
+ if (flags & GRN_TABLE_GROUP_CALC_SUM) {
+ size += GRN_RSET_SUM_SIZE;
+ }
+ if (flags & GRN_TABLE_GROUP_CALC_AVG) {
+ size += GRN_RSET_AVG_SIZE;
+ }
+
+ return size;
+}
+
+void
+grn_rset_recinfo_update_calc_values(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table,
+ grn_obj *value)
+{
+ grn_table_group_flags flags;
+ byte *values;
+ grn_obj value_int64;
+ grn_obj value_float;
+
+ flags = DB_OBJ(table)->flags.group;
+
+ values = (((byte *)ri->subrecs) +
+ GRN_RSET_SUBRECS_SIZE(DB_OBJ(table)->subrec_size,
+ DB_OBJ(table)->max_n_subrecs));
+
+ GRN_INT64_INIT(&value_int64, 0);
+ GRN_FLOAT_INIT(&value_float, 0);
+
+ if (flags & (GRN_TABLE_GROUP_CALC_MAX |
+ GRN_TABLE_GROUP_CALC_MIN |
+ GRN_TABLE_GROUP_CALC_SUM)) {
+ grn_obj_cast(ctx, value, &value_int64, GRN_FALSE);
+ }
+ if (flags & GRN_TABLE_GROUP_CALC_AVG) {
+ grn_obj_cast(ctx, value, &value_float, GRN_FALSE);
+ }
+
+ if (flags & GRN_TABLE_GROUP_CALC_MAX) {
+ int64_t current_max = *((int64_t *)values);
+ int64_t value_raw = GRN_INT64_VALUE(&value_int64);
+ if (ri->n_subrecs == 1 || value_raw > current_max) {
+ *((int64_t *)values) = value_raw;
+ }
+ values += GRN_RSET_MAX_SIZE;
+ }
+ if (flags & GRN_TABLE_GROUP_CALC_MIN) {
+ int64_t current_min = *((int64_t *)values);
+ int64_t value_raw = GRN_INT64_VALUE(&value_int64);
+ if (ri->n_subrecs == 1 || value_raw < current_min) {
+ *((int64_t *)values) = value_raw;
+ }
+ values += GRN_RSET_MIN_SIZE;
+ }
+ if (flags & GRN_TABLE_GROUP_CALC_SUM) {
+ int64_t value_raw = GRN_INT64_VALUE(&value_int64);
+ *((int64_t *)values) += value_raw;
+ values += GRN_RSET_SUM_SIZE;
+ }
+ if (flags & GRN_TABLE_GROUP_CALC_AVG) {
+ double current_average = *((double *)values);
+ double value_raw = GRN_FLOAT_VALUE(&value_float);
+ *((double *)values) += (value_raw - current_average) / ri->n_subrecs;
+ values += GRN_RSET_AVG_SIZE;
+ }
+
+ GRN_OBJ_FIN(ctx, &value_float);
+ GRN_OBJ_FIN(ctx, &value_int64);
+}
+
+int64_t *
+grn_rset_recinfo_get_max_(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table)
+{
+ grn_table_group_flags flags;
+ byte *values;
+
+ flags = DB_OBJ(table)->flags.group;
+ if (!(flags & GRN_TABLE_GROUP_CALC_MAX)) {
+ return NULL;
+ }
+
+ values = (((byte *)ri->subrecs) +
+ GRN_RSET_SUBRECS_SIZE(DB_OBJ(table)->subrec_size,
+ DB_OBJ(table)->max_n_subrecs));
+
+ return (int64_t *)values;
+}
+
+int64_t
+grn_rset_recinfo_get_max(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table)
+{
+ int64_t *max_address;
+
+ max_address = grn_rset_recinfo_get_max_(ctx, ri, table);
+ if (max_address) {
+ return *max_address;
+ } else {
+ return 0;
+ }
+}
+
+void
+grn_rset_recinfo_set_max(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table,
+ int64_t max)
+{
+ int64_t *max_address;
+
+ max_address = grn_rset_recinfo_get_max_(ctx, ri, table);
+ if (!max_address) {
+ return;
+ }
+
+ *max_address = max;
+}
+
+int64_t *
+grn_rset_recinfo_get_min_(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table)
+{
+ grn_table_group_flags flags;
+ byte *values;
+
+ flags = DB_OBJ(table)->flags.group;
+ if (!(flags & GRN_TABLE_GROUP_CALC_MIN)) {
+ return NULL;
+ }
+
+ values = (((byte *)ri->subrecs) +
+ GRN_RSET_SUBRECS_SIZE(DB_OBJ(table)->subrec_size,
+ DB_OBJ(table)->max_n_subrecs));
+
+ if (flags & GRN_TABLE_GROUP_CALC_MAX) {
+ values += GRN_RSET_MAX_SIZE;
+ }
+
+ return (int64_t *)values;
+}
+
+int64_t
+grn_rset_recinfo_get_min(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table)
+{
+ int64_t *min_address;
+
+ min_address = grn_rset_recinfo_get_min_(ctx, ri, table);
+ if (min_address) {
+ return *min_address;
+ } else {
+ return 0;
+ }
+}
+
+void
+grn_rset_recinfo_set_min(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table,
+ int64_t min)
+{
+ int64_t *min_address;
+
+ min_address = grn_rset_recinfo_get_min_(ctx, ri, table);
+ if (!min_address) {
+ return;
+ }
+
+ *min_address = min;
+}
+
+int64_t *
+grn_rset_recinfo_get_sum_(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table)
+{
+ grn_table_group_flags flags;
+ byte *values;
+
+ flags = DB_OBJ(table)->flags.group;
+ if (!(flags & GRN_TABLE_GROUP_CALC_SUM)) {
+ return NULL;
+ }
+
+ values = (((byte *)ri->subrecs) +
+ GRN_RSET_SUBRECS_SIZE(DB_OBJ(table)->subrec_size,
+ DB_OBJ(table)->max_n_subrecs));
+
+ if (flags & GRN_TABLE_GROUP_CALC_MAX) {
+ values += GRN_RSET_MAX_SIZE;
+ }
+ if (flags & GRN_TABLE_GROUP_CALC_MIN) {
+ values += GRN_RSET_MIN_SIZE;
+ }
+
+ return (int64_t *)values;
+}
+
+int64_t
+grn_rset_recinfo_get_sum(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table)
+{
+ int64_t *sum_address;
+
+ sum_address = grn_rset_recinfo_get_sum_(ctx, ri, table);
+ if (sum_address) {
+ return *sum_address;
+ } else {
+ return 0;
+ }
+}
+
+void
+grn_rset_recinfo_set_sum(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table,
+ int64_t sum)
+{
+ int64_t *sum_address;
+
+ sum_address = grn_rset_recinfo_get_sum_(ctx, ri, table);
+ if (!sum_address) {
+ return;
+ }
+
+ *sum_address = sum;
+}
+
+double *
+grn_rset_recinfo_get_avg_(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table)
+{
+ grn_table_group_flags flags;
+ byte *values;
+
+ flags = DB_OBJ(table)->flags.group;
+ if (!(flags & GRN_TABLE_GROUP_CALC_AVG)) {
+ return NULL;
+ }
+
+ values = (((byte *)ri->subrecs) +
+ GRN_RSET_SUBRECS_SIZE(DB_OBJ(table)->subrec_size,
+ DB_OBJ(table)->max_n_subrecs));
+
+ if (flags & GRN_TABLE_GROUP_CALC_MAX) {
+ values += GRN_RSET_MAX_SIZE;
+ }
+ if (flags & GRN_TABLE_GROUP_CALC_MIN) {
+ values += GRN_RSET_MIN_SIZE;
+ }
+ if (flags & GRN_TABLE_GROUP_CALC_SUM) {
+ values += GRN_RSET_SUM_SIZE;
+ }
+
+ return (double *)values;
+}
+
+double
+grn_rset_recinfo_get_avg(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table)
+{
+ double *avg_address;
+
+ avg_address = grn_rset_recinfo_get_avg_(ctx, ri, table);
+ if (avg_address) {
+ return *avg_address;
+ } else {
+ return 0;
+ }
+}
+
+void
+grn_rset_recinfo_set_avg(grn_ctx *ctx,
+ grn_rset_recinfo *ri,
+ grn_obj *table,
+ double avg)
+{
+ double *avg_address;
+
+ avg_address = grn_rset_recinfo_get_avg_(ctx, ri, table);
+ if (!avg_address) {
+ return;
+ }
+
+ *avg_address = avg;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/scanner.c b/storage/mroonga/vendor/groonga/lib/scanner.c
new file mode 100644
index 00000000..9ac0f164
--- /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-1335 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
new file mode 100644
index 00000000..5791ad35
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/scorer.c
@@ -0,0 +1,189 @@
+/* -*- 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-1335 USA
+*/
+
+#include <string.h>
+
+#include "grn.h"
+#include "grn_db.h"
+#include "grn_scorer.h"
+#include <groonga/scorer.h>
+
+grn_obj *
+grn_scorer_matched_record_get_table(grn_ctx *ctx,
+ grn_scorer_matched_record *record)
+{
+ return record->table;
+}
+
+grn_obj *
+grn_scorer_matched_record_get_lexicon(grn_ctx *ctx,
+ grn_scorer_matched_record *record)
+{
+ return record->lexicon;
+}
+
+grn_id
+grn_scorer_matched_record_get_id(grn_ctx *ctx,
+ grn_scorer_matched_record *record)
+{
+ return record->id;
+}
+
+grn_obj *
+grn_scorer_matched_record_get_terms(grn_ctx *ctx,
+ grn_scorer_matched_record *record)
+{
+ return &(record->terms);
+}
+
+grn_obj *
+grn_scorer_matched_record_get_term_weights(grn_ctx *ctx,
+ grn_scorer_matched_record *record)
+{
+ return &(record->term_weights);
+}
+
+unsigned int
+grn_scorer_matched_record_get_total_term_weights(grn_ctx *ctx,
+ grn_scorer_matched_record *record)
+{
+ return record->total_term_weights;
+}
+
+long long unsigned int
+grn_scorer_matched_record_get_n_documents(grn_ctx *ctx,
+ grn_scorer_matched_record *record)
+{
+ return record->n_documents;
+}
+
+unsigned int
+grn_scorer_matched_record_get_n_occurrences(grn_ctx *ctx,
+ grn_scorer_matched_record *record)
+{
+ return record->n_occurrences;
+}
+
+long long unsigned int
+grn_scorer_matched_record_get_n_candidates(grn_ctx *ctx,
+ grn_scorer_matched_record *record)
+{
+ return record->n_candidates;
+}
+
+unsigned int
+grn_scorer_matched_record_get_n_tokens(grn_ctx *ctx,
+ grn_scorer_matched_record *record)
+{
+ return record->n_tokens;
+}
+
+int
+grn_scorer_matched_record_get_weight(grn_ctx *ctx,
+ grn_scorer_matched_record *record)
+{
+ return record->weight;
+}
+
+grn_obj *
+grn_scorer_matched_record_get_arg(grn_ctx *ctx,
+ grn_scorer_matched_record *record,
+ unsigned int i)
+{
+ grn_expr *expr;
+ grn_expr_code *codes_original;
+ uint32_t codes_curr_original;
+ grn_obj *arg;
+
+ if (!record->args_expr) {
+ return NULL;
+ }
+
+ expr = (grn_expr *)(record->args_expr);
+ /* TODO: support getting column value */
+ codes_original = expr->codes;
+ codes_curr_original = expr->codes_curr;
+ expr->codes += record->args_expr_offset;
+ expr->codes_curr = 1; /* TODO: support 1 or more codes */
+ arg = grn_expr_exec(ctx, (grn_obj *)expr, 0);
+ expr->codes_curr = codes_curr_original;
+ expr->codes = codes_original;
+
+ return arg;
+}
+
+unsigned int
+grn_scorer_matched_record_get_n_args(grn_ctx *ctx,
+ grn_scorer_matched_record *record)
+{
+ grn_expr *expr;
+ grn_expr_code *codes;
+ unsigned int n_args = 0;
+
+ if (!record->args_expr) {
+ return 0;
+ }
+
+ expr = (grn_expr *)(record->args_expr);
+ codes = expr->codes + record->args_expr_offset;
+ if (codes[0].op == GRN_OP_CALL) {
+ return 0;
+ }
+
+ n_args++;
+ for (; codes[0].op != GRN_OP_CALL; codes++) {
+ if (codes[0].op == GRN_OP_COMMA) {
+ n_args++;
+ }
+ }
+
+ return n_args;
+}
+
+grn_rc
+grn_scorer_register(grn_ctx *ctx,
+ const char *scorer_name_ptr,
+ int scorer_name_length,
+ grn_scorer_score_func *score)
+{
+ if (scorer_name_length == -1) {
+ scorer_name_length = strlen(scorer_name_ptr);
+ }
+
+ {
+ grn_obj *scorer_object = grn_proc_create(ctx,
+ 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()",
+ scorer_name_length, scorer_name_ptr);
+ return ctx->rc;
+ }
+
+ {
+ grn_proc *scorer = (grn_proc *)scorer_object;
+ scorer->callbacks.scorer.score = score;
+ }
+ }
+
+ return GRN_SUCCESS;
+}
+
diff --git a/storage/mroonga/vendor/groonga/lib/scorers.c b/storage/mroonga/vendor/groonga/lib/scorers.c
new file mode 100644
index 00000000..44a3e9b4
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/scorers.c
@@ -0,0 +1,96 @@
+/* -*- 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-1335 USA
+*/
+
+#include "grn_db.h"
+
+#include <groonga/scorer.h>
+
+#include <math.h>
+
+static double
+scorer_tf_idf(grn_ctx *ctx, grn_scorer_matched_record *record)
+{
+ double min_score = 1.0;
+ double tf;
+ double n_all_documents;
+ double n_candidates;
+ double n_tokens;
+ double n_estimated_match_documents;
+
+ tf = grn_scorer_matched_record_get_n_occurrences(ctx, record) +
+ grn_scorer_matched_record_get_total_term_weights(ctx, record);
+ n_all_documents = grn_scorer_matched_record_get_n_documents(ctx, record);
+ n_candidates = grn_scorer_matched_record_get_n_candidates(ctx, record);
+ n_tokens = grn_scorer_matched_record_get_n_tokens(ctx, record);
+ n_estimated_match_documents = n_candidates / n_tokens;
+
+ if (n_estimated_match_documents >= n_all_documents) {
+ return min_score;
+ } else {
+ double idf;
+ double tf_idf;
+
+ idf = log(n_all_documents / n_estimated_match_documents);
+ tf_idf = tf * idf;
+ return fmax(tf_idf, min_score);
+ }
+}
+
+static double
+scorer_tf_at_most(grn_ctx *ctx, grn_scorer_matched_record *record)
+{
+ double tf;
+ double max;
+ grn_obj *max_raw;
+
+ tf = grn_scorer_matched_record_get_n_occurrences(ctx, record) +
+ grn_scorer_matched_record_get_total_term_weights(ctx, record);
+ max_raw = grn_scorer_matched_record_get_arg(ctx, record, 0);
+
+ if (!max_raw) {
+ return tf;
+ }
+
+ if (max_raw->header.type != GRN_BULK) {
+ return tf;
+ }
+
+ if (max_raw->header.domain == GRN_DB_FLOAT) {
+ max = GRN_FLOAT_VALUE(max_raw);
+ } else {
+ grn_obj casted_max_raw;
+ GRN_FLOAT_INIT(&casted_max_raw, 0);
+ if (grn_obj_cast(ctx, max_raw, &casted_max_raw, GRN_FALSE) != GRN_SUCCESS) {
+ GRN_OBJ_FIN(ctx, &casted_max_raw);
+ return tf;
+ } else {
+ max = GRN_FLOAT_VALUE(&casted_max_raw);
+ }
+ GRN_OBJ_FIN(ctx, &casted_max_raw);
+ }
+
+ return fmin(tf, max);
+}
+
+grn_rc
+grn_db_init_builtin_scorers(grn_ctx *ctx)
+{
+ grn_scorer_register(ctx, "scorer_tf_idf", -1, scorer_tf_idf);
+ grn_scorer_register(ctx, "scorer_tf_at_most", -1, scorer_tf_at_most);
+ return GRN_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/snip.c b/storage/mroonga/vendor/groonga/lib/snip.c
new file mode 100644
index 00000000..4693dc2b
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/snip.c
@@ -0,0 +1,841 @@
+/* -*- c-basic-offset: 2 -*- */
+/* Copyright(C) 2009-2014 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-1335 USA
+*/
+#include "grn.h"
+#include <string.h>
+#include <stddef.h>
+#include "grn_snip.h"
+#include "grn_ctx.h"
+
+#if !defined MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+#if !defined MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+static int
+grn_bm_check_euc(const unsigned char *x, const size_t y)
+{
+ const unsigned char *p;
+ for (p = x + y - 1; p >= x && *p >= 0x80U; p--);
+ return (int) ((x + y - p) & 1);
+}
+
+static int
+grn_bm_check_sjis(const unsigned char *x, const size_t y)
+{
+ const unsigned char *p;
+ for (p = x + y - 1; p >= x; p--)
+ if ((*p < 0x81U) || (*p > 0x9fU && *p < 0xe0U) || (*p > 0xfcU))
+ break;
+ return (int) ((x + y - p) & 1);
+}
+
+/*
+static void
+grn_bm_suffixes(const unsigned char *x, size_t m, size_t *suff)
+{
+ size_t f, g;
+ intptr_t i;
+ f = 0;
+ suff[m - 1] = m;
+ g = m - 1;
+ for (i = m - 2; i >= 0; --i) {
+ if (i > (intptr_t) g && suff[i + m - 1 - f] < i - g)
+ suff[i] = suff[i + m - 1 - f];
+ else {
+ if (i < (intptr_t) g)
+ g = i;
+ f = i;
+ while (g > 0 && x[g] == x[g + m - 1 - f])
+ --g;
+ suff[i] = f - g;
+ }
+ }
+}
+*/
+
+static void
+grn_bm_preBmBc(const unsigned char *x, size_t m, size_t *bmBc)
+{
+ size_t i;
+ for (i = 0; i < ASIZE; ++i) {
+ bmBc[i] = m;
+ }
+ for (i = 0; i < m - 1; ++i) {
+ bmBc[(unsigned int) x[i]] = m - (i + 1);
+ }
+}
+
+#define GRN_BM_COMPARE do { \
+ if (string_checks[found]) { \
+ size_t offset = cond->last_offset, found_alpha_head = cond->found_alpha_head; \
+ /* calc real offset */\
+ for (i = cond->last_found; i < found; i++) { \
+ if (string_checks[i] > 0) { \
+ found_alpha_head = i; \
+ offset += string_checks[i]; \
+ } \
+ } \
+ /* if real offset is in a character, move it the head of the character */ \
+ if (string_checks[found] < 0) { \
+ offset -= string_checks[found_alpha_head]; \
+ cond->last_found = found_alpha_head; \
+ } else { \
+ cond->last_found = found; \
+ } \
+ cond->start_offset = cond->last_offset = offset; \
+ if (flags & GRN_SNIP_SKIP_LEADING_SPACES) { \
+ while (cond->start_offset < string_original_length_in_bytes && \
+ (i = grn_isspace(string_original + cond->start_offset, \
+ string_encoding))) { cond->start_offset += i; } \
+ } \
+ for (i = cond->last_found; i < found + m; i++) { \
+ if (string_checks[i] > 0) { \
+ offset += string_checks[i]; \
+ } \
+ } \
+ cond->end_offset = offset; \
+ cond->found = found + shift; \
+ cond->found_alpha_head = found_alpha_head; \
+ /* printf("bm: cond:%p found:%zd last_found:%zd st_off:%zd ed_off:%zd\n", cond, cond->found,cond->last_found,cond->start_offset,cond->end_offset); */ \
+ return; \
+ } \
+} while (0)
+
+#define GRN_BM_BM_COMPARE do { \
+ if (p[-2] == ck) { \
+ for (i = 3; i <= m && p[-(intptr_t)i] == cp[-(intptr_t)i]; ++i) { \
+ } \
+ if (i > m) { \
+ found = p - y - m; \
+ GRN_BM_COMPARE; \
+ } \
+ } \
+} while (0)
+
+void
+grn_bm_tunedbm(grn_ctx *ctx, snip_cond *cond, grn_obj *string, int flags)
+{
+ register unsigned char *limit, ck;
+ register const unsigned char *p, *cp;
+ register size_t *bmBc, delta1, i;
+
+ const unsigned char *x;
+ unsigned char *y;
+ size_t shift, found;
+
+ const char *string_original;
+ unsigned int string_original_length_in_bytes;
+ const short *string_checks;
+ grn_encoding string_encoding;
+ const char *string_norm, *keyword_norm;
+ unsigned int n, m;
+
+ grn_string_get_original(ctx, string,
+ &string_original, &string_original_length_in_bytes);
+ string_checks = grn_string_get_checks(ctx, string);
+ string_encoding = grn_string_get_encoding(ctx, string);
+ grn_string_get_normalized(ctx, string, &string_norm, &n, NULL);
+ grn_string_get_normalized(ctx, cond->keyword, &keyword_norm, &m, NULL);
+
+ y = (unsigned char *)string_norm;
+ if (m == 1) {
+ if (n > cond->found) {
+ shift = 1;
+ p = memchr(y + cond->found, keyword_norm[0], n - cond->found);
+ if (p != NULL) {
+ found = p - y;
+ GRN_BM_COMPARE;
+ }
+ }
+ cond->stopflag = SNIPCOND_STOP;
+ return;
+ }
+
+ x = (unsigned char *)keyword_norm;
+ bmBc = cond->bmBc;
+ shift = cond->shift;
+
+ /* Restart */
+ p = y + m + cond->found;
+ cp = x + m;
+ ck = cp[-2];
+
+ /* 12 means 1(initial offset) + 10 (in loop) + 1 (shift) */
+ if (n - cond->found > 12 * m) {
+ limit = y + n - 11 * m;
+ while (p <= limit) {
+ p += bmBc[p[-1]];
+ if(!(delta1 = bmBc[p[-1]])) {
+ goto check;
+ }
+ p += delta1;
+ p += bmBc[p[-1]];
+ p += bmBc[p[-1]];
+ if(!(delta1 = bmBc[p[-1]])) {
+ goto check;
+ }
+ p += delta1;
+ p += bmBc[p[-1]];
+ p += bmBc[p[-1]];
+ if(!(delta1 = bmBc[p[-1]])) {
+ goto check;
+ }
+ p += delta1;
+ p += bmBc[p[-1]];
+ p += bmBc[p[-1]];
+ continue;
+ check:
+ GRN_BM_BM_COMPARE;
+ p += shift;
+ }
+ }
+ /* limit check + search */
+ limit = y + n;
+ while(p <= limit) {
+ if (!(delta1 = bmBc[p[-1]])) {
+ GRN_BM_BM_COMPARE;
+ p += shift;
+ }
+ p += delta1;
+ }
+ cond->stopflag = SNIPCOND_STOP;
+}
+
+static size_t
+count_mapped_chars(const char *str, const char *end)
+{
+ const char *p;
+ size_t dl;
+
+ dl = 0;
+ for (p = str; p != end; p++) {
+ switch (*p) {
+ case '<':
+ case '>':
+ dl += 4; /* &lt; or &gt; */
+ break;
+ case '&':
+ dl += 5; /* &amp; */
+ break;
+ case '"':
+ dl += 6; /* &quot; */
+ break;
+ default:
+ dl++;
+ break;
+ }
+ }
+ return dl;
+}
+
+grn_rc
+grn_snip_cond_close(grn_ctx *ctx, snip_cond *cond)
+{
+ if (!cond) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (cond->keyword) {
+ grn_obj_close(ctx, cond->keyword);
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_snip_cond_init(grn_ctx *ctx, snip_cond *sc, const char *keyword, unsigned int keyword_len,
+ grn_encoding enc, grn_obj *normalizer, int flags)
+{
+ const char *norm;
+ unsigned int norm_blen;
+ int f = GRN_STR_REMOVEBLANK;
+ memset(sc, 0, sizeof(snip_cond));
+ if (!(sc->keyword = grn_string_open(ctx, keyword, keyword_len,
+ normalizer, f))) {
+ GRN_LOG(ctx, GRN_LOG_ALERT,
+ "grn_string_open on snip_cond_init failed!");
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ grn_string_get_normalized(ctx, sc->keyword, &norm, &norm_blen, NULL);
+ if (!norm_blen) {
+ grn_snip_cond_close(ctx, sc);
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (norm_blen != 1) {
+ grn_bm_preBmBc((unsigned char *)norm, norm_blen, sc->bmBc);
+ sc->shift = sc->bmBc[(unsigned char)norm[norm_blen - 1]];
+ sc->bmBc[(unsigned char)norm[norm_blen - 1]] = 0;
+ }
+ return GRN_SUCCESS;
+}
+
+void
+grn_snip_cond_reinit(snip_cond *cond)
+{
+ cond->found = 0;
+ cond->last_found = 0;
+ cond->last_offset = 0;
+ cond->start_offset = 0;
+ cond->end_offset = 0;
+
+ cond->count = 0;
+ cond->stopflag = SNIPCOND_NONSTOP;
+}
+
+inline static char *
+grn_snip_strndup(grn_ctx *ctx, const char *string, unsigned int string_len)
+{
+ char *copied_string;
+
+ copied_string = GRN_MALLOC(string_len + 1);
+ if (!copied_string) {
+ return NULL;
+ }
+ grn_memcpy(copied_string, string, string_len);
+ copied_string[string_len]= '\0'; /* not required, but for ql use */
+ return copied_string;
+}
+
+inline static grn_rc
+grn_snip_cond_set_tag(grn_ctx *ctx,
+ const char **dest_tag, size_t *dest_tag_len,
+ const char *tag, unsigned int tag_len,
+ const char *default_tag, unsigned int default_tag_len,
+ int copy_tag)
+{
+ if (tag) {
+ if (copy_tag) {
+ char *copied_tag;
+ copied_tag = grn_snip_strndup(ctx, tag, tag_len);
+ if (!copied_tag) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *dest_tag = copied_tag;
+ } else {
+ *dest_tag = tag;
+ }
+ *dest_tag_len = tag_len;
+ } else {
+ *dest_tag = default_tag;
+ *dest_tag_len = default_tag_len;
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_snip_set_normalizer(grn_ctx *ctx, grn_obj *snip,
+ grn_obj *normalizer)
+{
+ grn_snip *snip_;
+ if (!snip) {
+ return GRN_INVALID_ARGUMENT;
+ }
+
+ snip_ = (grn_snip *)snip;
+ snip_->normalizer = normalizer;
+ return GRN_SUCCESS;
+}
+
+grn_obj *
+grn_snip_get_normalizer(grn_ctx *ctx, grn_obj *snip)
+{
+ grn_snip *snip_;
+
+ if (!snip) {
+ return NULL;
+ }
+
+ snip_ = (grn_snip *)snip;
+ return snip_->normalizer;
+}
+
+grn_rc
+grn_snip_add_cond(grn_ctx *ctx, grn_obj *snip,
+ const char *keyword, unsigned int keyword_len,
+ const char *opentag, unsigned int opentag_len,
+ const char *closetag, unsigned int closetag_len)
+{
+ grn_rc rc;
+ int copy_tag;
+ snip_cond *cond;
+ unsigned int norm_blen;
+ grn_snip *snip_;
+
+ snip_ = (grn_snip *)snip;
+ if (!snip_ || !keyword || !keyword_len || snip_->cond_len >= MAX_SNIP_COND_COUNT) {
+ return GRN_INVALID_ARGUMENT;
+ }
+
+ cond = snip_->cond + snip_->cond_len;
+ if ((rc = grn_snip_cond_init(ctx, cond, keyword, keyword_len,
+ snip_->encoding, snip_->normalizer, snip_->flags))) {
+ return rc;
+ }
+ grn_string_get_normalized(ctx, cond->keyword, NULL, &norm_blen, NULL);
+ if (norm_blen > snip_->width) {
+ grn_snip_cond_close(ctx, cond);
+ return GRN_INVALID_ARGUMENT;
+ }
+
+ copy_tag = snip_->flags & GRN_SNIP_COPY_TAG;
+ rc = grn_snip_cond_set_tag(ctx,
+ &(cond->opentag), &(cond->opentag_len),
+ opentag, opentag_len,
+ snip_->defaultopentag, snip_->defaultopentag_len,
+ copy_tag);
+ if (rc) {
+ grn_snip_cond_close(ctx, cond);
+ return rc;
+ }
+
+ rc = grn_snip_cond_set_tag(ctx,
+ &(cond->closetag), &(cond->closetag_len),
+ closetag, closetag_len,
+ snip_->defaultclosetag, snip_->defaultclosetag_len,
+ copy_tag);
+ if (rc) {
+ if (opentag && copy_tag) {
+ GRN_FREE((void *)cond->opentag);
+ }
+ grn_snip_cond_close(ctx, cond);
+ return rc;
+ }
+
+ snip_->cond_len++;
+ return GRN_SUCCESS;
+}
+
+static size_t
+grn_snip_find_firstbyte(const char *string, grn_encoding encoding, size_t offset,
+ size_t doffset)
+{
+ switch (encoding) {
+ case GRN_ENC_EUC_JP:
+ while (!(grn_bm_check_euc((unsigned char *) string, offset)))
+ offset += doffset;
+ break;
+ case GRN_ENC_SJIS:
+ if (!(grn_bm_check_sjis((unsigned char *) string, offset)))
+ offset += doffset;
+ break;
+ case GRN_ENC_UTF8:
+ while ((signed char)string[offset] <= (signed char)0xc0)
+ offset += doffset;
+ break;
+ default:
+ break;
+ }
+ return offset;
+}
+
+inline static grn_rc
+grn_snip_set_default_tag(grn_ctx *ctx,
+ const char **dest_tag, size_t *dest_tag_len,
+ const char *tag, unsigned int tag_len,
+ int copy_tag)
+{
+ if (copy_tag && tag) {
+ char *copied_tag;
+ copied_tag = grn_snip_strndup(ctx, tag, tag_len);
+ if (!copied_tag) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *dest_tag = copied_tag;
+ } else {
+ *dest_tag = tag;
+ }
+ *dest_tag_len = tag_len;
+ return GRN_SUCCESS;
+}
+
+grn_obj *
+grn_snip_open(grn_ctx *ctx, int flags, unsigned int width,
+ unsigned int max_results,
+ const char *defaultopentag, unsigned int defaultopentag_len,
+ const char *defaultclosetag, unsigned int defaultclosetag_len,
+ grn_snip_mapping *mapping)
+{
+ int copy_tag;
+ grn_snip *ret = NULL;
+ if (!(ret = GRN_MALLOC(sizeof(grn_snip)))) {
+ GRN_LOG(ctx, GRN_LOG_ALERT, "grn_snip allocation failed on grn_snip_open");
+ return NULL;
+ }
+ if (max_results > MAX_SNIP_RESULT_COUNT || max_results == 0) {
+ GRN_LOG(ctx, GRN_LOG_WARNING, "max_results is invalid on grn_snip_open");
+ GRN_FREE(ret);
+ return NULL;
+ }
+ GRN_API_ENTER;
+ ret->encoding = ctx->encoding;
+ ret->flags = flags;
+ ret->width = width;
+ ret->max_results = max_results;
+ ret->defaultopentag = NULL;
+ ret->defaultclosetag = NULL;
+
+ copy_tag = flags & GRN_SNIP_COPY_TAG;
+ if (grn_snip_set_default_tag(ctx,
+ &(ret->defaultopentag),
+ &(ret->defaultopentag_len),
+ defaultopentag, defaultopentag_len,
+ copy_tag)) {
+ GRN_FREE(ret);
+ GRN_API_RETURN(NULL);
+ }
+
+ if (grn_snip_set_default_tag(ctx,
+ &(ret->defaultclosetag),
+ &(ret->defaultclosetag_len),
+ defaultclosetag, defaultclosetag_len,
+ copy_tag)) {
+ if (copy_tag && ret->defaultopentag) {
+ GRN_FREE((void *)ret->defaultopentag);
+ }
+ GRN_FREE(ret);
+ GRN_API_RETURN(NULL);
+ }
+
+ ret->cond_len = 0;
+ ret->mapping = mapping;
+ ret->nstr = NULL;
+ ret->tag_count = 0;
+ ret->snip_count = 0;
+ if (ret->flags & GRN_SNIP_NORMALIZE) {
+ ret->normalizer = GRN_NORMALIZER_AUTO;
+ } else {
+ ret->normalizer = NULL;
+ }
+
+ GRN_DB_OBJ_SET_TYPE(ret, GRN_SNIP);
+ {
+ grn_obj *db;
+ grn_id id;
+ db = grn_ctx_db(ctx);
+ id = grn_obj_register(ctx, db, NULL, 0);
+ DB_OBJ(ret)->header.domain = GRN_ID_NIL;
+ DB_OBJ(ret)->range = GRN_ID_NIL;
+ grn_db_obj_init(ctx, db, id, DB_OBJ(ret));
+ }
+
+ GRN_API_RETURN((grn_obj *)ret);
+}
+
+static grn_rc
+exec_clean(grn_ctx *ctx, grn_snip *snip)
+{
+ snip_cond *cond, *cond_end;
+ if (snip->nstr) {
+ grn_obj_close(ctx, snip->nstr);
+ snip->nstr = NULL;
+ }
+ snip->tag_count = 0;
+ snip->snip_count = 0;
+ for (cond = snip->cond, cond_end = cond + snip->cond_len;
+ cond < cond_end; cond++) {
+ grn_snip_cond_reinit(cond);
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_snip_close(grn_ctx *ctx, grn_snip *snip)
+{
+ snip_cond *cond, *cond_end;
+ if (!snip) { return GRN_INVALID_ARGUMENT; }
+ GRN_API_ENTER;
+ if (snip->flags & GRN_SNIP_COPY_TAG) {
+ int i;
+ snip_cond *sc;
+ const char *dot = snip->defaultopentag, *dct = snip->defaultclosetag;
+ for (i = snip->cond_len, sc = snip->cond; i; i--, sc++) {
+ if (sc->opentag != dot) { GRN_FREE((void *)sc->opentag); }
+ if (sc->closetag != dct) { GRN_FREE((void *)sc->closetag); }
+ }
+ if (dot) { GRN_FREE((void *)dot); }
+ if (dct) { GRN_FREE((void *)dct); }
+ }
+ if (snip->nstr) {
+ grn_obj_close(ctx, snip->nstr);
+ }
+ for (cond = snip->cond, cond_end = cond + snip->cond_len;
+ cond < cond_end; cond++) {
+ grn_snip_cond_close(ctx, cond);
+ }
+ GRN_FREE(snip);
+ GRN_API_RETURN(GRN_SUCCESS);
+}
+
+grn_rc
+grn_snip_exec(grn_ctx *ctx, grn_obj *snip, const char *string, unsigned int string_len,
+ unsigned int *nresults, unsigned int *max_tagged_len)
+{
+ size_t i;
+ grn_snip *snip_;
+ int f = GRN_STR_WITH_CHECKS|GRN_STR_REMOVEBLANK;
+ if (!snip || !string || !nresults || !max_tagged_len) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ GRN_API_ENTER;
+ snip_ = (grn_snip *)snip;
+ exec_clean(ctx, snip_);
+ *nresults = 0;
+ snip_->nstr = grn_string_open(ctx, string, string_len, snip_->normalizer, f);
+ if (!snip_->nstr) {
+ exec_clean(ctx, snip_);
+ GRN_LOG(ctx, GRN_LOG_ALERT, "grn_string_open on grn_snip_exec failed !");
+ GRN_API_RETURN(ctx->rc);
+ }
+ for (i = 0; i < snip_->cond_len; i++) {
+ grn_bm_tunedbm(ctx, snip_->cond + i, snip_->nstr, snip_->flags);
+ }
+
+ {
+ _snip_tag_result *tag_result = snip_->tag_result;
+ _snip_result *snip_result = snip_->snip_result;
+ size_t last_end_offset = 0, last_last_end_offset = 0;
+ unsigned int unfound_cond_count = snip_->cond_len;
+
+ *max_tagged_len = 0;
+ while (1) {
+ size_t tagged_len = 0, last_tag_end = 0;
+ int_least8_t all_stop = 1, found_cond = 0;
+ snip_result->tag_count = 0;
+
+ while (1) {
+ size_t min_start_offset = (size_t) -1;
+ size_t max_end_offset = 0;
+ snip_cond *cond = NULL;
+
+ /* get condition which have minimum offset and is not stopped */
+ for (i = 0; i < snip_->cond_len; i++) {
+ if (snip_->cond[i].stopflag == SNIPCOND_NONSTOP &&
+ (min_start_offset > snip_->cond[i].start_offset ||
+ (min_start_offset == snip_->cond[i].start_offset &&
+ max_end_offset < snip_->cond[i].end_offset))) {
+ min_start_offset = snip_->cond[i].start_offset;
+ max_end_offset = snip_->cond[i].end_offset;
+ cond = &snip_->cond[i];
+ }
+ }
+ if (!cond) {
+ break;
+ }
+ /* check whether condtion is the first condition in snippet */
+ if (snip_result->tag_count == 0) {
+ /* skip condition if the number of rest snippet field is smaller than */
+ /* the number of unfound keywords. */
+ if (snip_->max_results - *nresults <= unfound_cond_count && cond->count > 0) {
+ int_least8_t exclude_other_cond = 1;
+ for (i = 0; i < snip_->cond_len; i++) {
+ if ((snip_->cond + i) != cond
+ && snip_->cond[i].end_offset <= cond->start_offset + snip_->width
+ && snip_->cond[i].count == 0) {
+ exclude_other_cond = 0;
+ }
+ }
+ if (exclude_other_cond) {
+ grn_bm_tunedbm(ctx, cond, snip_->nstr, snip_->flags);
+ continue;
+ }
+ }
+ snip_result->start_offset = cond->start_offset;
+ snip_result->first_tag_result_idx = snip_->tag_count;
+ } else {
+ if (cond->start_offset >= snip_result->start_offset + snip_->width) {
+ break;
+ }
+ /* check nesting to make valid HTML */
+ /* ToDo: allow <test><te>te</te><st>st</st></test> */
+ if (cond->start_offset < last_tag_end) {
+ grn_bm_tunedbm(ctx, cond, snip_->nstr, snip_->flags);
+ continue;
+ }
+ }
+ if (cond->end_offset > snip_result->start_offset + snip_->width) {
+ /* If a keyword gets across a snippet, */
+ /* it was skipped and never to be tagged. */
+ cond->stopflag = SNIPCOND_ACROSS;
+ grn_bm_tunedbm(ctx, cond, snip_->nstr, snip_->flags);
+ } else {
+ found_cond = 1;
+ if (cond->count == 0) {
+ unfound_cond_count--;
+ }
+ cond->count++;
+ last_end_offset = cond->end_offset;
+
+ tag_result->cond = cond;
+ tag_result->start_offset = cond->start_offset;
+ tag_result->end_offset = last_tag_end = cond->end_offset;
+
+ snip_result->tag_count++;
+ tag_result++;
+ tagged_len += cond->opentag_len + cond->closetag_len;
+ if (++snip_->tag_count >= MAX_SNIP_TAG_COUNT) {
+ break;
+ }
+ grn_bm_tunedbm(ctx, cond, snip_->nstr, snip_->flags);
+ }
+ }
+ if (!found_cond) {
+ break;
+ }
+ if (snip_result->start_offset + last_end_offset < snip_->width) {
+ snip_result->start_offset = 0;
+ } else {
+ snip_result->start_offset =
+ MAX(MIN
+ ((snip_result->start_offset + last_end_offset - snip_->width) / 2,
+ string_len - snip_->width), last_last_end_offset);
+ }
+ snip_result->start_offset =
+ grn_snip_find_firstbyte(string, snip_->encoding, snip_result->start_offset, 1);
+
+ snip_result->end_offset = snip_result->start_offset + snip_->width;
+ if (snip_result->end_offset < string_len) {
+ snip_result->end_offset =
+ grn_snip_find_firstbyte(string, snip_->encoding, snip_result->end_offset, -1);
+ } else {
+ snip_result->end_offset = string_len;
+ }
+ last_last_end_offset = snip_result->end_offset;
+
+ if (snip_->mapping == (grn_snip_mapping *) -1) {
+ tagged_len +=
+ count_mapped_chars(&string[snip_result->start_offset],
+ &string[snip_result->end_offset]) + 1;
+ } else {
+ tagged_len += snip_result->end_offset - snip_result->start_offset + 1;
+ }
+
+ *max_tagged_len = MAX(*max_tagged_len, tagged_len);
+
+ snip_result->last_tag_result_idx = snip_->tag_count - 1;
+ (*nresults)++;
+ snip_result++;
+
+ if (*nresults == snip_->max_results || snip_->tag_count == MAX_SNIP_TAG_COUNT) {
+ break;
+ }
+ for (i = 0; i < snip_->cond_len; i++) {
+ if (snip_->cond[i].stopflag != SNIPCOND_STOP) {
+ all_stop = 0;
+ snip_->cond[i].stopflag = SNIPCOND_NONSTOP;
+ }
+ }
+ if (all_stop) {
+ break;
+ }
+ }
+ }
+ snip_->snip_count = *nresults;
+ snip_->string = string;
+
+ snip_->max_tagged_len = *max_tagged_len;
+
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_rc
+grn_snip_get_result(grn_ctx *ctx, grn_obj *snip, const unsigned int index, char *result, unsigned int *result_len)
+{
+ char *p;
+ size_t i, j, k;
+ _snip_result *sres;
+ grn_snip *snip_;
+
+ snip_ = (grn_snip *)snip;
+ if (snip_->snip_count <= index || !snip_->nstr) {
+ return GRN_INVALID_ARGUMENT;
+ }
+
+ GRN_ASSERT(snip_->snip_count != 0 && snip_->tag_count != 0);
+
+ GRN_API_ENTER;
+ sres = &snip_->snip_result[index];
+ j = sres->first_tag_result_idx;
+ for (p = result, i = sres->start_offset; i < sres->end_offset; i++) {
+ for (; j <= sres->last_tag_result_idx && snip_->tag_result[j].start_offset == i; j++) {
+ if (snip_->tag_result[j].end_offset > sres->end_offset) {
+ continue;
+ }
+ grn_memcpy(p,
+ snip_->tag_result[j].cond->opentag,
+ snip_->tag_result[j].cond->opentag_len);
+ p += snip_->tag_result[j].cond->opentag_len;
+ }
+
+ if (snip_->mapping == GRN_SNIP_MAPPING_HTML_ESCAPE) {
+ switch (snip_->string[i]) {
+ case '<':
+ *p++ = '&';
+ *p++ = 'l';
+ *p++ = 't';
+ *p++ = ';';
+ break;
+ case '>':
+ *p++ = '&';
+ *p++ = 'g';
+ *p++ = 't';
+ *p++ = ';';
+ break;
+ case '&':
+ *p++ = '&';
+ *p++ = 'a';
+ *p++ = 'm';
+ *p++ = 'p';
+ *p++ = ';';
+ break;
+ case '"':
+ *p++ = '&';
+ *p++ = 'q';
+ *p++ = 'u';
+ *p++ = 'o';
+ *p++ = 't';
+ *p++ = ';';
+ break;
+ default:
+ *p++ = snip_->string[i];
+ break;
+ }
+ } else {
+ *p++ = snip_->string[i];
+ }
+
+ for (k = sres->last_tag_result_idx;
+ snip_->tag_result[k].end_offset <= sres->end_offset; k--) {
+ /* TODO: avoid all loop */
+ if (snip_->tag_result[k].end_offset == i + 1) {
+ grn_memcpy(p,
+ snip_->tag_result[k].cond->closetag,
+ snip_->tag_result[k].cond->closetag_len);
+ p += snip_->tag_result[k].cond->closetag_len;
+ }
+ if (k <= sres->first_tag_result_idx) {
+ break;
+ }
+ };
+ }
+ *p = '\0';
+
+ if(result_len) { *result_len = (unsigned int)(p - result); }
+ GRN_ASSERT((unsigned int)(p - result) <= snip_->max_tagged_len);
+
+ GRN_API_RETURN(ctx->rc);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/store.c b/storage/mroonga/vendor/groonga/lib/store.c
new file mode 100644
index 00000000..f579bc9e
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/store.c
@@ -0,0 +1,2864 @@
+/* -*- 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-1335 USA
+*/
+#include "grn.h"
+#include "grn_str.h"
+#include "grn_store.h"
+#include "grn_ctx_impl.h"
+#include "grn_output.h"
+#include <string.h>
+
+/* rectangular arrays */
+
+#define GRN_RA_W_SEGMENT 22
+#define GRN_RA_SEGMENT_SIZE (1 << GRN_RA_W_SEGMENT)
+
+static grn_ra *
+_grn_ra_create(grn_ctx *ctx, grn_ra *ra, const char *path, unsigned int element_size)
+{
+ grn_io *io;
+ int max_segments, n_elm, w_elm;
+ struct grn_ra_header *header;
+ unsigned int actual_size;
+ if (element_size > GRN_RA_SEGMENT_SIZE) {
+ GRN_LOG(ctx, GRN_LOG_ERROR, "element_size too large (%d)", element_size);
+ return NULL;
+ }
+ for (actual_size = 1; actual_size < element_size; actual_size *= 2) ;
+ max_segments = ((GRN_ID_MAX + 1) / GRN_RA_SEGMENT_SIZE) * actual_size;
+ io = grn_io_create(ctx, path, sizeof(struct grn_ra_header),
+ GRN_RA_SEGMENT_SIZE, max_segments, grn_io_auto,
+ GRN_IO_EXPIRE_SEGMENT);
+ if (!io) { return NULL; }
+ header = grn_io_header(io);
+ grn_io_set_type(io, GRN_COLUMN_FIX_SIZE);
+ header->element_size = actual_size;
+ n_elm = GRN_RA_SEGMENT_SIZE / header->element_size;
+ for (w_elm = GRN_RA_W_SEGMENT; (1 << w_elm) > n_elm; w_elm--);
+ ra->io = io;
+ ra->header = header;
+ ra->element_mask = n_elm - 1;
+ ra->element_width = w_elm;
+ return ra;
+}
+
+grn_ra *
+grn_ra_create(grn_ctx *ctx, const char *path, unsigned int element_size)
+{
+ grn_ra *ra = (grn_ra *)GRN_CALLOC(sizeof(grn_ra));
+ if (!ra) {
+ return NULL;
+ }
+ GRN_DB_OBJ_SET_TYPE(ra, GRN_COLUMN_FIX_SIZE);
+ if (!_grn_ra_create(ctx, ra, path, element_size)) {
+ GRN_FREE(ra);
+ return NULL;
+ }
+ return ra;
+}
+
+grn_ra *
+grn_ra_open(grn_ctx *ctx, const char *path)
+{
+ grn_io *io;
+ 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);
+ 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;
+ }
+ ra = GRN_MALLOCN(grn_ra, 1);
+ if (!ra) {
+ grn_io_close(ctx, io);
+ return NULL;
+ }
+ n_elm = GRN_RA_SEGMENT_SIZE / header->element_size;
+ for (w_elm = GRN_RA_W_SEGMENT; (1 << w_elm) > n_elm; w_elm--);
+ GRN_DB_OBJ_SET_TYPE(ra, GRN_COLUMN_FIX_SIZE);
+ ra->io = io;
+ ra->header = header;
+ ra->element_mask = n_elm - 1;
+ ra->element_width = w_elm;
+ return ra;
+}
+
+grn_rc
+grn_ra_info(grn_ctx *ctx, grn_ra *ra, unsigned int *element_size)
+{
+ if (!ra) { return GRN_INVALID_ARGUMENT; }
+ if (element_size) { *element_size = ra->header->element_size; }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+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_FREE(ra);
+ return rc;
+}
+
+grn_rc
+grn_ra_remove(grn_ctx *ctx, const char *path)
+{
+ if (!path) { return GRN_INVALID_ARGUMENT; }
+ return grn_io_remove(ctx, path);
+}
+
+grn_rc
+grn_ra_truncate(grn_ctx *ctx, grn_ra *ra)
+{
+ grn_rc rc;
+ const char *io_path;
+ char *path;
+ unsigned int element_size;
+ if ((io_path = grn_io_path(ra->io)) && *io_path != '\0') {
+ if (!(path = GRN_STRDUP(io_path))) {
+ ERR(GRN_NO_MEMORY_AVAILABLE, "cannot duplicate path: <%s>", io_path);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ } else {
+ path = NULL;
+ }
+ element_size = ra->header->element_size;
+ if ((rc = grn_io_close(ctx, ra->io))) { goto exit; }
+ ra->io = NULL;
+ if (path && (rc = grn_io_remove(ctx, path))) { goto exit; }
+ if (!_grn_ra_create(ctx, ra, path, element_size)) {
+ rc = GRN_UNKNOWN_ERROR;
+ }
+exit:
+ if (path) { GRN_FREE(path); }
+ return rc;
+}
+
+void *
+grn_ra_ref(grn_ctx *ctx, grn_ra *ra, grn_id id)
+{
+ void *p = NULL;
+ uint16_t seg;
+ if (id > GRN_ID_MAX) { return NULL; }
+ seg = id >> ra->element_width;
+ GRN_IO_SEG_REF(ra->io, seg, p);
+ if (!p) { return NULL; }
+ return (void *)(((byte *)p) + ((id & ra->element_mask) * ra->header->element_size));
+}
+
+grn_rc
+grn_ra_unref(grn_ctx *ctx, grn_ra *ra, grn_id id)
+{
+ uint16_t seg;
+ if (id > GRN_ID_MAX) { return GRN_INVALID_ARGUMENT; }
+ seg = id >> ra->element_width;
+ GRN_IO_SEG_UNREF(ra->io, seg);
+ return GRN_SUCCESS;
+}
+
+void *
+grn_ra_ref_cache(grn_ctx *ctx, grn_ra *ra, grn_id id, grn_ra_cache *cache)
+{
+ void *p = NULL;
+ uint16_t seg;
+ if (id > GRN_ID_MAX) { return NULL; }
+ seg = id >> ra->element_width;
+ if (seg == cache->seg) {
+ p = cache->p;
+ } else {
+ if (cache->seg != -1) { GRN_IO_SEG_UNREF(ra->io, cache->seg); }
+ GRN_IO_SEG_REF(ra->io, seg, p);
+ cache->seg = seg;
+ cache->p = p;
+ }
+ if (!p) { return NULL; }
+ return (void *)(((byte *)p) + ((id & ra->element_mask) * ra->header->element_size));
+}
+
+grn_rc
+grn_ra_cache_fin(grn_ctx *ctx, grn_ra *ra, grn_id id)
+{
+ uint16_t seg;
+ if (id > GRN_ID_MAX) { return GRN_INVALID_ARGUMENT; }
+ seg = id >> ra->element_width;
+ GRN_IO_SEG_UNREF(ra->io, seg);
+ return GRN_SUCCESS;
+}
+
+/**** jagged arrays ****/
+
+#define GRN_JA_W_SEGREGATE_THRESH_V1 7
+#define GRN_JA_W_SEGREGATE_THRESH_V2 16
+#define GRN_JA_W_CAPACITY 38
+#define GRN_JA_W_SEGMENT 22
+
+#define JA_ESEG_VOID (0xffffffffU)
+#define JA_SEGMENT_SIZE (1U << GRN_JA_W_SEGMENT)
+#define JA_W_EINFO 3
+#define JA_W_SEGMENTS_MAX (GRN_JA_W_CAPACITY - GRN_JA_W_SEGMENT)
+#define JA_W_EINFO_IN_A_SEGMENT (GRN_JA_W_SEGMENT - JA_W_EINFO)
+#define JA_N_EINFO_IN_A_SEGMENT (1U << JA_W_EINFO_IN_A_SEGMENT)
+#define JA_M_EINFO_IN_A_SEGMENT (JA_N_EINFO_IN_A_SEGMENT - 1)
+#define JA_N_GARBAGES_IN_A_SEGMENT ((1U << (GRN_JA_W_SEGMENT - 3)) - 2)
+#define JA_N_ELEMENT_VARIATION_V1 (GRN_JA_W_SEGREGATE_THRESH_V1 - JA_W_EINFO + 1)
+#define JA_N_ELEMENT_VARIATION_V2 (GRN_JA_W_SEGREGATE_THRESH_V2 - JA_W_EINFO + 1)
+#define JA_N_DSEGMENTS (1U << JA_W_SEGMENTS_MAX)
+#define JA_N_ESEGMENTS (1U << (GRN_ID_WIDTH - JA_W_EINFO_IN_A_SEGMENT))
+
+typedef struct _grn_ja_einfo grn_ja_einfo;
+
+struct _grn_ja_einfo {
+ union {
+ struct {
+ uint16_t seg;
+ uint16_t pos;
+ uint16_t size;
+ uint8_t c1;
+ uint8_t c2;
+ } n;
+ struct {
+ uint32_t size;
+ uint16_t seg;
+ uint8_t c1;
+ uint8_t c2;
+ } h;
+ uint8_t c[8];
+ } u;
+};
+
+#define ETINY (0x80)
+#define EHUGE (0x40)
+#define ETINY_P(e) ((e)->u.c[7] & ETINY)
+#define ETINY_ENC(e,_size) ((e)->u.c[7] = (_size) + ETINY)
+#define ETINY_DEC(e,_size) ((_size) = (e)->u.c[7] & ~(ETINY|EHUGE))
+#define EHUGE_P(e) ((e)->u.c[7] & EHUGE)
+#define EHUGE_ENC(e,_seg,_size) do {\
+ (e)->u.h.c1 = 0;\
+ (e)->u.h.c2 = EHUGE;\
+ (e)->u.h.seg = (_seg);\
+ (e)->u.h.size = (_size);\
+} while (0)
+#define EHUGE_DEC(e,_seg,_size) do {\
+ (_seg) = (e)->u.h.seg;\
+ (_size) = (e)->u.h.size;\
+} while (0)
+#define EINFO_ENC(e,_seg,_pos,_size) do {\
+ (e)->u.n.c1 = (_pos) >> 16;\
+ (e)->u.n.c2 = ((_size) >> 16);\
+ (e)->u.n.seg = (_seg);\
+ (e)->u.n.pos = (_pos);\
+ (e)->u.n.size = (_size);\
+} while (0)
+#define EINFO_DEC(e,_seg,_pos,_size) do {\
+ (_seg) = (e)->u.n.seg;\
+ (_pos) = ((e)->u.n.c1 << 16) + (e)->u.n.pos;\
+ (_size) = ((e)->u.n.c2 << 16) + (e)->u.n.size;\
+} while (0)
+
+typedef struct {
+ uint32_t seg;
+ uint32_t pos;
+} ja_pos;
+
+typedef struct {
+ uint32_t head;
+ uint32_t tail;
+ uint32_t nrecs;
+ uint32_t next;
+ ja_pos recs[JA_N_GARBAGES_IN_A_SEGMENT];
+} grn_ja_ginfo;
+
+struct grn_ja_header_v1 {
+ uint32_t flags;
+ uint32_t curr_seg;
+ uint32_t curr_pos;
+ uint32_t max_element_size;
+ ja_pos free_elements[JA_N_ELEMENT_VARIATION_V1];
+ uint32_t garbages[JA_N_ELEMENT_VARIATION_V1];
+ uint32_t ngarbages[JA_N_ELEMENT_VARIATION_V1];
+ uint32_t dsegs[JA_N_DSEGMENTS];
+ uint32_t esegs[JA_N_ESEGMENTS];
+};
+
+struct grn_ja_header_v2 {
+ uint32_t flags;
+ uint32_t curr_seg;
+ uint32_t curr_pos;
+ uint32_t max_element_size;
+ ja_pos free_elements[JA_N_ELEMENT_VARIATION_V2];
+ uint32_t garbages[JA_N_ELEMENT_VARIATION_V2];
+ uint32_t ngarbages[JA_N_ELEMENT_VARIATION_V2];
+ uint32_t dsegs[JA_N_DSEGMENTS];
+ uint32_t esegs[JA_N_ESEGMENTS];
+ uint8_t segregate_threshold;
+ uint8_t n_element_variation;
+};
+
+struct grn_ja_header {
+ uint32_t flags;
+ uint32_t *curr_seg;
+ uint32_t *curr_pos;
+ uint32_t max_element_size;
+ ja_pos *free_elements;
+ uint32_t *garbages;
+ uint32_t *ngarbages;
+ uint32_t *dsegs;
+ uint32_t *esegs;
+ uint8_t segregate_threshold;
+ uint8_t n_element_variation;
+};
+
+#define SEG_SEQ (0x10000000U)
+#define SEG_HUGE (0x20000000U)
+#define SEG_EINFO (0x30000000U)
+#define SEG_GINFO (0x40000000U)
+#define SEG_MASK (0xf0000000U)
+
+#define SEGMENTS_AT(ja,seg) ((ja)->header->dsegs[seg])
+#define SEGMENTS_SEGRE_ON(ja,seg,width) (SEGMENTS_AT(ja,seg) = width)
+#define SEGMENTS_SEQ_ON(ja,seg) (SEGMENTS_AT(ja,seg) = SEG_SEQ)
+#define SEGMENTS_HUGE_ON(ja,seg) (SEGMENTS_AT(ja,seg) = SEG_HUGE)
+#define SEGMENTS_EINFO_ON(ja,seg,lseg) (SEGMENTS_AT(ja,seg) = SEG_EINFO|(lseg))
+#define SEGMENTS_GINFO_ON(ja,seg,width) (SEGMENTS_AT(ja,seg) = SEG_GINFO|(width))
+#define SEGMENTS_OFF(ja,seg) (SEGMENTS_AT(ja,seg) = 0)
+
+static grn_ja *
+_grn_ja_create(grn_ctx *ctx, grn_ja *ja, const char *path,
+ unsigned int max_element_size, uint32_t flags)
+{
+ unsigned int i;
+ grn_io *io;
+ struct grn_ja_header *header;
+ struct grn_ja_header_v2 *header_v2;
+ io = grn_io_create(ctx, path, sizeof(struct grn_ja_header_v2),
+ JA_SEGMENT_SIZE, JA_N_DSEGMENTS, grn_io_auto,
+ GRN_IO_EXPIRE_SEGMENT);
+ if (!io) { return NULL; }
+ grn_io_set_type(io, GRN_COLUMN_VAR_SIZE);
+
+ header_v2 = grn_io_header(io);
+ header_v2->flags = flags;
+ header_v2->curr_seg = 0;
+ header_v2->curr_pos = JA_SEGMENT_SIZE;
+ header_v2->max_element_size = max_element_size;
+ for (i = 0; i < JA_N_ESEGMENTS; i++) { header_v2->esegs[i] = JA_ESEG_VOID; }
+ header_v2->segregate_threshold = GRN_JA_W_SEGREGATE_THRESH_V2;
+ header_v2->n_element_variation = JA_N_ELEMENT_VARIATION_V2;
+
+ header = GRN_MALLOCN(struct grn_ja_header, 1);
+ if (!header) {
+ grn_io_close(ctx, io);
+ return NULL;
+ }
+ header->flags = header_v2->flags;
+ header->curr_seg = &(header_v2->curr_seg);
+ header->curr_pos = &(header_v2->curr_pos);
+ header->max_element_size = header_v2->max_element_size;
+ header->free_elements = header_v2->free_elements;
+ header->garbages = header_v2->garbages;
+ header->ngarbages = header_v2->ngarbages;
+ header->dsegs = header_v2->dsegs;
+ header->esegs = header_v2->esegs;
+ header->segregate_threshold = header_v2->segregate_threshold;
+ header->n_element_variation = header_v2->n_element_variation;
+
+ ja->io = io;
+ ja->header = header;
+ SEGMENTS_EINFO_ON(ja, 0, 0);
+ header->esegs[0] = 0;
+ return ja;
+}
+
+grn_ja *
+grn_ja_create(grn_ctx *ctx, const char *path, unsigned int max_element_size, uint32_t flags)
+{
+ grn_ja *ja = NULL;
+ ja = (grn_ja *)GRN_CALLOC(sizeof(grn_ja));
+ if (!ja) {
+ return NULL;
+ }
+ GRN_DB_OBJ_SET_TYPE(ja, GRN_COLUMN_VAR_SIZE);
+ if (!_grn_ja_create(ctx, ja, path, max_element_size, flags)) {
+ GRN_FREE(ja);
+ return NULL;
+ }
+ return ja;
+}
+
+grn_ja *
+grn_ja_open(grn_ctx *ctx, const char *path)
+{
+ grn_io *io;
+ 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);
+ 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;
+ }
+ if (header_v2->segregate_threshold == 0) {
+ header_v2->segregate_threshold = GRN_JA_W_SEGREGATE_THRESH_V1;
+ }
+ if (header_v2->n_element_variation == 0) {
+ header_v2->n_element_variation = JA_N_ELEMENT_VARIATION_V1;
+ }
+ 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);
+ header = GRN_MALLOCN(struct grn_ja_header, 1);
+ if (!header) {
+ grn_io_close(ctx, io);
+ GRN_FREE(ja);
+ return NULL;
+ }
+
+ header->flags = header_v2->flags;
+ header->curr_seg = &(header_v2->curr_seg);
+ header->curr_pos = &(header_v2->curr_pos);
+ header->max_element_size = header_v2->max_element_size;
+ header->segregate_threshold = header_v2->segregate_threshold;
+ header->n_element_variation = header_v2->n_element_variation;
+ if (header->segregate_threshold == GRN_JA_W_SEGREGATE_THRESH_V1) {
+ struct grn_ja_header_v1 *header_v1 = (struct grn_ja_header_v1 *)header_v2;
+ header->free_elements = header_v1->free_elements;
+ header->garbages = header_v1->garbages;
+ header->ngarbages = header_v1->ngarbages;
+ header->dsegs = header_v1->dsegs;
+ header->esegs = header_v1->esegs;
+ } else {
+ header->free_elements = header_v2->free_elements;
+ header->garbages = header_v2->garbages;
+ header->ngarbages = header_v2->ngarbages;
+ header->dsegs = header_v2->dsegs;
+ header->esegs = header_v2->esegs;
+ }
+
+ ja->io = io;
+ ja->header = header;
+
+ return ja;
+}
+
+grn_rc
+grn_ja_info(grn_ctx *ctx, grn_ja *ja, unsigned int *max_element_size)
+{
+ if (!ja) { return GRN_INVALID_ARGUMENT; }
+ if (max_element_size) { *max_element_size = ja->header->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_FREE(ja->header);
+ GRN_FREE(ja);
+ return rc;
+}
+
+grn_rc
+grn_ja_remove(grn_ctx *ctx, const char *path)
+{
+ if (!path) { return GRN_INVALID_ARGUMENT; }
+ return grn_io_remove(ctx, path);
+}
+
+grn_rc
+grn_ja_truncate(grn_ctx *ctx, grn_ja *ja)
+{
+ grn_rc rc;
+ const char *io_path;
+ char *path;
+ unsigned int max_element_size;
+ uint32_t flags;
+ if ((io_path = grn_io_path(ja->io)) && *io_path != '\0') {
+ if (!(path = GRN_STRDUP(io_path))) {
+ ERR(GRN_NO_MEMORY_AVAILABLE, "cannot duplicate path: <%s>", io_path);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ } else {
+ path = NULL;
+ }
+ max_element_size = ja->header->max_element_size;
+ flags = ja->header->flags;
+ if ((rc = grn_io_close(ctx, ja->io))) { goto exit; }
+ ja->io = NULL;
+ if (path && (rc = grn_io_remove(ctx, path))) { goto exit; }
+ GRN_FREE(ja->header);
+ if (!_grn_ja_create(ctx, ja, path, max_element_size, flags)) {
+ rc = GRN_UNKNOWN_ERROR;
+ }
+exit:
+ if (path) { GRN_FREE(path); }
+ return rc;
+}
+
+static void *
+grn_ja_ref_raw(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_io_win *iw, uint32_t *value_len)
+{
+ uint32_t pseg = ja->header->esegs[id >> JA_W_EINFO_IN_A_SEGMENT];
+ iw->size = 0;
+ iw->addr = NULL;
+ iw->pseg = pseg;
+ iw->uncompressed_value = NULL;
+ if (pseg != JA_ESEG_VOID) {
+ grn_ja_einfo *einfo = NULL;
+ GRN_IO_SEG_REF(ja->io, pseg, einfo);
+ if (einfo) {
+ grn_ja_einfo *ei = &einfo[id & JA_M_EINFO_IN_A_SEGMENT];
+ if (ETINY_P(ei)) {
+ iw->tiny_p = 1;
+ ETINY_DEC(ei, iw->size);
+ iw->io = ja->io;
+ iw->ctx = ctx;
+ iw->addr = (void *)ei;
+ } else {
+ uint32_t jag, vpos, vsize;
+ iw->tiny_p = 0;
+ if (EHUGE_P(ei)) {
+ EHUGE_DEC(ei, jag, vsize);
+ vpos = 0;
+ } else {
+ EINFO_DEC(ei, jag, vpos, vsize);
+ }
+ grn_io_win_map(ja->io, ctx, iw, jag, vpos, vsize, grn_io_rdonly);
+ }
+ if (!iw->addr) { GRN_IO_SEG_UNREF(ja->io, pseg); }
+ }
+ }
+ *value_len = iw->size;
+ return iw->addr;
+}
+
+grn_rc
+grn_ja_unref(grn_ctx *ctx, grn_io_win *iw)
+{
+ if (iw->uncompressed_value) {
+ GRN_FREE(iw->uncompressed_value);
+ iw->uncompressed_value = NULL;
+ }
+ 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;
+}
+
+#define DELETED 0x80000000
+
+static grn_rc
+grn_ja_free(grn_ctx *ctx, grn_ja *ja, grn_ja_einfo *einfo)
+{
+ grn_ja_ginfo *ginfo = NULL;
+ uint32_t seg, pos, element_size, aligned_size, m, *gseg;
+ if (ETINY_P(einfo)) { return GRN_SUCCESS; }
+ if (EHUGE_P(einfo)) {
+ uint32_t n;
+ EHUGE_DEC(einfo, seg, element_size);
+ n = ((element_size + JA_SEGMENT_SIZE - 1) >> GRN_JA_W_SEGMENT);
+ for (; n--; seg++) { SEGMENTS_OFF(ja, seg); }
+ return GRN_SUCCESS;
+ }
+ EINFO_DEC(einfo, seg, pos, element_size);
+ if (!element_size) { return GRN_SUCCESS; }
+ {
+ int es = element_size - 1;
+ GRN_BIT_SCAN_REV(es, m);
+ m++;
+ }
+ if (m > ja->header->segregate_threshold) {
+ byte *addr = NULL;
+ GRN_IO_SEG_REF(ja->io, seg, addr);
+ if (!addr) { return GRN_NO_MEMORY_AVAILABLE; }
+ aligned_size = (element_size + sizeof(grn_id) - 1) & ~(sizeof(grn_id) - 1);
+ *(uint32_t *)(addr + pos - sizeof(grn_id)) = DELETED|aligned_size;
+ if (SEGMENTS_AT(ja, seg) < (aligned_size + sizeof(grn_id)) + SEG_SEQ) {
+ GRN_LOG(ctx, GRN_WARN, "inconsistent ja entry detected (%d > %d)",
+ element_size, SEGMENTS_AT(ja, seg) - SEG_SEQ);
+ }
+ SEGMENTS_AT(ja, seg) -= (aligned_size + sizeof(grn_id));
+ if (SEGMENTS_AT(ja, seg) == SEG_SEQ) {
+ /* reuse the segment */
+ SEGMENTS_OFF(ja, seg);
+ if (seg == *(ja->header->curr_seg)) {
+ *(ja->header->curr_pos) = JA_SEGMENT_SIZE;
+ }
+ }
+ GRN_IO_SEG_UNREF(ja->io, seg);
+ } else {
+ uint32_t lseg = 0, lseg_;
+ gseg = &ja->header->garbages[m - JA_W_EINFO];
+ while ((lseg_ = *gseg)) {
+ if (lseg) { GRN_IO_SEG_UNREF(ja->io, lseg); }
+ GRN_IO_SEG_REF(ja->io, lseg_, ginfo);
+ if (!ginfo) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ lseg = lseg_;
+ if (ginfo->nrecs < JA_N_GARBAGES_IN_A_SEGMENT) { break; }
+ gseg = &ginfo->next;
+ }
+ if (!lseg_) {
+ uint32_t i = 0;
+ while (SEGMENTS_AT(ja, i)) {
+ if (++i >= JA_N_DSEGMENTS) {
+ if (lseg) { GRN_IO_SEG_UNREF(ja->io, lseg); }
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ SEGMENTS_GINFO_ON(ja, i, m - JA_W_EINFO);
+ *gseg = i;
+ lseg_ = *gseg;
+ if (lseg) { GRN_IO_SEG_UNREF(ja->io, lseg); }
+ GRN_IO_SEG_REF(ja->io, lseg_, ginfo);
+ lseg = lseg_;
+ if (!ginfo) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ ginfo->head = 0;
+ ginfo->tail = 0;
+ ginfo->nrecs = 0;
+ ginfo->next = 0;
+ }
+ ginfo->recs[ginfo->head].seg = seg;
+ ginfo->recs[ginfo->head].pos = pos;
+ if (++ginfo->head == JA_N_GARBAGES_IN_A_SEGMENT) { ginfo->head = 0; }
+ ginfo->nrecs++;
+ ja->header->ngarbages[m - JA_W_EINFO]++;
+ if (lseg) { GRN_IO_SEG_UNREF(ja->io, lseg); }
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ja_replace(grn_ctx *ctx, grn_ja *ja, grn_id id,
+ grn_ja_einfo *ei, uint64_t *cas)
+{
+ grn_rc rc = GRN_SUCCESS;
+ uint32_t lseg, *pseg, pos;
+ grn_ja_einfo *einfo = NULL, eback;
+ lseg = id >> JA_W_EINFO_IN_A_SEGMENT;
+ pos = id & JA_M_EINFO_IN_A_SEGMENT;
+ pseg = &ja->header->esegs[lseg];
+ if (grn_io_lock(ctx, ja->io, grn_lock_timeout)) {
+ return ctx->rc;
+ }
+ if (*pseg == JA_ESEG_VOID) {
+ unsigned int i = 0;
+ while (SEGMENTS_AT(ja, i)) {
+ if (++i >= JA_N_DSEGMENTS) {
+ ERR(GRN_NOT_ENOUGH_SPACE, "grn_ja file (%s) is full", ja->io->path);
+ rc = GRN_NOT_ENOUGH_SPACE;
+ goto exit;
+ }
+ }
+ SEGMENTS_EINFO_ON(ja, i, lseg);
+ GRN_IO_SEG_REF(ja->io, i, einfo);
+ if (einfo) {
+ *pseg = i;
+ memset(einfo, 0, JA_SEGMENT_SIZE);
+ }
+ } else {
+ GRN_IO_SEG_REF(ja->io, *pseg, einfo);
+ }
+ if (!einfo) {
+ rc = GRN_NO_MEMORY_AVAILABLE;
+ goto exit;
+ }
+ eback = einfo[pos];
+ if (cas && *cas != *((uint64_t *)&eback)) {
+ ERR(GRN_CAS_ERROR, "cas failed (%d)", id);
+ GRN_IO_SEG_UNREF(ja->io, *pseg);
+ rc = GRN_CAS_ERROR;
+ goto exit;
+ }
+ // smb_wmb();
+ {
+ uint64_t *location = (uint64_t *)(einfo + pos);
+ uint64_t value = *((uint64_t *)ei);
+ GRN_SET_64BIT(location, value);
+ }
+ GRN_IO_SEG_UNREF(ja->io, *pseg);
+ grn_ja_free(ctx, ja, &eback);
+exit :
+ grn_io_unlock(ja->io);
+ return rc;
+}
+
+#define JA_N_GARBAGES_TH 10
+
+// todo : grn_io_win_map cause verbose copy when nseg > 1, it should be copied directly.
+static grn_rc
+grn_ja_alloc(grn_ctx *ctx, grn_ja *ja, grn_id id,
+ uint32_t element_size, grn_ja_einfo *einfo, grn_io_win *iw)
+{
+ byte *addr = NULL;
+ iw->io = ja->io;
+ iw->ctx = ctx;
+ iw->cached = 1;
+ if (element_size < 8) {
+ ETINY_ENC(einfo, element_size);
+ iw->tiny_p = 1;
+ iw->addr = (void *)einfo;
+ return GRN_SUCCESS;
+ }
+ iw->tiny_p = 0;
+ if (grn_io_lock(ctx, ja->io, grn_lock_timeout)) { return ctx->rc; }
+ if (element_size + sizeof(grn_id) > JA_SEGMENT_SIZE) {
+ uint i;
+ int j, n = (element_size + JA_SEGMENT_SIZE - 1) >> GRN_JA_W_SEGMENT;
+ for (i = 0, j = -1; i < JA_N_DSEGMENTS; i++) {
+ if (SEGMENTS_AT(ja, i)) {
+ j = i;
+ } else {
+ if (i == j + n) {
+ j++;
+ addr = grn_io_win_map(ja->io, ctx, iw, j, 0, element_size, grn_io_wronly);
+ if (!addr) {
+ grn_io_unlock(ja->io);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ EHUGE_ENC(einfo, j, element_size);
+ for (; j <= i; j++) { SEGMENTS_HUGE_ON(ja, j); }
+ grn_io_unlock(ja->io);
+ return GRN_SUCCESS;
+ }
+ }
+ }
+ GRN_LOG(ctx, GRN_LOG_CRIT, "ja full. requested element_size=%d.", element_size);
+ grn_io_unlock(ja->io);
+ return GRN_NO_MEMORY_AVAILABLE;
+ } else {
+ ja_pos *vp;
+ int m, aligned_size, es = element_size - 1;
+ GRN_BIT_SCAN_REV(es, m);
+ m++;
+ if (m > ja->header->segregate_threshold) {
+ uint32_t seg = *(ja->header->curr_seg);
+ uint32_t pos = *(ja->header->curr_pos);
+ if (pos + element_size + sizeof(grn_id) > JA_SEGMENT_SIZE) {
+ seg = 0;
+ while (SEGMENTS_AT(ja, seg)) {
+ if (++seg >= JA_N_DSEGMENTS) {
+ grn_io_unlock(ja->io);
+ GRN_LOG(ctx, GRN_LOG_CRIT, "ja full. seg=%d.", seg);
+ return GRN_NOT_ENOUGH_SPACE;
+ }
+ }
+ SEGMENTS_SEQ_ON(ja, seg);
+ *(ja->header->curr_seg) = seg;
+ pos = 0;
+ }
+ GRN_IO_SEG_REF(ja->io, seg, addr);
+ if (!addr) {
+ grn_io_unlock(ja->io);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *(grn_id *)(addr + pos) = id;
+ aligned_size = (element_size + sizeof(grn_id) - 1) & ~(sizeof(grn_id) - 1);
+ if (pos + aligned_size < JA_SEGMENT_SIZE) {
+ *(grn_id *)(addr + pos + aligned_size) = GRN_ID_NIL;
+ }
+ SEGMENTS_AT(ja, seg) += aligned_size + sizeof(grn_id);
+ pos += sizeof(grn_id);
+ EINFO_ENC(einfo, seg, pos, element_size);
+ iw->segment = seg;
+ iw->addr = addr + pos;
+ *(ja->header->curr_pos) = pos + aligned_size;
+ grn_io_unlock(ja->io);
+ return GRN_SUCCESS;
+ } else {
+ uint32_t lseg = 0, lseg_;
+ aligned_size = 1 << m;
+ if (ja->header->ngarbages[m - JA_W_EINFO] > JA_N_GARBAGES_TH) {
+ grn_ja_ginfo *ginfo = NULL;
+ uint32_t seg, pos, *gseg;
+ gseg = &ja->header->garbages[m - JA_W_EINFO];
+ while ((lseg_ = *gseg)) {
+ GRN_IO_SEG_REF(ja->io, lseg_, ginfo);
+ if (!ginfo) {
+ if (lseg) { GRN_IO_SEG_UNREF(ja->io, lseg); }
+ grn_io_unlock(ja->io);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ if (ginfo->next || ginfo->nrecs > JA_N_GARBAGES_TH) {
+ seg = ginfo->recs[ginfo->tail].seg;
+ pos = ginfo->recs[ginfo->tail].pos;
+ GRN_IO_SEG_REF(ja->io, seg, addr);
+ if (!addr) {
+ if (lseg) { GRN_IO_SEG_UNREF(ja->io, lseg); }
+ GRN_IO_SEG_UNREF(ja->io, lseg_);
+ grn_io_unlock(ja->io);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ EINFO_ENC(einfo, seg, pos, element_size);
+ iw->segment = seg;
+ iw->addr = addr + pos;
+ if (++ginfo->tail == JA_N_GARBAGES_IN_A_SEGMENT) { ginfo->tail = 0; }
+ ginfo->nrecs--;
+ ja->header->ngarbages[m - JA_W_EINFO]--;
+ if (!ginfo->nrecs) {
+ SEGMENTS_OFF(ja, *gseg);
+ *gseg = ginfo->next;
+ }
+ if (lseg) { GRN_IO_SEG_UNREF(ja->io, lseg); }
+ GRN_IO_SEG_UNREF(ja->io, lseg_);
+ grn_io_unlock(ja->io);
+ return GRN_SUCCESS;
+ }
+ if (lseg) { GRN_IO_SEG_UNREF(ja->io, lseg); }
+ if (!ginfo->next) {
+ GRN_IO_SEG_UNREF(ja->io, lseg_);
+ break;
+ }
+ lseg = lseg_;
+ gseg = &ginfo->next;
+ }
+ }
+ vp = &ja->header->free_elements[m - JA_W_EINFO];
+ if (!vp->seg) {
+ int i = 0;
+ while (SEGMENTS_AT(ja, i)) {
+ if (++i >= JA_N_DSEGMENTS) {
+ grn_io_unlock(ja->io);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ SEGMENTS_SEGRE_ON(ja, i, m);
+ vp->seg = i;
+ vp->pos = 0;
+ }
+ }
+ EINFO_ENC(einfo, vp->seg, vp->pos, element_size);
+ GRN_IO_SEG_REF(ja->io, vp->seg, addr);
+ if (!addr) {
+ grn_io_unlock(ja->io);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ iw->segment = vp->seg;
+ iw->addr = addr + vp->pos;
+ if ((vp->pos += aligned_size) == JA_SEGMENT_SIZE) {
+ vp->seg = 0;
+ vp->pos = 0;
+ }
+ iw->uncompressed_value = NULL;
+ grn_io_unlock(ja->io);
+ return GRN_SUCCESS;
+ }
+}
+
+static grn_rc
+set_value(grn_ctx *ctx, grn_ja *ja, grn_id id, void *value, uint32_t value_len,
+ grn_ja_einfo *einfo)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_io_win iw;
+ if ((ja->header->flags & GRN_OBJ_RING_BUFFER) &&
+ value_len >= ja->header->max_element_size) {
+ if ((rc = grn_ja_alloc(ctx, ja, id, value_len + sizeof(uint32_t), einfo, &iw))) {
+ return rc;
+ }
+ grn_memcpy(iw.addr, value, value_len);
+ memset((byte *)iw.addr + value_len, 0, sizeof(uint32_t));
+ grn_io_win_unmap(&iw);
+ } else {
+ if ((rc = grn_ja_alloc(ctx, ja, id, value_len, einfo, &iw))) { return rc; }
+ grn_memcpy(iw.addr, value, value_len);
+ grn_io_win_unmap(&iw);
+ }
+ return 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)
+{
+ int rc;
+ int64_t buf;
+ grn_io_win iw;
+ grn_ja_einfo einfo;
+
+ if ((flags & GRN_OBJ_SET_MASK) == GRN_OBJ_SET &&
+ value_len > 0) {
+ grn_io_win jw;
+ uint32_t old_len;
+ void *old_value;
+ grn_bool same_value = GRN_FALSE;
+
+ old_value = grn_ja_ref(ctx, ja, id, &jw, &old_len);
+ if (value_len == old_len && memcmp(value, old_value, value_len) == 0) {
+ same_value = GRN_TRUE;
+ }
+ grn_ja_unref(ctx, &jw);
+ if (same_value) {
+ return GRN_SUCCESS;
+ }
+ }
+
+ switch (flags & GRN_OBJ_SET_MASK) {
+ case GRN_OBJ_APPEND :
+ if (value_len) {
+ grn_io_win jw;
+ uint32_t old_len;
+ void *oldvalue = grn_ja_ref(ctx, ja, id, &jw, &old_len);
+ if (oldvalue) {
+ if ((ja->header->flags & GRN_OBJ_RING_BUFFER) &&
+ old_len + value_len >= ja->header->max_element_size) {
+ if (old_len >= ja->header->max_element_size) {
+ byte *b = oldvalue;
+ uint32_t el = old_len - sizeof(uint32_t);
+ uint32_t pos = *((uint32_t *)(b + el));
+ GRN_ASSERT(pos < el);
+ if (el <= pos + value_len) {
+ uint32_t rest = el - pos;
+ grn_memcpy(b + pos, value, rest);
+ grn_memcpy(b, (byte *)value + rest, value_len - rest);
+ *((uint32_t *)(b + el)) = value_len - rest;
+ } else {
+ grn_memcpy(b + pos, value, value_len);
+ *((uint32_t *)(b + el)) = pos + value_len;
+ }
+ return GRN_SUCCESS;
+ } else {
+ if ((rc = grn_ja_alloc(ctx, ja, id,
+ value_len + old_len + sizeof(uint32_t),
+ &einfo, &iw))) {
+ grn_ja_unref(ctx, &jw);
+ return rc;
+ }
+ grn_memcpy(iw.addr, oldvalue, old_len);
+ grn_memcpy((byte *)iw.addr + old_len, value, value_len);
+ memset((byte *)iw.addr + old_len + value_len, 0, sizeof(uint32_t));
+ grn_io_win_unmap(&iw);
+ }
+ } else {
+ if ((rc = grn_ja_alloc(ctx, ja, id, value_len + old_len, &einfo, &iw))) {
+ grn_ja_unref(ctx, &jw);
+ return rc;
+ }
+ grn_memcpy(iw.addr, oldvalue, old_len);
+ grn_memcpy((byte *)iw.addr + old_len, value, value_len);
+ grn_io_win_unmap(&iw);
+ }
+ grn_ja_unref(ctx, &jw);
+ } else {
+ set_value(ctx, ja, id, value, value_len, &einfo);
+ }
+ }
+ break;
+ case GRN_OBJ_PREPEND :
+ if (value_len) {
+ grn_io_win jw;
+ uint32_t old_len;
+ void *oldvalue = grn_ja_ref(ctx, ja, id, &jw, &old_len);
+ if (oldvalue) {
+ if ((ja->header->flags & GRN_OBJ_RING_BUFFER) &&
+ old_len + value_len >= ja->header->max_element_size) {
+ if (old_len >= ja->header->max_element_size) {
+ byte *b = oldvalue;
+ uint32_t el = old_len - sizeof(uint32_t);
+ uint32_t pos = *((uint32_t *)(b + el));
+ GRN_ASSERT(pos < el);
+ if (pos < value_len) {
+ uint32_t rest = value_len - pos;
+ grn_memcpy(b, (byte *)value + rest, pos);
+ grn_memcpy(b + el - rest, value, rest);
+ *((uint32_t *)(b + el)) = el - rest;
+ } else {
+ grn_memcpy(b + pos - value_len, value, value_len);
+ *((uint32_t *)(b + el)) = pos - value_len;
+ }
+ return GRN_SUCCESS;
+ } else {
+ if ((rc = grn_ja_alloc(ctx, ja, id,
+ value_len + old_len + sizeof(uint32_t),
+ &einfo, &iw))) {
+ grn_ja_unref(ctx, &jw);
+ return rc;
+ }
+ grn_memcpy(iw.addr, value, value_len);
+ grn_memcpy((byte *)iw.addr + value_len, oldvalue, old_len);
+ memset((byte *)iw.addr + value_len + old_len, 0, sizeof(uint32_t));
+ grn_io_win_unmap(&iw);
+ }
+ } else {
+ if ((rc = grn_ja_alloc(ctx, ja, id, value_len + old_len, &einfo, &iw))) {
+ grn_ja_unref(ctx, &jw);
+ return rc;
+ }
+ grn_memcpy(iw.addr, value, value_len);
+ grn_memcpy((byte *)iw.addr + value_len, oldvalue, old_len);
+ grn_io_win_unmap(&iw);
+ }
+ grn_ja_unref(ctx, &jw);
+ } else {
+ set_value(ctx, ja, id, value, value_len, &einfo);
+ }
+ }
+ break;
+ case GRN_OBJ_DECR :
+ if (value_len == sizeof(int64_t)) {
+ int64_t *v = (int64_t *)&buf;
+ *v = -(*(int64_t *)value);
+ value = v;
+ } else if (value_len == sizeof(int32_t)) {
+ int32_t *v = (int32_t *)&buf;
+ *v = -(*(int32_t *)value);
+ value = v;
+ } else {
+ return GRN_INVALID_ARGUMENT;
+ }
+ /* fallthru */
+ case GRN_OBJ_INCR :
+ {
+ grn_io_win jw;
+ uint32_t old_len;
+ void *oldvalue = grn_ja_ref(ctx, ja, id, &jw, &old_len);
+ if (oldvalue && old_len) {
+ grn_rc rc = GRN_INVALID_ARGUMENT;
+ if (old_len == sizeof(int64_t) && value_len == sizeof(int64_t)) {
+ (*(int64_t *)oldvalue) += (*(int64_t *)value);
+ rc = GRN_SUCCESS;
+ } else if (old_len == sizeof(int32_t) && value_len == sizeof(int32_t)) {
+ (*(int32_t *)oldvalue) += (*(int32_t *)value);
+ rc = GRN_SUCCESS;
+ }
+ grn_ja_unref(ctx, &jw);
+ return rc;
+ }
+ }
+ /* fallthru */
+ case GRN_OBJ_SET :
+ if (value_len) {
+ set_value(ctx, ja, id, value, value_len, &einfo);
+ } else {
+ memset(&einfo, 0, sizeof(grn_ja_einfo));
+ }
+ break;
+ default :
+ ERR(GRN_INVALID_ARGUMENT, "grn_ja_put_raw called with illegal flags value");
+ return GRN_INVALID_ARGUMENT;
+ }
+ if ((rc = grn_ja_replace(ctx, ja, id, &einfo, cas))) {
+ if (!grn_io_lock(ctx, ja->io, grn_lock_timeout)) {
+ grn_ja_free(ctx, ja, &einfo);
+ grn_io_unlock(ja->io);
+ }
+ }
+ return rc;
+}
+
+grn_rc
+grn_ja_putv(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_obj *vector, int flags)
+{
+ grn_obj header, footer;
+ grn_rc rc = GRN_SUCCESS;
+ grn_section *vp;
+ int i, f = 0, n = grn_vector_size(ctx, vector);
+ GRN_TEXT_INIT(&header, 0);
+ GRN_TEXT_INIT(&footer, 0);
+ grn_text_benc(ctx, &header, n);
+ for (i = 0, vp = vector->u.v.sections; i < n; i++, vp++) {
+ grn_text_benc(ctx, &header, vp->length);
+ if (vp->weight || vp->domain) { f = 1; }
+ }
+ if (f) {
+ for (i = 0, vp = vector->u.v.sections; i < n; i++, vp++) {
+ grn_text_benc(ctx, &footer, vp->weight);
+ grn_text_benc(ctx, &footer, vp->domain);
+ }
+ }
+ {
+ grn_io_win iw;
+ grn_ja_einfo einfo;
+ grn_obj *body = vector->u.v.body;
+ size_t sizeh = GRN_BULK_VSIZE(&header);
+ size_t sizev = body ? GRN_BULK_VSIZE(body) : 0;
+ size_t sizef = GRN_BULK_VSIZE(&footer);
+ if ((rc = grn_ja_alloc(ctx, ja, id, sizeh + sizev + sizef, &einfo, &iw))) { goto exit; }
+ grn_memcpy(iw.addr, GRN_BULK_HEAD(&header), sizeh);
+ if (body) {
+ grn_memcpy((char *)iw.addr + sizeh, GRN_BULK_HEAD(body), sizev);
+ }
+ if (f) {
+ grn_memcpy((char *)iw.addr + sizeh + sizev, GRN_BULK_HEAD(&footer), sizef);
+ }
+ grn_io_win_unmap(&iw);
+ rc = grn_ja_replace(ctx, ja, id, &einfo, NULL);
+ }
+exit :
+ GRN_OBJ_FIN(ctx, &footer);
+ GRN_OBJ_FIN(ctx, &header);
+ return rc;
+}
+
+uint32_t
+grn_ja_size(grn_ctx *ctx, grn_ja *ja, grn_id id)
+{
+ grn_ja_einfo *einfo = NULL, *ei;
+ uint32_t lseg, *pseg, pos, size;
+ lseg = id >> JA_W_EINFO_IN_A_SEGMENT;
+ pos = id & JA_M_EINFO_IN_A_SEGMENT;
+ pseg = &ja->header->esegs[lseg];
+ if (*pseg == JA_ESEG_VOID) {
+ ctx->rc = GRN_INVALID_ARGUMENT;
+ return 0;
+ }
+ GRN_IO_SEG_REF(ja->io, *pseg, einfo);
+ if (!einfo) {
+ ctx->rc = GRN_NO_MEMORY_AVAILABLE;
+ return 0;
+ }
+ ei = &einfo[pos];
+ if (ETINY_P(ei)) {
+ ETINY_DEC(ei, size);
+ } else {
+ if (EHUGE_P(ei)) {
+ size = ei->u.h.size;
+ } else {
+ size = (ei->u.n.c2 << 16) + ei->u.n.size;
+ }
+ }
+ GRN_IO_SEG_UNREF(ja->io, *pseg);
+ return size;
+}
+
+grn_rc
+grn_ja_element_info(grn_ctx *ctx, grn_ja *ja, grn_id id,
+ uint64_t *cas, uint32_t *pos, uint32_t *size)
+{
+ uint32_t pseg = ja->header->esegs[id >> JA_W_EINFO_IN_A_SEGMENT];
+ if (pseg == JA_ESEG_VOID) {
+ return GRN_INVALID_ARGUMENT;
+ } else {
+ grn_ja_einfo *einfo = NULL;
+ GRN_IO_SEG_REF(ja->io, pseg, einfo);
+ if (einfo) {
+ grn_ja_einfo *ei;
+ *cas = *((uint64_t *)&einfo[id & JA_M_EINFO_IN_A_SEGMENT]);
+ ei = (grn_ja_einfo *)cas;
+ if (ETINY_P(ei)) {
+ ETINY_DEC(ei, *size);
+ *pos = 0;
+ } else {
+ uint32_t jag;
+ if (EHUGE_P(ei)) {
+ EHUGE_DEC(ei, jag, *size);
+ *pos = 0;
+ } else {
+ EINFO_DEC(ei, jag, *pos, *size);
+ }
+ }
+ GRN_IO_SEG_UNREF(ja->io, pseg);
+ } else {
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+ 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;
+ 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;
+ }
+
+ 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;
+ 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(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 = 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;
+ 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;
+}
+#endif /* GRN_WITH_ZLIB */
+
+#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 *raw_value;
+ uint32_t raw_value_len;
+ void *lz4_value;
+ uint32_t lz4_value_len;
+ void *unpacked_value;
+ uint32_t uncompressed_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;
+ }
+
+ 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;
+ }
+ if (LZ4_decompress_safe((const char *)(lz4_value),
+ (char *)(iw->uncompressed_value),
+ lz4_value_len,
+ 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 = 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
+ case GRN_OBJ_COMPRESS_ZLIB :
+ return grn_ja_ref_zlib(ctx, ja, id, iw, value_len);
+#endif /* GRN_WITH_ZLIB */
+#ifdef GRN_WITH_LZ4
+ case GRN_OBJ_COMPRESS_LZ4 :
+ return grn_ja_ref_lz4(ctx, ja, id, iw, value_len);
+#endif /* GRN_WITH_LZ4 */
+#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 *
+grn_ja_get_value(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_obj *value)
+{
+ void *v;
+ uint32_t len;
+ grn_io_win iw;
+ if (!value) {
+ if (!(value = grn_obj_open(ctx, GRN_BULK, 0, 0))) {
+ ERR(GRN_INVALID_ARGUMENT, "grn_obj_get_value failed");
+ goto exit;
+ }
+ }
+ if ((v = grn_ja_ref(ctx, ja, id, &iw, &len))) {
+ if ((ja->header->flags & GRN_OBJ_RING_BUFFER) &&
+ len > ja->header->max_element_size) {
+ byte *b = v;
+ uint32_t el = len - sizeof(uint32_t);
+ uint32_t pos = *((uint32_t *)(b + el));
+ GRN_ASSERT(pos < el);
+ grn_bulk_write(ctx, value, (char *)(b + pos), el - pos);
+ grn_bulk_write(ctx, value, (char *)(b), pos);
+ } else {
+ grn_bulk_write(ctx, value, v, len);
+ }
+ grn_ja_unref(ctx, &iw);
+ }
+exit :
+ return value;
+}
+
+#ifdef GRN_WITH_ZLIB
+inline static grn_rc
+grn_ja_put_zlib(grn_ctx *ctx, grn_ja *ja, grn_id id,
+ void *value, uint32_t value_len, int flags, uint64_t *cas)
+{
+ grn_rc rc;
+ 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;
+ 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);
+ 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;
+ zrc = deflate(&zstream, Z_FINISH);
+ if (zrc != Z_STREAM_END) {
+ deflateEnd(&zstream);
+ GRN_FREE(zvalue);
+ 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;
+ zrc = deflateEnd(&zstream);
+ if (zrc != Z_OK) {
+ GRN_FREE(zvalue);
+ 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;
+ rc = grn_ja_put_raw(ctx, ja, id, zvalue, zvalue_len + sizeof(uint64_t), flags, cas);
+ GRN_FREE(zvalue);
+ return rc;
+}
+#endif /* GRN_WITH_ZLIB */
+
+#ifdef GRN_WITH_LZ4
+inline static grn_rc
+grn_ja_put_lz4(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;
+ char *lz4_value;
+ 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) {
+ 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 */
+
+#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 (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);
+ }
+
+ 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_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_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
+ 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
+ case GRN_OBJ_COMPRESS_LZ4 :
+ return grn_ja_put_lz4(ctx, ja, id, value, value_len, flags, cas);
+#endif /* GRN_WITH_LZ4 */
+#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
+grn_ja_defrag_seg(grn_ctx *ctx, grn_ja *ja, uint32_t seg)
+{
+ byte *v = NULL, *ve;
+ uint32_t element_size, cum = 0, *seginfo = &SEGMENTS_AT(ja,seg), sum;
+ sum = (*seginfo & ~SEG_MASK);
+ GRN_IO_SEG_REF(ja->io, seg, v);
+ if (!v) { return GRN_NO_MEMORY_AVAILABLE; }
+ ve = v + JA_SEGMENT_SIZE;
+ while (v < ve && cum < sum) {
+ grn_id id = *((grn_id *)v);
+ if (!id) { break; }
+ if (id & DELETED) {
+ element_size = (id & ~DELETED);
+ } else {
+ uint64_t cas;
+ uint32_t pos;
+ if (grn_ja_element_info(ctx, ja, id, &cas, &pos, &element_size)) { break; }
+ if (v + sizeof(uint32_t) != ve - JA_SEGMENT_SIZE + pos) {
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "dseges[%d] = pos unmatch (%d != %" GRN_FMT_LLD ")",
+ seg, pos, (long long int)(v + sizeof(uint32_t) + JA_SEGMENT_SIZE - ve));
+ break;
+ }
+ if (grn_ja_put(ctx, ja, id, v + sizeof(uint32_t), element_size, GRN_OBJ_SET, &cas)) {
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "dseges[%d] = put failed (%d)", seg, id);
+ break;
+ }
+ element_size = (element_size + sizeof(grn_id) - 1) & ~(sizeof(grn_id) - 1);
+ cum += sizeof(uint32_t) + element_size;
+ }
+ v += sizeof(uint32_t) + element_size;
+ }
+ if (*seginfo) {
+ GRN_LOG(ctx, GRN_LOG_WARNING, "dseges[%d] = %d after defrag", seg, (*seginfo & ~SEG_MASK));
+ }
+ GRN_IO_SEG_UNREF(ja->io, seg);
+ return GRN_SUCCESS;
+}
+
+int
+grn_ja_defrag(grn_ctx *ctx, grn_ja *ja, int threshold)
+{
+ int nsegs = 0;
+ uint32_t seg, ts = 1U << (GRN_JA_W_SEGMENT - threshold);
+ for (seg = 0; seg < JA_N_DSEGMENTS; seg++) {
+ if (seg == *(ja->header->curr_seg)) { continue; }
+ if (((SEGMENTS_AT(ja, seg) & SEG_MASK) == SEG_SEQ) &&
+ ((SEGMENTS_AT(ja, seg) & ~SEG_MASK) < ts)) {
+ if (!grn_ja_defrag_seg(ctx, ja, seg)) { nsegs++; }
+ }
+ }
+ return nsegs;
+}
+
+void
+grn_ja_check(grn_ctx *ctx, grn_ja *ja)
+{
+ char buf[8];
+ uint32_t seg;
+ struct grn_ja_header *h = ja->header;
+ GRN_OUTPUT_ARRAY_OPEN("RESULT", 8);
+ GRN_OUTPUT_MAP_OPEN("SUMMARY", 8);
+ GRN_OUTPUT_CSTR("flags");
+ grn_itoh(h->flags, buf, 8);
+ GRN_OUTPUT_STR(buf, 8);
+ GRN_OUTPUT_CSTR("curr seg");
+ GRN_OUTPUT_INT64(*(h->curr_seg));
+ GRN_OUTPUT_CSTR("curr pos");
+ GRN_OUTPUT_INT64(*(h->curr_pos));
+ GRN_OUTPUT_CSTR("max_element_size");
+ GRN_OUTPUT_INT64(h->max_element_size);
+ GRN_OUTPUT_CSTR("segregate_threshold");
+ GRN_OUTPUT_INT64(h->segregate_threshold);
+ GRN_OUTPUT_CSTR("n_element_variation");
+ GRN_OUTPUT_INT64(h->n_element_variation);
+ GRN_OUTPUT_MAP_CLOSE();
+ GRN_OUTPUT_ARRAY_OPEN("DETAIL", -1);
+ for (seg = 0; seg < JA_N_DSEGMENTS; seg++) {
+ int dseg = SEGMENTS_AT(ja, seg);
+ if (dseg) {
+ GRN_OUTPUT_MAP_OPEN("SEG", -1);
+ GRN_OUTPUT_CSTR("seg id");
+ GRN_OUTPUT_INT64(seg);
+ GRN_OUTPUT_CSTR("seg type");
+ GRN_OUTPUT_INT64((dseg & SEG_MASK)>>28);
+ GRN_OUTPUT_CSTR("seg value");
+ GRN_OUTPUT_INT64(dseg & ~SEG_MASK);
+ if ((dseg & SEG_MASK) == SEG_SEQ) {
+ byte *v = NULL, *ve;
+ uint32_t element_size, cum = 0, sum = dseg & ~SEG_MASK;
+ uint32_t n_del_elements = 0, n_elements = 0, s_del_elements = 0, s_elements = 0;
+ GRN_IO_SEG_REF(ja->io, seg, v);
+ if (v) {
+ /*
+ GRN_OUTPUT_CSTR("seg seq");
+ GRN_OUTPUT_ARRAY_OPEN("SEQ", -1);
+ */
+ ve = v + JA_SEGMENT_SIZE;
+ while (v < ve && cum < sum) {
+ grn_id id = *((grn_id *)v);
+ /*
+ GRN_OUTPUT_MAP_OPEN("ENTRY", -1);
+ GRN_OUTPUT_CSTR("id");
+ GRN_OUTPUT_INT64(id);
+ */
+ if (!id) { break; }
+ if (id & DELETED) {
+ element_size = (id & ~DELETED);
+ n_del_elements++;
+ s_del_elements += element_size;
+ } else {
+ element_size = grn_ja_size(ctx, ja, id);
+ element_size = (element_size + sizeof(grn_id) - 1) & ~(sizeof(grn_id) - 1);
+ cum += sizeof(uint32_t) + element_size;
+ n_elements++;
+ s_elements += sizeof(uint32_t) + element_size;
+ }
+ v += sizeof(uint32_t) + element_size;
+ /*
+ GRN_OUTPUT_CSTR("size");
+ GRN_OUTPUT_INT64(element_size);
+ GRN_OUTPUT_CSTR("cum");
+ GRN_OUTPUT_INT64(cum);
+ GRN_OUTPUT_MAP_CLOSE();
+ */
+ }
+ GRN_IO_SEG_UNREF(ja->io, seg);
+ /*
+ GRN_OUTPUT_ARRAY_CLOSE();
+ */
+ GRN_OUTPUT_CSTR("n_elements");
+ GRN_OUTPUT_INT64(n_elements);
+ GRN_OUTPUT_CSTR("s_elements");
+ GRN_OUTPUT_INT64(s_elements);
+ GRN_OUTPUT_CSTR("n_del_elements");
+ GRN_OUTPUT_INT64(n_del_elements);
+ GRN_OUTPUT_CSTR("s_del_elements");
+ GRN_OUTPUT_INT64(s_del_elements);
+ if (cum != sum) {
+ GRN_OUTPUT_CSTR("cum gap");
+ GRN_OUTPUT_INT64(cum - sum);
+ }
+ }
+ }
+ GRN_OUTPUT_MAP_CLOSE();
+ }
+ }
+ GRN_OUTPUT_ARRAY_CLOSE();
+ 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 ****/
+
+/*
+
+static int len_sum = 0;
+static int img_sum = 0;
+static int simple_sum = 0;
+static int skip_sum = 0;
+
+grn_vgram *
+grn_vgram_create(const char *path)
+{
+ grn_vgram *s;
+ 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_FREE(s);
+ return NULL;
+ }
+ return s;
+}
+
+grn_vgram *
+grn_vgram_open(const char *path)
+{
+ grn_vgram *s;
+ if (!(s = GRN_MALLOCN(grn_vgram, 1))) { return NULL; }
+ s->vgram = grn_sym_open(path);
+ if (!s->vgram) {
+ GRN_FREE(s);
+ return NULL;
+ }
+ return s;
+}
+
+grn_vgram_buf *
+grn_vgram_buf_open(size_t len)
+{
+ grn_vgram_buf *b;
+ if (!(b = GRN_MALLOCN(grn_vgram_buf, 1))) { return NULL; }
+ b->len = len;
+ 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_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;
+}
+
+grn_rc
+grn_vgram_buf_add(grn_vgram_buf *b, grn_id tid)
+{
+ uint8_t dummybuf[8], *dummyp;
+ if (b->tvp < b->tve) { *b->tvp++ = tid; }
+ dummyp = dummybuf;
+ GRN_B_ENC(tid, dummyp);
+ simple_sum += dummyp - dummybuf;
+ return GRN_SUCCESS;
+}
+
+typedef struct {
+ grn_id vid;
+ grn_id tid;
+} vgram_key;
+
+grn_rc
+grn_vgram_update(grn_vgram *vgram, grn_id rid, grn_vgram_buf *b, grn_hash *terms)
+{
+ grn_inv_updspec **u;
+ if (b && b->tvs < b->tvp) {
+ grn_id *t0, *tn;
+ for (t0 = b->tvs; t0 < b->tvp - 1; t0++) {
+ grn_vgram_vnode *v, **vp;
+ if (grn_set_at(terms, t0, (void **) &u)) {
+ vp = &(*u)->vnodes;
+ for (tn = t0 + 1; tn < b->tvp; tn++) {
+ for (v = *vp; v && v->tid != *tn; v = v->cdr) ;
+ if (!v) {
+ if (b->vpp < b->vpe) {
+ v = b->vpp++;
+ } else {
+ // todo;
+ break;
+ }
+ v->car = NULL;
+ v->cdr = *vp;
+ *vp = v;
+ v->tid = *tn;
+ v->vid = 0;
+ v->freq = 0;
+ v->len = tn - t0;
+ }
+ v->freq++;
+ if (v->vid) {
+ vp = &v->car;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ {
+ grn_set *th = grn_set_open(sizeof(grn_id), sizeof(int), 0);
+ if (!th) { return GRN_NO_MEMORY_AVAILABLE; }
+ if (t0 == b->tvp) { GRN_LOG(ctx, GRN_LOG_DEBUG, "t0 == tvp"); }
+ for (t0 = b->tvs; t0 < b->tvp; t0++) {
+ grn_id vid, vid0 = *t0, vid1 = 0;
+ grn_vgram_vnode *v, *v2 = NULL, **vp;
+ if (grn_set_at(terms, t0, (void **) &u)) {
+ vp = &(*u)->vnodes;
+ for (tn = t0 + 1; tn < b->tvp; tn++) {
+ for (v = *vp; v; v = v->cdr) {
+ if (!v->vid && (v->freq < 2 || v->freq * v->len < 4)) {
+ *vp = v->cdr;
+ v->freq = 0;
+ }
+ if (v->tid == *tn) { break; }
+ vp = &v->cdr;
+ }
+ if (v) {
+ if (v->freq) {
+ v2 = v;
+ vid1 = vid0;
+ vid0 = v->vid;
+ }
+ if (v->vid) {
+ vp = &v->car;
+ continue;
+ }
+ }
+ break;
+ }
+ }
+ if (v2) {
+ if (!v2->vid) {
+ vgram_key key;
+ key.vid = vid1;
+ key.tid = v2->tid;
+ if (!(v2->vid = grn_sym_get(vgram->vgram, (char *)&key))) {
+ grn_set_close(th);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ vid = *t0 = v2->vid * 2 + 1;
+ memset(t0 + 1, 0, sizeof(grn_id) * v2->len);
+ t0 += v2->len;
+ } else {
+ vid = *t0 *= 2;
+ }
+ {
+ int *tf;
+ if (!grn_set_get(th, &vid, (void **) &tf)) {
+ grn_set_close(th);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ (*tf)++;
+ }
+ }
+ if (!th->n_entries) { GRN_LOG(ctx, GRN_LOG_DEBUG, "th->n_entries == 0"); }
+ {
+ int j = 0;
+ int skip = 0;
+ grn_set_eh *ehs, *ehp, *ehe;
+ grn_set_sort_optarg arg;
+ uint8_t *ps = GRN_MALLOC(b->len * 2), *pp, *pe;
+ if (!ps) {
+ grn_set_close(th);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ pp = ps;
+ pe = ps + b->len * 2;
+ arg.mode = grn_sort_descending;
+ arg.compar = NULL;
+ arg.compar_arg = (void *)(intptr_t)sizeof(grn_id);
+ ehs = grn_set_sort(th, 0, &arg);
+ if (!ehs) {
+ GRN_FREE(ps);
+ grn_set_close(th);
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ GRN_B_ENC(th->n_entries, pp);
+ for (ehp = ehs, ehe = ehs + th->n_entries; ehp < ehe; ehp++, j++) {
+ int *id = (int *)GRN_SET_INTVAL(*ehp);
+ GRN_B_ENC(*GRN_SET_INTKEY(*ehp), pp);
+ *id = j;
+ }
+ for (t0 = b->tvs; t0 < b->tvp; t0++) {
+ if (*t0) {
+ int *id;
+ if (!grn_set_at(th, t0, (void **) &id)) {
+ GRN_LOG(ctx, GRN_LOG_ERROR, "lookup error (%d)", *t0);
+ }
+ GRN_B_ENC(*id, pp);
+ } else {
+ skip++;
+ }
+ }
+ len_sum += b->len;
+ img_sum += pp - ps;
+ skip_sum += skip;
+ GRN_FREE(ehs);
+ GRN_FREE(ps);
+ }
+ grn_set_close(th);
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_vgram_buf_close(grn_vgram_buf *b)
+{
+ if (!b) { return GRN_INVALID_ARGUMENT; }
+ if (b->tvs) { GRN_FREE(b->tvs); }
+ if (b->vps) { GRN_FREE(b->vps); }
+ GRN_FREE(b);
+ return GRN_SUCCESS;
+}
+
+grn_rc
+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_FREE(vgram);
+ return GRN_SUCCESS;
+}
+*/
diff --git a/storage/mroonga/vendor/groonga/lib/str.c b/storage/mroonga/vendor/groonga/lib/str.c
new file mode 100644
index 00000000..4f0a3a98
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/str.c
@@ -0,0 +1,3276 @@
+/* -*- 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-1335 USA
+*/
+#include "grn.h"
+#include <limits.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
+#endif /* _ISOC99_SOURCE */
+#include <math.h>
+
+#if defined(HAVE__GMTIME64_S) && defined(__GNUC__)
+# ifdef _WIN64
+# define gmtime_s(tm, time) _gmtime64_s(tm, time)
+# else /* _WIN64 */
+# define gmtime_s(tm, time) _gmtime32_s(tm, time)
+# endif /* _WIN64 */
+#endif /* defined(HAVE__GMTIME64_S) && defined(__GNUC__) */
+
+inline static int
+grn_str_charlen_utf8(grn_ctx *ctx, const unsigned char *str, const unsigned char *end)
+{
+ /* MEMO: This function allows non-null-terminated string as str. */
+ /* But requires the end of string. */
+ if (end <= str || !*str) {
+ return 0;
+ }
+ if (*str & 0x80) {
+ int i;
+ int len;
+ GRN_BIT_SCAN_REV(~(((uint) *str) << 24), len);
+ len = 31 - len;
+ if ((unsigned int)(len - 2) >= 3) { /* (len == 1 || len >= 5) */
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "grn_str_charlen_utf8(): first byte is invalid");
+ return 0;
+ }
+ if (str + len > end) {
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "grn_str_charlen_utf8(): incomplete character");
+ return 0;
+ }
+ for (i = 1; i < len; ++i) {
+ if ((str[i] & 0xc0) != 0x80) {
+ GRN_LOG(ctx, GRN_LOG_WARNING,
+ "grn_str_charlen_utf8(): <%d>th byte is invalid",
+ i + 1);
+ return 0;
+ }
+ }
+ return len;
+ } else {
+ return 1;
+ }
+}
+
+unsigned int
+grn_str_charlen(grn_ctx *ctx, const char *str, grn_encoding encoding)
+{
+ /* MEMO: This function requires null-terminated string as str.*/
+ unsigned char *p = (unsigned char *) str;
+ if (!*p) { return 0; }
+ switch (encoding) {
+ case GRN_ENC_EUC_JP :
+ if (*p & 0x80) {
+ if (*(p + 1)) {
+ return 2;
+ } else {
+ /* This is invalid character */
+ GRN_LOG(ctx, GRN_LOG_WARNING, "invalid euc-jp string end on grn_str_charlen");
+ return 0;
+ }
+ }
+ return 1;
+ case GRN_ENC_UTF8 :
+ if (*p & 0x80) {
+ int b, w;
+ size_t size;
+ for (b = 0x40, w = 0; b && (*p & b); b >>= 1, w++);
+ if (!w) {
+ GRN_LOG(ctx, GRN_LOG_WARNING, "invalid utf8 string(1) on grn_str_charlen");
+ return 0;
+ }
+ for (size = 1; w--; size++) {
+ if (!*++p || (*p & 0xc0) != 0x80) {
+ GRN_LOG(ctx, GRN_LOG_WARNING, "invalid utf8 string(2) on grn_str_charlen");
+ return 0;
+ }
+ }
+ return size;
+ } else {
+ return 1;
+ }
+ case GRN_ENC_SJIS :
+ if (*p & 0x80) {
+ /* we regard 0xa0 as JIS X 0201 KANA. adjusted to other tools. */
+ if (0xa0 <= *p && *p <= 0xdf) {
+ /* hankaku-kana */
+ return 1;
+ } else if (!(*(p + 1))) {
+ /* This is invalid character */
+ GRN_LOG(ctx, GRN_LOG_WARNING, "invalid sjis string end on grn_str_charlen");
+ return 0;
+ } else {
+ return 2;
+ }
+ } else {
+ return 1;
+ }
+ default :
+ return 1;
+ }
+ return 0;
+}
+
+int
+grn_charlen_(grn_ctx *ctx, const char *str, const char *end, grn_encoding encoding)
+{
+ /* MEMO: This function allows non-null-terminated string as str. */
+ /* But requires the end of string. */
+ unsigned char *p = (unsigned char *) str;
+ if (p >= (unsigned char *)end) { return 0; }
+ switch (encoding) {
+ case GRN_ENC_EUC_JP :
+ if (*p & 0x80) {
+ if ((p + 1) < (unsigned char *)end) {
+ return 2;
+ } else {
+ /* This is invalid character */
+ GRN_LOG(ctx, GRN_LOG_WARNING, "invalid euc-jp string end on grn_charlen");
+ return 0;
+ }
+ }
+ return 1;
+ case GRN_ENC_UTF8 :
+ return grn_str_charlen_utf8(ctx, p, (unsigned char *)end);
+ case GRN_ENC_SJIS :
+ if (*p & 0x80) {
+ /* we regard 0xa0 as JIS X 0201 KANA. adjusted to other tools. */
+ if (0xa0 <= *p && *p <= 0xdf) {
+ /* hankaku-kana */
+ return 1;
+ } else if (++p >= (unsigned char *)end) {
+ /* This is invalid character */
+ GRN_LOG(ctx, GRN_LOG_WARNING, "invalid sjis string end on grn_charlen");
+ return 0;
+ } else {
+ return 2;
+ }
+ } else {
+ return 1;
+ }
+ default :
+ return 1;
+ }
+ return 0;
+}
+
+int
+grn_charlen(grn_ctx *ctx, const char *str, const char *end)
+{
+ return grn_charlen_(ctx, str, end, ctx->encoding);
+}
+
+static unsigned char symbol[] = {
+ ',', '.', 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
+};
+
+inline static grn_rc
+normalize_euc(grn_ctx *ctx, grn_str *nstr)
+{
+ static uint16_t hankana[] = {
+ 0xa1a1, 0xa1a3, 0xa1d6, 0xa1d7, 0xa1a2, 0xa1a6, 0xa5f2, 0xa5a1, 0xa5a3,
+ 0xa5a5, 0xa5a7, 0xa5a9, 0xa5e3, 0xa5e5, 0xa5e7, 0xa5c3, 0xa1bc, 0xa5a2,
+ 0xa5a4, 0xa5a6, 0xa5a8, 0xa5aa, 0xa5ab, 0xa5ad, 0xa5af, 0xa5b1, 0xa5b3,
+ 0xa5b5, 0xa5b7, 0xa5b9, 0xa5bb, 0xa5bd, 0xa5bf, 0xa5c1, 0xa5c4, 0xa5c6,
+ 0xa5c8, 0xa5ca, 0xa5cb, 0xa5cc, 0xa5cd, 0xa5ce, 0xa5cf, 0xa5d2, 0xa5d5,
+ 0xa5d8, 0xa5db, 0xa5de, 0xa5df, 0xa5e0, 0xa5e1, 0xa5e2, 0xa5e4, 0xa5e6,
+ 0xa5e8, 0xa5e9, 0xa5ea, 0xa5eb, 0xa5ec, 0xa5ed, 0xa5ef, 0xa5f3, 0xa1ab,
+ 0xa1eb
+ };
+ static unsigned char dakuten[] = {
+ 0xf4, 0, 0, 0, 0, 0xac, 0, 0xae, 0, 0xb0, 0, 0xb2, 0, 0xb4, 0, 0xb6, 0,
+ 0xb8, 0, 0xba, 0, 0xbc, 0, 0xbe, 0, 0xc0, 0, 0xc2, 0, 0, 0xc5, 0, 0xc7,
+ 0, 0xc9, 0, 0, 0, 0, 0, 0, 0xd0, 0, 0, 0xd3, 0, 0, 0xd6, 0, 0, 0xd9, 0,
+ 0, 0xdc
+ };
+ static unsigned char handaku[] = {
+ 0xd1, 0, 0, 0xd4, 0, 0, 0xd7, 0, 0, 0xda, 0, 0, 0xdd
+ };
+ int16_t *ch;
+ const unsigned char *s, *s_, *e;
+ unsigned char *d, *d0, *d_, b;
+ uint_least8_t *cp, *ctypes, ctype;
+ size_t size = nstr->orig_blen, length = 0;
+ int removeblankp = nstr->flags & GRN_STR_REMOVEBLANK;
+ if (!(nstr->norm = GRN_MALLOC(size * 2 + 1))) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ d0 = (unsigned char *) nstr->norm;
+ if (nstr->flags & GRN_STR_WITH_CHECKS) {
+ if (!(nstr->checks = GRN_MALLOC(size * 2 * sizeof(int16_t) + 1))) {
+ GRN_FREE(nstr->norm);
+ nstr->norm = NULL;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ ch = nstr->checks;
+ if (nstr->flags & GRN_STR_WITH_CTYPES) {
+ if (!(nstr->ctypes = GRN_MALLOC(size + 1))) {
+ GRN_FREE(nstr->checks);
+ GRN_FREE(nstr->norm);
+ nstr->checks = NULL;
+ nstr->norm = NULL;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ cp = ctypes = nstr->ctypes;
+ e = (unsigned char *)nstr->orig + size;
+ for (s = s_ = (unsigned char *) nstr->orig, d = d_ = d0; s < e; s++) {
+ if ((*s & 0x80)) {
+ if (((s + 1) < e) && (*(s + 1) & 0x80)) {
+ unsigned char c1 = *s++, c2 = *s, c3 = 0;
+ switch (c1 >> 4) {
+ case 0x08 :
+ if (c1 == 0x8e && 0xa0 <= c2 && c2 <= 0xdf) {
+ uint16_t c = hankana[c2 - 0xa0];
+ switch (c) {
+ case 0xa1ab :
+ if (d > d0 + 1 && d[-2] == 0xa5
+ && 0xa6 <= d[-1] && d[-1] <= 0xdb && (b = dakuten[d[-1] - 0xa6])) {
+ *(d - 1) = b;
+ if (ch) { ch[-1] += 2; s_ += 2; }
+ continue;
+ } else {
+ *d++ = c >> 8; *d = c & 0xff;
+ }
+ break;
+ case 0xa1eb :
+ if (d > d0 + 1 && d[-2] == 0xa5
+ && 0xcf <= d[-1] && d[-1] <= 0xdb && (b = handaku[d[-1] - 0xcf])) {
+ *(d - 1) = b;
+ if (ch) { ch[-1] += 2; s_ += 2; }
+ continue;
+ } else {
+ *d++ = c >> 8; *d = c & 0xff;
+ }
+ break;
+ default :
+ *d++ = c >> 8; *d = c & 0xff;
+ break;
+ }
+ ctype = GRN_CHAR_KATAKANA;
+ } else {
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_OTHERS;
+ }
+ break;
+ case 0x09 :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_OTHERS;
+ break;
+ case 0x0a :
+ switch (c1 & 0x0f) {
+ case 1 :
+ switch (c2) {
+ case 0xbc :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_KATAKANA;
+ break;
+ case 0xb9 :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_KANJI;
+ break;
+ case 0xa1 :
+ if (removeblankp) {
+ if (cp > ctypes) { *(cp - 1) |= GRN_STR_BLANK; }
+ continue;
+ } else {
+ *d = ' ';
+ ctype = GRN_STR_BLANK|GRN_CHAR_SYMBOL;
+ }
+ break;
+ default :
+ if (c2 >= 0xa4 && (c3 = symbol[c2 - 0xa4])) {
+ *d = c3;
+ ctype = GRN_CHAR_SYMBOL;
+ } else {
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_OTHERS;
+ }
+ break;
+ }
+ break;
+ case 2 :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_SYMBOL;
+ break;
+ case 3 :
+ c3 = c2 - 0x80;
+ if ('a' <= c3 && c3 <= 'z') {
+ ctype = GRN_CHAR_ALPHA;
+ *d = c3;
+ } else if ('A' <= c3 && c3 <= 'Z') {
+ ctype = GRN_CHAR_ALPHA;
+ *d = c3 + 0x20;
+ } else if ('0' <= c3 && c3 <= '9') {
+ ctype = GRN_CHAR_DIGIT;
+ *d = c3;
+ } else {
+ ctype = GRN_CHAR_OTHERS;
+ *d++ = c1; *d = c2;
+ }
+ break;
+ case 4 :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_HIRAGANA;
+ break;
+ case 5 :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_KATAKANA;
+ break;
+ case 6 :
+ case 7 :
+ case 8 :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_SYMBOL;
+ break;
+ default :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_OTHERS;
+ break;
+ }
+ break;
+ default :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_KANJI;
+ break;
+ }
+ } else {
+ /* skip invalid character */
+ continue;
+ }
+ } else {
+ unsigned char c = *s;
+ switch (c >> 4) {
+ case 0 :
+ case 1 :
+ /* skip unprintable ascii */
+ if (cp > ctypes) { *(cp - 1) |= GRN_STR_BLANK; }
+ continue;
+ case 2 :
+ if (c == 0x20) {
+ if (removeblankp) {
+ if (cp > ctypes) { *(cp - 1) |= GRN_STR_BLANK; }
+ continue;
+ } else {
+ *d = ' ';
+ ctype = GRN_STR_BLANK|GRN_CHAR_SYMBOL;
+ }
+ } else {
+ *d = c;
+ ctype = GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 3 :
+ *d = c;
+ ctype = (c <= 0x39) ? GRN_CHAR_DIGIT : GRN_CHAR_SYMBOL;
+ break;
+ case 4 :
+ *d = ('A' <= c) ? c + 0x20 : c;
+ ctype = (c == 0x40) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 5 :
+ *d = (c <= 'Z') ? c + 0x20 : c;
+ ctype = (c <= 0x5a) ? GRN_CHAR_ALPHA : GRN_CHAR_SYMBOL;
+ break;
+ case 6 :
+ *d = c;
+ ctype = (c == 0x60) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 7 :
+ *d = c;
+ ctype = (c <= 0x7a) ? GRN_CHAR_ALPHA : (c == 0x7f ? GRN_CHAR_OTHERS : GRN_CHAR_SYMBOL);
+ break;
+ default :
+ *d = c;
+ ctype = GRN_CHAR_OTHERS;
+ break;
+ }
+ }
+ d++;
+ length++;
+ if (cp) { *cp++ = ctype; }
+ if (ch) {
+ *ch++ = (int16_t)(s + 1 - s_);
+ s_ = s + 1;
+ while (++d_ < d) { *ch++ = 0; }
+ }
+ }
+ if (cp) { *cp = GRN_CHAR_NULL; }
+ *d = '\0';
+ nstr->length = length;
+ nstr->norm_blen = (size_t)(d - (unsigned char *)nstr->norm);
+ return GRN_SUCCESS;
+}
+
+#ifdef GRN_WITH_NFKC
+inline static grn_rc
+normalize_utf8(grn_ctx *ctx, grn_str *nstr)
+{
+ int16_t *ch;
+ const unsigned char *s, *s_, *s__ = NULL, *p, *p2, *pe, *e;
+ unsigned char *d, *d_, *de;
+ uint_least8_t *cp;
+ size_t length = 0, ls, lp, size = nstr->orig_blen, ds = size * 3;
+ int removeblankp = nstr->flags & GRN_STR_REMOVEBLANK;
+ if (!(nstr->norm = GRN_MALLOC(ds + 1))) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ if (nstr->flags & GRN_STR_WITH_CHECKS) {
+ if (!(nstr->checks = GRN_MALLOC(ds * sizeof(int16_t) + 1))) {
+ GRN_FREE(nstr->norm); nstr->norm = NULL;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ ch = nstr->checks;
+ if (nstr->flags & GRN_STR_WITH_CTYPES) {
+ if (!(nstr->ctypes = GRN_MALLOC(ds + 1))) {
+ if (nstr->checks) { GRN_FREE(nstr->checks); nstr->checks = NULL; }
+ GRN_FREE(nstr->norm); nstr->norm = NULL;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ cp = nstr->ctypes;
+ d = (unsigned char *)nstr->norm;
+ de = d + ds;
+ d_ = NULL;
+ e = (unsigned char *)nstr->orig + size;
+ for (s = s_ = (unsigned char *)nstr->orig; ; s += ls) {
+ if (!(ls = grn_str_charlen_utf8(ctx, s, e))) {
+ break;
+ }
+ 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_compose(d_, p))) {
+ p = p2;
+ pe = p + strlen((char *)p);
+ if (cp) { cp--; }
+ if (ch) {
+ ch -= (d - d_);
+ s_ = s__;
+ }
+ d = d_;
+ length--;
+ }
+ for (; ; p += lp) {
+ if (!(lp = grn_str_charlen_utf8(ctx, p, pe))) {
+ break;
+ }
+ if ((*p == ' ' && removeblankp) || *p < 0x20 /* skip unprintable ascii */ ) {
+ if (cp > nstr->ctypes) { *(cp - 1) |= GRN_STR_BLANK; }
+ } else {
+ if (de <= d + lp) {
+ unsigned char *norm;
+ ds += (ds >> 1) + lp;
+ if (!(norm = GRN_REALLOC(nstr->norm, ds + 1))) {
+ if (nstr->ctypes) { GRN_FREE(nstr->ctypes); nstr->ctypes = NULL; }
+ if (nstr->checks) { GRN_FREE(nstr->checks); nstr->checks = NULL; }
+ GRN_FREE(nstr->norm); nstr->norm = NULL;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ de = norm + ds;
+ d = norm + (d - (unsigned char *)nstr->norm);
+ nstr->norm = (char *)norm;
+ if (ch) {
+ int16_t *checks;
+ if (!(checks = GRN_REALLOC(nstr->checks, ds * sizeof(int16_t)+ 1))) {
+ if (nstr->ctypes) { GRN_FREE(nstr->ctypes); nstr->ctypes = NULL; }
+ GRN_FREE(nstr->checks); nstr->checks = NULL;
+ GRN_FREE(nstr->norm); nstr->norm = NULL;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ ch = checks + (ch - nstr->checks);
+ nstr->checks = checks;
+ }
+ if (cp) {
+ uint_least8_t *ctypes;
+ if (!(ctypes = GRN_REALLOC(nstr->ctypes, ds + 1))) {
+ GRN_FREE(nstr->ctypes); nstr->ctypes = NULL;
+ if (nstr->checks) { GRN_FREE(nstr->checks); nstr->checks = NULL; }
+ GRN_FREE(nstr->norm); nstr->norm = NULL;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ cp = ctypes + (cp - nstr->ctypes);
+ nstr->ctypes = ctypes;
+ }
+ }
+ grn_memcpy(d, p, lp);
+ d_ = d;
+ d += lp;
+ length++;
+ if (cp) { *cp++ = grn_nfkc_char_type(p); }
+ if (ch) {
+ size_t i;
+ if (s_ == s + ls) {
+ *ch++ = -1;
+ } else {
+ *ch++ = (int16_t)(s + ls - s_);
+ s__ = s_;
+ s_ = s + ls;
+ }
+ for (i = lp; i > 1; i--) { *ch++ = 0; }
+ }
+ }
+ }
+ }
+ if (cp) { *cp = GRN_CHAR_NULL; }
+ *d = '\0';
+ nstr->length = length;
+ nstr->norm_blen = (size_t)(d - (unsigned char *)nstr->norm);
+ return GRN_SUCCESS;
+}
+#endif /* GRN_WITH_NFKC */
+
+inline static grn_rc
+normalize_sjis(grn_ctx *ctx, grn_str *nstr)
+{
+ static uint16_t hankana[] = {
+ 0x8140, 0x8142, 0x8175, 0x8176, 0x8141, 0x8145, 0x8392, 0x8340, 0x8342,
+ 0x8344, 0x8346, 0x8348, 0x8383, 0x8385, 0x8387, 0x8362, 0x815b, 0x8341,
+ 0x8343, 0x8345, 0x8347, 0x8349, 0x834a, 0x834c, 0x834e, 0x8350, 0x8352,
+ 0x8354, 0x8356, 0x8358, 0x835a, 0x835c, 0x835e, 0x8360, 0x8363, 0x8365,
+ 0x8367, 0x8369, 0x836a, 0x836b, 0x836c, 0x836d, 0x836e, 0x8371, 0x8374,
+ 0x8377, 0x837a, 0x837d, 0x837e, 0x8380, 0x8381, 0x8382, 0x8384, 0x8386,
+ 0x8388, 0x8389, 0x838a, 0x838b, 0x838c, 0x838d, 0x838f, 0x8393, 0x814a,
+ 0x814b
+ };
+ static unsigned char dakuten[] = {
+ 0x94, 0, 0, 0, 0, 0x4b, 0, 0x4d, 0, 0x4f, 0, 0x51, 0, 0x53, 0, 0x55, 0,
+ 0x57, 0, 0x59, 0, 0x5b, 0, 0x5d, 0, 0x5f, 0, 0x61, 0, 0, 0x64, 0, 0x66,
+ 0, 0x68, 0, 0, 0, 0, 0, 0, 0x6f, 0, 0, 0x72, 0, 0, 0x75, 0, 0, 0x78, 0,
+ 0, 0x7b
+ };
+ static unsigned char handaku[] = {
+ 0x70, 0, 0, 0x73, 0, 0, 0x76, 0, 0, 0x79, 0, 0, 0x7c
+ };
+ int16_t *ch;
+ const unsigned char *s, *s_;
+ unsigned char *d, *d0, *d_, b, *e;
+ uint_least8_t *cp, *ctypes, ctype;
+ size_t size = nstr->orig_blen, length = 0;
+ int removeblankp = nstr->flags & GRN_STR_REMOVEBLANK;
+ if (!(nstr->norm = GRN_MALLOC(size * 2 + 1))) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ d0 = (unsigned char *) nstr->norm;
+ if (nstr->flags & GRN_STR_WITH_CHECKS) {
+ if (!(nstr->checks = GRN_MALLOC(size * 2 * sizeof(int16_t) + 1))) {
+ GRN_FREE(nstr->norm);
+ nstr->norm = NULL;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ ch = nstr->checks;
+ if (nstr->flags & GRN_STR_WITH_CTYPES) {
+ if (!(nstr->ctypes = GRN_MALLOC(size + 1))) {
+ GRN_FREE(nstr->checks);
+ GRN_FREE(nstr->norm);
+ nstr->checks = NULL;
+ nstr->norm = NULL;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ cp = ctypes = nstr->ctypes;
+ e = (unsigned char *)nstr->orig + size;
+ for (s = s_ = (unsigned char *) nstr->orig, d = d_ = d0; s < e; s++) {
+ if ((*s & 0x80)) {
+ if (0xa0 <= *s && *s <= 0xdf) {
+ uint16_t c = hankana[*s - 0xa0];
+ switch (c) {
+ case 0x814a :
+ if (d > d0 + 1 && d[-2] == 0x83
+ && 0x45 <= d[-1] && d[-1] <= 0x7a && (b = dakuten[d[-1] - 0x45])) {
+ *(d - 1) = b;
+ if (ch) { ch[-1]++; s_++; }
+ continue;
+ } else {
+ *d++ = c >> 8; *d = c & 0xff;
+ }
+ break;
+ case 0x814b :
+ if (d > d0 + 1 && d[-2] == 0x83
+ && 0x6e <= d[-1] && d[-1] <= 0x7a && (b = handaku[d[-1] - 0x6e])) {
+ *(d - 1) = b;
+ if (ch) { ch[-1]++; s_++; }
+ continue;
+ } else {
+ *d++ = c >> 8; *d = c & 0xff;
+ }
+ break;
+ default :
+ *d++ = c >> 8; *d = c & 0xff;
+ break;
+ }
+ ctype = GRN_CHAR_KATAKANA;
+ } else {
+ if ((s + 1) < e && 0x40 <= *(s + 1) && *(s + 1) <= 0xfc) {
+ unsigned char c1 = *s++, c2 = *s, c3 = 0;
+ if (0x81 <= c1 && c1 <= 0x87) {
+ switch (c1 & 0x0f) {
+ case 1 :
+ switch (c2) {
+ case 0x5b :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_KATAKANA;
+ break;
+ case 0x58 :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_KANJI;
+ break;
+ case 0x40 :
+ if (removeblankp) {
+ if (cp > ctypes) { *(cp - 1) |= GRN_STR_BLANK; }
+ continue;
+ } else {
+ *d = ' ';
+ ctype = GRN_STR_BLANK|GRN_CHAR_SYMBOL;
+ }
+ break;
+ default :
+ if (0x43 <= c2 && c2 <= 0x7e && (c3 = symbol[c2 - 0x43])) {
+ *d = c3;
+ ctype = GRN_CHAR_SYMBOL;
+ } else if (0x7f <= c2 && c2 <= 0x97 && (c3 = symbol[c2 - 0x44])) {
+ *d = c3;
+ ctype = GRN_CHAR_SYMBOL;
+ } else {
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_OTHERS;
+ }
+ break;
+ }
+ break;
+ case 2 :
+ c3 = c2 - 0x1f;
+ if (0x4f <= c2 && c2 <= 0x58) {
+ ctype = GRN_CHAR_DIGIT;
+ *d = c2 - 0x1f;
+ } else if (0x60 <= c2 && c2 <= 0x79) {
+ ctype = GRN_CHAR_ALPHA;
+ *d = c2 + 0x01;
+ } else if (0x81 <= c2 && c2 <= 0x9a) {
+ ctype = GRN_CHAR_ALPHA;
+ *d = c2 - 0x20;
+ } else if (0x9f <= c2 && c2 <= 0xf1) {
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_HIRAGANA;
+ } else {
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_OTHERS;
+ }
+ break;
+ case 3 :
+ if (0x40 <= c2 && c2 <= 0x96) {
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_KATAKANA;
+ } else {
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 4 :
+ case 7 :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_SYMBOL;
+ break;
+ default :
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_OTHERS;
+ break;
+ }
+ } else {
+ *d++ = c1; *d = c2;
+ ctype = GRN_CHAR_KANJI;
+ }
+ } else {
+ /* skip invalid character */
+ continue;
+ }
+ }
+ } else {
+ unsigned char c = *s;
+ switch (c >> 4) {
+ case 0 :
+ case 1 :
+ /* skip unprintable ascii */
+ if (cp > ctypes) { *(cp - 1) |= GRN_STR_BLANK; }
+ continue;
+ case 2 :
+ if (c == 0x20) {
+ if (removeblankp) {
+ if (cp > ctypes) { *(cp - 1) |= GRN_STR_BLANK; }
+ continue;
+ } else {
+ *d = ' ';
+ ctype = GRN_STR_BLANK|GRN_CHAR_SYMBOL;
+ }
+ } else {
+ *d = c;
+ ctype = GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 3 :
+ *d = c;
+ ctype = (c <= 0x39) ? GRN_CHAR_DIGIT : GRN_CHAR_SYMBOL;
+ break;
+ case 4 :
+ *d = ('A' <= c) ? c + 0x20 : c;
+ ctype = (c == 0x40) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 5 :
+ *d = (c <= 'Z') ? c + 0x20 : c;
+ ctype = (c <= 0x5a) ? GRN_CHAR_ALPHA : GRN_CHAR_SYMBOL;
+ break;
+ case 6 :
+ *d = c;
+ ctype = (c == 0x60) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 7 :
+ *d = c;
+ ctype = (c <= 0x7a) ? GRN_CHAR_ALPHA : (c == 0x7f ? GRN_CHAR_OTHERS : GRN_CHAR_SYMBOL);
+ break;
+ default :
+ *d = c;
+ ctype = GRN_CHAR_OTHERS;
+ break;
+ }
+ }
+ d++;
+ length++;
+ if (cp) { *cp++ = ctype; }
+ if (ch) {
+ *ch++ = (int16_t)(s + 1 - s_);
+ s_ = s + 1;
+ while (++d_ < d) { *ch++ = 0; }
+ }
+ }
+ if (cp) { *cp = GRN_CHAR_NULL; }
+ *d = '\0';
+ nstr->length = length;
+ nstr->norm_blen = (size_t)(d - (unsigned char *)nstr->norm);
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+normalize_none(grn_ctx *ctx, grn_str *nstr)
+{
+ int16_t *ch;
+ const unsigned char *s, *s_, *e;
+ unsigned char *d, *d0, *d_;
+ uint_least8_t *cp, *ctypes, ctype;
+ size_t size = nstr->orig_blen, length = 0;
+ int removeblankp = nstr->flags & GRN_STR_REMOVEBLANK;
+ if (!(nstr->norm = GRN_MALLOC(size + 1))) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ d0 = (unsigned char *) nstr->norm;
+ if (nstr->flags & GRN_STR_WITH_CHECKS) {
+ if (!(nstr->checks = GRN_MALLOC(size * sizeof(int16_t) + 1))) {
+ GRN_FREE(nstr->norm);
+ nstr->norm = NULL;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ ch = nstr->checks;
+ if (nstr->flags & GRN_STR_WITH_CTYPES) {
+ if (!(nstr->ctypes = GRN_MALLOC(size + 1))) {
+ GRN_FREE(nstr->checks);
+ GRN_FREE(nstr->norm);
+ nstr->checks = NULL;
+ nstr->norm = NULL;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ cp = ctypes = nstr->ctypes;
+ e = (unsigned char *)nstr->orig + size;
+ for (s = s_ = (unsigned char *) nstr->orig, d = d_ = d0; s < e; s++) {
+ unsigned char c = *s;
+ switch (c >> 4) {
+ case 0 :
+ case 1 :
+ /* skip unprintable ascii */
+ if (cp > ctypes) { *(cp - 1) |= GRN_STR_BLANK; }
+ continue;
+ case 2 :
+ if (c == 0x20) {
+ if (removeblankp) {
+ if (cp > ctypes) { *(cp - 1) |= GRN_STR_BLANK; }
+ continue;
+ } else {
+ *d = ' ';
+ ctype = GRN_STR_BLANK|GRN_CHAR_SYMBOL;
+ }
+ } else {
+ *d = c;
+ ctype = GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 3 :
+ *d = c;
+ ctype = (c <= 0x39) ? GRN_CHAR_DIGIT : GRN_CHAR_SYMBOL;
+ break;
+ case 4 :
+ *d = ('A' <= c) ? c + 0x20 : c;
+ ctype = (c == 0x40) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 5 :
+ *d = (c <= 'Z') ? c + 0x20 : c;
+ ctype = (c <= 0x5a) ? GRN_CHAR_ALPHA : GRN_CHAR_SYMBOL;
+ break;
+ case 6 :
+ *d = c;
+ ctype = (c == 0x60) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 7 :
+ *d = c;
+ ctype = (c <= 0x7a) ? GRN_CHAR_ALPHA : (c == 0x7f ? GRN_CHAR_OTHERS : GRN_CHAR_SYMBOL);
+ break;
+ default :
+ *d = c;
+ ctype = GRN_CHAR_OTHERS;
+ break;
+ }
+ d++;
+ length++;
+ if (cp) { *cp++ = ctype; }
+ if (ch) {
+ *ch++ = (int16_t)(s + 1 - s_);
+ s_ = s + 1;
+ while (++d_ < d) { *ch++ = 0; }
+ }
+ }
+ if (cp) { *cp = GRN_CHAR_NULL; }
+ *d = '\0';
+ nstr->length = length;
+ nstr->norm_blen = (size_t)(d - (unsigned char *)nstr->norm);
+ return GRN_SUCCESS;
+}
+
+/* use cp1252 as latin1 */
+inline static grn_rc
+normalize_latin1(grn_ctx *ctx, grn_str *nstr)
+{
+ int16_t *ch;
+ const unsigned char *s, *s_, *e;
+ unsigned char *d, *d0, *d_;
+ uint_least8_t *cp, *ctypes, ctype;
+ size_t size = nstr->orig_blen, length = 0;
+ int removeblankp = nstr->flags & GRN_STR_REMOVEBLANK;
+ if (!(nstr->norm = GRN_MALLOC(size + 1))) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ d0 = (unsigned char *) nstr->norm;
+ if (nstr->flags & GRN_STR_WITH_CHECKS) {
+ if (!(nstr->checks = GRN_MALLOC(size * sizeof(int16_t) + 1))) {
+ GRN_FREE(nstr->norm);
+ nstr->norm = NULL;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ ch = nstr->checks;
+ if (nstr->flags & GRN_STR_WITH_CTYPES) {
+ if (!(nstr->ctypes = GRN_MALLOC(size + 1))) {
+ GRN_FREE(nstr->checks);
+ GRN_FREE(nstr->norm);
+ nstr->checks = NULL;
+ nstr->norm = NULL;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ cp = ctypes = nstr->ctypes;
+ e = (unsigned char *)nstr->orig + size;
+ for (s = s_ = (unsigned char *) nstr->orig, d = d_ = d0; s < e; s++) {
+ unsigned char c = *s;
+ switch (c >> 4) {
+ case 0 :
+ case 1 :
+ /* skip unprintable ascii */
+ if (cp > ctypes) { *(cp - 1) |= GRN_STR_BLANK; }
+ continue;
+ case 2 :
+ if (c == 0x20) {
+ if (removeblankp) {
+ if (cp > ctypes) { *(cp - 1) |= GRN_STR_BLANK; }
+ continue;
+ } else {
+ *d = ' ';
+ ctype = GRN_STR_BLANK|GRN_CHAR_SYMBOL;
+ }
+ } else {
+ *d = c;
+ ctype = GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 3 :
+ *d = c;
+ ctype = (c <= 0x39) ? GRN_CHAR_DIGIT : GRN_CHAR_SYMBOL;
+ break;
+ case 4 :
+ *d = ('A' <= c) ? c + 0x20 : c;
+ ctype = (c == 0x40) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 5 :
+ *d = (c <= 'Z') ? c + 0x20 : c;
+ ctype = (c <= 0x5a) ? GRN_CHAR_ALPHA : GRN_CHAR_SYMBOL;
+ break;
+ case 6 :
+ *d = c;
+ ctype = (c == 0x60) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 7 :
+ *d = c;
+ ctype = (c <= 0x7a) ? GRN_CHAR_ALPHA : (c == 0x7f ? GRN_CHAR_OTHERS : GRN_CHAR_SYMBOL);
+ break;
+ case 8 :
+ if (c == 0x8a || c == 0x8c || c == 0x8e) {
+ *d = c + 0x10;
+ ctype = GRN_CHAR_ALPHA;
+ } else {
+ *d = c;
+ ctype = GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 9 :
+ if (c == 0x9a || c == 0x9c || c == 0x9e || c == 0x9f) {
+ *d = (c == 0x9f) ? c + 0x60 : c;
+ ctype = GRN_CHAR_ALPHA;
+ } else {
+ *d = c;
+ ctype = GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 0x0c :
+ *d = c + 0x20;
+ ctype = GRN_CHAR_ALPHA;
+ break;
+ case 0x0d :
+ *d = (c == 0xd7 || c == 0xdf) ? c : c + 0x20;
+ ctype = (c == 0xd7) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 0x0e :
+ *d = c;
+ ctype = GRN_CHAR_ALPHA;
+ break;
+ case 0x0f :
+ *d = c;
+ ctype = (c == 0xf7) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ default :
+ *d = c;
+ ctype = GRN_CHAR_OTHERS;
+ break;
+ }
+ d++;
+ length++;
+ if (cp) { *cp++ = ctype; }
+ if (ch) {
+ *ch++ = (int16_t)(s + 1 - s_);
+ s_ = s + 1;
+ while (++d_ < d) { *ch++ = 0; }
+ }
+ }
+ if (cp) { *cp = GRN_CHAR_NULL; }
+ *d = '\0';
+ nstr->length = length;
+ nstr->norm_blen = (size_t)(d - (unsigned char *)nstr->norm);
+ return GRN_SUCCESS;
+}
+
+inline static grn_rc
+normalize_koi8r(grn_ctx *ctx, grn_str *nstr)
+{
+ int16_t *ch;
+ const unsigned char *s, *s_, *e;
+ unsigned char *d, *d0, *d_;
+ uint_least8_t *cp, *ctypes, ctype;
+ size_t size = strlen(nstr->orig), length = 0;
+ int removeblankp = nstr->flags & GRN_STR_REMOVEBLANK;
+ if (!(nstr->norm = GRN_MALLOC(size + 1))) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ d0 = (unsigned char *) nstr->norm;
+ if (nstr->flags & GRN_STR_WITH_CHECKS) {
+ if (!(nstr->checks = GRN_MALLOC(size * sizeof(int16_t) + 1))) {
+ GRN_FREE(nstr->norm);
+ nstr->norm = NULL;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ ch = nstr->checks;
+ if (nstr->flags & GRN_STR_WITH_CTYPES) {
+ if (!(nstr->ctypes = GRN_MALLOC(size + 1))) {
+ GRN_FREE(nstr->checks);
+ GRN_FREE(nstr->norm);
+ nstr->checks = NULL;
+ nstr->norm = NULL;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ cp = ctypes = nstr->ctypes;
+ e = (unsigned char *)nstr->orig + size;
+ for (s = s_ = (unsigned char *) nstr->orig, d = d_ = d0; s < e; s++) {
+ unsigned char c = *s;
+ switch (c >> 4) {
+ case 0 :
+ case 1 :
+ /* skip unprintable ascii */
+ if (cp > ctypes) { *(cp - 1) |= GRN_STR_BLANK; }
+ continue;
+ case 2 :
+ if (c == 0x20) {
+ if (removeblankp) {
+ if (cp > ctypes) { *(cp - 1) |= GRN_STR_BLANK; }
+ continue;
+ } else {
+ *d = ' ';
+ ctype = GRN_STR_BLANK|GRN_CHAR_SYMBOL;
+ }
+ } else {
+ *d = c;
+ ctype = GRN_CHAR_SYMBOL;
+ }
+ break;
+ case 3 :
+ *d = c;
+ ctype = (c <= 0x39) ? GRN_CHAR_DIGIT : GRN_CHAR_SYMBOL;
+ break;
+ case 4 :
+ *d = ('A' <= c) ? c + 0x20 : c;
+ ctype = (c == 0x40) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 5 :
+ *d = (c <= 'Z') ? c + 0x20 : c;
+ ctype = (c <= 0x5a) ? GRN_CHAR_ALPHA : GRN_CHAR_SYMBOL;
+ break;
+ case 6 :
+ *d = c;
+ ctype = (c == 0x60) ? GRN_CHAR_SYMBOL : GRN_CHAR_ALPHA;
+ break;
+ case 7 :
+ *d = c;
+ ctype = (c <= 0x7a) ? GRN_CHAR_ALPHA : (c == 0x7f ? GRN_CHAR_OTHERS : GRN_CHAR_SYMBOL);
+ break;
+ case 0x0a :
+ *d = c;
+ ctype = (c == 0xa3) ? GRN_CHAR_ALPHA : GRN_CHAR_OTHERS;
+ break;
+ case 0x0b :
+ if (c == 0xb3) {
+ *d = c - 0x10;
+ ctype = GRN_CHAR_ALPHA;
+ } else {
+ *d = c;
+ ctype = GRN_CHAR_OTHERS;
+ }
+ break;
+ case 0x0c :
+ case 0x0d :
+ *d = c;
+ ctype = GRN_CHAR_ALPHA;
+ break;
+ case 0x0e :
+ case 0x0f :
+ *d = c - 0x20;
+ ctype = GRN_CHAR_ALPHA;
+ break;
+ default :
+ *d = c;
+ ctype = GRN_CHAR_OTHERS;
+ break;
+ }
+ d++;
+ length++;
+ if (cp) { *cp++ = ctype; }
+ if (ch) {
+ *ch++ = (int16_t)(s + 1 - s_);
+ s_ = s + 1;
+ while (++d_ < d) { *ch++ = 0; }
+ }
+ }
+ if (cp) { *cp = GRN_CHAR_NULL; }
+ *d = '\0';
+ nstr->length = length;
+ nstr->norm_blen = (size_t)(d - (unsigned char *)nstr->norm);
+ return GRN_SUCCESS;
+}
+
+static grn_str *
+grn_fakenstr_open(grn_ctx *ctx, const char *str, size_t str_len, grn_encoding encoding, int flags)
+{
+ /* TODO: support GRN_STR_REMOVEBLANK flag and ctypes */
+ grn_str *nstr;
+ if (!(nstr = GRN_MALLOC(sizeof(grn_str)))) {
+ GRN_LOG(ctx, GRN_LOG_ALERT, "memory allocation on grn_fakenstr_open failed !");
+ return NULL;
+ }
+ if (!(nstr->norm = GRN_MALLOC(str_len + 1))) {
+ GRN_LOG(ctx, GRN_LOG_ALERT, "memory allocation for keyword on grn_snip_add_cond failed !");
+ GRN_FREE(nstr);
+ return NULL;
+ }
+ nstr->orig = str;
+ nstr->orig_blen = str_len;
+ grn_memcpy(nstr->norm, str, str_len);
+ nstr->norm[str_len] = '\0';
+ nstr->norm_blen = str_len;
+ nstr->ctypes = NULL;
+ nstr->flags = flags;
+
+ if (flags & GRN_STR_WITH_CHECKS) {
+ int16_t f = 0;
+ unsigned char c;
+ size_t i;
+ if (!(nstr->checks = (int16_t *) GRN_MALLOC(sizeof(int16_t) * str_len))) {
+ GRN_FREE(nstr->norm);
+ GRN_FREE(nstr);
+ return NULL;
+ }
+ switch (encoding) {
+ case GRN_ENC_EUC_JP:
+ for (i = 0; i < str_len; i++) {
+ if (!f) {
+ c = (unsigned char) str[i];
+ f = ((c >= 0xa1U && c <= 0xfeU) || c == 0x8eU ? 2 : (c == 0x8fU ? 3 : 1)
+ );
+ nstr->checks[i] = f;
+ } else {
+ nstr->checks[i] = 0;
+ }
+ f--;
+ }
+ break;
+ case GRN_ENC_SJIS:
+ for (i = 0; i < str_len; i++) {
+ if (!f) {
+ c = (unsigned char) str[i];
+ f = (c >= 0x81U && ((c <= 0x9fU) || (c >= 0xe0U && c <= 0xfcU)) ? 2 : 1);
+ nstr->checks[i] = f;
+ } else {
+ nstr->checks[i] = 0;
+ }
+ f--;
+ }
+ break;
+ case GRN_ENC_UTF8:
+ for (i = 0; i < str_len; i++) {
+ if (!f) {
+ c = (unsigned char) str[i];
+ f = (c & 0x80U ? (c & 0x20U ? (c & 0x10U ? 4 : 3)
+ : 2)
+ : 1);
+ nstr->checks[i] = f;
+ } else {
+ nstr->checks[i] = 0;
+ }
+ f--;
+ }
+ break;
+ default:
+ for (i = 0; i < str_len; i++) {
+ nstr->checks[i] = 1;
+ }
+ break;
+ }
+ } else {
+ nstr->checks = NULL;
+ }
+ return nstr;
+}
+
+grn_str *
+grn_str_open_(grn_ctx *ctx, const char *str, unsigned int str_len, int flags, grn_encoding encoding)
+{
+ grn_rc rc;
+ grn_str *nstr;
+ if (!str || !str_len) { return NULL; }
+
+ if (!(flags & GRN_STR_NORMALIZE)) {
+ return grn_fakenstr_open(ctx, str, str_len, encoding, flags);
+ }
+
+ if (!(nstr = GRN_MALLOC(sizeof(grn_str)))) {
+ GRN_LOG(ctx, GRN_LOG_ALERT, "memory allocation on grn_str_open failed !");
+ return NULL;
+ }
+ nstr->orig = str;
+ nstr->orig_blen = str_len;
+ nstr->norm = NULL;
+ nstr->norm_blen = 0;
+ nstr->checks = NULL;
+ nstr->ctypes = NULL;
+ nstr->encoding = encoding;
+ nstr->flags = flags;
+ switch (encoding) {
+ case GRN_ENC_EUC_JP :
+ rc = normalize_euc(ctx, nstr);
+ break;
+ case GRN_ENC_UTF8 :
+#ifdef GRN_WITH_NFKC
+ rc = normalize_utf8(ctx, nstr);
+#else /* GRN_WITH_NFKC */
+ rc = normalize_none(ctx, nstr);
+#endif /* GRN_WITH_NFKC */
+ break;
+ case GRN_ENC_SJIS :
+ rc = normalize_sjis(ctx, nstr);
+ break;
+ case GRN_ENC_LATIN1 :
+ rc = normalize_latin1(ctx, nstr);
+ break;
+ case GRN_ENC_KOI8R :
+ rc = normalize_koi8r(ctx, nstr);
+ break;
+ default :
+ rc = normalize_none(ctx, nstr);
+ break;
+ }
+ if (rc) {
+ grn_str_close(ctx, nstr);
+ return NULL;
+ }
+ return nstr;
+}
+
+grn_str *
+grn_str_open(grn_ctx *ctx, const char *str, unsigned int str_len, int flags)
+{
+ return grn_str_open_(ctx, str, str_len, flags, ctx->encoding);
+}
+
+grn_rc
+grn_str_close(grn_ctx *ctx, grn_str *nstr)
+{
+ if (nstr) {
+ if (nstr->norm) { GRN_FREE(nstr->norm); }
+ if (nstr->ctypes) { GRN_FREE(nstr->ctypes); }
+ if (nstr->checks) { GRN_FREE(nstr->checks); }
+ GRN_FREE(nstr);
+ return GRN_SUCCESS;
+ } else {
+ return GRN_INVALID_ARGUMENT;
+ }
+}
+
+static const char *grn_enc_string[] = {
+ "default",
+ "none",
+ "euc_jp",
+ "utf8",
+ "sjis",
+ "latin1",
+ "koi8r"
+};
+
+const char *
+grn_encoding_to_string(grn_encoding enc)
+{
+ if (enc < (sizeof(grn_enc_string) / sizeof(char *))) {
+ return grn_enc_string[enc];
+ } else {
+ return "unknown";
+ }
+}
+
+grn_encoding
+grn_encoding_parse(const char *str)
+{
+ grn_encoding e = GRN_ENC_UTF8;
+ int i = sizeof(grn_enc_string) / sizeof(grn_enc_string[0]);
+ while (i--) {
+ if (!strcmp(str, grn_enc_string[i])) {
+ e = (grn_encoding)i;
+ }
+ }
+ return e;
+}
+
+size_t
+grn_str_len(grn_ctx *ctx, const char *str, grn_encoding encoding, const char **last)
+{
+ size_t len, tlen;
+ const char *p = NULL;
+ for (len = 0; ; len++) {
+ p = str;
+ if (!(tlen = grn_str_charlen(ctx, str, encoding))) {
+ break;
+ }
+ str += tlen;
+ }
+ if (last) { *last = p; }
+ return len;
+}
+
+int
+grn_isspace(const char *str, grn_encoding encoding)
+{
+ const unsigned char *s = (const unsigned char *) str;
+ if (!s) { return 0; }
+ switch (s[0]) {
+ case ' ' :
+ case '\f' :
+ case '\n' :
+ case '\r' :
+ case '\t' :
+ case '\v' :
+ return 1;
+ case 0x81 :
+ if (encoding == GRN_ENC_SJIS && s[1] == 0x40) { return 2; }
+ break;
+ case 0xA1 :
+ if (encoding == GRN_ENC_EUC_JP && s[1] == 0xA1) { return 2; }
+ break;
+ case 0xE3 :
+ if (encoding == GRN_ENC_UTF8 && s[1] == 0x80 && s[2] == 0x80) { return 3; }
+ break;
+ default :
+ break;
+ }
+ return 0;
+}
+
+int8_t
+grn_atoi8(const char *nptr, const char *end, const char **rest)
+{
+ const char *p = nptr;
+ int8_t v = 0, t, n = 0, o = 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 || (!n && t == INT8_MIN)) { v = 0; break; }
+ v = t;
+ o = 0;
+ p++;
+ }
+ if (rest) { *rest = o ? nptr : p; }
+ return n ? v : -v;
+}
+
+uint8_t
+grn_atoui8(const char *nptr, const char *end, const char **rest)
+{
+ uint8_t v = 0, t;
+ while (nptr < end && *nptr >= '0' && *nptr <= '9') {
+ t = v * 10 + (*nptr - '0');
+ if (t < v) { v = 0; break; }
+ v = t;
+ nptr++;
+ }
+ if (rest) { *rest = nptr; }
+ return v;
+}
+
+int16_t
+grn_atoi16(const char *nptr, const char *end, const char **rest)
+{
+ const char *p = nptr;
+ int16_t v = 0, t, n = 0, o = 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 || (!n && t == INT16_MIN)) { v = 0; break; }
+ v = t;
+ o = 0;
+ p++;
+ }
+ if (rest) { *rest = o ? nptr : p; }
+ return n ? v : -v;
+}
+
+uint16_t
+grn_atoui16(const char *nptr, const char *end, const char **rest)
+{
+ uint16_t v = 0, t;
+ while (nptr < end && *nptr >= '0' && *nptr <= '9') {
+ t = v * 10 + (*nptr - '0');
+ if (t < v) { v = 0; break; }
+ v = t;
+ nptr++;
+ }
+ if (rest) { *rest = nptr; }
+ return v;
+}
+
+int
+grn_atoi(const char *nptr, const char *end, const char **rest)
+{
+ const char *p = nptr;
+ int v = 0, t, n = 0, o = 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 || (!n && t == INT32_MIN)) { v = 0; break; }
+ v = t;
+ o = 0;
+ p++;
+ }
+ if (rest) { *rest = o ? nptr : p; }
+ return n ? v : -v;
+}
+
+unsigned int
+grn_atoui(const char *nptr, const char *end, const char **rest)
+{
+ unsigned int v = 0, t;
+ while (nptr < end && *nptr >= '0' && *nptr <= '9') {
+ t = v * 10 + (*nptr - '0');
+ if (t < v) { v = 0; break; }
+ v = t;
+ nptr++;
+ }
+ if (rest) { *rest = nptr; }
+ return v;
+}
+
+int64_t
+grn_atoll(const char *nptr, const char *end, const char **rest)
+{
+ const char *p = nptr;
+ int o = 0;
+ int64_t v = 0;
+ if (p < end && *p == '-') {
+ p++;
+ o = 1;
+ 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 v;
+}
+
+uint64_t
+grn_atoull(const char *nptr, const char *end, const char **rest)
+{
+ uint64_t v = 0, t;
+ while (nptr < end && *nptr >= '0' && *nptr <= '9') {
+ t = v * 10 + (*nptr - '0');
+ if (t < v) { v = 0; break; }
+ v = t;
+ nptr++;
+ }
+ if (rest) { *rest = nptr; }
+ return v;
+}
+
+unsigned int
+grn_htoui(const char *nptr, const char *end, const char **rest)
+{
+ unsigned int v = 0, t;
+ while (nptr < end) {
+ switch (*nptr) {
+ case '0' :
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ case '8' :
+ case '9' :
+ t = v * 16 + (*nptr++ - '0');
+ break;
+ case 'a' :
+ case 'b' :
+ case 'c' :
+ case 'd' :
+ case 'e' :
+ case 'f' :
+ t = v * 16 + (*nptr++ - 'a') + 10;
+ break;
+ case 'A' :
+ case 'B' :
+ case 'C' :
+ case 'D' :
+ case 'E' :
+ case 'F' :
+ t = v * 16 + (*nptr++ - 'A') + 10;
+ break;
+ default :
+ v = 0; goto exit;
+ }
+ if (t < v) { v = 0; goto exit; }
+ v = t;
+ }
+exit :
+ if (rest) { *rest = nptr; }
+ return v;
+}
+
+void
+grn_itoh(unsigned int i, char *p, unsigned int len)
+{
+ static const char *hex = "0123456789ABCDEF";
+ p += len - 1;
+ while (len--) {
+ *p-- = hex[i & 0xf];
+ i >>= 4;
+ }
+}
+
+grn_rc
+grn_itoa(int i, char *p, char *end, char **rest)
+{
+ char *q;
+ if (p >= end) { return GRN_INVALID_ARGUMENT; }
+ q = p;
+ if (i < 0) {
+ *p++ = '-';
+ q = p;
+ if (i == INT_MIN) {
+ if (p >= end) { return GRN_INVALID_ARGUMENT; }
+ *p++ = (-(i % 10)) + '0';
+ i /= 10;
+ }
+ i = -i;
+ }
+ do {
+ if (p >= end) { return GRN_INVALID_ARGUMENT; }
+ *p++ = i % 10 + '0';
+ } while ((i /= 10) > 0);
+ if (rest) { *rest = p; }
+ for (p--; q < p; q++, p--) {
+ char t = *q;
+ *q = *p;
+ *p = t;
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_itoa_padded(int i, char *p, char *end, char ch)
+{
+ char *q;
+ if (p >= end) { return GRN_INVALID_ARGUMENT; }
+ if (i < 0) {
+ *p++ = '-';
+ if (i == INT_MIN) {
+ if (p >= end) { return GRN_INVALID_ARGUMENT; }
+ *p++ = (-(i % 10)) + '0';
+ i /= 10;
+ }
+ i = -i;
+ }
+ q = end - 1;
+ do {
+ if (q < p) { return GRN_INVALID_ARGUMENT; }
+ *q-- = i % 10 + '0';
+ } while ((i /= 10) > 0);
+ while (q >= p) {
+ *q-- = ch;
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_lltoa(int64_t i, char *p, char *end, char **rest)
+{
+ char *q;
+ if (p >= end) { return GRN_INVALID_ARGUMENT; }
+ q = p;
+ if (i < 0) {
+ *p++ = '-';
+ q = p;
+ if (i == INT64_MIN) {
+ *p++ = (-(i % 10)) + '0';
+ i /= 10;
+ }
+ i = -i;
+ }
+ do {
+ if (p >= end) { return GRN_INVALID_ARGUMENT; }
+ *p++ = i % 10 + '0';
+ } while ((i /= 10) > 0);
+ if (rest) { *rest = p; }
+ for (p--; q < p; q++, p--) {
+ char t = *q;
+ *q = *p;
+ *p = t;
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_ulltoa(uint64_t i, char *p, char *end, char **rest)
+{
+ char *q;
+ if (p >= end) { return GRN_INVALID_ARGUMENT; }
+ q = p;
+ do {
+ if (p >= end) { return GRN_INVALID_ARGUMENT; }
+ *p++ = i % 10 + '0';
+ } while ((i /= 10) > 0);
+ if (rest) { *rest = p; }
+ for (p--; q < p; q++, p--) {
+ char t = *q;
+ *q = *p;
+ *p = t;
+ }
+ return GRN_SUCCESS;
+}
+
+#define I2B(i) \
+ ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(i) & 0x3f])
+
+#define B2I(b) \
+ (((b) < '+' || 'z' < (b)) ? 0xff : "\x3e\xff\xff\xff\x3f\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\xff\xff\xff\xff\xff\xff\xff\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\xff\xff\xff\xff\xff\xff\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33"[(b) - '+'])
+
+#define MASK 0x34d34d34
+
+char *
+grn_itob(grn_id id, char *p)
+{
+ id ^= MASK;
+ *p++ = I2B(id >> 24);
+ *p++ = I2B(id >> 18);
+ *p++ = I2B(id >> 12);
+ *p++ = I2B(id >> 6);
+ *p++ = I2B(id);
+ return p;
+}
+
+grn_id
+grn_btoi(char *b)
+{
+ uint8_t i;
+ grn_id id = 0;
+ int len = 5;
+ while (len--) {
+ char c = *b++;
+ if ((i = B2I(c)) == 0xff) { return 0; }
+ id = (id << 6) + i;
+ }
+ return id ^ MASK;
+}
+
+#define I2B32H(i) ("0123456789ABCDEFGHIJKLMNOPQRSTUV"[(i) & 0x1f])
+
+char *
+grn_lltob32h(int64_t i, char *p)
+{
+ uint64_t u = (uint64_t)i + 0x8000000000000000ULL;
+ *p++ = I2B32H(u >> 60);
+ *p++ = I2B32H(u >> 55);
+ *p++ = I2B32H(u >> 50);
+ *p++ = I2B32H(u >> 45);
+ *p++ = I2B32H(u >> 40);
+ *p++ = I2B32H(u >> 35);
+ *p++ = I2B32H(u >> 30);
+ *p++ = I2B32H(u >> 25);
+ *p++ = I2B32H(u >> 20);
+ *p++ = I2B32H(u >> 15);
+ *p++ = I2B32H(u >> 10);
+ *p++ = I2B32H(u >> 5);
+ *p++ = I2B32H(u);
+ return p;
+}
+
+char *
+grn_ulltob32h(uint64_t i, char *p)
+{
+ char lb = (i >> 59) & 0x10;
+ i += 0x8000000000000000ULL;
+ *p++ = lb + I2B32H(i >> 60);
+ *p++ = I2B32H(i >> 55);
+ *p++ = I2B32H(i >> 50);
+ *p++ = I2B32H(i >> 45);
+ *p++ = I2B32H(i >> 40);
+ *p++ = I2B32H(i >> 35);
+ *p++ = I2B32H(i >> 30);
+ *p++ = I2B32H(i >> 25);
+ *p++ = I2B32H(i >> 20);
+ *p++ = I2B32H(i >> 15);
+ *p++ = I2B32H(i >> 10);
+ *p++ = I2B32H(i >> 5);
+ *p++ = I2B32H(i);
+ return p;
+}
+
+grn_rc
+grn_aton(grn_ctx *ctx, const char *p, const char *end, const char **rest,
+ grn_obj *res)
+{
+ if (*p == '+') {
+ p++;
+ }
+
+ switch (*p) {
+ case '-' :
+ case '0' : case '1' : case '2' : case '3' : case '4' :
+ case '5' : case '6' : case '7' : case '8' : case '9' :
+ {
+ int64_t int64;
+ char rest_char;
+ int64 = grn_atoll(p, end, rest);
+ rest_char = **rest;
+ if (end == *rest) {
+ if ((int64_t)INT32_MIN <= int64 && int64 <= (int64_t)INT32_MAX) {
+ grn_obj_reinit(ctx, res, GRN_DB_INT32, 0);
+ GRN_INT32_SET(ctx, res, int64);
+ } else if ((int64_t)INT32_MAX < int64 && int64 <= (int64_t)UINT32_MAX) {
+ grn_obj_reinit(ctx, res, GRN_DB_UINT32, 0);
+ GRN_UINT32_SET(ctx, res, int64);
+ } else {
+ grn_obj_reinit(ctx, res, GRN_DB_INT64, 0);
+ GRN_INT64_SET(ctx, res, int64);
+ }
+ } 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;
+ }
+
+ return GRN_SUCCESS;
+}
+
+int
+grn_str_tok(const char *str, size_t str_len, char delim, 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;
+ for (;;str++) {
+ if (str == str_end) {
+ *tok++ = str;
+ break;
+ }
+ if (delim == *str) {
+ // *str = '\0';
+ *tok++ = str;
+ if (tok == tok_end) { break; }
+ }
+ }
+ }
+ if (rest) { *rest = str; }
+ return tok - tokbuf;
+}
+
+inline static int
+op_getopt_flag(int *flags, const grn_str_getopt_opt *o,
+ int argc, char * const argv[], int i, const char *optvalue)
+{
+ switch (o->op) {
+ case GETOPT_OP_NONE:
+ break;
+ case GETOPT_OP_ON:
+ *flags |= o->flag;
+ break;
+ case GETOPT_OP_OFF:
+ *flags &= ~o->flag;
+ break;
+ case GETOPT_OP_UPDATE:
+ *flags = o->flag;
+ break;
+ default:
+ return i;
+ }
+ if (o->arg) {
+ if (optvalue) {
+ *o->arg = (char *)optvalue;
+ } else if (++i < argc) {
+ *o->arg = argv[i];
+ } else {
+ return -1;
+ }
+ }
+ return i;
+}
+
+int
+grn_str_getopt(int argc, char * const argv[], const grn_str_getopt_opt *opts,
+ int *flags)
+{
+ int i;
+ for (i = 1; i < argc; i++) {
+ const char * v = argv[i];
+ if (*v == '-') {
+ const grn_str_getopt_opt *o;
+ int found;
+ if (*++v == '-') {
+ const char *eq;
+ size_t len;
+ found = 0;
+ v++;
+ for (eq = v; *eq != '\0' && *eq != '='; eq++) {}
+ len = eq - v;
+ for (o = opts; o->opt != '\0' || o->longopt != NULL; o++) {
+ if (o->longopt && strlen(o->longopt) == len &&
+ !memcmp(v, o->longopt, len)) {
+ i = op_getopt_flag(flags, o, argc, argv, i,
+ (*eq == '\0' ? NULL : eq + 1));
+ if (i < 0) {
+ fprintf(stderr, "%s: option '--%s' needs argument.\n", argv[0], o->longopt);
+ return -1;
+ }
+ found = 1;
+ break;
+ }
+ }
+ if (!found) { goto exit; }
+ } else {
+ const char *p;
+ for (p = v; *p; p++) {
+ found = 0;
+ for (o = opts; o->opt != '\0' || o->longopt != NULL; o++) {
+ if (o->opt && *p == o->opt) {
+ i = op_getopt_flag(flags, o, argc, argv, i, NULL);
+ if (i < 0) {
+ fprintf(stderr, "%s: option '-%c' needs argument.\n", argv[0], *p);
+ return -1;
+ }
+ found = 1;
+ break;
+ }
+ }
+ if (!found) { goto exit; }
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ return i;
+exit:
+ fprintf(stderr, "%s: cannot recognize option '%s'.\n", argv[0], argv[i]);
+ return -1;
+}
+
+#define UNIT_SIZE (1 << 12)
+#define UNIT_MASK (UNIT_SIZE - 1)
+
+int grn_bulk_margin_size = 0;
+
+grn_rc
+grn_bulk_resize(grn_ctx *ctx, grn_obj *buf, unsigned int newsize)
+{
+ char *head;
+ unsigned int rounded_newsize;
+ newsize += grn_bulk_margin_size + 1;
+ if (GRN_BULK_OUTP(buf)) {
+ rounded_newsize = (newsize + (UNIT_MASK)) & ~UNIT_MASK;
+ if (rounded_newsize < newsize) { return GRN_NOT_ENOUGH_SPACE; }
+ newsize = rounded_newsize;
+ head = buf->u.b.head - (buf->u.b.head ? grn_bulk_margin_size : 0);
+ if (!(head = GRN_REALLOC(head, newsize))) { return GRN_NO_MEMORY_AVAILABLE; }
+ buf->u.b.curr = head + grn_bulk_margin_size + GRN_BULK_VSIZE(buf);
+ buf->u.b.head = head + grn_bulk_margin_size;
+ buf->u.b.tail = head + newsize;
+ } else {
+ if (newsize > GRN_BULK_BUFSIZE) {
+ rounded_newsize = (newsize + (UNIT_MASK)) & ~UNIT_MASK;
+ if (rounded_newsize < newsize) { return GRN_NOT_ENOUGH_SPACE; }
+ newsize = rounded_newsize;
+ if (!(head = GRN_MALLOC(newsize))) { return GRN_NO_MEMORY_AVAILABLE; }
+ grn_memcpy(head, GRN_BULK_HEAD(buf), GRN_BULK_VSIZE(buf));
+ buf->u.b.curr = head + grn_bulk_margin_size + GRN_BULK_VSIZE(buf);
+ buf->u.b.head = head + grn_bulk_margin_size;
+ buf->u.b.tail = head + newsize;
+ buf->header.impl_flags |= GRN_OBJ_OUTPLACE;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_bulk_reinit(grn_ctx *ctx, grn_obj *buf, unsigned int size)
+{
+ GRN_BULK_REWIND(buf);
+ return grn_bulk_resize(ctx, buf, size);
+}
+
+grn_rc
+grn_bulk_write(grn_ctx *ctx, grn_obj *buf, const char *str, unsigned int len)
+{
+ grn_rc rc = GRN_SUCCESS;
+ char *curr;
+ if (GRN_BULK_REST(buf) < len) {
+ if ((rc = grn_bulk_resize(ctx, buf, GRN_BULK_VSIZE(buf) + len))) { return rc; }
+ }
+ curr = GRN_BULK_CURR(buf);
+ if (str)
+ grn_memcpy(curr, str, len);
+ GRN_BULK_INCR_LEN(buf, len);
+ return rc;
+}
+
+grn_rc
+grn_bulk_write_from(grn_ctx *ctx, grn_obj *bulk,
+ const char *str, unsigned int from, unsigned int len)
+{
+ grn_rc rc = grn_bulk_truncate(ctx, bulk, from);
+ if (!rc) { rc = grn_bulk_write(ctx, bulk, str, len); }
+ return rc;
+}
+
+grn_rc
+grn_bulk_reserve(grn_ctx *ctx, grn_obj *buf, unsigned int len)
+{
+ grn_rc rc = GRN_SUCCESS;
+ if (GRN_BULK_REST(buf) < len) {
+ if ((rc = grn_bulk_resize(ctx, buf, GRN_BULK_VSIZE(buf) + len))) { return rc; }
+ }
+ return rc;
+}
+
+grn_rc
+grn_bulk_space(grn_ctx *ctx, grn_obj *buf, unsigned int len)
+{
+ grn_rc rc = grn_bulk_reserve(ctx, buf, len);
+ if (!rc) {
+ GRN_BULK_INCR_LEN(buf, len);
+ }
+ return rc;
+}
+
+static grn_rc
+grn_bulk_space_clear(grn_ctx *ctx, grn_obj *buf, unsigned int len)
+{
+ grn_rc rc = grn_bulk_reserve(ctx, buf, len);
+ if (!rc) {
+ memset(GRN_BULK_CURR(buf), 0, len);
+ GRN_BULK_INCR_LEN(buf, len);
+ }
+ return rc;
+}
+
+grn_rc
+grn_bulk_truncate(grn_ctx *ctx, grn_obj *bulk, unsigned int len)
+{
+ if (GRN_BULK_OUTP(bulk)) {
+ if ((bulk->u.b.tail - bulk->u.b.head) < len) {
+ return grn_bulk_space_clear(ctx, bulk, len);
+ } else {
+ bulk->u.b.curr = bulk->u.b.head + len;
+ }
+ } else {
+ if (GRN_BULK_BUFSIZE < len) {
+ return grn_bulk_space_clear(ctx, bulk, len);
+ } else {
+ bulk->header.flags &= ~GRN_BULK_BUFSIZE_MAX;
+ bulk->header.flags += len;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_text_itoa(grn_ctx *ctx, grn_obj *buf, int i)
+{
+ grn_rc rc = GRN_SUCCESS;
+ for (;;) {
+ char *curr = GRN_BULK_CURR(buf);
+ char *tail = GRN_BULK_TAIL(buf);
+ if (grn_itoa(i, curr, tail, &curr)) {
+ if ((rc = grn_bulk_resize(ctx, buf, GRN_BULK_WSIZE(buf) + UNIT_SIZE))) { return rc; }
+ } else {
+ GRN_BULK_SET_CURR(buf, curr);
+ break;
+ }
+ }
+ return rc;
+}
+
+grn_rc
+grn_text_itoa_padded(grn_ctx *ctx, grn_obj *buf, int i, char ch, unsigned int len)
+{
+ grn_rc rc = GRN_SUCCESS;
+ char *curr;
+ if ((rc = grn_bulk_reserve(ctx, buf, len))) { return rc; }
+ curr = GRN_BULK_CURR(buf);
+ if (!grn_itoa_padded(i, curr, curr + len, ch)) {
+ GRN_BULK_SET_CURR(buf, curr + len);
+ }
+ return rc;
+}
+
+grn_rc
+grn_text_lltoa(grn_ctx *ctx, grn_obj *buf, long long int i)
+{
+ grn_rc rc = GRN_SUCCESS;
+ for (;;) {
+ char *curr = GRN_BULK_CURR(buf);
+ char *tail = GRN_BULK_TAIL(buf);
+ if (grn_lltoa(i, curr, tail, &curr)) {
+ if ((rc = grn_bulk_resize(ctx, buf, GRN_BULK_WSIZE(buf) + UNIT_SIZE))) { return rc; }
+ } else {
+ GRN_BULK_SET_CURR(buf, curr);
+ break;
+ }
+ }
+ return rc;
+}
+
+grn_rc
+grn_text_ulltoa(grn_ctx *ctx, grn_obj *buf, unsigned long long int i)
+{
+ grn_rc rc = GRN_SUCCESS;
+ for (;;) {
+ char *curr = GRN_BULK_CURR(buf);
+ char *tail = GRN_BULK_TAIL(buf);
+ if (grn_ulltoa(i, curr, tail, &curr)) {
+ if ((rc = grn_bulk_resize(ctx, buf, GRN_BULK_WSIZE(buf) + UNIT_SIZE))) { return rc; }
+ } else {
+ GRN_BULK_SET_CURR(buf, curr);
+ break;
+ }
+ }
+ return rc;
+}
+
+inline static void
+ftoa_(grn_ctx *ctx, grn_obj *buf, double d)
+{
+ char *start;
+ size_t before_size;
+ size_t len;
+#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);
+ grn_text_printf(ctx, buf, "%#.*g", DIGIT_NUMBER, d);
+ len = GRN_BULK_VSIZE(buf) - before_size;
+ start = GRN_BULK_CURR(buf) - len;
+#undef FIRST_BUFFER_SIZE
+#undef DIGIT_NUMBER
+ if (start[len - 1] == '.') {
+ GRN_TEXT_PUTC(ctx, buf, '0');
+ } else {
+ char *p, *q;
+ start[len] = '\0';
+ if ((p = strchr(start, 'e'))) {
+ for (q = p; *(q - 2) != '.' && *(q - 1) == '0'; q--) { len--; }
+ grn_memmove(q, p, start + len - q);
+ } else {
+ for (q = start + len; *(q - 2) != '.' && *(q - 1) == '0'; q--) { len--; }
+ }
+ grn_bulk_truncate(ctx, buf, before_size + len);
+ }
+}
+
+grn_rc
+grn_text_ftoa(grn_ctx *ctx, grn_obj *buf, double d)
+{
+ grn_rc rc = GRN_SUCCESS;
+ if (GRN_BULK_REST(buf) < 32) {
+ if ((rc = grn_bulk_resize(ctx, buf, GRN_BULK_VSIZE(buf) + 32))) { return rc; }
+ }
+#ifdef HAVE_FPCLASSIFY
+ switch (fpclassify(d)) {
+ case FP_NAN :
+ GRN_TEXT_PUTS(ctx, buf, "#<nan>");
+ break;
+ case FP_INFINITE :
+ GRN_TEXT_PUTS(ctx, buf, d > 0 ? "#i1/0" : "#i-1/0");
+ break;
+ default :
+ ftoa_(ctx, buf, d);
+ break;
+ }
+#else /* HAVE_FPCLASSIFY */
+ if (d == d) {
+ if (d != 0 && ((d / 2.0) == d)) {
+ GRN_TEXT_PUTS(ctx, buf, d > 0 ? "#i1/0" : "#i-1/0");
+ } else {
+ ftoa_(ctx, buf, d);
+ }
+ } else {
+ GRN_TEXT_PUTS(ctx, buf, "#<nan>");
+ }
+#endif /* HAVE_FPCLASSIFY */
+ return rc;
+}
+
+grn_rc
+grn_text_itoh(grn_ctx *ctx, grn_obj *buf, int i, unsigned int len)
+{
+ grn_rc rc = GRN_SUCCESS;
+ if (GRN_BULK_REST(buf) < len) {
+ if ((rc = grn_bulk_resize(ctx, buf, GRN_BULK_VSIZE(buf) + len))) { return rc; }
+ }
+ grn_itoh(i, GRN_BULK_CURR(buf), len);
+ GRN_BULK_INCR_LEN(buf, len);
+ return rc;
+}
+
+grn_rc
+grn_text_itob(grn_ctx *ctx, grn_obj *buf, grn_id id)
+{
+ size_t len = 5;
+ grn_rc rc = GRN_SUCCESS;
+ if (GRN_BULK_REST(buf) < len) {
+ if ((rc = grn_bulk_resize(ctx, buf, GRN_BULK_VSIZE(buf) + len))) { return rc; }
+ }
+ grn_itob(id, GRN_BULK_CURR(buf));
+ GRN_BULK_INCR_LEN(buf, len);
+ return rc;
+}
+
+grn_rc
+grn_text_lltob32h(grn_ctx *ctx, grn_obj *buf, long long int i)
+{
+ size_t len = 13;
+ grn_rc rc = GRN_SUCCESS;
+ if (GRN_BULK_REST(buf) < len) {
+ if ((rc = grn_bulk_resize(ctx, buf, GRN_BULK_VSIZE(buf) + len))) { return rc; }
+ }
+ grn_lltob32h(i, GRN_BULK_CURR(buf));
+ GRN_BULK_INCR_LEN(buf, len);
+ return rc;
+}
+
+grn_rc
+grn_text_esc(grn_ctx *ctx, grn_obj *buf, const char *s, unsigned int len)
+{
+ const char *e;
+ unsigned int l;
+ grn_rc rc = GRN_SUCCESS;
+
+ GRN_TEXT_PUTC(ctx, buf, '"');
+ for (e = s + len; s < e; s += l) {
+ if (!(l = grn_charlen(ctx, s, e))) { break; }
+ if (l == 1) {
+ switch (*s) {
+ case '"' :
+ grn_bulk_write(ctx, buf, "\\\"", 2);
+ break;
+ case '\\' :
+ grn_bulk_write(ctx, buf, "\\\\", 2);
+ break;
+ case '\b' :
+ grn_bulk_write(ctx, buf, "\\b", 2);
+ break;
+ case '\f' :
+ grn_bulk_write(ctx, buf, "\\f", 2);
+ break;
+ case '\n' :
+ grn_bulk_write(ctx, buf, "\\n", 2);
+ break;
+ case '\r' :
+ grn_bulk_write(ctx, buf, "\\r", 2);
+ break;
+ case '\t' :
+ grn_bulk_write(ctx, buf, "\\t", 2);
+ break;
+ case '\x00': case '\x01': case '\x02': case '\x03': case '\x04': case '\x05':
+ case '\x06': case '\x07': case '\x0b': case '\x0e': case '\x0f': case '\x10':
+ case '\x11': case '\x12': case '\x13': case '\x14': case '\x15': case '\x16':
+ case '\x17': case '\x18': case '\x19': case '\x1a': case '\x1b': case '\x1c':
+ case '\x1d': case '\x1e': case '\x1f': case '\x7f':
+ if (!(rc = grn_bulk_write(ctx, buf, "\\u", 2))) {
+ if ((rc = grn_text_itoh(ctx, buf, *s, 4))) {
+ GRN_BULK_INCR_LEN(buf, -2);
+ return rc;
+ }
+ } else {
+ return rc;
+ }
+ break;
+ default :
+ GRN_TEXT_PUTC(ctx, buf, *s);
+ }
+ } else if (l == 3) {
+ if (*s == '\xe2' && *(s + 1) == '\x80') {
+ switch (*(s + 2)) {
+ case '\xa8': /* \u2028 */
+ grn_bulk_write(ctx, buf, "\\u2028", 6);
+ break;
+ case '\xa9': /* \u2029 */
+ grn_bulk_write(ctx, buf, "\\u2029", 6);
+ break;
+ default:
+ grn_bulk_write(ctx, buf, s, l);
+ }
+ } else {
+ grn_bulk_write(ctx, buf, s, l);
+ }
+ } else {
+ grn_bulk_write(ctx, buf, s, l);
+ }
+ }
+ GRN_TEXT_PUTC(ctx, buf, '"');
+ return rc;
+}
+
+grn_rc
+grn_text_escape_xml(grn_ctx *ctx, grn_obj *buf, const char *s, unsigned int len)
+{
+ const char *e;
+ unsigned int l;
+ grn_rc rc = GRN_SUCCESS;
+
+ for (e = s + len; s < e; s += l) {
+ if (!(l = grn_charlen(ctx, s, e))) { break; }
+ if (l == 1) {
+ switch (*s) {
+ case '"' :
+ grn_bulk_write(ctx, buf, "&quot;", 6);
+ break;
+ case '<' :
+ grn_bulk_write(ctx, buf, "&lt;", 4);
+ break;
+ case '>' :
+ grn_bulk_write(ctx, buf, "&gt;", 4);
+ break;
+ case '&' :
+ grn_bulk_write(ctx, buf, "&amp;", 5);
+ break;
+ default :
+ GRN_TEXT_PUTC(ctx, buf, *s);
+ }
+ } else {
+ grn_bulk_write(ctx, buf, s, l);
+ }
+ }
+ return rc;
+}
+
+#define TOK_ESC (0x80)
+
+const char *
+grn_text_unesc_tok(grn_ctx *ctx, grn_obj *buf, const char *s, const char *e, char *tok_type)
+{
+ const char *p;
+ unsigned int len;
+ uint8_t stat = GRN_TOK_VOID;
+ for (p = s; p < e; p += len) {
+ if (!(len = grn_charlen(ctx, p, e))) {
+ p = e;
+ stat &= ~TOK_ESC;
+ goto exit;
+ }
+ switch (stat) {
+ case GRN_TOK_VOID :
+ if (*p == ' ') { continue; }
+ switch (*p) {
+ case '"' :
+ stat = GRN_TOK_STRING;
+ break;
+ case '\'' :
+ stat = GRN_TOK_QUOTE;
+ break;
+ case ')' :
+ case '(' :
+ GRN_TEXT_PUT(ctx, buf, p, len);
+ p += len;
+ stat = GRN_TOK_SYMBOL;
+ goto exit;
+ case '\\' :
+ stat = GRN_TOK_SYMBOL|TOK_ESC;
+ break;
+ default :
+ stat = GRN_TOK_SYMBOL;
+ GRN_TEXT_PUT(ctx, buf, p, len);
+ break;
+ }
+ break;
+ case GRN_TOK_SYMBOL :
+ if (*p == ' ') { goto exit; }
+ switch (*p) {
+ case '\'' :
+ case '"' :
+ case ')' :
+ case '(' :
+ goto exit;
+ case '\\' :
+ stat |= TOK_ESC;
+ break;
+ default :
+ GRN_TEXT_PUT(ctx, buf, p, len);
+ break;
+ }
+ break;
+ case GRN_TOK_STRING :
+ switch (*p) {
+ case '"' :
+ p += len;
+ goto exit;
+ case '\\' :
+ stat |= TOK_ESC;
+ break;
+ default :
+ GRN_TEXT_PUT(ctx, buf, p, len);
+ break;
+ }
+ break;
+ case GRN_TOK_QUOTE :
+ switch (*p) {
+ case '\'' :
+ p += len;
+ goto exit;
+ case '\\' :
+ stat |= TOK_ESC;
+ break;
+ default :
+ GRN_TEXT_PUT(ctx, buf, p, len);
+ break;
+ }
+ break;
+ case GRN_TOK_SYMBOL|TOK_ESC :
+ case GRN_TOK_STRING|TOK_ESC :
+ case GRN_TOK_QUOTE|TOK_ESC :
+ switch (*p) {
+ case 'b' :
+ GRN_TEXT_PUTC(ctx, buf, '\b');
+ break;
+ case 'f' :
+ GRN_TEXT_PUTC(ctx, buf, '\f');
+ break;
+ case 'n' :
+ GRN_TEXT_PUTC(ctx, buf, '\n');
+ break;
+ case 'r' :
+ GRN_TEXT_PUTC(ctx, buf, '\r');
+ break;
+ case 't' :
+ GRN_TEXT_PUTC(ctx, buf, '\t');
+ break;
+ default :
+ GRN_TEXT_PUT(ctx, buf, p, len);
+ break;
+ }
+ stat &= ~TOK_ESC;
+ break;
+ }
+ }
+exit :
+ *tok_type = stat;
+ return p;
+}
+
+grn_rc
+grn_text_benc(grn_ctx *ctx, grn_obj *buf, unsigned int v)
+{
+ grn_rc rc = GRN_SUCCESS;
+ uint8_t *p;
+ if (GRN_BULK_REST(buf) < 5) {
+ if ((rc = grn_bulk_resize(ctx, buf, GRN_BULK_VSIZE(buf) + 5))) { return rc; }
+ }
+ p = (uint8_t *)GRN_BULK_CURR(buf);
+ GRN_B_ENC(v, p);
+ GRN_BULK_SET_CURR(buf, (char *)p);
+ return rc;
+}
+
+/* 0x00 - 0x7f */
+static const int_least8_t urlenc_tbl[] = {
+ 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, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1
+};
+
+grn_rc
+grn_text_urlenc(grn_ctx *ctx, grn_obj *buf, const char *s, unsigned int len)
+{
+ const char *e, c = '%';
+ for (e = s + len; s < e; s++) {
+ if ((signed char)*s < 0 || urlenc_tbl[(int)*s]) {
+ if (!grn_bulk_write(ctx, buf, &c, 1)) {
+ if (grn_text_itoh(ctx, buf, *s, 2)) {
+ GRN_BULK_INCR_LEN(buf, -1);
+ }
+ }
+ } else {
+ GRN_TEXT_PUTC(ctx, buf, *s);
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+static const char *weekdays[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
+static const char *months[12] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+grn_rc
+grn_text_time2rfc1123(grn_ctx *ctx, grn_obj *bulk, int sec)
+{
+ time_t tsec;
+ struct tm *t;
+#ifdef HAVE__GMTIME64_S
+ struct tm tm;
+ tsec = (time_t)sec;
+ t = (gmtime_s(&tm, &tsec) == 0) ? &tm : NULL;
+#else /* HAVE__GMTIME64_S */
+# ifdef HAVE_GMTIME_R
+ struct tm tm;
+ tsec = (time_t)sec;
+ t = gmtime_r(&tsec, &tm);
+# else /* HAVE_GMTIME_R */
+ tsec = (time_t)sec;
+ t = gmtime(&tsec);
+# endif /* HAVE_GMTIME_R */
+#endif /* HAVE__GMTIME64_S */
+ if (t) {
+ GRN_TEXT_SET(ctx, bulk, weekdays[t->tm_wday], 3);
+ GRN_TEXT_PUTS(ctx, bulk, ", ");
+ grn_text_itoa_padded(ctx, bulk, t->tm_mday, '0', 2);
+ GRN_TEXT_PUTS(ctx, bulk, " ");
+ GRN_TEXT_PUT(ctx, bulk, months[t->tm_mon], 3);
+ GRN_TEXT_PUTS(ctx, bulk, " ");
+ grn_text_itoa(ctx, bulk, t->tm_year + 1900);
+ GRN_TEXT_PUTS(ctx, bulk, " ");
+ grn_text_itoa_padded(ctx, bulk, t->tm_hour, '0', 2);
+ GRN_TEXT_PUTS(ctx, bulk, ":");
+ grn_text_itoa_padded(ctx, bulk, t->tm_min, '0', 2);
+ GRN_TEXT_PUTS(ctx, bulk, ":");
+ grn_text_itoa_padded(ctx, bulk, t->tm_sec, '0', 2);
+ GRN_TEXT_PUTS(ctx, bulk, " GMT");
+ } else {
+ GRN_TEXT_SETS(ctx, bulk, "Mon, 16 Mar 1980 20:40:00 GMT");
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_text_printf(grn_ctx *ctx, grn_obj *bulk, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ grn_text_vprintf(ctx, bulk, format, args);
+ va_end(args);
+
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_text_vprintf(grn_ctx *ctx, grn_obj *bulk, const char *format, va_list args)
+{
+ grn_bool is_written = GRN_FALSE;
+ int written_size;
+
+ {
+ int rest_size;
+ va_list copied_args;
+
+ rest_size = GRN_BULK_REST(bulk);
+ va_copy(copied_args, args);
+ written_size = vsnprintf(GRN_BULK_CURR(bulk), rest_size,
+ format, copied_args);
+ va_end(copied_args);
+
+ if (0 <= written_size && written_size < rest_size) {
+ is_written = GRN_TRUE;
+ }
+ }
+
+ if (!is_written) {
+#ifdef WIN32
+# define N_NEW_SIZES 3
+ int i;
+ int new_sizes[N_NEW_SIZES];
+
+ new_sizes[0] = GRN_BULK_REST(bulk) + strlen(format) * 2;
+ new_sizes[1] = new_sizes[0] + 4096;
+ new_sizes[2] = new_sizes[0] + 65536;
+
+ for (i = 0; i < N_NEW_SIZES; i++) {
+ grn_rc rc;
+ int new_size = new_sizes[i];
+ va_list copied_args;
+
+ rc = grn_bulk_reserve(ctx, bulk, GRN_BULK_VSIZE(bulk) + new_size);
+ if (rc) {
+ return rc;
+ }
+ va_copy(copied_args, args);
+ written_size = vsnprintf(GRN_BULK_CURR(bulk), new_size,
+ format, copied_args);
+ va_end(copied_args);
+ if (written_size != -1) {
+ break;
+ }
+ }
+# undef N_NEW_SIZES
+#else /* WIN32 */
+ grn_rc rc;
+ int required_size = written_size + 1; /* "+ 1" for terminate '\0'. */
+
+ rc = grn_bulk_reserve(ctx, bulk, GRN_BULK_VSIZE(bulk) + required_size);
+ if (rc) {
+ return rc;
+ }
+ written_size = vsnprintf(GRN_BULK_CURR(bulk), required_size,
+ format, args);
+#endif /* WIN32 */
+ }
+
+ if (written_size < 0) {
+ return GRN_INVALID_ARGUMENT;
+ }
+
+ GRN_BULK_INCR_LEN(bulk, written_size);
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_bulk_fin(grn_ctx *ctx, grn_obj *buf)
+{
+ if (!(buf->header.impl_flags & GRN_OBJ_REFER)) {
+ if (GRN_BULK_OUTP(buf) && buf->u.b.head) {
+ GRN_REALLOC(buf->u.b.head - grn_bulk_margin_size, 0);
+ }
+ }
+ buf->header.flags = 0;
+ buf->header.impl_flags &= ~GRN_OBJ_DO_SHALLOW_COPY;
+ buf->u.b.head = NULL;
+ buf->u.b.curr = NULL;
+ buf->u.b.tail = NULL;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_substring(grn_ctx *ctx, char **str, char **str_end, int start, int end, grn_encoding encoding)
+{
+ int i;
+ size_t l;
+ char *s = *str, *e = *str_end;
+ for (i = 0; s < e; i++, s += l) {
+ if (i == start) { *str = s; }
+ if (!(l = grn_charlen(ctx, s, e))) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ if (i == end) {
+ *str_end = s;
+ break;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+static void
+grn_text_atoj(grn_ctx *ctx, grn_obj *bulk, grn_obj *obj, grn_id id)
+{
+ uint32_t vs;
+ grn_obj buf;
+ if (obj->header.type == GRN_ACCESSOR) {
+ grn_accessor *a = (grn_accessor *)obj;
+ GRN_TEXT_INIT(&buf, 0);
+ for (;;) {
+ GRN_BULK_REWIND(&buf);
+ switch (a->action) {
+ case GRN_ACCESSOR_GET_ID :
+ GRN_UINT32_PUT(ctx, &buf, id);
+ buf.header.domain = GRN_DB_UINT32;
+ break;
+ case GRN_ACCESSOR_GET_KEY :
+ grn_table_get_key2(ctx, a->obj, id, &buf);
+ buf.header.domain = DB_OBJ(a->obj)->header.domain;
+ break;
+ case GRN_ACCESSOR_GET_VALUE :
+ grn_obj_get_value(ctx, a->obj, id, &buf);
+ buf.header.domain = GRN_DB_INT32; /* fix me */
+ 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);
+ }
+ buf.header.domain = GRN_DB_INT32;
+ break;
+ case GRN_ACCESSOR_GET_NSUBRECS :
+ {
+ grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs);
+ GRN_INT32_PUT(ctx, &buf, ri->n_subrecs);
+ }
+ buf.header.domain = GRN_DB_INT32;
+ break;
+ case GRN_ACCESSOR_GET_COLUMN_VALUE :
+ if ((a->obj->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) == GRN_OBJ_COLUMN_VECTOR) {
+ if (a->next) {
+ grn_id *idp;
+ grn_obj_get_value(ctx, a->obj, id, &buf);
+ idp = (grn_id *)GRN_BULK_HEAD(&buf);
+ GRN_TEXT_PUTC(ctx, bulk, '[');
+ for (vs = GRN_BULK_VSIZE(&buf) / sizeof(grn_id); vs--; idp++) {
+ grn_text_atoj(ctx, bulk, (grn_obj *)a->next, *idp);
+ if (vs) { GRN_TEXT_PUTC(ctx, bulk, ','); }
+ }
+ GRN_TEXT_PUTC(ctx, bulk, ']');
+ } else {
+ grn_text_atoj(ctx, bulk, a->obj, id);
+ }
+ goto exit;
+ } else {
+ grn_obj_get_value(ctx, a->obj, id, &buf);
+ }
+ break;
+ case GRN_ACCESSOR_GET_DB_OBJ :
+ /* todo */
+ break;
+ case GRN_ACCESSOR_LOOKUP :
+ /* todo */
+ break;
+ case GRN_ACCESSOR_FUNCALL :
+ /* todo */
+ break;
+ }
+ if (a->next) {
+ a = a->next;
+ id = *((grn_id *)GRN_BULK_HEAD(&buf));
+ } else {
+ break;
+ }
+ }
+ } else {
+ switch (obj->header.type) {
+ case GRN_COLUMN_FIX_SIZE :
+ GRN_VALUE_FIX_SIZE_INIT(&buf, 0, DB_OBJ(obj)->range);
+ break;
+ case GRN_COLUMN_VAR_SIZE :
+ if ((obj->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) == GRN_OBJ_COLUMN_VECTOR) {
+ grn_obj *range = grn_ctx_at(ctx, DB_OBJ(obj)->range);
+ if (range->header.flags & GRN_OBJ_KEY_VAR_SIZE) {
+ GRN_VALUE_VAR_SIZE_INIT(&buf, GRN_OBJ_VECTOR, DB_OBJ(obj)->range);
+ } else {
+ GRN_VALUE_FIX_SIZE_INIT(&buf, GRN_OBJ_VECTOR, DB_OBJ(obj)->range);
+ }
+ } else {
+ GRN_VALUE_VAR_SIZE_INIT(&buf, 0, DB_OBJ(obj)->range);
+ }
+ break;
+ case GRN_COLUMN_INDEX :
+ GRN_UINT32_INIT(&buf, 0);
+ break;
+ default:
+ GRN_TEXT_INIT(&buf, 0);
+ break;
+ }
+ grn_obj_get_value(ctx, obj, id, &buf);
+ }
+ grn_text_otoj(ctx, bulk, &buf, NULL);
+exit :
+ grn_obj_close(ctx, &buf);
+}
+
+grn_rc
+grn_text_otoj(grn_ctx *ctx, grn_obj *bulk, grn_obj *obj, grn_obj_format *format)
+{
+ grn_obj buf;
+ GRN_TEXT_INIT(&buf, 0);
+ switch (obj->header.type) {
+ case GRN_BULK :
+ switch (obj->header.domain) {
+ case GRN_DB_VOID :
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ grn_text_esc(ctx, bulk, GRN_BULK_HEAD(obj), GRN_BULK_VSIZE(obj));
+ break;
+ case GRN_DB_BOOL :
+ if (*((unsigned char *)GRN_BULK_HEAD(obj))) {
+ GRN_TEXT_PUTS(ctx, bulk, "true");
+ } else {
+ GRN_TEXT_PUTS(ctx, bulk, "false");
+ }
+ break;
+ case GRN_DB_INT8 :
+ grn_text_itoa(ctx, bulk, GRN_BULK_VSIZE(obj) ? GRN_INT8_VALUE(obj) : 0);
+ break;
+ case GRN_DB_UINT8 :
+ grn_text_lltoa(ctx, bulk, GRN_BULK_VSIZE(obj) ? GRN_UINT8_VALUE(obj) : 0);
+ break;
+ case GRN_DB_INT16 :
+ grn_text_itoa(ctx, bulk, GRN_BULK_VSIZE(obj) ? GRN_INT16_VALUE(obj) : 0);
+ break;
+ case GRN_DB_UINT16 :
+ grn_text_lltoa(ctx, bulk, GRN_BULK_VSIZE(obj) ? GRN_UINT16_VALUE(obj) : 0);
+ break;
+ case GRN_DB_INT32 :
+ grn_text_itoa(ctx, bulk, GRN_BULK_VSIZE(obj) ? GRN_INT32_VALUE(obj) : 0);
+ break;
+ case GRN_DB_UINT32 :
+ grn_text_lltoa(ctx, bulk, GRN_BULK_VSIZE(obj) ? GRN_UINT32_VALUE(obj) : 0);
+ break;
+ case GRN_DB_INT64 :
+ grn_text_lltoa(ctx, bulk, GRN_BULK_VSIZE(obj) ? GRN_INT64_VALUE(obj) : 0);
+ break;
+ case GRN_DB_UINT64 :
+ grn_text_ulltoa(ctx, bulk, GRN_BULK_VSIZE(obj) ? GRN_UINT64_VALUE(obj) : 0);
+ break;
+ case GRN_DB_FLOAT :
+ grn_text_ftoa(ctx, bulk, GRN_BULK_VSIZE(obj) ? GRN_FLOAT_VALUE(obj) : 0);
+ break;
+ case GRN_DB_TIME :
+ {
+ double dv = *((int64_t *)GRN_BULK_HEAD(obj));
+ dv /= 1000000.0;
+ grn_text_ftoa(ctx, bulk, dv);
+ }
+ break;
+ case GRN_DB_TOKYO_GEO_POINT :
+ case GRN_DB_WGS84_GEO_POINT :
+ if (GRN_BULK_VSIZE(obj) == sizeof(grn_geo_point)) {
+ grn_geo_point *gp = (grn_geo_point *)GRN_BULK_HEAD(obj);
+ GRN_TEXT_PUTC(ctx, bulk, '"');
+ grn_text_itoa(ctx, bulk, gp->latitude);
+ GRN_TEXT_PUTC(ctx, bulk, 'x');
+ grn_text_itoa(ctx, bulk, gp->longitude);
+ GRN_TEXT_PUTC(ctx, bulk, '"');
+ } else {
+ GRN_TEXT_PUTS(ctx, bulk, "\"\"");
+ }
+ break;
+ default :
+ if (format) {
+ int j;
+ int ncolumns = GRN_BULK_VSIZE(&format->columns)/sizeof(grn_obj *);
+ grn_id id = GRN_RECORD_VALUE(obj);
+ grn_obj **columns = (grn_obj **)GRN_BULK_HEAD(&format->columns);
+ 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_PUTS(ctx, bulk, "],");
+ }
+ GRN_TEXT_PUTC(ctx, bulk, '[');
+ for (j = 0; j < ncolumns; j++) {
+ if (j) { GRN_TEXT_PUTC(ctx, bulk, ','); }
+ grn_text_atoj(ctx, bulk, columns[j], id);
+ }
+ GRN_TEXT_PUTC(ctx, bulk, ']');
+ } else {
+ if (GRN_BULK_VSIZE(obj) == 0) {
+ GRN_TEXT_PUTS(ctx, bulk, "null");
+ } else {
+ grn_obj *table = grn_ctx_at(ctx, obj->header.domain);
+ grn_id id = GRN_RECORD_VALUE(obj);
+ if (table && table->header.type != GRN_TABLE_NO_KEY) {
+ /* todo : temporal patch. grn_table_at() is kinda costful... */
+ if (grn_table_at(ctx, table, id)) {
+ grn_obj *accessor = grn_obj_column(ctx, table,
+ GRN_COLUMN_NAME_KEY,
+ GRN_COLUMN_NAME_KEY_LEN);
+ if (accessor) {
+ grn_obj_get_value(ctx, accessor, id, &buf);
+ grn_obj_unlink(ctx, accessor);
+ }
+ }
+ grn_text_otoj(ctx, bulk, &buf, format);
+ } else {
+ grn_text_lltoa(ctx, bulk, id);
+ }
+ }
+ }
+ }
+ break;
+ case GRN_UVECTOR :
+ if (format) {
+ 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, ',');
+ }
+ 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 {
+ GRN_BULK_REWIND(&buf);
+ grn_table_get_key2(ctx, domain, id, &buf);
+ grn_text_otoj(ctx, bulk, &buf, NULL);
+ }
+ } else {
+ GRN_TEXT_PUTC(ctx, bulk, '"');
+ grn_text_ulltoa(ctx, bulk, id);
+ GRN_TEXT_PUTC(ctx, bulk, '"');
+ }
+ GRN_TEXT_PUTC(ctx, bulk, ':');
+ grn_text_ulltoa(ctx, bulk, weight);
+ }
+ 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, ']');
+ }
+ 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, ']');
+ }
+ } else {
+ grn_obj *range = grn_ctx_at(ctx, obj->header.domain);
+ if (range && range->header.type == GRN_TYPE) {
+ grn_id value_size = ((struct _grn_type *)range)->obj.range;
+ char *v = (char *)GRN_BULK_HEAD(obj),
+ *ve = (char *)GRN_BULK_CURR(obj);
+ GRN_TEXT_PUTC(ctx, bulk, '[');
+ if (v < ve) {
+ for (;;) {
+ grn_obj value;
+ GRN_OBJ_INIT(&value, GRN_BULK, 0, obj->header.domain);
+ grn_bulk_write_from(ctx, &value, v, 0, value_size);
+ grn_text_otoj(ctx, bulk, &value, NULL);
+
+ v += value_size;
+ if (v < ve) {
+ GRN_TEXT_PUTC(ctx, bulk, ',');
+ } else {
+ break;
+ }
+ }
+ }
+ GRN_TEXT_PUTC(ctx, bulk, ']');
+ } else {
+ grn_id *v = (grn_id *)GRN_BULK_HEAD(obj),
+ *ve = (grn_id *)GRN_BULK_CURR(obj);
+ GRN_TEXT_PUTC(ctx, bulk, '[');
+ if (v < ve) {
+ for (;;) {
+ if (range->header.type != GRN_TABLE_NO_KEY) {
+ grn_obj key;
+ GRN_OBJ_INIT(&key, GRN_BULK, 0, range->header.domain);
+ grn_table_get_key2(ctx, range, *v, &key);
+ grn_text_otoj(ctx, bulk, &key, NULL);
+ GRN_OBJ_FIN(ctx, &key);
+ } else {
+ grn_text_lltoa(ctx, bulk, *v);
+ }
+ v++;
+ if (v < ve) {
+ GRN_TEXT_PUTC(ctx, bulk, ',');
+ } else {
+ break;
+ }
+ }
+ }
+ GRN_TEXT_PUTC(ctx, bulk, ']');
+ }
+ }
+ break;
+ case GRN_VECTOR :
+ if (obj->header.domain == GRN_DB_VOID) {
+ ERR(GRN_INVALID_ARGUMENT, "invalid obj->header.domain");
+ } else {
+ unsigned int i, n;
+ grn_obj value;
+ grn_obj weight;
+ grn_bool with_weight;
+
+ GRN_VOID_INIT(&value);
+ GRN_UINT32_INIT(&weight, 0);
+ with_weight = (format && format->flags & GRN_OBJ_FORMAT_WITH_WEIGHT);
+ n = grn_vector_size(ctx, obj);
+ 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;
+ grn_id domain;
+ if (i) { GRN_TEXT_PUTC(ctx, bulk, ','); }
+
+ length = grn_vector_get_element(ctx, obj, i,
+ &_value, &_weight, &domain);
+ if (domain != GRN_DB_VOID) {
+ grn_obj_reinit(ctx, &value, domain, 0);
+ } else {
+ grn_obj_reinit(ctx, &value, obj->header.domain, 0);
+ }
+ 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);
+ }
+ }
+ if (with_weight) {
+ GRN_TEXT_PUTC(ctx, bulk, '}');
+ } else {
+ GRN_TEXT_PUTC(ctx, bulk, ']');
+ }
+ GRN_OBJ_FIN(ctx, &value);
+ GRN_OBJ_FIN(ctx, &weight);
+ }
+ break;
+ case GRN_PVECTOR :
+ if (format) {
+ ERR(GRN_FUNCTION_NOT_IMPLEMENTED,
+ "cannot print GRN_PVECTOR using grn_obj_format");
+ } else {
+ unsigned int i, n;
+ GRN_TEXT_PUTC(ctx, bulk, '[');
+ n = GRN_BULK_VSIZE(obj) / sizeof(grn_obj *);
+ for (i = 0; i < n; i++) {
+ grn_obj *value;
+
+ if (i) { GRN_TEXT_PUTC(ctx, bulk, ','); }
+ value = GRN_PTR_VALUE_AT(obj, i);
+ grn_text_otoj(ctx, bulk, value, NULL);
+ }
+ GRN_TEXT_PUTC(ctx, bulk, ']');
+ }
+ break;
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ if (format) {
+ int i, j;
+ int ncolumns = GRN_BULK_VSIZE(&format->columns)/sizeof(grn_obj *);
+ grn_obj **columns = (grn_obj **)GRN_BULK_HEAD(&format->columns);
+ grn_table_cursor *tc = grn_table_cursor_open(ctx, obj, NULL, 0, NULL, 0,
+ format->offset, format->limit,
+ GRN_CURSOR_ASCENDING);
+ if (!tc) { ERRCLR(ctx); }
+ GRN_TEXT_PUTS(ctx, bulk, "[[");
+ grn_text_itoa(ctx, bulk, format->nhits);
+ GRN_TEXT_PUTC(ctx, bulk, ']');
+ 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, ']');
+ }
+ if (tc) {
+ grn_id id;
+ for (i = 0; (id = grn_table_cursor_next(ctx, tc)) != GRN_ID_NIL; i++) {
+ GRN_TEXT_PUTS(ctx, bulk, ",[");
+ for (j = 0; j < ncolumns; j++) {
+ if (j) { GRN_TEXT_PUTC(ctx, bulk, ','); }
+ grn_text_atoj(ctx, bulk, columns[j], id);
+ }
+ GRN_TEXT_PUTC(ctx, bulk, ']');
+ }
+ grn_table_cursor_close(ctx, tc);
+ }
+ GRN_TEXT_PUTC(ctx, bulk, ']');
+ } else {
+ int i;
+ grn_id id;
+ grn_obj *column = grn_obj_column(ctx, obj,
+ GRN_COLUMN_NAME_KEY,
+ GRN_COLUMN_NAME_KEY_LEN);
+ grn_table_cursor *tc = grn_table_cursor_open(ctx, obj, NULL, 0, NULL, 0,
+ 0, -1, GRN_CURSOR_ASCENDING);
+ GRN_TEXT_PUTC(ctx, bulk, '[');
+ if (tc) {
+ for (i = 0; (id = grn_table_cursor_next(ctx, tc)) != GRN_ID_NIL; i++) {
+ if (i) { GRN_TEXT_PUTC(ctx, bulk, ','); }
+ GRN_BULK_REWIND(&buf);
+ grn_obj_get_value(ctx, column, id, &buf);
+ grn_text_esc(ctx, bulk, GRN_BULK_HEAD(&buf), GRN_BULK_VSIZE(&buf));
+ }
+ grn_table_cursor_close(ctx, tc);
+ }
+ GRN_TEXT_PUTC(ctx, bulk, ']');
+ grn_obj_unlink(ctx, column);
+ }
+ break;
+ }
+ grn_obj_close(ctx, &buf);
+ return GRN_SUCCESS;
+}
+
+const char *
+grn_text_urldec(grn_ctx *ctx, grn_obj *buf, const char *p, const char *e, char d)
+{
+ while (p < e) {
+ if (*p == d) {
+ p++; break;
+ } else if (*p == '%' && p + 3 <= e) {
+ const char *r;
+ unsigned int c = grn_htoui(p + 1, p + 3, &r);
+ if (p + 3 == r) {
+ GRN_TEXT_PUTC(ctx, buf, c);
+ p += 3;
+ } else {
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "invalid %% sequence (%c%c)", p[1], p[2]);
+ GRN_TEXT_PUTC(ctx, buf, '%');
+ p += 1;
+ }
+ } else {
+ GRN_TEXT_PUTC(ctx, buf, *p);
+ p++;
+ }
+ }
+ return p;
+}
+
+const char *
+grn_text_cgidec(grn_ctx *ctx, grn_obj *buf, const char *p, const char *e,
+ const char *delimiters)
+{
+ while (p < e) {
+ grn_bool found_delimiter = GRN_FALSE;
+ const char *delimiter;
+ for (delimiter = delimiters; *delimiter; delimiter++) {
+ if (*p == *delimiter) {
+ found_delimiter = GRN_TRUE;
+ break;
+ }
+ }
+ if (found_delimiter) {
+ p++;
+ break;
+ }
+
+ if (*p == '+') {
+ GRN_TEXT_PUTC(ctx, buf, ' ');
+ p++;
+ } else if (*p == '%' && p + 3 <= e) {
+ const char *r;
+ unsigned int c = grn_htoui(p + 1, p + 3, &r);
+ if (p + 3 == r) {
+ GRN_TEXT_PUTC(ctx, buf, c);
+ p += 3;
+ } else {
+ GRN_LOG(ctx, GRN_LOG_NOTICE, "invalid %% sequence (%c%c)", p[1], p[2]);
+ GRN_TEXT_PUTC(ctx, buf, '%');
+ p += 1;
+ }
+ } else {
+ GRN_TEXT_PUTC(ctx, buf, *p);
+ p++;
+ }
+ }
+ return p;
+}
+
+void
+grn_str_url_path_normalize(grn_ctx *ctx, const char *path, size_t path_len,
+ char *buf, size_t buf_len)
+{
+ char *b = buf, *be = buf + buf_len - 1;
+ const char *p = path, *pe = path + path_len, *pc;
+
+ if (buf_len < 2) { return; }
+
+ while (p < pe) {
+ for (pc = p; pc < pe && *pc != '/'; pc++) {}
+ if (*p == '.') {
+ if (pc == p + 2 && *(p + 1) == '.') {
+ /* '..' */
+ if (b - buf >= 2) {
+ for (b -= 2; *b != '/' && b >= buf; b--) {}
+ }
+ if (*b == '/') {
+ b++;
+ ERR(GRN_INVALID_ARGUMENT, "parent path doesn't exist.");
+ }
+ p = pc + 1;
+ continue;
+ } else if (pc == p + 1) {
+ /* '.' */
+ p = pc + 1;
+ continue;
+ }
+ }
+ if (be - b >= pc - p) {
+ grn_memcpy(b, p, (pc - p));
+ b += pc - p;
+ p = pc;
+ if (p < pe && *pc == '/' && be > b) {
+ *b++ = '/';
+ p++;
+ }
+ }
+ }
+ *b = '\0';
+}
+
+grn_bool
+grn_bulk_is_zero(grn_ctx *ctx, grn_obj *obj)
+{
+ const char *v = GRN_BULK_HEAD(obj);
+ unsigned int s = GRN_BULK_VSIZE(obj);
+ for (; s; s--, v++) {
+ if (*v) { return GRN_FALSE; }
+ }
+ return GRN_TRUE;
+}
+
diff --git a/storage/mroonga/vendor/groonga/lib/string.c b/storage/mroonga/vendor/groonga/lib/string.c
new file mode 100644
index 00000000..8e591100
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/string.c
@@ -0,0 +1,416 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2009-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-1335 USA
+*/
+
+#include "grn.h"
+#include <string.h>
+#include "grn_string.h"
+#include "grn_normalizer.h"
+#include "grn_str.h"
+#include "grn_util.h"
+
+#include <groonga/tokenizer.h>
+
+static grn_string *
+grn_fake_string_open(grn_ctx *ctx, grn_string *string)
+{
+ /* TODO: support GRN_STRING_REMOVE_BLANK flag and ctypes */
+ grn_string *nstr = string;
+ const char *str;
+ unsigned int str_len;
+
+ str = nstr->original;
+ str_len = nstr->original_length_in_bytes;
+
+ if (!(nstr->normalized = GRN_MALLOC(str_len + 1))) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[strinig][fake] failed to allocate normalized text space");
+ grn_string_close(ctx, (grn_obj *)nstr);
+ return NULL;
+ }
+
+ if (nstr->flags & GRN_STRING_REMOVE_TOKENIZED_DELIMITER &&
+ ctx->encoding == GRN_ENC_UTF8) {
+ int char_length;
+ const char *source_current = str;
+ const char *source_end = str + str_len;
+ char *destination = nstr->normalized;
+ unsigned int destination_length = 0;
+ while ((char_length = grn_charlen(ctx, source_current, source_end)) > 0) {
+ if (!grn_tokenizer_is_tokenized_delimiter(ctx,
+ source_current, char_length,
+ ctx->encoding)) {
+ grn_memcpy(destination, source_current, char_length);
+ destination += char_length;
+ destination_length += char_length;
+ }
+ source_current += char_length;
+ }
+ nstr->normalized[destination_length] = '\0';
+ nstr->normalized_length_in_bytes = destination_length;
+ } else {
+ grn_memcpy(nstr->normalized, str, str_len);
+ nstr->normalized[str_len] = '\0';
+ nstr->normalized_length_in_bytes = str_len;
+ }
+
+ if (nstr->flags & GRN_STRING_WITH_CHECKS) {
+ int16_t f = 0;
+ unsigned char c;
+ size_t i;
+ if (!(nstr->checks = (int16_t *) GRN_MALLOC(sizeof(int16_t) * str_len))) {
+ grn_string_close(ctx, (grn_obj *)nstr);
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[strinig][fake] failed to allocate checks space");
+ return NULL;
+ }
+ switch (nstr->encoding) {
+ case GRN_ENC_EUC_JP:
+ for (i = 0; i < str_len; i++) {
+ if (!f) {
+ c = (unsigned char) str[i];
+ f = ((c >= 0xa1U && c <= 0xfeU) || c == 0x8eU ? 2 : (c == 0x8fU ? 3 : 1)
+ );
+ nstr->checks[i] = f;
+ } else {
+ nstr->checks[i] = 0;
+ }
+ f--;
+ }
+ break;
+ case GRN_ENC_SJIS:
+ for (i = 0; i < str_len; i++) {
+ if (!f) {
+ c = (unsigned char) str[i];
+ f = (c >= 0x81U && ((c <= 0x9fU) || (c >= 0xe0U && c <= 0xfcU)) ? 2 : 1);
+ nstr->checks[i] = f;
+ } else {
+ nstr->checks[i] = 0;
+ }
+ f--;
+ }
+ break;
+ case GRN_ENC_UTF8:
+ for (i = 0; i < str_len; i++) {
+ if (!f) {
+ c = (unsigned char) str[i];
+ f = (c & 0x80U ? (c & 0x20U ? (c & 0x10U ? 4 : 3)
+ : 2)
+ : 1);
+ nstr->checks[i] = f;
+ } else {
+ nstr->checks[i] = 0;
+ }
+ f--;
+ }
+ break;
+ default:
+ for (i = 0; i < str_len; i++) {
+ nstr->checks[i] = 1;
+ }
+ break;
+ }
+ }
+ return nstr;
+}
+
+grn_obj *
+grn_string_open_(grn_ctx *ctx, const char *str, unsigned int str_len,
+ grn_obj *normalizer, int flags, grn_encoding encoding)
+{
+ grn_string *string;
+ grn_obj *obj;
+ grn_bool is_normalizer_auto;
+
+ if (!str || !str_len) {
+ return NULL;
+ }
+
+ is_normalizer_auto = (normalizer == GRN_NORMALIZER_AUTO);
+ if (is_normalizer_auto) {
+ normalizer = grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1);
+ if (!normalizer) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[string][open] NormalizerAuto normalizer isn't available");
+ return NULL;
+ }
+ }
+
+ string = GRN_MALLOCN(grn_string, 1);
+ if (!string) {
+ if (is_normalizer_auto) {
+ grn_obj_unlink(ctx, normalizer);
+ }
+ GRN_LOG(ctx, GRN_LOG_ALERT,
+ "[string][open] failed to allocate memory");
+ return NULL;
+ }
+
+ obj = (grn_obj *)string;
+ GRN_OBJ_INIT(obj, GRN_STRING, GRN_OBJ_ALLOCATED, GRN_ID_NIL);
+ string->original = str;
+ string->original_length_in_bytes = str_len;
+ string->normalized = NULL;
+ string->normalized_length_in_bytes = 0;
+ string->n_characters = 0;
+ string->checks = NULL;
+ string->ctypes = NULL;
+ string->encoding = encoding;
+ string->flags = flags;
+
+ if (!normalizer) {
+ return (grn_obj *)grn_fake_string_open(ctx, string);
+ }
+
+ grn_normalizer_normalize(ctx, normalizer, (grn_obj *)string);
+ if (ctx->rc) {
+ grn_obj_close(ctx, obj);
+ obj = NULL;
+ }
+
+ if (is_normalizer_auto) {
+ grn_obj_unlink(ctx, normalizer);
+ }
+
+ return obj;
+}
+
+grn_obj *
+grn_string_open(grn_ctx *ctx, const char *str, unsigned int str_len,
+ grn_obj *normalizer, int flags)
+{
+ return grn_string_open_(ctx, str, str_len, normalizer, flags, ctx->encoding);
+}
+
+grn_rc
+grn_string_get_original(grn_ctx *ctx, grn_obj *string,
+ const char **original,
+ unsigned int *length_in_bytes)
+{
+ grn_rc rc;
+ grn_string *string_ = (grn_string *)string;
+ GRN_API_ENTER;
+ if (string_) {
+ if (original) { *original = string_->original; }
+ if (length_in_bytes) {
+ *length_in_bytes = string_->original_length_in_bytes;
+ }
+ rc = GRN_SUCCESS;
+ } else {
+ rc = GRN_INVALID_ARGUMENT;
+ }
+ GRN_API_RETURN(rc);
+}
+
+int
+grn_string_get_flags(grn_ctx *ctx, grn_obj *string)
+{
+ int flags = 0;
+ grn_string *string_ = (grn_string *)string;
+ GRN_API_ENTER;
+ if (string_) {
+ flags = string_->flags;
+ }
+ GRN_API_RETURN(flags);
+}
+
+grn_rc
+grn_string_get_normalized(grn_ctx *ctx, grn_obj *string,
+ const char **normalized,
+ unsigned int *length_in_bytes,
+ unsigned int *n_characters)
+{
+ grn_rc rc;
+ grn_string *string_ = (grn_string *)string;
+ GRN_API_ENTER;
+ if (string_) {
+ if (normalized) { *normalized = string_->normalized; }
+ if (length_in_bytes) {
+ *length_in_bytes = string_->normalized_length_in_bytes;
+ }
+ 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);
+}
+
+grn_rc
+grn_string_set_normalized(grn_ctx *ctx, grn_obj *string,
+ char *normalized, unsigned int length_in_bytes,
+ unsigned int n_characters)
+{
+ grn_rc rc;
+ grn_string *string_ = (grn_string *)string;
+ GRN_API_ENTER;
+ if (string_) {
+ if (string_->normalized) { GRN_FREE(string_->normalized); }
+ string_->normalized = normalized;
+ string_->normalized_length_in_bytes = length_in_bytes;
+ string_->n_characters = n_characters;
+ rc = GRN_SUCCESS;
+ } else {
+ rc = GRN_INVALID_ARGUMENT;
+ }
+ GRN_API_RETURN(rc);
+}
+
+const short *
+grn_string_get_checks(grn_ctx *ctx, grn_obj *string)
+{
+ int16_t *checks = NULL;
+ grn_string *string_ = (grn_string *)string;
+ GRN_API_ENTER;
+ if (string_) {
+ checks = string_->checks;
+ } else {
+ checks = NULL;
+ }
+ GRN_API_RETURN(checks);
+}
+
+grn_rc
+grn_string_set_checks(grn_ctx *ctx, grn_obj *string, short *checks)
+{
+ grn_rc rc;
+ grn_string *string_ = (grn_string *)string;
+ GRN_API_ENTER;
+ if (string_) {
+ if (string_->checks) { GRN_FREE(string_->checks); }
+ string_->checks = checks;
+ rc = GRN_SUCCESS;
+ } else {
+ rc = GRN_INVALID_ARGUMENT;
+ }
+ GRN_API_RETURN(rc);
+}
+
+const unsigned char *
+grn_string_get_types(grn_ctx *ctx, grn_obj *string)
+{
+ unsigned char *types = NULL;
+ grn_string *string_ = (grn_string *)string;
+ GRN_API_ENTER;
+ if (string_) {
+ types = string_->ctypes;
+ } else {
+ types = NULL;
+ }
+ GRN_API_RETURN(types);
+}
+
+grn_rc
+grn_string_set_types(grn_ctx *ctx, grn_obj *string, unsigned char *types)
+{
+ grn_rc rc;
+ grn_string *string_ = (grn_string *)string;
+ GRN_API_ENTER;
+ if (string_) {
+ if (string_->ctypes) { GRN_FREE(string_->ctypes); }
+ string_->ctypes = types;
+ rc = GRN_SUCCESS;
+ } else {
+ rc = GRN_INVALID_ARGUMENT;
+ }
+ GRN_API_RETURN(rc);
+}
+
+grn_encoding
+grn_string_get_encoding(grn_ctx *ctx, grn_obj *string)
+{
+ grn_encoding encoding = GRN_ENC_NONE;
+ grn_string *string_ = (grn_string *)string;
+ GRN_API_ENTER;
+ if (string_) {
+ encoding = string_->encoding;
+ }
+ GRN_API_RETURN(encoding);
+}
+
+grn_rc
+grn_string_inspect(grn_ctx *ctx, grn_obj *buffer, grn_obj *string)
+{
+ grn_string *string_ = (grn_string *)string;
+
+ GRN_TEXT_PUTS(ctx, buffer, "#<string:");
+
+ GRN_TEXT_PUTS(ctx, buffer, " original:<");
+ GRN_TEXT_PUT(ctx, buffer,
+ string_->original,
+ string_->original_length_in_bytes);
+ GRN_TEXT_PUTS(ctx, buffer, ">");
+ GRN_TEXT_PUTS(ctx, buffer, "(");
+ grn_text_itoa(ctx, buffer, string_->original_length_in_bytes);
+ GRN_TEXT_PUTS(ctx, buffer, ")");
+
+ GRN_TEXT_PUTS(ctx, buffer, " normalized:<");
+ GRN_TEXT_PUT(ctx, buffer,
+ string_->normalized,
+ string_->normalized_length_in_bytes);
+ GRN_TEXT_PUTS(ctx, buffer, ">");
+ GRN_TEXT_PUTS(ctx, buffer, "(");
+ grn_text_itoa(ctx, buffer, string_->normalized_length_in_bytes);
+ GRN_TEXT_PUTS(ctx, buffer, ")");
+
+ GRN_TEXT_PUTS(ctx, buffer, " n_characters:");
+ grn_text_itoa(ctx, buffer, string_->n_characters);
+
+ GRN_TEXT_PUTS(ctx, buffer, " encoding:");
+ grn_inspect_encoding(ctx, buffer, string_->encoding);
+
+ GRN_TEXT_PUTS(ctx, buffer, " flags:");
+ if (string_->flags & GRN_STRING_REMOVE_BLANK) {
+ GRN_TEXT_PUTS(ctx, buffer, "REMOVE_BLANK|");
+ }
+ if (string_->flags & GRN_STRING_WITH_TYPES) {
+ GRN_TEXT_PUTS(ctx, buffer, "WITH_TYPES|");
+ }
+ if (string_->flags & GRN_STRING_WITH_CHECKS) {
+ GRN_TEXT_PUTS(ctx, buffer, "WITH_CHECKS|");
+ }
+ if (string_->flags & GRN_STRING_REMOVE_TOKENIZED_DELIMITER) {
+ GRN_TEXT_PUTS(ctx, buffer, "REMOVE_TOKENIZED_DELIMITER|");
+ }
+ if (GRN_TEXT_VALUE(buffer)[GRN_TEXT_LEN(buffer) - 1] == '|') {
+ grn_bulk_truncate(ctx, buffer, GRN_TEXT_LEN(buffer) - 1);
+ }
+
+ GRN_TEXT_PUTS(ctx, buffer, ">");
+
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_string_close(grn_ctx *ctx, grn_obj *string)
+{
+ grn_rc rc;
+ grn_string *string_ = (grn_string *)string;
+ if (string_) {
+ if (string_->normalized) { GRN_FREE(string_->normalized); }
+ if (string_->ctypes) { GRN_FREE(string_->ctypes); }
+ if (string_->checks) { GRN_FREE(string_->checks); }
+ GRN_FREE(string);
+ rc = GRN_SUCCESS;
+ } else {
+ rc = GRN_INVALID_ARGUMENT;
+ }
+ 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 00000000..0047c787
--- /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-1335 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 00000000..7e823ab3
--- /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-1335 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 00000000..b11bc7a0
--- /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-1335 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
new file mode 100644
index 00000000..179d0f31
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/token_cursor.c
@@ -0,0 +1,386 @@
+/* -*- 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-1335 USA
+*/
+#include "grn_token_cursor.h"
+#include "grn_string.h"
+#include "grn_pat.h"
+#include "grn_dat.h"
+
+static void
+grn_token_cursor_open_initialize_token_filters(grn_ctx *ctx,
+ grn_token_cursor *token_cursor)
+{
+ 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_cursor->token_filter.data[i] =
+ token_filter->callbacks.token_filter.init(ctx,
+ token_cursor->table,
+ token_cursor->mode);
+ }
+}
+
+grn_token_cursor *
+grn_token_cursor_open(grn_ctx *ctx, grn_obj *table,
+ const char *str, size_t str_len,
+ grn_tokenize_mode mode, unsigned int flags)
+{
+ grn_token_cursor *token_cursor;
+ grn_encoding encoding;
+ grn_obj *tokenizer;
+ grn_obj *normalizer;
+ grn_obj *token_filters;
+ grn_table_flags table_flags;
+ if (grn_table_get_info(ctx, table, &table_flags, &encoding, &tokenizer,
+ &normalizer, &token_filters)) {
+ return NULL;
+ }
+ if (!(token_cursor = GRN_MALLOC(sizeof(grn_token_cursor)))) { return NULL; }
+ token_cursor->table = table;
+ token_cursor->mode = mode;
+ token_cursor->encoding = encoding;
+ token_cursor->tokenizer = tokenizer;
+ 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;
+ token_cursor->nstr = NULL;
+ token_cursor->curr_size = 0;
+ token_cursor->pos = -1;
+ token_cursor->status = GRN_TOKEN_CURSOR_DOING;
+ token_cursor->force_prefix = GRN_FALSE;
+ if (tokenizer) {
+ grn_obj str_, flags_, mode_;
+ GRN_TEXT_INIT(&str_, GRN_OBJ_DO_SHALLOW_COPY);
+ GRN_TEXT_SET_REF(&str_, str, str_len);
+ GRN_UINT32_INIT(&flags_, 0);
+ GRN_UINT32_SET(ctx, &flags_, flags);
+ GRN_UINT32_INIT(&mode_, 0);
+ GRN_UINT32_SET(ctx, &mode_, mode);
+ token_cursor->pctx.caller = NULL;
+ token_cursor->pctx.user_data.ptr = NULL;
+ token_cursor->pctx.proc = (grn_proc *)tokenizer;
+ token_cursor->pctx.hooks = NULL;
+ token_cursor->pctx.currh = NULL;
+ token_cursor->pctx.phase = PROC_INIT;
+ grn_ctx_push(ctx, &mode_);
+ grn_ctx_push(ctx, &str_);
+ grn_ctx_push(ctx, &flags_);
+ ((grn_proc *)tokenizer)->funcs[PROC_INIT](ctx, 1, &table, &token_cursor->pctx.user_data);
+ grn_obj_close(ctx, &flags_);
+ grn_obj_close(ctx, &str_);
+ grn_obj_close(ctx, &mode_);
+ } else {
+ int nflags = 0;
+ token_cursor->nstr = grn_string_open_(ctx, str, str_len,
+ normalizer,
+ nflags,
+ token_cursor->encoding);
+ if (token_cursor->nstr) {
+ const char *normalized;
+ grn_string_get_normalized(ctx, token_cursor->nstr,
+ &normalized, &(token_cursor->curr_size), NULL);
+ token_cursor->curr = (const unsigned char *)normalized;
+ } else {
+ ERR(GRN_TOKENIZER_ERROR,
+ "[token-cursor][open] failed to grn_string_open()");
+ }
+ }
+
+ 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);
+ token_cursor = NULL;
+ }
+ return token_cursor;
+}
+
+static int
+grn_token_cursor_next_apply_token_filters(grn_ctx *ctx,
+ grn_token_cursor *token_cursor,
+ grn_obj *current_token_data,
+ grn_obj *status)
+{
+ grn_obj *token_filters = token_cursor->token_filter.objects;
+ unsigned int i, n_token_filters;
+ grn_token current_token;
+ grn_token next_token;
+
+ if (token_filters) {
+ n_token_filters = GRN_BULK_VSIZE(token_filters) / sizeof(grn_obj *);
+ } else {
+ n_token_filters = 0;
+ }
+
+ GRN_TEXT_INIT(&(current_token.data), GRN_OBJ_DO_SHALLOW_COPY);
+ GRN_TEXT_SET(ctx, &(current_token.data),
+ GRN_TEXT_VALUE(current_token_data),
+ GRN_TEXT_LEN(current_token_data));
+ current_token.status = GRN_INT32_VALUE(status);
+ GRN_TEXT_INIT(&(next_token.data), GRN_OBJ_DO_SHALLOW_COPY);
+ GRN_TEXT_SET(ctx, &(next_token.data),
+ GRN_TEXT_VALUE(&(current_token.data)),
+ GRN_TEXT_LEN(&(current_token.data)));
+ next_token.status = current_token.status;
+
+ 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 |\
+ GRN_TOKEN_SKIP_WITH_POSITION)
+ if (current_token.status & SKIP_FLAGS) {
+ break;
+ }
+#undef SKIP_FLAGS
+
+ token_filter->callbacks.token_filter.filter(ctx,
+ &current_token,
+ &next_token,
+ data);
+ GRN_TEXT_SET(ctx, &(current_token.data),
+ GRN_TEXT_VALUE(&(next_token.data)),
+ GRN_TEXT_LEN(&(next_token.data)));
+ current_token.status = next_token.status;
+ }
+
+ token_cursor->curr =
+ (const unsigned char *)GRN_TEXT_VALUE(&(current_token.data));
+ token_cursor->curr_size = GRN_TEXT_LEN(&(current_token.data));
+
+ return current_token.status;
+}
+
+grn_id
+grn_token_cursor_next(grn_ctx *ctx, grn_token_cursor *token_cursor)
+{
+ int status;
+ grn_id tid = GRN_ID_NIL;
+ grn_obj *table = token_cursor->table;
+ grn_obj *tokenizer = token_cursor->tokenizer;
+ while (token_cursor->status != GRN_TOKEN_CURSOR_DONE) {
+ if (tokenizer) {
+ grn_obj *curr_, *stat_;
+ ((grn_proc *)tokenizer)->funcs[PROC_NEXT](ctx, 1, &table, &token_cursor->pctx.user_data);
+ stat_ = grn_ctx_pop(ctx);
+ curr_ = grn_ctx_pop(ctx);
+ status = grn_token_cursor_next_apply_token_filters(ctx, token_cursor,
+ curr_, stat_);
+ token_cursor->status =
+ ((status & GRN_TOKEN_LAST) ||
+ (token_cursor->mode == GRN_TOKENIZE_GET &&
+ (status & GRN_TOKEN_REACH_END)))
+ ? GRN_TOKEN_CURSOR_DONE : GRN_TOKEN_CURSOR_DOING;
+ token_cursor->force_prefix = GRN_FALSE;
+#define SKIP_FLAGS \
+ (GRN_TOKEN_SKIP | GRN_TOKEN_SKIP_WITH_POSITION)
+ if (status & SKIP_FLAGS) {
+ if (status & GRN_TOKEN_SKIP) {
+ token_cursor->pos++;
+ }
+ if (token_cursor->status == GRN_TOKEN_CURSOR_DONE && tid == GRN_ID_NIL) {
+ token_cursor->status = GRN_TOKEN_CURSOR_DONE_SKIP;
+ break;
+ } else {
+ continue;
+ }
+ }
+#undef SKIP_FLAGS
+ if (status & GRN_TOKEN_FORCE_PREFIX) {
+ token_cursor->force_prefix = GRN_TRUE;
+ }
+ if (token_cursor->curr_size == 0) {
+ if (token_cursor->status != GRN_TOKEN_CURSOR_DONE) {
+ char tokenizer_name[GRN_TABLE_MAX_KEY_SIZE];
+ int tokenizer_name_length;
+ tokenizer_name_length =
+ grn_obj_name(ctx, token_cursor->tokenizer,
+ tokenizer_name, GRN_TABLE_MAX_KEY_SIZE);
+ GRN_LOG(ctx, GRN_WARN,
+ "[token_next] ignore an empty token: <%.*s>: <%.*s>",
+ tokenizer_name_length, tokenizer_name,
+ token_cursor->orig_blen, token_cursor->orig);
+ }
+ continue;
+ }
+ if (token_cursor->curr_size > GRN_TABLE_MAX_KEY_SIZE) {
+ GRN_LOG(ctx, GRN_WARN,
+ "[token_next] ignore too long token. "
+ "Token must be less than or equal to %d: <%d>(<%.*s>)",
+ GRN_TABLE_MAX_KEY_SIZE,
+ token_cursor->curr_size,
+ token_cursor->curr_size, token_cursor->curr);
+ continue;
+ }
+ if (status & GRN_TOKEN_UNMATURED) {
+ if (status & GRN_TOKEN_OVERLAP) {
+ if (token_cursor->mode == GRN_TOKENIZE_GET) {
+ token_cursor->pos++;
+ continue;
+ }
+ } else {
+ if (status & GRN_TOKEN_REACH_END) {
+ token_cursor->force_prefix = GRN_TRUE;
+ }
+ }
+ }
+ } else {
+ token_cursor->status = GRN_TOKEN_CURSOR_DONE;
+ }
+ if (token_cursor->mode == GRN_TOKENIZE_ADD) {
+ switch (table->header.type) {
+ case GRN_TABLE_PAT_KEY :
+ if (grn_io_lock(ctx, ((grn_pat *)table)->io, grn_lock_timeout)) {
+ tid = GRN_ID_NIL;
+ } else {
+ tid = grn_pat_add(ctx, (grn_pat *)table, token_cursor->curr, token_cursor->curr_size,
+ NULL, NULL);
+ grn_io_unlock(((grn_pat *)table)->io);
+ }
+ break;
+ case GRN_TABLE_DAT_KEY :
+ if (grn_io_lock(ctx, ((grn_dat *)table)->io, grn_lock_timeout)) {
+ tid = GRN_ID_NIL;
+ } else {
+ tid = grn_dat_add(ctx, (grn_dat *)table, token_cursor->curr, token_cursor->curr_size,
+ NULL, NULL);
+ grn_io_unlock(((grn_dat *)table)->io);
+ }
+ break;
+ case GRN_TABLE_HASH_KEY :
+ if (grn_io_lock(ctx, ((grn_hash *)table)->io, grn_lock_timeout)) {
+ tid = GRN_ID_NIL;
+ } else {
+ tid = grn_hash_add(ctx, (grn_hash *)table, token_cursor->curr, token_cursor->curr_size,
+ NULL, NULL);
+ grn_io_unlock(((grn_hash *)table)->io);
+ }
+ break;
+ case GRN_TABLE_NO_KEY :
+ if (token_cursor->curr_size == sizeof(grn_id)) {
+ tid = *((grn_id *)token_cursor->curr);
+ } else {
+ tid = GRN_ID_NIL;
+ }
+ break;
+ }
+ } 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);
+ break;
+ case GRN_TABLE_DAT_KEY :
+ tid = grn_dat_get(ctx, (grn_dat *)table, token_cursor->curr, token_cursor->curr_size, NULL);
+ break;
+ case GRN_TABLE_HASH_KEY :
+ tid = grn_hash_get(ctx, (grn_hash *)table, token_cursor->curr, token_cursor->curr_size, NULL);
+ break;
+ case GRN_TABLE_NO_KEY :
+ if (token_cursor->curr_size == sizeof(grn_id)) {
+ tid = *((grn_id *)token_cursor->curr);
+ } else {
+ tid = GRN_ID_NIL;
+ }
+ break;
+ }
+ }
+ 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++;
+ break;
+ }
+ return tid;
+}
+
+static void
+grn_token_cursor_close_token_filters(grn_ctx *ctx,
+ grn_token_cursor *token_cursor)
+{
+ 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, data);
+ }
+ GRN_FREE(token_cursor->token_filter.data);
+}
+
+grn_rc
+grn_token_cursor_close(grn_ctx *ctx, grn_token_cursor *token_cursor)
+{
+ if (token_cursor) {
+ if (token_cursor->tokenizer) {
+ ((grn_proc *)token_cursor->tokenizer)->funcs[PROC_FIN](ctx, 1, &token_cursor->table,
+ &token_cursor->pctx.user_data);
+ }
+ grn_token_cursor_close_token_filters(ctx, token_cursor);
+ if (token_cursor->nstr) {
+ grn_obj_close(ctx, token_cursor->nstr);
+ }
+ GRN_FREE(token_cursor);
+ return GRN_SUCCESS;
+ } else {
+ return GRN_INVALID_ARGUMENT;
+ }
+}
diff --git a/storage/mroonga/vendor/groonga/lib/token_filter.c b/storage/mroonga/vendor/groonga/lib/token_filter.c
new file mode 100644
index 00000000..55367762
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/token_filter.c
@@ -0,0 +1,59 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ 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
+ 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-1335 USA
+*/
+
+#include <string.h>
+
+#include "grn.h"
+#include "grn_db.h"
+#include <groonga/token_filter.h>
+
+grn_rc
+grn_token_filter_register(grn_ctx *ctx,
+ const char *plugin_name_ptr,
+ int plugin_name_length,
+ grn_token_filter_init_func *init,
+ grn_token_filter_filter_func *filter,
+ grn_token_filter_fin_func *fin)
+{
+ if (plugin_name_length == -1) {
+ plugin_name_length = strlen(plugin_name_ptr);
+ }
+
+ {
+ grn_obj *token_filter_object = grn_proc_create(ctx,
+ plugin_name_ptr,
+ plugin_name_length,
+ GRN_PROC_TOKEN_FILTER,
+ NULL, NULL, NULL, 0, NULL);
+ if (token_filter_object == NULL) {
+ GRN_PLUGIN_ERROR(ctx, GRN_TOKEN_FILTER_ERROR,
+ "[token-filter][%.*s] failed to grn_proc_create()",
+ plugin_name_length, plugin_name_ptr);
+ return ctx->rc;
+ }
+
+ {
+ grn_proc *token_filter = (grn_proc *)token_filter_object;
+ token_filter->callbacks.token_filter.init = init;
+ token_filter->callbacks.token_filter.filter = filter;
+ token_filter->callbacks.token_filter.fin = fin;
+ }
+ }
+
+ return GRN_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/tokenizer.c b/storage/mroonga/vendor/groonga/lib/tokenizer.c
new file mode 100644
index 00000000..faf47fd6
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/tokenizer.c
@@ -0,0 +1,375 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2012-2014 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-1335 USA
+*/
+#include "grn.h"
+#include <groonga/tokenizer.h>
+
+#include <string.h>
+
+#include "grn_ctx.h"
+#include "grn_db.h"
+#include "grn_str.h"
+#include "grn_string.h"
+#include "grn_token_cursor.h"
+
+/*
+ Just for backward compatibility. See grn_plugin_charlen() instead.
+ */
+int
+grn_tokenizer_charlen(grn_ctx *ctx, const char *str_ptr,
+ unsigned int str_length, grn_encoding encoding)
+{
+ return grn_plugin_charlen(ctx, str_ptr, str_length, encoding);
+}
+
+/*
+ Just for backward compatibility. See grn_plugin_isspace() instead.
+ */
+int
+grn_tokenizer_isspace(grn_ctx *ctx, const char *str_ptr,
+ unsigned int str_length, grn_encoding encoding)
+{
+ return grn_plugin_isspace(ctx, str_ptr, str_length, encoding);
+}
+
+grn_bool
+grn_tokenizer_is_tokenized_delimiter(grn_ctx *ctx,
+ const char *str_ptr,
+ unsigned int str_length,
+ grn_encoding encoding)
+{
+ if (encoding != GRN_ENC_UTF8) {
+ return GRN_FALSE;
+ }
+
+ if (str_length != GRN_TOKENIZER_TOKENIZED_DELIMITER_UTF8_LEN) {
+ return GRN_FALSE;
+ }
+
+ return memcmp(str_ptr,
+ GRN_TOKENIZER_TOKENIZED_DELIMITER_UTF8,
+ GRN_TOKENIZER_TOKENIZED_DELIMITER_UTF8_LEN) == 0;
+}
+
+grn_bool
+grn_tokenizer_have_tokenized_delimiter(grn_ctx *ctx,
+ const char *str_ptr,
+ unsigned int str_length,
+ grn_encoding encoding)
+{
+ int char_length;
+ const char *current = str_ptr;
+ const char *end = str_ptr + str_length;
+
+ if (encoding != GRN_ENC_UTF8) {
+ return GRN_FALSE;
+ }
+
+ if (str_length == 0) {
+ return GRN_FALSE;
+ }
+
+ while ((char_length = grn_charlen_(ctx, current, end, encoding)) > 0) {
+ if (grn_tokenizer_is_tokenized_delimiter(ctx,
+ current, char_length,
+ encoding)) {
+ return GRN_TRUE;
+ }
+ current += char_length;
+ }
+ return GRN_FALSE;
+}
+
+grn_tokenizer_query *
+grn_tokenizer_query_open(grn_ctx *ctx, int num_args, grn_obj **args,
+ unsigned int normalize_flags)
+{
+ grn_obj *flags = grn_ctx_pop(ctx);
+ grn_obj *query_str = grn_ctx_pop(ctx);
+ grn_obj *tokenize_mode = grn_ctx_pop(ctx);
+
+ if (query_str == NULL) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "missing argument");
+ return NULL;
+ }
+
+ if ((num_args < 1) || (args == NULL) || (args[0] == NULL)) {
+ GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "invalid NULL pointer");
+ return NULL;
+ }
+
+ {
+ grn_tokenizer_query * const query =
+ GRN_PLUGIN_MALLOC(ctx, sizeof(grn_tokenizer_query));
+ if (query == NULL) {
+ return NULL;
+ }
+ query->normalized_query = NULL;
+ query->query_buf = NULL;
+ if (flags) {
+ query->flags = GRN_UINT32_VALUE(flags);
+ } else {
+ query->flags = 0;
+ }
+ if (tokenize_mode) {
+ query->tokenize_mode = GRN_UINT32_VALUE(tokenize_mode);
+ } else {
+ query->tokenize_mode = GRN_TOKENIZE_ADD;
+ }
+ query->token_mode = query->tokenize_mode;
+
+ {
+ grn_obj * const table = args[0];
+ 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);
+ grn_obj *normalizer = NULL;
+
+ if (query_buf == NULL) {
+ GRN_PLUGIN_FREE(ctx, query);
+ GRN_PLUGIN_ERROR(ctx, GRN_TOKENIZER_ERROR,
+ "[tokenizer] failed to duplicate query");
+ return NULL;
+ }
+ grn_table_get_info(ctx, table, &table_flags, &table_encoding, NULL,
+ &normalizer, NULL);
+ {
+ grn_obj *normalized_query;
+ if (table_flags & GRN_OBJ_KEY_NORMALIZE) {
+ normalizer = GRN_NORMALIZER_AUTO;
+ }
+ normalized_query = grn_string_open_(ctx,
+ GRN_TEXT_VALUE(query_str),
+ GRN_TEXT_LEN(query_str),
+ normalizer,
+ normalize_flags,
+ table_encoding);
+ if (!normalized_query) {
+ GRN_PLUGIN_FREE(ctx, query_buf);
+ GRN_PLUGIN_FREE(ctx, query);
+ GRN_PLUGIN_ERROR(ctx, GRN_TOKENIZER_ERROR,
+ "[tokenizer] failed to open normalized string");
+ return NULL;
+ }
+ query->normalized_query = normalized_query;
+ grn_memcpy(query_buf, GRN_TEXT_VALUE(query_str), query_length);
+ query_buf[query_length] = '\0';
+ query->query_buf = query_buf;
+ query->ptr = query_buf;
+ query->length = query_length;
+ }
+ query->encoding = table_encoding;
+
+ if (query->flags & GRN_TOKEN_CURSOR_ENABLE_TOKENIZED_DELIMITER) {
+ const char *normalized_string;
+ unsigned int normalized_string_length;
+
+ grn_string_get_normalized(ctx,
+ query->normalized_query,
+ &normalized_string,
+ &normalized_string_length,
+ NULL);
+ query->have_tokenized_delimiter =
+ grn_tokenizer_have_tokenized_delimiter(ctx,
+ normalized_string,
+ normalized_string_length,
+ query->encoding);
+ } else {
+ query->have_tokenized_delimiter = GRN_FALSE;
+ }
+ }
+ return query;
+ }
+}
+
+grn_tokenizer_query *
+grn_tokenizer_query_create(grn_ctx *ctx, int num_args, grn_obj **args)
+{
+ return grn_tokenizer_query_open(ctx, num_args, args, 0);
+}
+
+void
+grn_tokenizer_query_close(grn_ctx *ctx, grn_tokenizer_query *query)
+{
+ if (query != NULL) {
+ if (query->normalized_query != NULL) {
+ grn_obj_unlink(ctx, query->normalized_query);
+ }
+ if (query->query_buf != NULL) {
+ GRN_PLUGIN_FREE(ctx, query->query_buf);
+ }
+ GRN_PLUGIN_FREE(ctx, query);
+ }
+}
+
+void
+grn_tokenizer_query_destroy(grn_ctx *ctx, grn_tokenizer_query *query)
+{
+ grn_tokenizer_query_close(ctx, query);
+}
+
+void
+grn_tokenizer_token_init(grn_ctx *ctx, grn_tokenizer_token *token)
+{
+ GRN_TEXT_INIT(&token->str, GRN_OBJ_DO_SHALLOW_COPY);
+ GRN_UINT32_INIT(&token->status, 0);
+}
+
+void
+grn_tokenizer_token_fin(grn_ctx *ctx, grn_tokenizer_token *token)
+{
+ GRN_OBJ_FIN(ctx, &(token->str));
+ GRN_OBJ_FIN(ctx, &(token->status));
+}
+
+void
+grn_tokenizer_token_push(grn_ctx *ctx, grn_tokenizer_token *token,
+ const char *str_ptr, unsigned int str_length,
+ grn_token_status status)
+{
+ GRN_TEXT_SET_REF(&token->str, str_ptr, str_length);
+ GRN_UINT32_SET(ctx, &token->status, status);
+ grn_ctx_push(ctx, &token->str);
+ grn_ctx_push(ctx, &token->status);
+}
+
+const char *
+grn_tokenizer_tokenized_delimiter_next(grn_ctx *ctx,
+ grn_tokenizer_token *token,
+ const char *str_ptr,
+ unsigned int str_length,
+ grn_encoding encoding)
+{
+ size_t char_length = 0;
+ const char *start = str_ptr;
+ const char *current;
+ const char *end = str_ptr + str_length;
+ const char *next_start = NULL;
+ unsigned int token_length;
+ grn_token_status status;
+
+ for (current = start; current < end; current += char_length) {
+ char_length = grn_charlen_(ctx, current, end, encoding);
+ if (char_length == 0) {
+ break;
+ }
+ if (grn_tokenizer_is_tokenized_delimiter(ctx, current, char_length,
+ encoding)) {
+ next_start = str_ptr + (current - start + char_length);
+ break;
+ }
+ }
+
+ token_length = current - start;
+ if (current == end) {
+ status = GRN_TOKENIZER_LAST;
+ } else {
+ status = GRN_TOKENIZER_CONTINUE;
+ }
+ grn_tokenizer_token_push(ctx, token, start, token_length, status);
+
+ return next_start;
+}
+
+grn_rc
+grn_tokenizer_register(grn_ctx *ctx, const char *plugin_name_ptr,
+ unsigned int plugin_name_length,
+ grn_proc_func *init, grn_proc_func *next,
+ grn_proc_func *fin)
+{
+ grn_expr_var vars[] = {
+ { NULL, 0 },
+ { NULL, 0 },
+ { NULL, 0 }
+ };
+ GRN_TEXT_INIT(&vars[0].value, 0);
+ GRN_TEXT_INIT(&vars[1].value, 0);
+ GRN_UINT32_INIT(&vars[2].value, 0);
+
+ {
+ /*
+ grn_proc_create() registers a plugin to the database which is associated
+ with `ctx'. A returned object must not be finalized here.
+ */
+ grn_obj * const obj = grn_proc_create(ctx, plugin_name_ptr,
+ plugin_name_length,
+ GRN_PROC_TOKENIZER,
+ init, next, fin, 3, vars);
+ if (obj == NULL) {
+ GRN_PLUGIN_ERROR(ctx, GRN_TOKENIZER_ERROR, "grn_proc_create() failed");
+ return ctx->rc;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+grn_obj *
+grn_token_get_data(grn_ctx *ctx, grn_token *token)
+{
+ GRN_API_ENTER;
+ if (!token) {
+ ERR(GRN_INVALID_ARGUMENT, "token must not be NULL");
+ GRN_API_RETURN(NULL);
+ }
+ GRN_API_RETURN(&(token->data));
+}
+
+grn_rc
+grn_token_set_data(grn_ctx *ctx,
+ grn_token *token,
+ const char *str_ptr,
+ int str_length)
+{
+ GRN_API_ENTER;
+ if (!token) {
+ ERR(GRN_INVALID_ARGUMENT, "token must not be NULL");
+ goto exit;
+ }
+ if (str_length == -1) {
+ str_length = strlen(str_ptr);
+ }
+ GRN_TEXT_SET(ctx, &(token->data), str_ptr, str_length);
+exit:
+ GRN_API_RETURN(ctx->rc);
+}
+
+grn_token_status
+grn_token_get_status(grn_ctx *ctx, grn_token *token)
+{
+ GRN_API_ENTER;
+ if (!token) {
+ ERR(GRN_INVALID_ARGUMENT, "token must not be NULL");
+ GRN_API_RETURN(GRN_TOKEN_CONTINUE);
+ }
+ GRN_API_RETURN(token->status);
+}
+
+grn_rc
+grn_token_set_status(grn_ctx *ctx,
+ grn_token *token,
+ grn_token_status status)
+{
+ GRN_API_ENTER;
+ if (!token) {
+ ERR(GRN_INVALID_ARGUMENT, "token must not be NULL");
+ goto exit;
+ }
+ token->status = status;
+exit:
+ GRN_API_RETURN(ctx->rc);
+}
diff --git a/storage/mroonga/vendor/groonga/lib/tokenizers.c b/storage/mroonga/vendor/groonga/lib/tokenizers.c
new file mode 100644
index 00000000..3daacce7
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/tokenizers.c
@@ -0,0 +1,890 @@
+/* -*- 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-1335 USA
+*/
+#include <string.h>
+#include "grn_token_cursor.h"
+#include "grn_string.h"
+#include "grn_plugin.h"
+#include <groonga/tokenizer.h>
+
+grn_obj *grn_tokenizer_uvector = NULL;
+
+typedef struct {
+ grn_tokenizer_token token;
+ byte *curr;
+ byte *tail;
+ uint32_t unit;
+} grn_uvector_tokenizer;
+
+static grn_obj *
+uvector_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_obj *str, *flags, *mode;
+ grn_uvector_tokenizer *tokenizer;
+ if (!(flags = grn_ctx_pop(ctx))) {
+ ERR(GRN_INVALID_ARGUMENT, "[tokenizer][uvector] missing argument: flags");
+ return NULL;
+ }
+ if (!(str = grn_ctx_pop(ctx))) {
+ ERR(GRN_INVALID_ARGUMENT, "[tokenizer][uvector] missing argument: string");
+ return NULL;
+ }
+ if (!(mode = grn_ctx_pop(ctx))) {
+ ERR(GRN_INVALID_ARGUMENT, "[tokenizer][uvector] missing argument: mode");
+ return NULL;
+ }
+ if (!(tokenizer = GRN_MALLOC(sizeof(grn_uvector_tokenizer)))) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[tokenizer][uvector] "
+ "memory allocation to grn_uvector_tokenizer failed");
+ return NULL;
+ }
+ user_data->ptr = tokenizer;
+
+ grn_tokenizer_token_init(ctx, &(tokenizer->token));
+ tokenizer->curr = (byte *)GRN_TEXT_VALUE(str);
+ tokenizer->tail = tokenizer->curr + GRN_TEXT_LEN(str);
+ tokenizer->unit = sizeof(grn_id);
+ return NULL;
+}
+
+static grn_obj *
+uvector_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_uvector_tokenizer *tokenizer = user_data->ptr;
+ byte *p = tokenizer->curr + tokenizer->unit;
+ if (tokenizer->tail < p) {
+ grn_tokenizer_token_push(ctx, &(tokenizer->token),
+ (const char *)tokenizer->curr, 0,
+ GRN_TOKEN_LAST);
+ } else {
+ grn_token_status status;
+ if (tokenizer->tail == p) {
+ status = GRN_TOKEN_LAST;
+ } else {
+ status = GRN_TOKEN_CONTINUE;
+ }
+ grn_tokenizer_token_push(ctx, &(tokenizer->token),
+ (const char *)tokenizer->curr, tokenizer->unit,
+ status);
+ tokenizer->curr = p;
+ }
+ return NULL;
+}
+
+static grn_obj *
+uvector_fin(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_uvector_tokenizer *tokenizer = user_data->ptr;
+ if (!tokenizer) {
+ return NULL;
+ }
+ grn_tokenizer_token_fin(ctx, &(tokenizer->token));
+ GRN_FREE(tokenizer);
+ return NULL;
+}
+
+typedef struct {
+ const uint8_t *delimiter;
+ uint32_t delimiter_len;
+ const unsigned char *next;
+ const unsigned char *end;
+ grn_tokenizer_token token;
+ grn_tokenizer_query *query;
+ grn_bool have_tokenized_delimiter;
+} grn_delimited_tokenizer;
+
+static grn_obj *
+delimited_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data,
+ const uint8_t *delimiter, uint32_t delimiter_len)
+{
+ grn_tokenizer_query *query;
+ unsigned int normalize_flags = 0;
+ const char *normalized;
+ unsigned int normalized_length_in_bytes;
+ grn_delimited_tokenizer *tokenizer;
+
+ query = grn_tokenizer_query_open(ctx, nargs, args, normalize_flags);
+ if (!query) {
+ return NULL;
+ }
+
+ if (!(tokenizer = GRN_MALLOC(sizeof(grn_delimited_tokenizer)))) {
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[tokenizer][delimit] "
+ "memory allocation to grn_delimited_tokenizer failed");
+ grn_tokenizer_query_close(ctx, query);
+ return NULL;
+ }
+ user_data->ptr = tokenizer;
+
+ tokenizer->query = query;
+
+ tokenizer->have_tokenized_delimiter =
+ grn_tokenizer_have_tokenized_delimiter(ctx,
+ tokenizer->query->ptr,
+ tokenizer->query->length,
+ tokenizer->query->encoding);
+ tokenizer->delimiter = delimiter;
+ tokenizer->delimiter_len = delimiter_len;
+ grn_string_get_normalized(ctx, tokenizer->query->normalized_query,
+ &normalized, &normalized_length_in_bytes,
+ NULL);
+ tokenizer->next = (const unsigned char *)normalized;
+ tokenizer->end = tokenizer->next + normalized_length_in_bytes;
+
+ grn_tokenizer_token_init(ctx, &(tokenizer->token));
+
+ return NULL;
+}
+
+static grn_obj *
+delimited_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_delimited_tokenizer *tokenizer = user_data->ptr;
+
+ if (tokenizer->have_tokenized_delimiter) {
+ unsigned int rest_length;
+ rest_length = tokenizer->end - tokenizer->next;
+ tokenizer->next =
+ (unsigned char *)grn_tokenizer_tokenized_delimiter_next(
+ ctx,
+ &(tokenizer->token),
+ (const char *)tokenizer->next,
+ rest_length,
+ tokenizer->query->encoding);
+ } else {
+ size_t cl;
+ const unsigned char *p = tokenizer->next, *r;
+ const unsigned char *e = tokenizer->end;
+ grn_token_status status;
+ for (r = p; r < e; r += cl) {
+ if (!(cl = grn_charlen_(ctx, (char *)r, (char *)e,
+ tokenizer->query->encoding))) {
+ tokenizer->next = (unsigned char *)e;
+ break;
+ }
+ {
+ grn_bool found_delimiter = GRN_FALSE;
+ const unsigned char *current_end = r;
+ while (current_end + tokenizer->delimiter_len <= e &&
+ !memcmp(current_end,
+ tokenizer->delimiter, tokenizer->delimiter_len)) {
+ current_end += tokenizer->delimiter_len;
+ tokenizer->next = current_end;
+ found_delimiter = GRN_TRUE;
+ }
+ if (found_delimiter) {
+ break;
+ }
+ }
+ }
+ if (r == e) {
+ status = GRN_TOKEN_LAST;
+ } else {
+ status = GRN_TOKEN_CONTINUE;
+ }
+ grn_tokenizer_token_push(ctx,
+ &(tokenizer->token),
+ (const char *)p,
+ r - p,
+ status);
+ }
+
+ return NULL;
+}
+
+static grn_obj *
+delimited_fin(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_delimited_tokenizer *tokenizer = user_data->ptr;
+ if (!tokenizer) {
+ return NULL;
+ }
+ grn_tokenizer_query_close(ctx, tokenizer->query);
+ grn_tokenizer_token_fin(ctx, &(tokenizer->token));
+ GRN_FREE(tokenizer);
+ return NULL;
+}
+
+static grn_obj *
+delimit_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ static const uint8_t delimiter[1] = {' '};
+ return delimited_init(ctx, nargs, args, user_data, delimiter, 1);
+}
+
+static grn_obj *
+delimit_null_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ static const uint8_t delimiter[1] = {'\0'};
+ return delimited_init(ctx, nargs, args, user_data, delimiter, 1);
+}
+
+/* ngram tokenizer */
+
+static grn_bool grn_ngram_tokenizer_remove_blank_disable = GRN_FALSE;
+
+typedef struct {
+ grn_tokenizer_token token;
+ grn_tokenizer_query *query;
+ uint8_t uni_alpha;
+ uint8_t uni_digit;
+ uint8_t uni_symbol;
+ uint8_t ngram_unit;
+ uint8_t ignore_blank;
+ uint8_t overlap;
+ int32_t pos;
+ uint32_t skip;
+ const unsigned char *next;
+ const unsigned char *end;
+ const uint_least8_t *ctypes;
+ uint32_t len;
+ uint32_t tail;
+} grn_ngram_tokenizer;
+
+static grn_obj *
+ngram_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data, uint8_t ngram_unit,
+ uint8_t uni_alpha, uint8_t uni_digit, uint8_t uni_symbol, uint8_t ignore_blank)
+{
+ unsigned int normalize_flags =
+ GRN_STRING_REMOVE_BLANK |
+ GRN_STRING_WITH_TYPES |
+ GRN_STRING_REMOVE_TOKENIZED_DELIMITER;
+ grn_tokenizer_query *query;
+ const char *normalized;
+ 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;
+ }
+
+ if (!(tokenizer = GRN_MALLOC(sizeof(grn_ngram_tokenizer)))) {
+ grn_tokenizer_query_close(ctx, query);
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[tokenizer][ngram] "
+ "memory allocation to grn_ngram_tokenizer failed");
+ return NULL;
+ }
+ user_data->ptr = tokenizer;
+
+ grn_tokenizer_token_init(ctx, &(tokenizer->token));
+ tokenizer->query = query;
+
+ tokenizer->uni_alpha = uni_alpha;
+ tokenizer->uni_digit = uni_digit;
+ tokenizer->uni_symbol = uni_symbol;
+ tokenizer->ngram_unit = ngram_unit;
+ tokenizer->ignore_blank = ignore_blank;
+ tokenizer->overlap = 0;
+ tokenizer->pos = 0;
+ tokenizer->skip = 0;
+
+ grn_string_get_normalized(ctx, tokenizer->query->normalized_query,
+ &normalized, &normalized_length_in_bytes,
+ &(tokenizer->len));
+ tokenizer->next = (const unsigned char *)normalized;
+ tokenizer->end = tokenizer->next + normalized_length_in_bytes;
+ tokenizer->ctypes =
+ grn_string_get_types(ctx, tokenizer->query->normalized_query);
+ return NULL;
+}
+
+static grn_obj *
+unigram_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{ return ngram_init(ctx, nargs, args, user_data, 1, 1, 1, 1, 0); }
+
+static grn_obj *
+bigram_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{ return ngram_init(ctx, nargs, args, user_data, 2, 1, 1, 1, 0); }
+
+static grn_obj *
+trigram_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{ return ngram_init(ctx, nargs, args, user_data, 3, 1, 1, 1, 0); }
+
+static grn_obj *
+bigrams_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{ return ngram_init(ctx, nargs, args, user_data, 2, 1, 1, 0, 0); }
+
+static grn_obj *
+bigramsa_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{ return ngram_init(ctx, nargs, args, user_data, 2, 0, 1, 0, 0); }
+
+static grn_obj *
+bigramsad_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{ return ngram_init(ctx, nargs, args, user_data, 2, 0, 0, 0, 0); }
+
+static grn_obj *
+bigrami_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{ return ngram_init(ctx, nargs, args, user_data, 2, 1, 1, 1, 1); }
+
+static grn_obj *
+bigramis_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{ return ngram_init(ctx, nargs, args, user_data, 2, 1, 1, 0, 1); }
+
+static grn_obj *
+bigramisa_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{ return ngram_init(ctx, nargs, args, user_data, 2, 0, 1, 0, 1); }
+
+static grn_obj *
+bigramisad_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{ return ngram_init(ctx, nargs, args, user_data, 2, 0, 0, 0, 1); }
+
+static grn_obj *
+ngram_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ size_t cl;
+ grn_ngram_tokenizer *tokenizer = user_data->ptr;
+ const unsigned char *p = tokenizer->next, *r = p, *e = tokenizer->end;
+ int32_t len = 0, pos = tokenizer->pos + tokenizer->skip;
+ grn_token_status status = 0;
+ const uint_least8_t *cp = tokenizer->ctypes ? tokenizer->ctypes + pos : NULL;
+ if (cp && tokenizer->uni_alpha && GRN_STR_CTYPE(*cp) == GRN_CHAR_ALPHA) {
+ while ((cl = grn_charlen_(ctx, (char *)r, (char *)e,
+ tokenizer->query->encoding))) {
+ len++;
+ r += cl;
+ if (/* !tokenizer->ignore_blank && */ GRN_STR_ISBLANK(*cp)) { break; }
+ if (GRN_STR_CTYPE(*++cp) != GRN_CHAR_ALPHA) { break; }
+ }
+ tokenizer->next = r;
+ tokenizer->overlap = 0;
+ } else if (cp &&
+ tokenizer->uni_digit &&
+ GRN_STR_CTYPE(*cp) == GRN_CHAR_DIGIT) {
+ while ((cl = grn_charlen_(ctx, (char *)r, (char *)e,
+ tokenizer->query->encoding))) {
+ len++;
+ r += cl;
+ if (/* !tokenizer->ignore_blank && */ GRN_STR_ISBLANK(*cp)) { break; }
+ if (GRN_STR_CTYPE(*++cp) != GRN_CHAR_DIGIT) { break; }
+ }
+ tokenizer->next = r;
+ tokenizer->overlap = 0;
+ } else if (cp &&
+ tokenizer->uni_symbol &&
+ GRN_STR_CTYPE(*cp) == GRN_CHAR_SYMBOL) {
+ while ((cl = grn_charlen_(ctx, (char *)r, (char *)e,
+ tokenizer->query->encoding))) {
+ len++;
+ r += cl;
+ if (!tokenizer->ignore_blank && GRN_STR_ISBLANK(*cp)) { break; }
+ if (GRN_STR_CTYPE(*++cp) != GRN_CHAR_SYMBOL) { break; }
+ }
+ tokenizer->next = r;
+ tokenizer->overlap = 0;
+ } else {
+#ifdef PRE_DEFINED_UNSPLIT_WORDS
+ const unsigned char *key = NULL;
+ // todo : grn_pat_lcp_search
+ if ((tid = grn_sym_common_prefix_search(sym, p))) {
+ if (!(key = _grn_sym_key(sym, tid))) {
+ tokenizer->status = GRN_TOKEN_CURSOR_NOT_FOUND;
+ return NULL;
+ }
+ len = grn_str_len(key, tokenizer->query->encoding, NULL);
+ }
+ r = p + grn_charlen_(ctx, p, e, tokenizer->query->encoding);
+ if (tid && (len > 1 || r == p)) {
+ if (r != p && pos + len - 1 <= tokenizer->tail) { continue; }
+ p += strlen(key);
+ if (!*p && tokenizer->mode == GRN_TOKEN_GET) {
+ tokenizer->status = GRN_TOKEN_CURSOR_DONE;
+ }
+ }
+#endif /* PRE_DEFINED_UNSPLIT_WORDS */
+ if ((cl = grn_charlen_(ctx, (char *)r, (char *)e,
+ tokenizer->query->encoding))) {
+ len++;
+ r += cl;
+ tokenizer->next = r;
+ while (len < tokenizer->ngram_unit &&
+ (cl = grn_charlen_(ctx, (char *)r, (char *)e,
+ tokenizer->query->encoding))) {
+ if (cp) {
+ if (!tokenizer->ignore_blank && GRN_STR_ISBLANK(*cp)) { break; }
+ cp++;
+ if ((tokenizer->uni_alpha && GRN_STR_CTYPE(*cp) == GRN_CHAR_ALPHA) ||
+ (tokenizer->uni_digit && GRN_STR_CTYPE(*cp) == GRN_CHAR_DIGIT) ||
+ (tokenizer->uni_symbol && GRN_STR_CTYPE(*cp) == GRN_CHAR_SYMBOL)) {
+ break;
+ }
+ }
+ len++;
+ r += cl;
+ }
+ if (tokenizer->overlap) {
+ status |= GRN_TOKEN_OVERLAP;
+ }
+ if (len < tokenizer->ngram_unit) {
+ status |= GRN_TOKEN_UNMATURED;
+ }
+ tokenizer->overlap = (len > 1) ? 1 : 0;
+ }
+ }
+ tokenizer->pos = pos;
+ tokenizer->len = len;
+ tokenizer->tail = pos + len - 1;
+ if (p == r || tokenizer->next == e) {
+ tokenizer->skip = 0;
+ status |= GRN_TOKEN_LAST;
+ } else {
+ tokenizer->skip = tokenizer->overlap ? 1 : len;
+ }
+ if (r == e) { status |= GRN_TOKEN_REACH_END; }
+ grn_tokenizer_token_push(ctx,
+ &(tokenizer->token),
+ (const char *)p,
+ r - p,
+ status);
+ return NULL;
+}
+
+static grn_obj *
+ngram_fin(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_ngram_tokenizer *tokenizer = user_data->ptr;
+ if (!tokenizer) {
+ return NULL;
+ }
+ grn_tokenizer_token_fin(ctx, &(tokenizer->token));
+ grn_tokenizer_query_close(ctx, tokenizer->query);
+ GRN_FREE(tokenizer);
+ return NULL;
+}
+
+/* regexp tokenizer */
+
+typedef struct {
+ grn_tokenizer_token token;
+ grn_tokenizer_query *query;
+ struct {
+ int32_t n_skip_tokens;
+ } get;
+ grn_bool is_begin;
+ grn_bool is_end;
+ grn_bool is_start_token;
+ grn_bool is_overlapping;
+ const char *next;
+ const char *end;
+ unsigned int nth_char;
+ const uint_least8_t *char_types;
+ grn_obj buffer;
+} grn_regexp_tokenizer;
+
+static grn_obj *
+regexp_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ unsigned int normalize_flags = GRN_STRING_WITH_TYPES;
+ grn_tokenizer_query *query;
+ const char *normalized;
+ unsigned int normalized_length_in_bytes;
+ grn_regexp_tokenizer *tokenizer;
+
+ query = grn_tokenizer_query_open(ctx, nargs, args, normalize_flags);
+ if (!query) {
+ return NULL;
+ }
+
+ tokenizer = GRN_MALLOC(sizeof(grn_regexp_tokenizer));
+ if (!tokenizer) {
+ grn_tokenizer_query_close(ctx, query);
+ ERR(GRN_NO_MEMORY_AVAILABLE,
+ "[tokenizer][regexp] failed to allocate memory");
+ return NULL;
+ }
+ user_data->ptr = tokenizer;
+
+ grn_tokenizer_token_init(ctx, &(tokenizer->token));
+ tokenizer->query = query;
+
+ tokenizer->get.n_skip_tokens = 0;
+
+ tokenizer->is_begin = GRN_TRUE;
+ tokenizer->is_end = GRN_FALSE;
+ tokenizer->is_start_token = GRN_TRUE;
+ tokenizer->is_overlapping = GRN_FALSE;
+
+ grn_string_get_normalized(ctx, tokenizer->query->normalized_query,
+ &normalized, &normalized_length_in_bytes,
+ NULL);
+ tokenizer->next = normalized;
+ tokenizer->end = tokenizer->next + normalized_length_in_bytes;
+ tokenizer->nth_char = 0;
+ tokenizer->char_types =
+ grn_string_get_types(ctx, tokenizer->query->normalized_query);
+
+ GRN_TEXT_INIT(&(tokenizer->buffer), 0);
+
+ return NULL;
+}
+
+static grn_obj *
+regexp_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ int char_len;
+ grn_token_status status = 0;
+ grn_regexp_tokenizer *tokenizer = user_data->ptr;
+ unsigned int n_characters = 0;
+ int ngram_unit = 2;
+ grn_obj *buffer = &(tokenizer->buffer);
+ const char *current = tokenizer->next;
+ const char *end = tokenizer->end;
+ 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;
+ grn_bool break_by_blank = GRN_FALSE;
+ grn_bool break_by_end_mark = GRN_FALSE;
+
+ GRN_BULK_REWIND(buffer);
+ tokenizer->is_begin = GRN_FALSE;
+ tokenizer->is_start_token = GRN_FALSE;
+
+ if (char_types) {
+ char_types += tokenizer->nth_char;
+ }
+
+ if (mode != GRN_TOKEN_GET) {
+ if (is_begin) {
+ grn_tokenizer_token_push(ctx,
+ &(tokenizer->token),
+ GRN_TOKENIZER_BEGIN_MARK_UTF8,
+ GRN_TOKENIZER_BEGIN_MARK_UTF8_LEN,
+ status);
+ return NULL;
+ }
+
+ if (tokenizer->is_end) {
+ status |= GRN_TOKEN_LAST | GRN_TOKEN_REACH_END;
+ grn_tokenizer_token_push(ctx,
+ &(tokenizer->token),
+ GRN_TOKENIZER_END_MARK_UTF8,
+ GRN_TOKENIZER_END_MARK_UTF8_LEN,
+ status);
+ return NULL;
+ }
+ if (is_start_token) {
+ if (char_types && GRN_STR_ISBLANK(char_types[-1])) {
+ status |= GRN_TOKEN_SKIP;
+ grn_tokenizer_token_push(ctx, &(tokenizer->token), "", 0, status);
+ return NULL;
+ }
+ }
+ }
+
+ char_len = grn_charlen_(ctx, current, end, tokenizer->query->encoding);
+ if (char_len == 0) {
+ status |= GRN_TOKEN_LAST | GRN_TOKEN_REACH_END;
+ grn_tokenizer_token_push(ctx, &(tokenizer->token), "", 0, status);
+ return NULL;
+ }
+
+ if (mode == GRN_TOKEN_GET) {
+ 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;
+ tokenizer->next = current;
+ tokenizer->nth_char++;
+ if (current == end) {
+ status |= GRN_TOKEN_LAST | GRN_TOKEN_REACH_END;
+ }
+ grn_tokenizer_token_push(ctx,
+ &(tokenizer->token),
+ GRN_TOKENIZER_BEGIN_MARK_UTF8,
+ GRN_TOKENIZER_BEGIN_MARK_UTF8_LEN,
+ status);
+ return NULL;
+ }
+
+ if (current + char_len == end &&
+ char_len == GRN_TOKENIZER_END_MARK_UTF8_LEN &&
+ memcmp(current, GRN_TOKENIZER_END_MARK_UTF8, char_len) == 0) {
+ status |= GRN_TOKEN_LAST | GRN_TOKEN_REACH_END;
+ grn_tokenizer_token_push(ctx,
+ &(tokenizer->token),
+ GRN_TOKENIZER_END_MARK_UTF8,
+ GRN_TOKENIZER_END_MARK_UTF8_LEN,
+ status);
+ return NULL;
+ }
+ }
+
+ while (GRN_TRUE) {
+ n_characters++;
+ GRN_TEXT_PUT(ctx, buffer, current, char_len);
+ current += char_len;
+ if (n_characters == 1) {
+ tokenizer->next = current;
+ tokenizer->nth_char++;
+ }
+
+ if (char_types) {
+ uint_least8_t char_type;
+ char_type = char_types[0];
+ char_types++;
+ if (GRN_STR_ISBLANK(char_type)) {
+ break_by_blank = GRN_TRUE;
+ }
+ }
+
+ char_len = grn_charlen_(ctx, (const char *)current, (const char *)end,
+ tokenizer->query->encoding);
+ if (char_len == 0) {
+ break;
+ }
+
+ if (mode == GRN_TOKEN_GET &&
+ current + char_len == end &&
+ char_len == GRN_TOKENIZER_END_MARK_UTF8_LEN &&
+ memcmp(current, GRN_TOKENIZER_END_MARK_UTF8, char_len) == 0) {
+ break_by_end_mark = GRN_TRUE;
+ }
+
+ if (break_by_blank || break_by_end_mark) {
+ break;
+ }
+
+ if (n_characters == ngram_unit) {
+ break;
+ }
+ }
+
+ if (tokenizer->is_overlapping) {
+ status |= GRN_TOKEN_OVERLAP;
+ }
+ if (n_characters < ngram_unit) {
+ status |= GRN_TOKEN_UNMATURED;
+ }
+ tokenizer->is_overlapping = (n_characters > 1);
+
+ if (mode == GRN_TOKEN_GET) {
+ if (current == end) {
+ tokenizer->is_end = GRN_TRUE;
+ status |= GRN_TOKEN_LAST | GRN_TOKEN_REACH_END;
+ if (status & GRN_TOKEN_UNMATURED) {
+ status |= GRN_TOKEN_FORCE_PREFIX;
+ }
+ } else {
+ if (break_by_blank) {
+ tokenizer->get.n_skip_tokens = 0;
+ tokenizer->is_start_token = GRN_TRUE;
+ } else if (break_by_end_mark) {
+ if (!is_start_token && (status & GRN_TOKEN_UNMATURED)) {
+ status |= GRN_TOKEN_SKIP;
+ }
+ } else if (tokenizer->get.n_skip_tokens > 0) {
+ tokenizer->get.n_skip_tokens--;
+ status |= GRN_TOKEN_SKIP;
+ } else {
+ tokenizer->get.n_skip_tokens = ngram_unit - 1;
+ }
+ }
+ } else {
+ if (tokenizer->next == end) {
+ tokenizer->is_end = GRN_TRUE;
+ }
+ if (break_by_blank) {
+ tokenizer->is_start_token = GRN_TRUE;
+ }
+ }
+
+ grn_tokenizer_token_push(ctx,
+ &(tokenizer->token),
+ GRN_TEXT_VALUE(buffer),
+ GRN_TEXT_LEN(buffer),
+ status);
+
+ return NULL;
+}
+
+static grn_obj *
+regexp_fin(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+ grn_regexp_tokenizer *tokenizer = user_data->ptr;
+ if (!tokenizer) {
+ return NULL;
+ }
+ grn_tokenizer_token_fin(ctx, &(tokenizer->token));
+ grn_tokenizer_query_close(ctx, tokenizer->query);
+ GRN_OBJ_FIN(ctx, &(tokenizer->buffer));
+ GRN_FREE(tokenizer);
+ return NULL;
+}
+
+/* external */
+
+grn_rc
+grn_tokenizers_init(void)
+{
+ static grn_proc _grn_tokenizer_uvector;
+ _grn_tokenizer_uvector.obj.db = NULL;
+ _grn_tokenizer_uvector.obj.id = GRN_ID_NIL;
+ _grn_tokenizer_uvector.obj.header.domain = GRN_ID_NIL;
+ _grn_tokenizer_uvector.obj.range = GRN_ID_NIL;
+ _grn_tokenizer_uvector.funcs[PROC_INIT] = uvector_init;
+ _grn_tokenizer_uvector.funcs[PROC_NEXT] = uvector_next;
+ _grn_tokenizer_uvector.funcs[PROC_FIN] = uvector_fin;
+ grn_tokenizer_uvector = (grn_obj *)&_grn_tokenizer_uvector;
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_tokenizers_fin(void)
+{
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_db_init_mecab_tokenizer(grn_ctx *ctx)
+{
+ switch (GRN_CTX_GET_ENCODING(ctx)) {
+ case GRN_ENC_EUC_JP :
+ case GRN_ENC_UTF8 :
+ case GRN_ENC_SJIS :
+#if defined(GRN_EMBEDDED) && defined(GRN_WITH_MECAB)
+ {
+ GRN_PLUGIN_DECLARE_FUNCTIONS(tokenizers_mecab);
+ grn_rc rc;
+ rc = GRN_PLUGIN_IMPL_NAME_TAGGED(init, tokenizers_mecab)(ctx);
+ if (rc == GRN_SUCCESS) {
+ rc = GRN_PLUGIN_IMPL_NAME_TAGGED(register, tokenizers_mecab)(ctx);
+ if (rc != GRN_SUCCESS) {
+ GRN_PLUGIN_IMPL_NAME_TAGGED(fin, tokenizers_mecab)(ctx);
+ }
+ }
+ return rc;
+ }
+#else /* defined(GRN_EMBEDDED) && defined(GRN_WITH_MECAB) */
+ {
+ const char *mecab_plugin_name = "tokenizers/mecab";
+ char *path;
+ path = grn_plugin_find_path(ctx, mecab_plugin_name);
+ if (path) {
+ GRN_FREE(path);
+ return grn_plugin_register(ctx, mecab_plugin_name);
+ } else {
+ return GRN_NO_SUCH_FILE_OR_DIRECTORY;
+ }
+ }
+#endif /* defined(GRN_EMBEDDED) && defined(GRN_WITH_MECAB) */
+ break;
+ default :
+ return GRN_OPERATION_NOT_SUPPORTED;
+ }
+}
+
+void
+grn_db_fin_mecab_tokenizer(grn_ctx *ctx)
+{
+ switch (GRN_CTX_GET_ENCODING(ctx)) {
+ case GRN_ENC_EUC_JP :
+ case GRN_ENC_UTF8 :
+ case GRN_ENC_SJIS :
+#if defined(GRN_EMBEDDED) && defined(GRN_WITH_MECAB)
+ {
+ GRN_PLUGIN_DECLARE_FUNCTIONS(tokenizers_mecab);
+ GRN_PLUGIN_IMPL_NAME_TAGGED(fin, tokenizers_mecab)(ctx);
+ }
+#else /* defined(GRN_EMBEDDED) && defined(GRN_WITH_MECAB) */
+ {
+ const char *mecab_plugin_name = "tokenizers/mecab";
+ char *path;
+ path = grn_plugin_find_path(ctx, mecab_plugin_name);
+ if (path) {
+ GRN_FREE(path);
+ grn_plugin_unregister(ctx, mecab_plugin_name);
+ }
+ }
+#endif /* defined(GRN_EMBEDDED) && defined(GRN_WITH_MECAB) */
+ break;
+ default :
+ break;
+ }
+ return;
+}
+
+#define DEF_TOKENIZER(name, init, next, fin, vars)\
+ (grn_proc_create(ctx, (name), (sizeof(name) - 1),\
+ GRN_PROC_TOKENIZER, (init), (next), (fin), 3, (vars)))
+
+grn_rc
+grn_db_init_builtin_tokenizers(grn_ctx *ctx)
+{
+ grn_obj *obj;
+ grn_expr_var vars[] = {
+ {NULL, 0},
+ {NULL, 0},
+ {NULL, 0}
+ };
+ GRN_TEXT_INIT(&vars[0].value, 0);
+ 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; }
+ obj = DEF_TOKENIZER("TokenUnigram",
+ unigram_init, ngram_next, ngram_fin, vars);
+ if (!obj || ((grn_db_obj *)obj)->id != GRN_DB_UNIGRAM) { return GRN_FILE_CORRUPT; }
+ obj = DEF_TOKENIZER("TokenBigram",
+ bigram_init, ngram_next, ngram_fin, vars);
+ if (!obj || ((grn_db_obj *)obj)->id != GRN_DB_BIGRAM) { return GRN_FILE_CORRUPT; }
+ obj = DEF_TOKENIZER("TokenTrigram",
+ trigram_init, ngram_next, ngram_fin, vars);
+ if (!obj || ((grn_db_obj *)obj)->id != GRN_DB_TRIGRAM) { return GRN_FILE_CORRUPT; }
+
+ DEF_TOKENIZER("TokenBigramSplitSymbol",
+ bigrams_init, ngram_next, ngram_fin, vars);
+ DEF_TOKENIZER("TokenBigramSplitSymbolAlpha",
+ bigramsa_init, ngram_next, ngram_fin, vars);
+ DEF_TOKENIZER("TokenBigramSplitSymbolAlphaDigit",
+ bigramsad_init, ngram_next, ngram_fin, vars);
+ DEF_TOKENIZER("TokenBigramIgnoreBlank",
+ bigrami_init, ngram_next, ngram_fin, vars);
+ DEF_TOKENIZER("TokenBigramIgnoreBlankSplitSymbol",
+ bigramis_init, ngram_next, ngram_fin, vars);
+ DEF_TOKENIZER("TokenBigramIgnoreBlankSplitSymbolAlpha",
+ bigramisa_init, ngram_next, ngram_fin, vars);
+ DEF_TOKENIZER("TokenBigramIgnoreBlankSplitSymbolAlphaDigit",
+ bigramisad_init, ngram_next, ngram_fin, vars);
+ DEF_TOKENIZER("TokenDelimitNull",
+ delimit_null_init, delimited_next, delimited_fin, vars);
+ DEF_TOKENIZER("TokenRegexp",
+ regexp_init, regexp_next, regexp_fin, vars);
+ return GRN_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/ts.c b/storage/mroonga/vendor/groonga/lib/ts.c
new file mode 100644
index 00000000..909f4864
--- /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-1335 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= 0;
+ 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 00000000..f1f21df4
--- /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 00000000..5d89b059
--- /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 00000000..65521d71
--- /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-1335 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 00000000..f8077f0f
--- /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-1335 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 00000000..779e4cae
--- /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-1335 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 00000000..f12034f7
--- /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-1335 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 00000000..16576fbc
--- /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-1335 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 00000000..b50e886d
--- /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-1335 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 00000000..a742e062
--- /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-1335 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 00000000..f9795ed1
--- /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-1335 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 00000000..4ae90003
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/ts/ts_expr_node.c
@@ -0,0 +1,5325 @@
+/* -*- 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-1335 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_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 !grn_ts_op_equal_float(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= 0;
+ 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 00000000..bcc9f371
--- /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-1335 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 00000000..10e6d2fc
--- /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-1335 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 00000000..77205983
--- /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-1335 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 00000000..844a0ee6
--- /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-1335 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 00000000..64262b77
--- /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-1335 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 00000000..7c34de96
--- /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-1335 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 00000000..3a8c9c0f
--- /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-1335 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 00000000..462bccfa
--- /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-1335 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 00000000..6a614663
--- /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-1335 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 00000000..d80479e1
--- /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-1335 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 00000000..9f200fa3
--- /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-1335 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 00000000..11371233
--- /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-1335 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 00000000..389eec42
--- /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-1335 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 00000000..18e66060
--- /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-1335 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 00000000..24a6a507
--- /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-1335 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 00000000..6696444a
--- /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-1335 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
new file mode 100644
index 00000000..43066c3f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/util.c
@@ -0,0 +1,1643 @@
+/* -*- 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-1335 USA
+*/
+
+#include "grn_db.h"
+#include "grn_pat.h"
+#include "grn_ii.h"
+#include "grn_util.h"
+#include "grn_string.h"
+#include "grn_expr.h"
+#include "grn_load.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#ifdef WIN32
+# include <io.h>
+# include <share.h>
+#endif /* WIN32 */
+
+grn_rc
+grn_normalize_offset_and_limit(grn_ctx *ctx, int size, int *p_offset, int *p_limit)
+{
+ int end;
+ int offset = *p_offset;
+ int limit = *p_limit;
+
+ if (offset < 0) {
+ offset += size;
+ if (offset < 0) {
+ *p_offset = 0;
+ *p_limit = 0;
+ return GRN_TOO_SMALL_OFFSET;
+ }
+ } else if (offset != 0 && offset >= size) {
+ *p_offset = 0;
+ *p_limit = 0;
+ return GRN_TOO_LARGE_OFFSET;
+ }
+
+ if (limit < 0) {
+ limit += size + 1;
+ if (limit < 0) {
+ *p_offset = 0;
+ *p_limit = 0;
+ return GRN_TOO_SMALL_LIMIT;
+ }
+ } else if (limit > size) {
+ limit = size;
+ }
+
+ /* At this point, offset and limit must be zero or positive. */
+ end = offset + limit;
+ if (end > size) {
+ limit -= end - size;
+ }
+ *p_offset = offset;
+ *p_limit = limit;
+ return GRN_SUCCESS;
+}
+
+grn_obj *
+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 > 0) {
+ grn_bulk_space(ctx, buf, name_size);
+ grn_obj_name(ctx, obj, GRN_BULK_CURR(buf) - name_size, name_size);
+ } else {
+ 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;
+}
+
+grn_obj *
+grn_inspect_encoding(grn_ctx *ctx, grn_obj *buf, grn_encoding encoding)
+{
+ switch (encoding) {
+ case GRN_ENC_DEFAULT :
+ GRN_TEXT_PUTS(ctx, buf, "default(");
+ grn_inspect_encoding(ctx, buf, grn_get_default_encoding());
+ GRN_TEXT_PUTS(ctx, buf, ")");
+ break;
+ case GRN_ENC_NONE :
+ GRN_TEXT_PUTS(ctx, buf, "none");
+ break;
+ case GRN_ENC_EUC_JP :
+ GRN_TEXT_PUTS(ctx, buf, "EUC-JP");
+ break;
+ case GRN_ENC_UTF8 :
+ GRN_TEXT_PUTS(ctx, buf, "UTF-8");
+ break;
+ case GRN_ENC_SJIS :
+ GRN_TEXT_PUTS(ctx, buf, "Shift_JIS");
+ break;
+ case GRN_ENC_LATIN1 :
+ GRN_TEXT_PUTS(ctx, buf, "Latin-1");
+ break;
+ case GRN_ENC_KOI8R :
+ GRN_TEXT_PUTS(ctx, buf, "KOI8-R");
+ break;
+ default :
+ GRN_TEXT_PUTS(ctx, buf, "unknown(");
+ grn_text_itoa(ctx, buf, encoding);
+ GRN_TEXT_PUTS(ctx, buf, ")");
+ break;
+ }
+
+ return buf;
+}
+
+grn_obj *
+grn_inspect_type(grn_ctx *ctx, grn_obj *buf, unsigned char type)
+{
+ switch (type) {
+ case GRN_VOID :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_VOID");
+ break;
+ case GRN_BULK :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_BULK");
+ break;
+ case GRN_PTR :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_PTR");
+ break;
+ case GRN_UVECTOR :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_UVECTOR");
+ break;
+ case GRN_PVECTOR :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_PVECTOR");
+ break;
+ case GRN_VECTOR :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_VECTOR");
+ break;
+ case GRN_MSG :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_MSG");
+ break;
+ case GRN_QUERY :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_QUERY");
+ break;
+ case GRN_ACCESSOR :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_ACCESSOR");
+ break;
+ case GRN_SNIP :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_SNIP");
+ break;
+ case GRN_PATSNIP :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_PATSNIP");
+ break;
+ case GRN_STRING :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_STRING");
+ break;
+ case GRN_CURSOR_TABLE_HASH_KEY :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_CURSOR_TABLE_HASH_KEY");
+ break;
+ case GRN_CURSOR_TABLE_PAT_KEY :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_CURSOR_TABLE_PAT_KEY");
+ break;
+ case GRN_CURSOR_TABLE_DAT_KEY :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_CURSOR_TABLE_DAT_KEY");
+ break;
+ case GRN_CURSOR_TABLE_NO_KEY :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_CURSOR_TABLE_NO_KEY");
+ break;
+ case GRN_CURSOR_COLUMN_INDEX :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_CURSOR_COLUMN_INDEX");
+ break;
+ case GRN_CURSOR_COLUMN_GEO_INDEX :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_CURSOR_COLUMN_GEO_INDEX");
+ break;
+ case GRN_TYPE :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_TYPE");
+ break;
+ case GRN_PROC :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_PROC");
+ break;
+ case GRN_EXPR :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_EXPR");
+ break;
+ case GRN_TABLE_HASH_KEY :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_TABLE_HASH_KEY");
+ break;
+ case GRN_TABLE_PAT_KEY :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_TABLE_PAT_KEY");
+ break;
+ case GRN_TABLE_DAT_KEY :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_TABLE_DAT_KEY");
+ break;
+ case GRN_TABLE_NO_KEY :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_TABLE_NO_KEY");
+ break;
+ case GRN_DB :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_DB");
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_COLUMN_FIX_SIZE");
+ break;
+ case GRN_COLUMN_VAR_SIZE :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_COLUMN_VAR_SIZE");
+ break;
+ case GRN_COLUMN_INDEX :
+ GRN_TEXT_PUTS(ctx, buf, "GRN_COLUMN_INDEX");
+ break;
+ default:
+ {
+#define TYPE_IN_HEX_SIZE 5 /* "0xXX" */
+ char type_in_hex[TYPE_IN_HEX_SIZE];
+ grn_snprintf(type_in_hex,
+ TYPE_IN_HEX_SIZE,
+ TYPE_IN_HEX_SIZE,
+ "%#02x", type);
+#undef TYPE_IN_HEX_SIZE
+ GRN_TEXT_PUTS(ctx, buf, "(unknown: ");
+ GRN_TEXT_PUTS(ctx, buf, type_in_hex);
+ GRN_TEXT_PUTS(ctx, buf, ")");
+ }
+ break;
+ }
+
+ 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)
+{
+ grn_proc *proc = (grn_proc *)obj;
+ uint32_t i;
+
+ GRN_TEXT_PUTS(ctx, buf, "#<proc:");
+ switch (proc->type) {
+ case GRN_PROC_INVALID :
+ GRN_TEXT_PUTS(ctx, buf, "invalid");
+ GRN_TEXT_PUTS(ctx, buf, ">");
+ return GRN_SUCCESS;
+ break;
+ case GRN_PROC_TOKENIZER :
+ GRN_TEXT_PUTS(ctx, buf, "tokenizer");
+ break;
+ case GRN_PROC_COMMAND :
+ GRN_TEXT_PUTS(ctx, buf, "command");
+ break;
+ case GRN_PROC_FUNCTION :
+ GRN_TEXT_PUTS(ctx, buf, "function");
+ break;
+ case GRN_PROC_HOOK :
+ GRN_TEXT_PUTS(ctx, buf, "hook");
+ break;
+ case GRN_PROC_NORMALIZER :
+ GRN_TEXT_PUTS(ctx, buf, "normalizer");
+ break;
+ case GRN_PROC_TOKEN_FILTER :
+ GRN_TEXT_PUTS(ctx, buf, "token-filter");
+ break;
+ 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, " ");
+
+ grn_inspect_name(ctx, buf, obj);
+ GRN_TEXT_PUTS(ctx, buf, " ");
+
+ GRN_TEXT_PUTS(ctx, buf, "arguments:[");
+ for (i = 0; i < proc->nvars; i++) {
+ grn_expr_var *var = proc->vars + i;
+ if (i != 0) {
+ GRN_TEXT_PUTS(ctx, buf, ", ");
+ }
+ GRN_TEXT_PUT(ctx, buf, var->name, var->name_size);
+ }
+ GRN_TEXT_PUTS(ctx, buf, "]");
+
+ GRN_TEXT_PUTS(ctx, buf, ">");
+
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_expr_code_inspect_indented(grn_ctx *ctx,
+ grn_obj *buffer,
+ grn_expr_code *code,
+ const char *indent)
+{
+ if (!code) {
+ GRN_TEXT_PUTS(ctx, buffer, "(NULL)");
+ return GRN_SUCCESS;
+ }
+
+ GRN_TEXT_PUTS(ctx, buffer, "<");
+ GRN_TEXT_PUTS(ctx, buffer, grn_operator_to_string(code->op));
+ GRN_TEXT_PUTS(ctx, buffer, " ");
+ GRN_TEXT_PUTS(ctx, buffer, "n_args:");
+ grn_text_itoa(ctx, buffer, code->nargs);
+ GRN_TEXT_PUTS(ctx, buffer, ", ");
+ GRN_TEXT_PUTS(ctx, buffer, "flags:");
+ grn_text_itoh(ctx, buffer, code->flags, 1);
+ GRN_TEXT_PUTS(ctx, buffer, ", ");
+ GRN_TEXT_PUTS(ctx, buffer, "modify:");
+ grn_text_itoa(ctx, buffer, code->modify);
+ GRN_TEXT_PUTS(ctx, buffer, ", ");
+ GRN_TEXT_PUTS(ctx, buffer, "value:");
+ grn_inspect_indented(ctx, buffer, code->value, " ");
+ GRN_TEXT_PUTS(ctx, buffer, ">");
+
+ return GRN_SUCCESS;
+}
+
+grn_rc
+grn_expr_inspect(grn_ctx *ctx, grn_obj *buffer, grn_obj *expr)
+{
+ grn_expr *e = (grn_expr *)expr;
+
+ GRN_TEXT_PUTS(ctx, buffer, "#<expr\n");
+ {
+ int i = 0;
+ grn_obj *value;
+ const char *name;
+ uint32_t name_len;
+ unsigned int n_vars;
+ grn_hash *vars = grn_expr_get_vars(ctx, expr, &n_vars);
+ GRN_TEXT_PUTS(ctx, buffer, " vars:{");
+ GRN_HASH_EACH(ctx, vars, id, &name, &name_len, &value, {
+ if (i++) {
+ GRN_TEXT_PUTC(ctx, buffer, ',');
+ }
+ GRN_TEXT_PUTS(ctx, buffer, "\n ");
+ GRN_TEXT_PUT(ctx, buffer, name, name_len);
+ GRN_TEXT_PUTC(ctx, buffer, ':');
+ grn_inspect_indented(ctx, buffer, value, " ");
+ });
+ GRN_TEXT_PUTS(ctx, buffer, "\n },");
+ }
+
+ {
+ uint32_t i;
+ grn_expr_code *code;
+ GRN_TEXT_PUTS(ctx, buffer, "\n codes:{");
+ for (i = 0, code = e->codes; i < e->codes_curr; i++, code++) {
+ if (i) { GRN_TEXT_PUTC(ctx, buffer, ','); }
+ GRN_TEXT_PUTS(ctx, buffer, "\n ");
+ grn_text_itoa(ctx, buffer, i);
+ GRN_TEXT_PUTS(ctx, buffer, ":");
+ grn_expr_code_inspect_indented(ctx, buffer, code, " ");
+ }
+ GRN_TEXT_PUTS(ctx, buffer, "\n }");
+ }
+
+ GRN_TEXT_PUTS(ctx, buffer, "\n>");
+
+ return GRN_SUCCESS;
+}
+
+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;
+
+ GRN_TEXT_PUTS(ctx, buffer, "[");
+ n = GRN_BULK_VSIZE(pvector) / sizeof(grn_obj *);
+ for (i = 0; i < n; i++) {
+ grn_obj *element = GRN_PTR_VALUE_AT(pvector, i);
+
+ if (i > 0) {
+ GRN_TEXT_PUTS(ctx, buffer, ", ");
+ }
+
+ grn_inspect(ctx, buffer, element);
+ }
+ GRN_TEXT_PUTS(ctx, buffer, "]");
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_vector_inspect(grn_ctx *ctx, grn_obj *buffer, grn_obj *vector)
+{
+ int i;
+ grn_obj *body = vector->u.v.body;
+
+ GRN_TEXT_PUTS(ctx, buffer, "[");
+ for (i = 0; i < vector->u.v.n_sections; i++) {
+ grn_section *section = &(vector->u.v.sections[i]);
+ const char *value_raw;
+
+ if (i > 0) {
+ GRN_TEXT_PUTS(ctx, buffer, ", ");
+ }
+
+ value_raw = GRN_BULK_HEAD(body) + section->offset;
+ GRN_TEXT_PUTS(ctx, buffer, "{");
+ GRN_TEXT_PUTS(ctx, buffer, "\"value\":");
+ {
+ grn_obj value_object;
+ GRN_OBJ_INIT(&value_object, GRN_BULK, GRN_OBJ_DO_SHALLOW_COPY,
+ section->domain);
+ GRN_TEXT_SET(ctx, &value_object, value_raw, section->length);
+ grn_inspect(ctx, buffer, &value_object);
+ GRN_OBJ_FIN(ctx, &value_object);
+ }
+ GRN_TEXT_PUTS(ctx, buffer, ", \"weight\":");
+ grn_text_itoa(ctx, buffer, section->weight);
+ GRN_TEXT_PUTS(ctx, buffer, "}");
+ }
+ GRN_TEXT_PUTS(ctx, buffer, "]");
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_accessor_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ 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
+grn_type_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ grn_id range_id;
+
+ GRN_TEXT_PUTS(ctx, buf, "#<type ");
+ grn_inspect_name(ctx, buf, obj);
+
+ range_id = grn_obj_get_range(ctx, obj);
+ GRN_TEXT_PUTS(ctx, buf, " size:");
+ grn_text_lltoa(ctx, buf, range_id);
+
+ GRN_TEXT_PUTS(ctx, buf, " type:");
+ if (obj->header.flags & GRN_OBJ_KEY_VAR_SIZE) {
+ GRN_TEXT_PUTS(ctx, buf, "var_size");
+ } else {
+ switch (obj->header.flags & GRN_OBJ_KEY_MASK) {
+ case GRN_OBJ_KEY_UINT :
+ GRN_TEXT_PUTS(ctx, buf, "uint");
+ break;
+ case GRN_OBJ_KEY_INT :
+ GRN_TEXT_PUTS(ctx, buf, "int");
+ break;
+ case GRN_OBJ_KEY_FLOAT :
+ GRN_TEXT_PUTS(ctx, buf, "float");
+ break;
+ case GRN_OBJ_KEY_GEO_POINT :
+ GRN_TEXT_PUTS(ctx, buf, "geo_point");
+ break;
+ default :
+ break;
+ }
+ }
+
+ GRN_TEXT_PUTS(ctx, buf, ">");
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_column_inspect_common(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ grn_id range_id;
+
+ grn_inspect_name(ctx, buf, obj);
+
+ range_id = grn_obj_get_range(ctx, obj);
+ if (range_id) {
+ grn_obj *range = grn_ctx_at(ctx, range_id);
+ GRN_TEXT_PUTS(ctx, buf, " range:");
+ if (range) {
+ grn_inspect_name(ctx, buf, range);
+ } else {
+ grn_text_lltoa(ctx, buf, range_id);
+ }
+ }
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_store_inspect_body(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ grn_column_inspect_common(ctx, buf, obj);
+ GRN_TEXT_PUTS(ctx, buf, " type:");
+ switch (obj->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) {
+ case GRN_OBJ_COLUMN_VECTOR :
+ GRN_TEXT_PUTS(ctx, buf, "vector");
+ break;
+ case GRN_OBJ_COLUMN_SCALAR :
+ GRN_TEXT_PUTS(ctx, buf, "scalar");
+ break;
+ default:
+ break;
+ }
+
+ GRN_TEXT_PUTS(ctx, buf, " compress:");
+ switch (obj->header.flags & GRN_OBJ_COMPRESS_MASK) {
+ case GRN_OBJ_COMPRESS_NONE :
+ GRN_TEXT_PUTS(ctx, buf, "none");
+ break;
+ case GRN_OBJ_COMPRESS_ZLIB :
+ GRN_TEXT_PUTS(ctx, buf, "zlib");
+ break;
+ 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;
+ }
+
+ if (obj->header.flags & GRN_OBJ_RING_BUFFER) {
+ GRN_TEXT_PUTS(ctx, buf, " ring_buffer:true");
+ }
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_ra_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ GRN_TEXT_PUTS(ctx, buf, "#<column:fix_size ");
+ grn_store_inspect_body(ctx, buf, obj);
+ GRN_TEXT_PUTS(ctx, buf, ">");
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_ja_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ GRN_TEXT_PUTS(ctx, buf, "#<column:var_size ");
+ grn_store_inspect_body(ctx, buf, obj);
+ GRN_TEXT_PUTS(ctx, buf, ">");
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_ii_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ grn_obj sources;
+ int i, n, have_flags = 0;
+ grn_id *source_ids;
+
+ GRN_TEXT_PUTS(ctx, buf, "#<column:index ");
+ grn_column_inspect_common(ctx, buf, obj);
+
+ GRN_TEXT_INIT(&sources, 0);
+ grn_obj_get_info(ctx, obj, GRN_INFO_SOURCE, &sources);
+ source_ids = (grn_id *)GRN_BULK_HEAD(&sources);
+ n = GRN_BULK_VSIZE(&sources) / sizeof(grn_id);
+ GRN_TEXT_PUTS(ctx, buf, " sources:[");
+ for (i = 0; i < n; i++) {
+ grn_id source_id;
+ grn_obj *source;
+ if (i) { GRN_TEXT_PUTS(ctx, buf, ", "); }
+ source_id = source_ids[i];
+ source = grn_ctx_at(ctx, source_id);
+ if (source) {
+ grn_inspect_name(ctx, buf, source);
+ } else {
+ grn_text_lltoa(ctx, buf, source_id);
+ }
+ }
+ GRN_TEXT_PUTS(ctx, buf, "]");
+ GRN_OBJ_FIN(ctx, &sources);
+
+ GRN_TEXT_PUTS(ctx, buf, " flags:");
+ if (obj->header.flags & GRN_OBJ_WITH_SECTION) {
+ GRN_TEXT_PUTS(ctx, buf, "SECTION");
+ have_flags = 1;
+ }
+ if (obj->header.flags & GRN_OBJ_WITH_WEIGHT) {
+ if (have_flags) { GRN_TEXT_PUTS(ctx, buf, "|"); }
+ GRN_TEXT_PUTS(ctx, buf, "WEIGHT");
+ have_flags = 1;
+ }
+ if (obj->header.flags & GRN_OBJ_WITH_POSITION) {
+ if (have_flags) { GRN_TEXT_PUTS(ctx, buf, "|"); }
+ GRN_TEXT_PUTS(ctx, buf, "POSITION");
+ have_flags = 1;
+ }
+ if (!have_flags) {
+ GRN_TEXT_PUTS(ctx, buf, "NONE");
+ }
+
+ GRN_TEXT_PUTS(ctx, buf, ">");
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_table_type_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ switch (obj->header.type) {
+ case GRN_TABLE_HASH_KEY:
+ GRN_TEXT_PUTS(ctx, buf, "hash");
+ break;
+ case GRN_TABLE_PAT_KEY:
+ GRN_TEXT_PUTS(ctx, buf, "pat");
+ break;
+ case GRN_TABLE_DAT_KEY:
+ GRN_TEXT_PUTS(ctx, buf, "dat");
+ break;
+ case GRN_TABLE_NO_KEY:
+ GRN_TEXT_PUTS(ctx, buf, "no_key");
+ break;
+ }
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_table_key_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ grn_obj *domain;
+ grn_id domain_id;
+
+ GRN_TEXT_PUTS(ctx, buf, "key:");
+ domain_id = obj->header.domain;
+ domain = grn_ctx_at(ctx, domain_id);
+ if (domain) {
+ grn_inspect_name(ctx, buf, domain);
+ } else if (domain_id) {
+ grn_text_lltoa(ctx, buf, domain_id);
+ } else {
+ GRN_TEXT_PUTS(ctx, buf, "(nil)");
+ }
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_table_columns_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ grn_hash *cols;
+
+ GRN_TEXT_PUTS(ctx, buf, "columns:[");
+ 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)) {
+ int i = 0;
+ grn_id *key;
+ GRN_HASH_EACH(ctx, cols, id, &key, NULL, NULL, {
+ grn_obj *col = grn_ctx_at(ctx, *key);
+ if (col) {
+ if (i++ > 0) { GRN_TEXT_PUTS(ctx, buf, ", "); }
+ grn_column_name_(ctx, col, buf);
+ }
+ });
+ }
+ grn_hash_close(ctx, cols);
+ }
+ GRN_TEXT_PUTS(ctx, buf, "]");
+
+ return GRN_SUCCESS;
+}
+
+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;
+
+ GRN_TEXT_PUTS(ctx, buf, "ids:[");
+ tc = grn_table_cursor_open(ctx, obj, NULL, 0, NULL, 0,
+ 0, -1, GRN_CURSOR_ASCENDING);
+ if (tc) {
+ int i = 0;
+ grn_id id;
+ while ((id = grn_table_cursor_next(ctx, tc))) {
+ if (i++ > 0) { GRN_TEXT_PUTS(ctx, buf, ", "); }
+ grn_text_lltoa(ctx, buf, id);
+ }
+ grn_table_cursor_close(ctx, tc);
+ }
+ GRN_TEXT_PUTS(ctx, buf, "]");
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_table_default_tokenizer_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ grn_obj *default_tokenizer;
+
+ GRN_TEXT_PUTS(ctx, buf, "default_tokenizer:");
+ default_tokenizer = grn_obj_get_info(ctx, obj,
+ GRN_INFO_DEFAULT_TOKENIZER, NULL);
+ if (default_tokenizer) {
+ grn_inspect_name(ctx, buf, default_tokenizer);
+ } else {
+ GRN_TEXT_PUTS(ctx, buf, "(nil)");
+ }
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_table_normalizer_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ grn_obj *normalizer;
+
+ GRN_TEXT_PUTS(ctx, buf, "normalizer:");
+ normalizer = grn_obj_get_info(ctx, obj, GRN_INFO_NORMALIZER, NULL);
+ if (normalizer) {
+ grn_inspect_name(ctx, buf, normalizer);
+ } else {
+ GRN_TEXT_PUTS(ctx, buf, "(nil)");
+ }
+
+ return GRN_SUCCESS;
+}
+
+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,
+ 0, -1, GRN_CURSOR_ASCENDING);
+ if (tc) {
+ int i = 0;
+ grn_id id;
+ 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);
+ GRN_BULK_REWIND(&key);
+ }
+ GRN_OBJ_FIN(ctx, &key);
+ grn_table_cursor_close(ctx, tc);
+ }
+ GRN_TEXT_PUTS(ctx, buf, "]");
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_table_subrec_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ GRN_TEXT_PUTS(ctx, buf, "subrec:");
+ if (obj->header.flags & GRN_OBJ_WITH_SUBREC) {
+ switch (obj->header.flags & GRN_OBJ_UNIT_MASK) {
+ case GRN_OBJ_UNIT_DOCUMENT_NONE :
+ GRN_TEXT_PUTS(ctx, buf, "document:none");
+ break;
+ case GRN_OBJ_UNIT_DOCUMENT_SECTION :
+ GRN_TEXT_PUTS(ctx, buf, "document:section");
+ break;
+ case GRN_OBJ_UNIT_DOCUMENT_POSITION :
+ GRN_TEXT_PUTS(ctx, buf, "document:position");
+ break;
+ case GRN_OBJ_UNIT_SECTION_NONE :
+ GRN_TEXT_PUTS(ctx, buf, "section:none");
+ break;
+ case GRN_OBJ_UNIT_SECTION_POSITION :
+ GRN_TEXT_PUTS(ctx, buf, "section:popsition");
+ break;
+ case GRN_OBJ_UNIT_POSITION_NONE :
+ GRN_TEXT_PUTS(ctx, buf, "section:none");
+ break;
+ case GRN_OBJ_UNIT_USERDEF_DOCUMENT :
+ GRN_TEXT_PUTS(ctx, buf, "userdef:document");
+ break;
+ case GRN_OBJ_UNIT_USERDEF_SECTION :
+ GRN_TEXT_PUTS(ctx, buf, "userdef:section");
+ break;
+ case GRN_OBJ_UNIT_USERDEF_POSITION :
+ GRN_TEXT_PUTS(ctx, buf, "userdef:position");
+ break;
+ }
+ } else {
+ GRN_TEXT_PUTS(ctx, buf, "none");
+ }
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_table_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ grn_id range_id;
+ grn_obj *range;
+
+ GRN_TEXT_PUTS(ctx, buf, "#<table:");
+ grn_table_type_inspect(ctx, buf, obj);
+ GRN_TEXT_PUTS(ctx, buf, " ");
+
+ grn_inspect_name(ctx, buf, obj);
+
+ if (obj->header.type != GRN_TABLE_NO_KEY) {
+ GRN_TEXT_PUTS(ctx, buf, " ");
+ grn_table_key_inspect(ctx, buf, obj);
+ }
+
+ GRN_TEXT_PUTS(ctx, buf, " value:");
+ range_id = grn_obj_get_range(ctx, obj);
+ range = grn_ctx_at(ctx, range_id);
+ if (range) {
+ grn_inspect_name(ctx, buf, range);
+ } else if (range_id) {
+ grn_text_lltoa(ctx, buf, range_id);
+ } else {
+ GRN_TEXT_PUTS(ctx, buf, "(nil)");
+ }
+
+ GRN_TEXT_PUTS(ctx, buf, " size:");
+ grn_text_lltoa(ctx, buf, grn_table_size(ctx, obj));
+
+ GRN_TEXT_PUTS(ctx, buf, " ");
+ grn_table_columns_inspect(ctx, buf, obj);
+
+ if (obj->header.type == GRN_TABLE_NO_KEY) {
+ GRN_TEXT_PUTS(ctx, buf, " ");
+ 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);
+
+ GRN_TEXT_PUTS(ctx, buf, " ");
+ grn_table_normalizer_inspect(ctx, buf, obj);
+
+ GRN_TEXT_PUTS(ctx, buf, " ");
+ grn_table_keys_inspect(ctx, buf, obj);
+ }
+
+ GRN_TEXT_PUTS(ctx, buf, " ");
+ grn_table_subrec_inspect(ctx, buf, obj);
+
+ if (obj->header.type == GRN_TABLE_PAT_KEY) {
+ GRN_TEXT_PUTS(ctx, buf, " nodes:");
+ grn_pat_inspect_nodes(ctx, (grn_pat *)obj, buf);
+ }
+
+ GRN_TEXT_PUTS(ctx, buf, ">");
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_db_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ grn_db *db = (grn_db *)obj;
+
+ GRN_TEXT_PUTS(ctx, buf, "#<db");
+
+ GRN_TEXT_PUTS(ctx, buf, " key_type:");
+ grn_table_type_inspect(ctx, buf, db->keys);
+
+ GRN_TEXT_PUTS(ctx, buf, " size:");
+ grn_text_lltoa(ctx, buf, grn_table_size(ctx, obj));
+
+ GRN_TEXT_PUTS(ctx, buf, ">");
+
+ return GRN_SUCCESS;
+}
+
+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, "(");
+ grn_text_itoa(ctx, buf, point / 1000 / 3600 % 3600);
+ GRN_TEXT_PUTS(ctx, buf, ", ");
+ grn_text_itoa(ctx, buf, point / 1000 / 60 % 60);
+ GRN_TEXT_PUTS(ctx, buf, ", ");
+ grn_text_itoa(ctx, buf, point / 1000 % 60);
+ GRN_TEXT_PUTS(ctx, buf, ", ");
+ grn_text_itoa(ctx, buf, point % 1000);
+ GRN_TEXT_PUTS(ctx, buf, ")");
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_geo_point_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ int latitude, longitude;
+
+ GRN_GEO_POINT_VALUE(obj, latitude, longitude);
+
+ GRN_TEXT_PUTS(ctx, buf, "[");
+ GRN_TEXT_PUTS(ctx, buf, "(");
+ grn_text_itoa(ctx, buf, latitude);
+ GRN_TEXT_PUTS(ctx, buf, ",");
+ grn_text_itoa(ctx, buf, longitude);
+ GRN_TEXT_PUTS(ctx, buf, ")");
+
+ GRN_TEXT_PUTS(ctx, buf, " (");
+ grn_geo_point_inspect_point(ctx, buf, latitude);
+ GRN_TEXT_PUTS(ctx, buf, ",");
+ grn_geo_point_inspect_point(ctx, buf, longitude);
+ GRN_TEXT_PUTS(ctx, buf, ")");
+
+ {
+ int i, j;
+ grn_geo_point point;
+ uint8_t encoded[sizeof(grn_geo_point)];
+
+ GRN_TEXT_PUTS(ctx, buf, " [");
+ point.latitude = latitude;
+ point.longitude = longitude;
+ grn_gton(encoded, &point, sizeof(grn_geo_point));
+ for (i = 0; i < sizeof(grn_geo_point); i++) {
+ if (i != 0) {
+ GRN_TEXT_PUTS(ctx, buf, " ");
+ }
+ for (j = 0; j < 8; j++) {
+ grn_text_itoa(ctx, buf, (encoded[i] >> (7 - j)) & 1);
+ }
+ }
+ GRN_TEXT_PUTS(ctx, buf, "]");
+ }
+
+ GRN_TEXT_PUTS(ctx, buf, "]");
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_json_load_open_bracket_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ uint32_t i, n;
+
+ n = GRN_UINT32_VALUE(obj);
+
+ GRN_TEXT_PUTS(ctx, buf, "[");
+ for (i = 0; i < n; i++) {
+ grn_obj *value;
+ value = obj + 1 + i;
+ if (i > 0) {
+ GRN_TEXT_PUTS(ctx, buf, ", ");
+ }
+ grn_inspect(ctx, buf, value);
+ }
+ GRN_TEXT_PUTS(ctx, buf, "]");
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_json_load_open_brace_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ uint32_t i, n;
+
+ n = GRN_UINT32_VALUE(obj);
+
+ GRN_TEXT_PUTS(ctx, buf, "{");
+ for (i = 0; i < n; i += 2) {
+ grn_obj *key, *value;
+ key = obj + 1 + i;
+ value = key + 1;
+ if (i > 0) {
+ GRN_TEXT_PUTS(ctx, buf, ", ");
+ }
+ grn_inspect(ctx, buf, key);
+ GRN_TEXT_PUTS(ctx, buf, ": ");
+ grn_inspect(ctx, buf, value);
+ }
+ GRN_TEXT_PUTS(ctx, buf, "}");
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_record_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ grn_obj *table;
+ grn_hash *cols;
+
+ table = grn_ctx_at(ctx, obj->header.domain);
+ GRN_TEXT_PUTS(ctx, buf, "#<record:");
+ if (table) {
+ grn_table_type_inspect(ctx, buf, table);
+ GRN_TEXT_PUTS(ctx, buf, ":");
+ grn_inspect_name(ctx, buf, table);
+ } else {
+ GRN_TEXT_PUTS(ctx, buf, "(anonymous table:");
+ grn_text_lltoa(ctx, buf, obj->header.domain);
+ GRN_TEXT_PUTS(ctx, buf, ")");
+ }
+
+ GRN_TEXT_PUTS(ctx, buf, " id:");
+ if (GRN_BULK_VSIZE(obj) == 0) {
+ GRN_TEXT_PUTS(ctx, buf, "(no value)");
+ } else {
+ grn_id id;
+
+ id = GRN_RECORD_VALUE(obj);
+ grn_text_lltoa(ctx, buf, id);
+
+ if (table && grn_table_at(ctx, table, id)) {
+ if (table->header.type != GRN_TABLE_NO_KEY) {
+ grn_obj key;
+ GRN_TEXT_PUTS(ctx, buf, " key:");
+ GRN_OBJ_INIT(&key, GRN_BULK, 0, table->header.domain);
+ grn_table_get_key2(ctx, table, id, &key);
+ grn_inspect(ctx, buf, &key);
+ GRN_OBJ_FIN(ctx, &key);
+ }
+ if ((cols = 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 *)cols)) {
+ grn_id *key;
+ GRN_HASH_EACH(ctx, cols, column_id, &key, NULL, NULL, {
+ grn_obj *col = grn_ctx_at(ctx, *key);
+ if (col) {
+ grn_obj value;
+ GRN_TEXT_INIT(&value, 0);
+ GRN_TEXT_PUTS(ctx, buf, " ");
+ grn_column_name_(ctx, col, buf);
+ GRN_TEXT_PUTS(ctx, buf, ":");
+ grn_obj_get_value(ctx, col, id, &value);
+ grn_inspect(ctx, buf, &value);
+ GRN_OBJ_FIN(ctx, &value);
+ }
+ });
+ }
+ grn_hash_close(ctx, cols);
+ }
+ } else {
+ GRN_TEXT_PUTS(ctx, buf, "(nonexistent)");
+ }
+ }
+
+ GRN_TEXT_PUTS(ctx, buf, ">");
+
+ return GRN_SUCCESS;
+}
+
+static grn_rc
+grn_uvector_record_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *obj)
+{
+ unsigned int i, n = 0;
+ grn_obj record;
+
+ GRN_RECORD_INIT(&record, 0, obj->header.domain);
+ GRN_TEXT_PUTS(ctx, buf, "[");
+ n = grn_vector_size(ctx, obj);
+ for (i = 0; i < n; i++) {
+ grn_id id;
+ unsigned int weight;
+
+ if (i > 0) {
+ GRN_TEXT_PUTS(ctx, buf, ", ");
+ }
+
+ id = grn_uvector_get_element(ctx, obj, i, &weight);
+ GRN_TEXT_PUTS(ctx, buf, "#<element record:");
+ GRN_RECORD_SET(ctx, &record, id);
+ grn_inspect(ctx, buf, &record);
+ grn_text_printf(ctx, buf, ", weight:%u>", weight);
+ }
+ GRN_TEXT_PUTS(ctx, buf, "]");
+ GRN_OBJ_FIN(ctx, &record);
+
+ return GRN_SUCCESS;
+}
+
+grn_obj *
+grn_inspect(grn_ctx *ctx, grn_obj *buffer, grn_obj *obj)
+{
+ grn_obj *domain;
+
+ if (!buffer) {
+ buffer = grn_obj_open(ctx, GRN_BULK, 0, GRN_DB_TEXT);
+ }
+
+ if (!obj) {
+ GRN_TEXT_PUTS(ctx, buffer, "(NULL)");
+ return buffer;
+ }
+
+ switch (obj->header.type) {
+ case GRN_VOID :
+ /* TODO */
+ 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);
+ return buffer;
+ case GRN_JSON_LOAD_OPEN_BRACKET :
+ grn_json_load_open_bracket_inspect(ctx, buffer, obj);
+ return buffer;
+ case GRN_JSON_LOAD_OPEN_BRACE :
+ grn_json_load_open_brace_inspect(ctx, buffer, obj);
+ return buffer;
+ default :
+ domain = grn_ctx_at(ctx, obj->header.domain);
+ if (domain) {
+ grn_id type = domain->header.type;
+ switch (type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ grn_record_inspect(ctx, buffer, obj);
+ return buffer;
+ default :
+ break;
+ }
+ }
+ }
+ break;
+ case GRN_PTR :
+ 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;
+ switch (type) {
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ grn_uvector_record_inspect(ctx, buffer, obj);
+ return buffer;
+ default :
+ break;
+ }
+ }
+ break;
+ case GRN_PVECTOR :
+ grn_pvector_inspect(ctx, buffer, obj);
+ return buffer;
+ case GRN_VECTOR :
+ grn_vector_inspect(ctx, buffer, obj);
+ return buffer;
+ case GRN_MSG :
+ /* TODO */
+ break;
+ case GRN_ACCESSOR :
+ grn_accessor_inspect(ctx, buffer, obj);
+ return buffer;
+ case GRN_SNIP :
+ case GRN_PATSNIP :
+ /* TODO */
+ break;
+ case GRN_STRING :
+ grn_string_inspect(ctx, buffer, obj);
+ break;
+ case GRN_CURSOR_TABLE_HASH_KEY :
+ /* TODO */
+ break;
+ case GRN_CURSOR_TABLE_PAT_KEY :
+ grn_pat_cursor_inspect(ctx, (grn_pat_cursor *)obj, buffer);
+ return buffer;
+ case GRN_CURSOR_TABLE_DAT_KEY :
+ case GRN_CURSOR_TABLE_NO_KEY :
+ case GRN_CURSOR_COLUMN_INDEX :
+ case GRN_CURSOR_COLUMN_GEO_INDEX :
+ /* TODO */
+ break;
+ case GRN_TYPE :
+ grn_type_inspect(ctx, buffer, obj);
+ return buffer;
+ case GRN_PROC :
+ grn_proc_inspect(ctx, buffer, obj);
+ return buffer;
+ case GRN_EXPR :
+ grn_expr_inspect(ctx, buffer, obj);
+ return buffer;
+ case GRN_TABLE_HASH_KEY :
+ case GRN_TABLE_PAT_KEY :
+ case GRN_TABLE_DAT_KEY :
+ case GRN_TABLE_NO_KEY :
+ grn_table_inspect(ctx, buffer, obj);
+ return buffer;
+ case GRN_DB :
+ grn_db_inspect(ctx, buffer, obj);
+ break;
+ case GRN_COLUMN_FIX_SIZE :
+ grn_ra_inspect(ctx, buffer, obj);
+ return buffer;
+ case GRN_COLUMN_VAR_SIZE :
+ grn_ja_inspect(ctx, buffer, obj);
+ return buffer;
+ case GRN_COLUMN_INDEX :
+ grn_ii_inspect(ctx, buffer, obj);
+ return buffer;
+ default :
+ break;
+ }
+
+ grn_text_otoj(ctx, buffer, obj, NULL);
+ return buffer;
+}
+
+grn_obj *
+grn_inspect_indented(grn_ctx *ctx, grn_obj *buffer, grn_obj *obj,
+ const char *indent)
+{
+ grn_obj sub_buffer;
+
+ GRN_TEXT_INIT(&sub_buffer, 0);
+ grn_inspect(ctx, &sub_buffer, obj);
+ {
+ const char *inspected = GRN_TEXT_VALUE(&sub_buffer);
+ size_t inspected_size = GRN_TEXT_LEN(&sub_buffer);
+ size_t i, line_start;
+
+ if (!buffer) {
+ buffer = grn_obj_open(ctx, GRN_BULK, 0, GRN_DB_TEXT);
+ }
+
+ line_start = 0;
+ for (i = 0; i < inspected_size; i++) {
+ if (inspected[i] == '\n') {
+ if (line_start != 0) {
+ GRN_TEXT_PUTS(ctx, buffer, indent);
+ }
+ GRN_TEXT_PUT(ctx, buffer, inspected + line_start, i + 1 - line_start);
+ line_start = i + 1;
+ }
+ }
+ if (line_start != 0) {
+ GRN_TEXT_PUTS(ctx, buffer, indent);
+ }
+ GRN_TEXT_PUT(ctx, buffer,
+ inspected + line_start,
+ inspected_size - line_start);
+ }
+ GRN_OBJ_FIN(ctx, &sub_buffer);
+
+ 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)
+{
+ grn_obj buffer;
+
+ GRN_TEXT_INIT(&buffer, 0);
+ grn_inspect(ctx, &buffer, obj);
+ printf("%.*s\n", (int)GRN_TEXT_LEN(&buffer), GRN_TEXT_VALUE(&buffer));
+ GRN_OBJ_FIN(ctx, &buffer);
+}
+
+void
+grn_p_geo_point(grn_ctx *ctx, grn_geo_point *point)
+{
+ grn_obj obj;
+
+ GRN_WGS84_GEO_POINT_INIT(&obj, 0);
+ GRN_GEO_POINT_SET(ctx, &obj, point->latitude, point->longitude);
+ grn_p(ctx, &obj);
+ GRN_OBJ_FIN(ctx, &obj);
+}
+
+void
+grn_p_ii_values(grn_ctx *ctx, grn_obj *ii)
+{
+ grn_obj buffer;
+
+ 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_FIN(ctx, &buffer);
+}
+
+void
+grn_p_expr_code(grn_ctx *ctx, grn_expr_code *code)
+{
+ grn_obj buffer;
+
+ 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_FIN(ctx, &buffer);
+}
+
+void
+grn_p_record(grn_ctx *ctx, grn_obj *table, grn_id id)
+{
+ 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);
+}
+
+#ifdef WIN32
+int
+grn_mkstemp(char *path_template)
+{
+ errno_t error;
+ size_t path_template_size;
+ int fd;
+
+ path_template_size = strlen(path_template) + 1;
+ error = _mktemp_s(path_template, path_template_size);
+ if (error != 0) {
+ return -1;
+ }
+
+ error = _sopen_s(&fd,
+ path_template,
+ _O_RDWR | _O_CREAT | _O_EXCL | _O_BINARY,
+ _SH_DENYNO,
+ _S_IREAD | _S_IWRITE);
+ if (error != 0) {
+ return -1;
+ }
+
+ return fd;
+}
+#else /* WIN32 */
+int
+grn_mkstemp(char *path_template)
+{
+# ifdef HAVE_MKSTEMP
+ return mkstemp(path_template);
+# else /* HAVE_MKSTEMP */
+ mktemp(path_template);
+ return open(path_template, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+# 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 00000000..27e8c9c8
--- /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-1335 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 00000000..7a177cd8
--- /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-1335 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 00000000..a363d711
--- /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-1335 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 00000000..fb8229ad
--- /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-1335 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 */
+}