summaryrefslogtreecommitdiff
path: root/storage/mroonga
diff options
context:
space:
mode:
authorKentoku SHIBA <kentokushiba@gmail.com>2015-07-02 04:12:21 +0900
committerKentoku SHIBA <kentokushiba@gmail.com>2015-07-02 04:12:21 +0900
commit06913d016268c4d0d7e19d19cbe6ca96a7f20e18 (patch)
tree08bb0719182c6eec97104f053f278c79983a3786 /storage/mroonga
parent031930489360b24032fd151c71292026b3747f32 (diff)
downloadmariadb-git-06913d016268c4d0d7e19d19cbe6ca96a7f20e18.tar.gz
Update Mroonga to the latest version on 2015-07-02T04:12:21+0900
Diffstat (limited to 'storage/mroonga')
-rw-r--r--storage/mroonga/CMakeLists.txt55
-rw-r--r--storage/mroonga/appveyor.yml10
-rw-r--r--storage/mroonga/build/makefiles/gettext.am21
-rw-r--r--storage/mroonga/build/makefiles/sphinx.am2
-rw-r--r--storage/mroonga/configure.ac24
-rw-r--r--storage/mroonga/ha_mroonga.cpp1759
-rw-r--r--storage/mroonga/ha_mroonga.hpp102
-rw-r--r--storage/mroonga/lib/mrn_condition_converter.cpp4
-rw-r--r--storage/mroonga/lib/mrn_condition_converter.hpp3
-rw-r--r--storage/mroonga/lib/mrn_database_manager.cpp15
-rw-r--r--storage/mroonga/lib/mrn_database_repairer.cpp2
-rw-r--r--storage/mroonga/lib/mrn_encoding.cpp1
-rw-r--r--storage/mroonga/lib/mrn_encoding.hpp6
-rw-r--r--storage/mroonga/lib/mrn_field_normalizer.cpp2
-rw-r--r--storage/mroonga/lib/mrn_field_normalizer.hpp6
-rw-r--r--storage/mroonga/lib/mrn_index_table_name.cpp31
-rw-r--r--storage/mroonga/lib/mrn_index_table_name.hpp7
-rw-r--r--storage/mroonga/lib/mrn_lock.cpp15
-rw-r--r--storage/mroonga/lib/mrn_lock.hpp5
-rw-r--r--storage/mroonga/lib/mrn_multiple_column_key_codec.cpp311
-rw-r--r--storage/mroonga/lib/mrn_multiple_column_key_codec.hpp46
-rw-r--r--storage/mroonga/lib/mrn_mysqlservices.cpp4
-rw-r--r--storage/mroonga/lib/mrn_smart_grn_obj.cpp6
-rw-r--r--storage/mroonga/lib/mrn_smart_grn_obj.hpp1
-rw-r--r--storage/mroonga/lib/mrn_time_converter.cpp45
-rw-r--r--storage/mroonga/lib/mrn_time_converter.hpp8
-rw-r--r--storage/mroonga/lib/mrn_value_decoder.cpp11
-rw-r--r--storage/mroonga/lib/mrn_value_decoder.hpp1
-rw-r--r--storage/mroonga/mrn_constants.hpp4
-rw-r--r--storage/mroonga/mrn_err.h6
-rw-r--r--storage/mroonga/mrn_mysql_compat.h67
-rw-r--r--storage/mroonga/mrn_table.cpp104
-rw-r--r--storage/mroonga/mrn_table.hpp18
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_embedded.inc19
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_groonga_plugin_register.inc22
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_mariadb.inc (renamed from storage/mroonga/mysql-test/mroonga/include/mroonga/have_fulltext_index_comment.inc)12
-rw-r--r--storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga.inc3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_comment.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_with_flags.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_parameter.result17
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_comment.result18
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_parameter.result26
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_type_comment.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_with_type.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_index_token_filters_one_token_filter.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_token_filter.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_date_strict.result23
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_flags_comment.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_vector.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_flags_parameter.result17
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_comment.result18
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_nonexistent.result6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_parameter.result26
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_type_comment.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_reference_type.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_type_nonexistent.result6
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_comment.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_none.result2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_parameter.result15
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_none.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_with_position_and_with_weight.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_with_position_and_with_weight.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_comment.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_comment.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_no_utf8_charset_with_utf8_normalizer.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_no_utf8_charset_with_utf8_normalizer.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_none.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_none.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_parameter.result21
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_comment.result31
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_default.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/fulltext_parser_default.result)24
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_off.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/fulltext_parser_off.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_multiple_token_filters.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_index_comment_multiple_token_filters.result)4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_one_token_filter.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_index_comment_one_token_filter.result)4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_parameter.result23
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_comment.result31
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_default.result33
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_off.result42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_parameter.result30
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_normalizer_default.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_primary_key_table_comment.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_normalizer_hash.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_primary_key_table_comment_with_using_hash.result)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_multiple_token_filters.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_table_comment_multiple_token_filters.result)4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_one_token_filter.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_table_comment_one_token_filter.result)4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_stop_word.result (renamed from storage/mroonga/mysql-test/mroonga/storage/r/fulltext_token_filters_skip.result)4
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_no_operator.result5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_with_minus.result5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_with_plus.result5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.result14
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_not_match_against.result20
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/fulltext_parser_comment.result29
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.result21
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/replace_select_varchar.result3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/replace_without_key.result2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/r/truncate.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/suite.pm5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_comment.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_with_flags.test)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_parameter.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_comment.test44
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_parameter.test47
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_type_comment.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_with_type.test)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_token_filters_one_token_filter.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_token_filter.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_date_strict.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_flags_comment.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_vector.test)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_flags_parameter.test39
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_comment.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_nonexistent.test29
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_parameter.test45
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_type_comment.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_reference_type.test)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_type_nonexistent.test29
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_comment.test39
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_none.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_parameter.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_none.test38
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_with_position_and_with_weight.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_with_position_and_with_weight.test)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_comment.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_comment.test)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_no_utf8_charset_with_utf8_normalizer.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_no_utf8_charset_with_utf8_normalizer.test)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_none.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_none.test)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_parameter.test40
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_comment.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_default.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/fulltext_parser_default.test)12
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_off.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/fulltext_parser_off.test)1
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_multiple_token_filters.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_index_comment_multiple_token_filters.test)3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_one_token_filter.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_index_comment_one_token_filter.test)3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_parameter.test44
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_comment.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_default.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_off.test47
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_parameter.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_default.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_primary_key_table_comment.test)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_hash.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_primary_key_table_comment_with_using_hash.test)0
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_multiple_token_filters.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_table_comment_multiple_token_filters.test)3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_one_token_filter.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_table_comment_one_token_filter.test)3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_stop_word.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/fulltext_token_filters_skip.test)3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.test38
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/fulltext_not_match_against.test21
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.test39
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/replace_select_varchar.test3
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/replace_without_key.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/truncate.test14
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_global.test1
-rw-r--r--storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_session.test1
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_comment.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_none.result9
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_parameter.result16
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_comment.result21
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_fulltext_index.result16
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_parameter.result21
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_parser_comment.result (renamed from storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_parser_comment.result)20
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_multiple_token_filters.result (renamed from storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_comment_multiple_token_filters.result)4
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_one_token_filter.result (renamed from storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_comment_one_token_filter.result)4
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_parameter.result25
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_comment.result29
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_parameter.result30
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_no_operator.result5
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_with_minus.result3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_with_plus.result3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_select.result4
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_many_records.result2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_matched_order.result26
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_no_order.result24
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_no_where_both_order.result26
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_myisam.result18
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_not_match_against.result20
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_TODO_SPLIT_ME.result16
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/r/truncate.result13
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/suite.pm5
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/count_star_with_index.test1
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_comment.test40
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_none.test40
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_parameter.test42
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_comment.test40
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_parameter.test41
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_parser_comment.test (renamed from storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_parser_comment.test)11
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_multiple_token_filters.test (renamed from storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_comment_multiple_token_filters.test)3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_one_token_filter.test (renamed from storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_comment_one_token_filter.test)3
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_parameter.test46
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_comment.test (renamed from storage/mroonga/mysql-test/mroonga/storage/t/fulltext_parser_comment.test)16
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_parameter.test (renamed from storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_fulltext_index.test)26
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test5
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_select.test2
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_many_records.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_matched_order.test50
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_no_order.test48
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_no_where_both_order.test50
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_myisam.test16
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_not_match_against.test22
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_TODO_SPLIT_ME.test4
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/truncate.test14
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_global.test1
-rw-r--r--storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_session.test1
-rwxr-xr-xstorage/mroonga/packages/apt/build-deb.sh6
-rw-r--r--storage/mroonga/packages/debian/changelog12
-rw-r--r--storage/mroonga/packages/rpm/centos/mariadb-mroonga.spec.in6
-rw-r--r--storage/mroonga/packages/rpm/centos/mysql55-mroonga.spec.in6
-rw-r--r--storage/mroonga/packages/rpm/centos/mysql56-community-mroonga.spec.in44
-rw-r--r--storage/mroonga/packages/rpm/centos/percona-server-56-mroonga.spec.in26
-rw-r--r--storage/mroonga/packages/source/Makefile.am6
-rwxr-xr-xstorage/mroonga/packages/ubuntu/upload.rb4
-rwxr-xr-xstorage/mroonga/packages/yum/sign-rpm.sh2
-rw-r--r--storage/mroonga/plugin_version2
-rwxr-xr-xstorage/mroonga/tools/travis/before_script.sh29
-rwxr-xr-xstorage/mroonga/tools/travis/script.sh14
-rw-r--r--storage/mroonga/vendor/groonga/CMakeLists.txt12
-rw-r--r--storage/mroonga/vendor/groonga/base_version2
-rw-r--r--storage/mroonga/vendor/groonga/bindings/php/groonga.c3
-rw-r--r--storage/mroonga/vendor/groonga/build/ac_macros/check_headers.m45
-rw-r--r--storage/mroonga/vendor/groonga/config.h.cmake7
-rw-r--r--storage/mroonga/vendor/groonga/configure.ac4
-rwxr-xr-xstorage/mroonga/vendor/groonga/examples/dictionary/edict/edict2grn.rb56
-rwxr-xr-xstorage/mroonga/vendor/groonga/examples/dictionary/gene95/gene2grn.rb63
-rw-r--r--storage/mroonga/vendor/groonga/groonga-httpd-conf.sh.in2
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/command.h2
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/groonga.h2
-rw-r--r--storage/mroonga/vendor/groonga/include/groonga/plugin.h5
-rw-r--r--storage/mroonga/vendor/groonga/lib/CMakeLists.txt9
-rw-r--r--storage/mroonga/vendor/groonga/lib/com.c27
-rw-r--r--storage/mroonga/vendor/groonga/lib/command.c8
-rw-r--r--storage/mroonga/vendor/groonga/lib/ctx.c57
-rw-r--r--storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c36
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat.cpp32
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/file-impl.cpp20
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/file-impl.hpp4
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/file.cpp8
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/file.hpp4
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/trie.cpp6
-rw-r--r--storage/mroonga/vendor/groonga/lib/dat/trie.hpp4
-rw-r--r--storage/mroonga/vendor/groonga/lib/db.c439
-rw-r--r--storage/mroonga/vendor/groonga/lib/egn.cpp3245
-rw-r--r--storage/mroonga/vendor/groonga/lib/error.c14
-rw-r--r--storage/mroonga/vendor/groonga/lib/expr.c284
-rw-r--r--storage/mroonga/vendor/groonga/lib/expr_code.c71
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn.h8
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ctx.h5
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ctx_impl_mrb.h3
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_dat.h4
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_db.h2
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_egn.h90
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_egn.hpp318
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_error.h1
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_expr_code.h37
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_ii.h5
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_io.h5
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_mrb.h2
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_plugin.h1
-rw-r--r--storage/mroonga/vendor/groonga/lib/grn_proc.h4
-rw-r--r--storage/mroonga/vendor/groonga/lib/ii.c152
-rw-r--r--storage/mroonga/vendor/groonga/lib/io.c197
-rw-r--r--storage/mroonga/vendor/groonga/lib/logger.c4
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb.c21
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c32
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c51
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_column.c19
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.c17
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c2
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c21
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c23
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_object.h2
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c202
-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.h34
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.c250
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.h34
-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.h34
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.c157
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.h34
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb7
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb1
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am1
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/scripts/table.rb90
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/sources.am8
-rw-r--r--storage/mroonga/vendor/groonga/lib/operator.c66
-rw-r--r--storage/mroonga/vendor/groonga/lib/output.c70
-rw-r--r--storage/mroonga/vendor/groonga/lib/plugin.c19
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc.c160
-rw-r--r--storage/mroonga/vendor/groonga/lib/sources.am5
-rw-r--r--storage/mroonga/vendor/groonga/lib/store.c7
-rw-r--r--storage/mroonga/vendor/groonga/lib/token_cursor.c2
-rw-r--r--storage/mroonga/vendor/groonga/lib/tokenizers.c203
-rw-r--r--storage/mroonga/vendor/groonga/plugins/CMakeLists.txt10
-rw-r--r--storage/mroonga/vendor/groonga/plugins/functions/CMakeLists.txt18
-rw-r--r--storage/mroonga/vendor/groonga/plugins/functions/vector.c4
-rw-r--r--storage/mroonga/vendor/groonga/plugins/query_expanders/CMakeLists.txt18
-rw-r--r--storage/mroonga/vendor/groonga/plugins/query_expanders/tsv.c4
-rw-r--r--storage/mroonga/vendor/groonga/plugins/ruby/CMakeLists.txt36
-rw-r--r--storage/mroonga/vendor/groonga/plugins/ruby/eval.c4
-rw-r--r--storage/mroonga/vendor/groonga/plugins/ruby/load.c4
-rw-r--r--storage/mroonga/vendor/groonga/plugins/sharding.rb2
-rw-r--r--storage/mroonga/vendor/groonga/plugins/sharding/CMakeLists.txt12
-rw-r--r--storage/mroonga/vendor/groonga/plugins/sharding/logical_enumerator.rb156
-rw-r--r--storage/mroonga/vendor/groonga/plugins/sharding/logical_select.rb332
-rw-r--r--storage/mroonga/vendor/groonga/plugins/sharding/logical_table_remove.rb70
-rw-r--r--storage/mroonga/vendor/groonga/plugins/sharding/sources.am2
-rw-r--r--storage/mroonga/vendor/groonga/plugins/suggest/CMakeLists.txt14
-rw-r--r--storage/mroonga/vendor/groonga/plugins/suggest/suggest.c4
-rw-r--r--storage/mroonga/vendor/groonga/plugins/table/CMakeLists.txt16
-rw-r--r--storage/mroonga/vendor/groonga/plugins/token_filters/CMakeLists.txt36
-rw-r--r--storage/mroonga/vendor/groonga/plugins/token_filters/stem.c4
-rw-r--r--storage/mroonga/vendor/groonga/plugins/token_filters/stop_word.c4
-rw-r--r--storage/mroonga/vendor/groonga/plugins/tokenizers/CMakeLists.txt36
-rw-r--r--storage/mroonga/vendor/groonga/plugins/tokenizers/kytea.cpp4
-rw-r--r--storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c20
-rwxr-xr-xstorage/mroonga/vendor/groonga/ra.rb12
-rw-r--r--storage/mroonga/vendor/groonga/src/grndb.c2
-rw-r--r--storage/mroonga/vendor/groonga/src/grnslap.c10
-rw-r--r--storage/mroonga/vendor/groonga/src/groonga.c13
-rw-r--r--storage/mroonga/vendor/groonga/src/groonga_benchmark.c12
-rw-r--r--storage/mroonga/vendor/groonga/src/groonga_mruby.c2
-rw-r--r--storage/mroonga/vendor/groonga/src/httpd/nginx-module/config8
-rw-r--r--storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c32
-rwxr-xr-xstorage/mroonga/vendor/groonga/tools/install/install-for-debian-jessie.sh17
-rw-r--r--storage/mroonga/vendor/groonga/vendor/mruby/CMakeLists.txt1
-rw-r--r--storage/mroonga/vendor/groonga/vendor/mruby/Makefile.am11
-rw-r--r--storage/mroonga/vendor/groonga/vendor/mruby/build_config.rb1
-rw-r--r--storage/mroonga/vendor/groonga/vendor/mruby/built_sources.am2
-rwxr-xr-xstorage/mroonga/vendor/groonga/vendor/mruby/mruby_build.rb6
-rw-r--r--storage/mroonga/vendor/groonga/vendor/mruby/sources.am6
-rw-r--r--storage/mroonga/vendor/groonga/vendor/onigmo/CMakeLists.txt13
-rw-r--r--storage/mroonga/vendor/groonga/vendor/onigmo/Makefile.am1
-rw-r--r--storage/mroonga/vendor/groonga/vendor/onigmo/config.h.cmake1
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/doc/text/news.md11
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/normalizers/CMakeLists.txt14
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/normalizers/mysql.c53
-rwxr-xr-xstorage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/build-deb.sh6
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/debian/changelog6
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/centos/groonga-normalizer-mysql.spec.in3
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/fedora/groonga-normalizer-mysql.spec.in3
-rw-r--r--storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version2
-rw-r--r--storage/mroonga/version2
-rw-r--r--storage/mroonga/version_in_hex2
-rw-r--r--storage/mroonga/version_micro2
329 files changed, 11200 insertions, 2136 deletions
diff --git a/storage/mroonga/CMakeLists.txt b/storage/mroonga/CMakeLists.txt
index e5d0abe5dcd..3b88d942165 100644
--- a/storage/mroonga/CMakeLists.txt
+++ b/storage/mroonga/CMakeLists.txt
@@ -39,11 +39,6 @@ if(BIG_ENDIAN)
endif()
endif()
-if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
- message(STATUS "Mroonga is not supported on Solaris")
- return()
-endif()
-
if(MSVC)
if(MSVC_VERSION LESS 1800)
set(MRN_OLD_MSVC_MESSAGE "Mroonga supports only MSVC 2013 or later")
@@ -115,6 +110,8 @@ if(MRN_GROONGA_BUNDLED)
add_subdirectory("${MRN_BUNDLED_GROONGA_RELATIVE_DIR}")
else()
+ set(MRN_GROONGA_EMBED OFF)
+
file(READ ${MRN_SOURCE_DIR}/required_groonga_version REQUIRED_GROONGA_VERSION)
string(STRIP "${REQUIRED_GROONGA_VERSION}" REQUIRED_GROONGA_VERSION)
@@ -323,8 +320,7 @@ set(MRN_ALL_SOURCES
if(MRN_BUNDLED)
mysql_add_plugin(mroonga
${MRN_ALL_SOURCES}
- STORAGE_ENGINE MODULE_ONLY DISABLED # see MDEV-7246
- RECOMPILE_FOR_EMBEDDED
+ STORAGE_ENGINE MODULE_ONLY
LINK_LIBRARIES ${MRN_LIBRARIES})
else()
add_library(mroonga MODULE ${MRN_ALL_SOURCES})
@@ -334,28 +330,33 @@ else()
option(WITH_DEBUG "Enable debug options" OFF)
if(WITH_DEBUG)
- add_definitions("-DSAFE_MUTEX")
+ set_property(TARGET mroonga APPEND PROPERTY
+ COMPILE_DEFINITIONS "SAFE_MUTEX")
if(CMAKE_COMPILER_IS_GNUCXX)
set(MRN_C_COMPILE_FLAGS "${MRN_C_COMPILE_FLAGS} -g3 -O0")
set(MRN_CXX_COMPILE_FLAGS "${MRN_CXX_COMPILE_FLAGS} -g3 -O0")
endif()
else()
- add_definitions("-DDBUG_OFF")
+ set_property(TARGET mroonga APPEND PROPERTY
+ COMPILE_DEFINITIONS "DBUG_OFF")
endif()
option(WITH_DEBUG_FULL "Enable full debug options" OFF)
if(WITH_DEBUG_FULL)
- add_definitions("-DSAFE_MUTEX" "SAFEMALLOC")
+ set_property(TARGET mroonga APPEND PROPERTY
+ COMPILE_DEFINITIONS "SAFE_MUTEX" "SAFEMALLOC")
endif()
option(DISABLE_FAST_MUTEXES "Force disabling fast mutex" OFF)
if(DISABLE_FAST_MUTEXES)
- add_definitions("-DFORCE_FAST_MUTEX_DISABLED=1")
+ set_property(TARGET mroonga APPEND PROPERTY
+ COMPILE_DEFINITIONS "FORCE_FAST_MUTEX_DISABLED=1")
endif()
option(WITH_FAST_MUTEXES "Enable fast mutex" OFF)
if(WITH_FAST_MUTEXES)
- add_definitions("-DMY_PTHREAD_FASTMUTEX")
+ set_property(TARGET mroonga APPEND PROPERTY
+ COMPILE_DEFINITIONS "MY_PTHREAD_FASTMUTEX")
endif()
if(CMAKE_COMPILER_IS_GNUCXX)
@@ -381,7 +382,8 @@ else()
COMPILE_FLAGS "${MRN_CXX_COMPILE_FLAGS}")
set_source_files_properties(${LIBMRN_NO_MYSQL_SOURCES} PROPERTIES
COMPILE_FLAGS "${MRN_CXX_COMPILE_FLAGS}")
- add_definitions("-DMYSQL_DYNAMIC_PLUGIN")
+ set_property(TARGET mroonga APPEND PROPERTY
+ COMPILE_DEFINITIONS "MYSQL_DYNAMIC_PLUGIN")
set_target_properties(mroonga PROPERTIES
PREFIX ""
OUTPUT_NAME "ha_mroonga")
@@ -390,16 +392,33 @@ else()
endif()
if(GROONGA_NORMALIZER_MYSQL_FOUND)
- add_definitions("-DWITH_GROONGA_NORMALIZER_MYSQL=1")
+ set_property(TARGET mroonga APPEND PROPERTY
+ COMPILE_DEFINITIONS "WITH_GROONGA_NORMALIZER_MYSQL=1")
if(MRN_GROONGA_NORMALIZER_MYSQL_EMBED)
- add_definitions("-DMRN_GROONGA_NORMALIZER_MYSQL_EMBED")
+ set_property(TARGET mroonga APPEND PROPERTY
+ COMPILE_DEFINITIONS "MRN_GROONGA_NORMALIZER_MYSQL_EMBEDDED")
else()
- add_definitions("-DGROONGA_NORMALIZER_MYSQL_PLUGIN_NAME=\"normalizers/mysql\"")
+ set_property(TARGET mroonga APPEND PROPERTY
+ COMPILE_DEFINITIONS "GROONGA_NORMALIZER_MYSQL_PLUGIN_NAME=\"normalizers/mysql\"")
endif()
endif()
-set(MRN_DEFAULT_PARSER "TokenBigram" CACHE STRING "The default fulltext parser")
-add_definitions("-DMRN_PARSER_DEFAULT=\"${MRN_DEFAULT_PARSER}\"")
+if(MRN_GROONGA_EMBED)
+ set_property(TARGET mroonga APPEND PROPERTY
+ COMPILE_DEFINITIONS "MRN_GROONGA_EMBEDDED")
+endif()
+
+set(MRN_DEFAULT_PARSER "" CACHE STRING
+ "The default fulltext parser (Deprecated. Use MRN_DEFAULT_TOKENIZER instead.)")
+set(MRN_DEFAULT_TOKENIZER "" CACHE STRING
+ "The default tokenizer for fulltext index")
+if(NOT ${MRN_DEFAULT_TOKENIZER} STREQUAL "")
+ set_property(TARGET mroonga APPEND PROPERTY
+ COMPILE_DEFINITIONS "MRN_DEFAULT_TOKENIZER=\"${MRN_DEFAULT_TOKENIZER}\"")
+elseif(NOT ${MRN_DEFAULT_PARSER} STREQUAL "")
+ set_property(TARGET mroonga APPEND PROPERTY
+ COMPILE_DEFINITIONS "MRN_DEFAULT_TOKENIZER=\"${MRN_DEFAULT_PARSER}\"")
+endif()
configure_file(
"${PROJECT_SOURCE_DIR}/mrn_version.h.in"
diff --git a/storage/mroonga/appveyor.yml b/storage/mroonga/appveyor.yml
index de368b85660..038d590054e 100644
--- a/storage/mroonga/appveyor.yml
+++ b/storage/mroonga/appveyor.yml
@@ -3,16 +3,16 @@ clone_depth: 10
install:
- cd ..
- choco install -y curl 7zip.commandline
- - curl -O http://mirror.jmu.edu/pub/mariadb/mariadb-10.0.17/source/mariadb-10.0.17.tar.gz
- - 7z x mariadb-10.0.17.tar.gz
- - 7z x mariadb-10.0.17.tar > nul
- - cd mariadb-10.0.17
+ - curl -O http://mirror.jmu.edu/pub/mariadb/mariadb-10.0.20/source/mariadb-10.0.20.tar.gz
+ - 7z x mariadb-10.0.20.tar.gz
+ - 7z x mariadb-10.0.20.tar > nul
+ - cd mariadb-10.0.20
- rmdir /S /Q storage\mroonga\
- move ..\mroonga storage\mroonga
- git clone --quiet --depth 1 https://github.com/groonga/groonga.git ..\groonga
- cd ..\groonga
- git submodule update --init
- - cd ..\mariadb-10.0.17
+ - cd ..\mariadb-10.0.20
- rmdir /S /Q ..\groonga\test\
- mkdir storage\mroonga\vendor
- move ..\groonga storage\mroonga\vendor\groonga
diff --git a/storage/mroonga/build/makefiles/gettext.am b/storage/mroonga/build/makefiles/gettext.am
index 9706b485dd1..9cea8ce63c1 100644
--- a/storage/mroonga/build/makefiles/gettext.am
+++ b/storage/mroonga/build/makefiles/gettext.am
@@ -1,6 +1,8 @@
include $(top_srcdir)/doc/files.am
include $(top_srcdir)/build/makefiles/sphinx-build.am
+CLEANFILES =
+
EXTRA_DIST += \
$(po_files)
@@ -11,9 +13,11 @@ endif
if DOCUMENT_BUILDABLE
BUILT_SOURCES += \
+ mo-build-stamp
+CLEANFILES += \
pot-build-stamp \
edit-po-build-stamp \
- $(mo_files)
+ mo-build-stamp
endif
SUFFIXES += .pot .po .mo .edit
@@ -47,8 +51,8 @@ SUFFIXES += .pot .po .mo .edit
msgfmt -o $@ $<
if DOCUMENT_BUILDABLE
-update: pot-build-stamp edit-po-build-stamp
-build: update $(mo_files)
+update: edit-po-build-stamp
+build: mo-build-stamp
else
update:
build:
@@ -68,6 +72,15 @@ pot-build-stamp: $(absolute_source_files)
$(MAKE) gettext
@touch $@
-edit-po-build-stamp: $(absolute_source_files)
+edit-po-build-stamp: pot-build-stamp
$(MAKE) $(edit_po_files)
@touch $@
+
+mo_build_stamp_dependencies = edit-po-build-stamp
+if DOCUMENT_BUILDABLE
+mo_build_stamp_dependencies += $(edit_po_files)
+endif
+
+mo-build-stamp: $(mo_build_stamp_dependencies)
+ $(MAKE) $(mo_files)
+ @touch $@
diff --git a/storage/mroonga/build/makefiles/sphinx.am b/storage/mroonga/build/makefiles/sphinx.am
index f84fb23b739..c68f62e26ec 100644
--- a/storage/mroonga/build/makefiles/sphinx.am
+++ b/storage/mroonga/build/makefiles/sphinx.am
@@ -106,7 +106,7 @@ help:
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
man: man-build-stamp
-html: html-build-stamp
+html: html-recursive html-build-stamp
dirhtml: dirhtml-build-stamp
pickle: pickle-build-stamp
json: json-build-stamp
diff --git a/storage/mroonga/configure.ac b/storage/mroonga/configure.ac
index dc127c17838..f60b481e0ea 100644
--- a/storage/mroonga/configure.ac
+++ b/storage/mroonga/configure.ac
@@ -309,20 +309,30 @@ CONFIG_OPTION_GROONGA_NORMALIZER_MYSQL
AC_ARG_WITH(default_parser,
[AS_HELP_STRING([--with-default-parser=PARSER],
- [specify the default fulltext parser like
+ [Deprecated. Use --with-default-tokenizer=TOKENIZER instead.
+ specify the default fulltext parser like
--with-default-parser=TokenMecab.
(default: TokenBigram)])],
[default_parser=$withval],
[default_parser=no])
if test x"$default_parser" != x"no"; then
- AC_DEFINE_UNQUOTED(MRN_PARSER_DEFAULT,
+ AC_DEFINE_UNQUOTED(MRN_TOKENIZER_DEFAULT,
"$default_parser",
- "specified default fulltext parser")
- MRN_DEFAULT_PARSER=$default_parser
-else
- MRN_DEFAULT_PARSER=TokenBigram
+ "specified the default tokenizer for fulltext index")
+fi
+
+AC_ARG_WITH(default_tokenizer,
+ [AS_HELP_STRING([--with-default-tokenizer=TOKENIZER],
+ [specify the default tokenizer for fulltext index like
+ --with-default-tokenizer=TokenMecab.
+ (default: TokenBigram)])],
+ [default_tokenizer=$withval],
+ [default_tokenizer=no])
+if test x"$default_tokenizer" != x"no"; then
+ AC_DEFINE_UNQUOTED(MRN_DEFAULT_TOKENIZER,
+ "$default_tokenizer",
+ "specified the default tokenizer for fulltext index")
fi
-AC_SUBST(MRN_DEFAULT_PARSER)
AC_ARG_ENABLE(fast_mutexes,
[AS_HELP_STRING([--disable-fast-mutexes],
diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp
index 83f03fcb272..a94278e19c2 100644
--- a/storage/mroonga/ha_mroonga.cpp
+++ b/storage/mroonga/ha_mroonga.cpp
@@ -27,14 +27,11 @@
#pragma implementation
#endif
-#if MYSQL_VERSION_ID >= 50500
-# include <sql_plugin.h>
-# include <sql_show.h>
-# include <key.h>
-# include <tztime.h>
-# include <sql_base.h>
-#endif
-
+#include <sql_plugin.h>
+#include <sql_show.h>
+#include <key.h>
+#include <tztime.h>
+#include <sql_base.h>
#include <sql_select.h>
#include <item_sum.h>
@@ -102,6 +99,10 @@
# include <sql_table.h>
#endif
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+# include <create_options.h>
+#endif
+
// for debug
#define MRN_CLASS_NAME "ha_mroonga"
@@ -110,7 +111,11 @@
#define MRN_LONG_TEXT_SIZE (1 << 31) // 2Gbytes
#ifdef MRN_HAVE_TDC_LOCK_TABLE_SHARE
-# define mrn_open_mutex(share) &((share)->tdc.LOCK_table_share)
+# ifdef MRN_TABLE_SHARE_TDC_IS_POINTER
+# define mrn_open_mutex(share) &((share)->tdc->LOCK_table_share)
+# else
+# define mrn_open_mutex(share) &((share)->tdc.LOCK_table_share)
+# endif
# define mrn_open_mutex_lock(share) do { \
TABLE_SHARE *share_ = share; \
if (share_ && share_->tmp_table == NO_TMP_TABLE) { \
@@ -156,24 +161,10 @@ static mysql_mutex_t *mrn_LOCK_open;
# define mrn_declare_plugin(NAME) maria_declare_plugin(NAME)
# define mrn_declare_plugin_end maria_declare_plugin_end
# define MRN_PLUGIN_LAST_VALUES MRN_VERSION, MariaDB_PLUGIN_MATURITY_STABLE
-# if MYSQL_VERSION_ID >= 100000
-# define MRN_ABORT_ON_WARNING(thd) thd_kill_level(thd)
-# else
-# define MRN_ABORT_ON_WARNING(thd) thd->abort_on_warning
-# endif
#else
# define mrn_declare_plugin(NAME) mysql_declare_plugin(NAME)
# define mrn_declare_plugin_end mysql_declare_plugin_end
-# ifdef MRN_PLUGIN_HAVE_FLAGS
-# define MRN_PLUGIN_LAST_VALUES NULL, 0
-# else
-# define MRN_PLUGIN_LAST_VALUES NULL
-# endif
-# if MYSQL_VERSION_ID >= 50706
-# define MRN_ABORT_ON_WARNING(thd) false
-# else
-# define MRN_ABORT_ON_WARNING(thd) thd->abort_on_warning
-# endif
+# define MRN_PLUGIN_LAST_VALUES NULL, 0
#endif
#if MYSQL_VERSION_ID >= 100007 && defined(MRN_MARIADB_P)
@@ -267,9 +258,7 @@ uint grn_atoui(const char *nptr, const char *end, const char **rest);
# ifdef MRN_TABLE_SHARE_HAVE_LOCK_SHARE
PSI_mutex_key *mrn_table_share_lock_share;
# endif
-# ifdef MRN_TABLE_SHARE_HAVE_LOCK_HA_DATA
PSI_mutex_key *mrn_table_share_lock_ha_data;
-# endif
# endif
static PSI_mutex_key mrn_open_tables_mutex_key;
static PSI_mutex_key mrn_long_term_share_mutex_key;
@@ -357,11 +346,6 @@ static const char *mrn_inspect_thr_lock_type(enum thr_lock_type lock_type)
case TL_WRITE_ALLOW_WRITE:
inspected = "TL_WRITE_ALLOW_WRITE";
break;
-#ifdef MRN_HAVE_TL_WRITE_ALLOW_READ
- case TL_WRITE_ALLOW_READ:
- inspected = "TL_WRITE_ALLOW_READ";
- break;
-#endif
#ifdef MRN_HAVE_TL_WRITE_CONCURRENT_DEFAULT
case TL_WRITE_CONCURRENT_DEFAULT:
inspected = "TL_WRITE_CONCURRENT_DEFAULT";
@@ -524,19 +508,15 @@ static const char *mrn_inspect_extra_function(enum ha_extra_function operation)
case HA_EXTRA_PREPARE_FOR_RENAME:
inspected = "HA_EXTRA_PREPARE_FOR_RENAME";
break;
-#ifdef MRN_HAVE_HA_EXTRA_ADD_CHILDREN_LIST
case HA_EXTRA_ADD_CHILDREN_LIST:
inspected = "HA_EXTRA_ADD_CHILDREN_LIST";
break;
-#endif
case HA_EXTRA_ATTACH_CHILDREN:
inspected = "HA_EXTRA_ATTACH_CHILDREN";
break;
-#ifdef MRN_HAVE_HA_EXTRA_IS_ATTACHED_CHILDREN
case HA_EXTRA_IS_ATTACHED_CHILDREN:
inspected = "HA_EXTRA_IS_ATTACHED_CHILDREN";
break;
-#endif
case HA_EXTRA_DETACH_CHILDREN:
inspected = "HA_EXTRA_DETACH_CHILDREN";
break;
@@ -597,7 +577,7 @@ static bool mrn_log_file_opened = false;
static grn_log_level mrn_log_level_default = GRN_LOG_DEFAULT_LEVEL;
static ulong mrn_log_level = mrn_log_level_default;
-char *mrn_default_parser = NULL;
+char *mrn_default_tokenizer = NULL;
char *mrn_default_wrapper_engine = NULL;
static int mrn_lock_timeout = grn_get_lock_timeout();
static char *mrn_libgroonga_version = const_cast<char *>(grn_get_version());
@@ -630,6 +610,11 @@ static TYPELIB mrn_boolean_mode_syntax_flags_typelib = {
NULL
};
#endif
+#ifdef MRN_GROONGA_EMBEDDED
+static my_bool mrn_libgroonga_embedded = TRUE;
+#else
+static my_bool mrn_libgroonga_embedded = FALSE;
+#endif
typedef enum {
MRN_ACTION_ON_ERROR_ERROR,
@@ -836,8 +821,8 @@ static MYSQL_SYSVAR_STR(log_file, mrn_log_file_path,
mrn_log_file_update,
MRN_LOG_FILE_PATH);
-static void mrn_default_parser_update(THD *thd, struct st_mysql_sys_var *var,
- void *var_ptr, const void *save)
+static void mrn_default_tokenizer_update(THD *thd, struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save)
{
MRN_DBUG_ENTER_FUNCTION();
const char *new_value = *((const char **)save);
@@ -848,12 +833,12 @@ static void mrn_default_parser_update(THD *thd, struct st_mysql_sys_var *var,
mrn_change_encoding(&ctx, system_charset_info);
if (strcmp(*old_value_ptr, new_value) == 0) {
GRN_LOG(&ctx, GRN_LOG_NOTICE,
- "default parser isn't changed "
- "because the requested default parser isn't different: <%s>",
+ "default tokenizer for fulltext index isn't changed "
+ "because the requested default tokenizer isn't different: <%s>",
new_value);
} else {
GRN_LOG(&ctx, GRN_LOG_NOTICE,
- "default fulltext parser is changed: <%s> -> <%s>",
+ "default tokenizer for fulltext index is changed: <%s> -> <%s>",
*old_value_ptr, new_value);
}
@@ -869,12 +854,20 @@ static void mrn_default_parser_update(THD *thd, struct st_mysql_sys_var *var,
DBUG_VOID_RETURN;
}
-static MYSQL_SYSVAR_STR(default_parser, mrn_default_parser,
+static MYSQL_SYSVAR_STR(default_parser, mrn_default_tokenizer,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
- "default fulltext parser",
+ "default fulltext parser "
+ "(Deprecated. Use mroonga_default_tokenizer instead.)",
NULL,
- mrn_default_parser_update,
- MRN_PARSER_DEFAULT);
+ mrn_default_tokenizer_update,
+ MRN_DEFAULT_TOKENIZER);
+
+static MYSQL_SYSVAR_STR(default_tokenizer, mrn_default_tokenizer,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
+ "default tokenizer for fulltext index",
+ NULL,
+ mrn_default_tokenizer_update,
+ MRN_DEFAULT_TOKENIZER);
static MYSQL_THDVAR_BOOL(
dry_write, /* name */
@@ -1084,11 +1077,19 @@ static MYSQL_THDVAR_INT(max_n_records_for_estimate,
INT_MAX,
0);
+static MYSQL_SYSVAR_BOOL(libgroonga_embedded, mrn_libgroonga_embedded,
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+ "Whether libgroonga is embedded or not",
+ NULL,
+ NULL,
+ mrn_libgroonga_embedded);
+
static struct st_mysql_sys_var *mrn_system_variables[] =
{
MYSQL_SYSVAR(log_level),
MYSQL_SYSVAR(log_file),
MYSQL_SYSVAR(default_parser),
+ MYSQL_SYSVAR(default_tokenizer),
MYSQL_SYSVAR(dry_write),
MYSQL_SYSVAR(enable_optimization),
MYSQL_SYSVAR(match_escalation_threshold),
@@ -1105,6 +1106,7 @@ static struct st_mysql_sys_var *mrn_system_variables[] =
MYSQL_SYSVAR(boolean_mode_syntax_flags),
#endif
MYSQL_SYSVAR(max_n_records_for_estimate),
+ MYSQL_SYSVAR(libgroonga_embedded),
NULL
};
@@ -1213,7 +1215,7 @@ static int mrn_close_connection(handlerton *hton, THD *thd)
MRN_DBUG_ENTER_FUNCTION();
void *p = *thd_ha_data(thd, mrn_hton_ptr);
if (p) {
- mrn_clear_alter_share(thd);
+ mrn_clear_slot_data(thd);
free(p);
*thd_ha_data(thd, mrn_hton_ptr) = (void *) NULL;
{
@@ -1409,13 +1411,14 @@ static grn_builtin_type mrn_grn_type_from_field(grn_ctx *ctx, Field *field,
return type;
}
-grn_obj_flags mrn_parse_grn_column_create_flags(THD *thd,
- grn_ctx *ctx,
- const char *flag_names,
- uint flag_names_length)
+static bool mrn_parse_grn_column_create_flags(THD *thd,
+ grn_ctx *ctx,
+ const char *flag_names,
+ uint flag_names_length,
+ grn_obj_flags *column_flags)
{
- grn_obj_flags flags = 0;
const char *flag_names_end = flag_names + flag_names_length;
+ bool found = false;
while (flag_names < flag_names_end) {
uint rest_length = flag_names_end - flag_names;
@@ -1425,14 +1428,17 @@ grn_obj_flags mrn_parse_grn_column_create_flags(THD *thd,
continue;
}
if (rest_length >= 13 && !memcmp(flag_names, "COLUMN_SCALAR", 13)) {
- flags |= GRN_OBJ_COLUMN_SCALAR;
+ *column_flags |= GRN_OBJ_COLUMN_SCALAR;
flag_names += 13;
+ found = true;
} else if (rest_length >= 13 && !memcmp(flag_names, "COLUMN_VECTOR", 13)) {
- flags |= GRN_OBJ_COLUMN_VECTOR;
+ *column_flags |= GRN_OBJ_COLUMN_VECTOR;
flag_names += 13;
+ found = true;
} else if (rest_length >= 13 && !memcmp(flag_names, "COMPRESS_ZLIB", 13)) {
if (mrn_libgroonga_support_zlib) {
- flags |= GRN_OBJ_COMPRESS_ZLIB;
+ *column_flags |= GRN_OBJ_COMPRESS_ZLIB;
+ found = true;
} else {
push_warning_printf(thd, MRN_SEVERITY_WARNING,
ER_MRN_UNSUPPORTED_COLUMN_FLAG_NUM,
@@ -1442,7 +1448,8 @@ grn_obj_flags mrn_parse_grn_column_create_flags(THD *thd,
flag_names += 13;
} else if (rest_length >= 12 && !memcmp(flag_names, "COMPRESS_LZ4", 12)) {
if (mrn_libgroonga_support_lz4) {
- flags |= GRN_OBJ_COMPRESS_LZ4;
+ *column_flags |= GRN_OBJ_COMPRESS_LZ4;
+ found = true;
} else {
push_warning_printf(thd, MRN_SEVERITY_WARNING,
ER_MRN_UNSUPPORTED_COLUMN_FLAG_NUM,
@@ -1459,20 +1466,18 @@ grn_obj_flags mrn_parse_grn_column_create_flags(THD *thd,
push_warning_printf(thd, MRN_SEVERITY_WARNING,
ER_MRN_INVALID_COLUMN_FLAG_NUM,
ER_MRN_INVALID_COLUMN_FLAG_STR,
- invalid_flag_name,
- "COLUMN_SCALAR");
- flags |= GRN_OBJ_COLUMN_SCALAR;
+ invalid_flag_name);
break;
}
}
- return flags;
+ return found;
}
-bool mrn_parse_grn_index_column_flags(THD *thd,
- grn_ctx *ctx,
- const char *flag_names,
- uint flag_names_length,
- grn_obj_flags *index_column_flags)
+static bool mrn_parse_grn_index_column_flags(THD *thd,
+ grn_ctx *ctx,
+ const char *flag_names,
+ uint flag_names_length,
+ grn_obj_flags *index_column_flags)
{
const char *flag_names_end = flag_names + flag_names_length;
bool found = false;
@@ -1588,6 +1593,24 @@ static uint mrn_alter_table_flags(uint flags)
}
#endif
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+static ha_create_table_option mrn_field_options[] =
+{
+ HA_FOPTION_STRING("GROONGA_TYPE", groonga_type),
+ HA_FOPTION_STRING("FLAGS", flags),
+ HA_FOPTION_END
+};
+
+static ha_create_table_option mrn_index_options[] =
+{
+ HA_IOPTION_STRING("TOKENIZER", tokenizer),
+ HA_IOPTION_STRING("NORMALIZER", normalizer),
+ HA_IOPTION_STRING("TOKEN_FILTERS", token_filters),
+ HA_IOPTION_STRING("FLAGS", flags),
+ HA_IOPTION_END
+};
+#endif
+
static int mrn_init(void *p)
{
// init handlerton
@@ -1606,6 +1629,10 @@ static int mrn_init(void *p)
#ifdef MRN_HAVE_HTON_ALTER_TABLE_FLAGS
hton->alter_table_flags = mrn_alter_table_flags;
#endif
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ hton->field_options = mrn_field_options;
+ hton->index_options = mrn_index_options;
+#endif
mrn_hton_ptr = hton;
#ifdef _WIN32
@@ -1629,11 +1656,9 @@ static int mrn_init(void *p)
(PSI_mutex_key *)GetProcAddress(current_module,
MRN_TABLE_SHARE_LOCK_SHARE_PROC);
# endif
-# ifdef MRN_TABLE_SHARE_HAVE_LOCK_HA_DATA
- mrn_table_share_lock_ha_data =
- (PSI_mutex_key *)GetProcAddress(current_module,
- MRN_TABLE_SHARE_LOCK_HA_DATA_PROC);
-# endif
+ mrn_table_share_lock_ha_data =
+ (PSI_mutex_key *)GetProcAddress(current_module,
+ MRN_TABLE_SHARE_LOCK_HA_DATA_PROC);
# endif
#else
mrn_binlog_filter = binlog_filter;
@@ -1790,7 +1815,7 @@ static int mrn_deinit(void *p)
mrn::Lock lock(&mrn_allocated_thds_mutex);
while ((tmp_thd = (THD *) my_hash_element(&mrn_allocated_thds, 0)))
{
- mrn_clear_alter_share(tmp_thd);
+ mrn_clear_slot_data(tmp_thd);
void *slot_ptr = mrn_get_slot_data(tmp_thd, false);
if (slot_ptr) free(slot_ptr);
*thd_ha_data(tmp_thd, mrn_hton_ptr) = (void *) NULL;
@@ -2367,10 +2392,10 @@ const char *ha_mroonga::table_type() const
const char *ha_mroonga::index_type(uint key_nr)
{
MRN_DBUG_ENTER_METHOD();
- KEY key_info = table->s->key_info[key_nr];
- if (key_info.algorithm == HA_KEY_ALG_FULLTEXT) {
+ KEY *key_info = &(table->s->key_info[key_nr]);
+ if (key_info->algorithm == HA_KEY_ALG_FULLTEXT) {
DBUG_RETURN("FULLTEXT");
- } else if (key_info.algorithm == HA_KEY_ALG_HASH) {
+ } else if (key_info->algorithm == HA_KEY_ALG_HASH) {
DBUG_RETURN("HASH");
} else {
DBUG_RETURN("BTREE");
@@ -2655,9 +2680,10 @@ ulonglong ha_mroonga::table_flags() const
ulong ha_mroonga::wrapper_index_flags(uint idx, uint part, bool all_parts) const
{
ulong index_flags;
- KEY key = table_share->key_info[idx];
+ KEY *key = &(table_share->key_info[idx]);
MRN_DBUG_ENTER_METHOD();
- if (key.algorithm == HA_KEY_ALG_BTREE || key.algorithm == HA_KEY_ALG_UNDEF) {
+ if (key->algorithm == HA_KEY_ALG_BTREE ||
+ key->algorithm == HA_KEY_ALG_UNDEF) {
MRN_SET_WRAP_SHARE_KEY(share, table->s);
MRN_SET_WRAP_TABLE_KEY(this, table);
index_flags = wrap_handler->index_flags(idx, part, all_parts);
@@ -2673,18 +2699,27 @@ ulong ha_mroonga::storage_index_flags(uint idx, uint part, bool all_parts) const
{
MRN_DBUG_ENTER_METHOD();
ulong flags;
- KEY key = table_share->key_info[idx];
- if (key.algorithm == HA_KEY_ALG_BTREE || key.algorithm == HA_KEY_ALG_UNDEF) {
+ KEY *key = &(table_share->key_info[idx]);
+ if (key->algorithm == HA_KEY_ALG_BTREE ||
+ key->algorithm == HA_KEY_ALG_UNDEF) {
flags = HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE;
bool need_normalize_p = false;
- Field *field = &key.key_part[part].field[0];
+ // TODO: MariaDB 10.1 passes key->user_defined_key_parts as part
+ // for ORDER BY DESC. We just it fallback to part = 0. We may use
+ // it for optimization in the future.
+ //
+ // See also: test_if_order_by_key() in sql/sql_select.cc.
+ if (KEY_N_KEY_PARTS(key) == part) {
+ part = 0;
+ }
+ Field *field = &(key->key_part[part].field[0]);
if (field && should_normalize(field)) {
need_normalize_p = true;
}
if (!need_normalize_p) {
flags |= HA_KEYREAD_ONLY;
}
- if (KEY_N_KEY_PARTS(&key) > 1 || !need_normalize_p) {
+ if (KEY_N_KEY_PARTS(key) > 1 || !need_normalize_p) {
flags |= HA_READ_ORDER;
}
} else {
@@ -2697,11 +2732,11 @@ ulong ha_mroonga::index_flags(uint idx, uint part, bool all_parts) const
{
MRN_DBUG_ENTER_METHOD();
- KEY key = table_share->key_info[idx];
- if (key.algorithm == HA_KEY_ALG_FULLTEXT) {
+ KEY *key = &(table_share->key_info[idx]);
+ if (key->algorithm == HA_KEY_ALG_FULLTEXT) {
DBUG_RETURN(HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR);
}
- if (mrn_is_geo_key(&key)) {
+ if (mrn_is_geo_key(key)) {
DBUG_RETURN(HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR);
}
@@ -2833,9 +2868,23 @@ int ha_mroonga::wrapper_create(const char *name, TABLE *table,
share = tmp_share;
MRN_SET_WRAP_SHARE_KEY(tmp_share, table->s);
MRN_SET_WRAP_TABLE_KEY(this, table);
- if (!(hnd =
- tmp_share->hton->create(tmp_share->hton, table->s,
- current_thd->mem_root)))
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ if (parse_engine_table_options(ha_thd(), tmp_share->hton, table->s)) {
+ MRN_SET_BASE_SHARE_KEY(tmp_share, table->s);
+ MRN_SET_BASE_TABLE_KEY(this, table);
+ share = NULL;
+ if (wrap_key_info)
+ {
+ my_free(wrap_key_info);
+ wrap_key_info = NULL;
+ }
+ base_key_info = NULL;
+ error = MRN_GET_ERROR_NUMBER;
+ DBUG_RETURN(error);
+ }
+#endif
+ hnd = get_new_handler(table->s, current_thd->mem_root, tmp_share->hton);
+ if (!hnd)
{
MRN_SET_BASE_SHARE_KEY(tmp_share, table->s);
MRN_SET_BASE_TABLE_KEY(this, table);
@@ -2848,7 +2897,6 @@ int ha_mroonga::wrapper_create(const char *name, TABLE *table,
base_key_info = NULL;
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
- hnd->init();
error = hnd->ha_create(name, table, info);
MRN_SET_BASE_SHARE_KEY(tmp_share, table->s);
MRN_SET_BASE_TABLE_KEY(this, table);
@@ -2856,7 +2904,7 @@ int ha_mroonga::wrapper_create(const char *name, TABLE *table,
delete hnd;
if (error) {
- wrapper_delete_index(name, tmp_share, mapper.table_name());
+ generic_delete_table(name, mapper.table_name());
}
if (wrap_key_info)
@@ -2949,8 +2997,7 @@ int ha_mroonga::wrapper_create_index_fulltext(const char *grn_table_name,
mrn_change_encoding(ctx, system_charset_info);
index_tables[i] = index_table;
- grn_obj *tokenizer = find_tokenizer(tmp_share->key_parser[i],
- tmp_share->key_parser_length[i]);
+ grn_obj *tokenizer = find_tokenizer(key_info, tmp_share, i);
if (tokenizer) {
grn_info_type info_type = GRN_INFO_DEFAULT_TOKENIZER;
grn_obj_set_info(ctx, index_table, info_type, tokenizer);
@@ -3097,14 +3144,14 @@ int ha_mroonga::wrapper_create_index(const char *name, TABLE *table,
for (i = 0; i < n_keys; i++) {
index_tables[i] = NULL;
- KEY key_info = table->s->key_info[i];
- if (key_info.algorithm == HA_KEY_ALG_FULLTEXT) {
+ KEY *key_info = &(table->s->key_info[i]);
+ if (key_info->algorithm == HA_KEY_ALG_FULLTEXT) {
error = wrapper_create_index_fulltext(grn_table_name,
- i, &key_info,
+ i, key_info,
index_tables, NULL, tmp_share);
- } else if (mrn_is_geo_key(&key_info)) {
+ } else if (mrn_is_geo_key(key_info)) {
error = wrapper_create_index_geo(grn_table_name,
- i, &key_info,
+ i, key_info,
index_tables, NULL, tmp_share);
}
}
@@ -3160,12 +3207,12 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
grn_obj *pkey_type;
uint pkey_nr = table->s->primary_key;
if (pkey_nr != MAX_INDEXES) {
- KEY key_info = table->s->key_info[pkey_nr];
+ KEY *key_info = &(table->s->key_info[pkey_nr]);
bool is_id;
- int key_parts = KEY_N_KEY_PARTS(&key_info);
+ int key_parts = KEY_N_KEY_PARTS(key_info);
if (key_parts == 1) {
- Field *pkey_field = key_info.key_part[0].field;
+ Field *pkey_field = key_info->key_part[0].field;
const char *column_name = pkey_field->field_name;
is_id = (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0);
@@ -3177,7 +3224,7 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
}
// default algorithm is BTREE ==> PAT
- if (!is_id && key_info.algorithm == HA_KEY_ALG_HASH) {
+ if (!is_id && key_info->algorithm == HA_KEY_ALG_HASH) {
table_flags |= GRN_OBJ_TABLE_HASH_KEY;
} else if (!is_id) {
table_flags |= GRN_OBJ_TABLE_PAT_KEY;
@@ -3212,8 +3259,8 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
if (table_flags == (GRN_OBJ_PERSISTENT | GRN_OBJ_TABLE_PAT_KEY) ||
table_flags == (GRN_OBJ_PERSISTENT | GRN_OBJ_TABLE_HASH_KEY)) {
- KEY key_info = table->s->key_info[pkey_nr];
- int key_parts = KEY_N_KEY_PARTS(&key_info);
+ KEY *key_info = &(table->s->key_info[pkey_nr]);
+ int key_parts = KEY_N_KEY_PARTS(key_info);
if (key_parts == 1) {
grn_obj *normalizer = NULL;
if (tmp_share->normalizer) {
@@ -3221,9 +3268,9 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
tmp_share->normalizer,
tmp_share->normalizer_length);
} else {
- Field *field = &(key_info.key_part->field[0]);
+ Field *field = &(key_info->key_part->field[0]);
if (should_normalize(field)) {
- normalizer = find_normalizer(&key_info);
+ normalizer = find_normalizer(key_info);
}
}
if (normalizer) {
@@ -3259,7 +3306,6 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
/* create columns */
uint n_columns = table->s->fields;
for (uint i = 0; i < n_columns; i++) {
- grn_obj *col_type;
Field *field = table->s->field[i];
const char *column_name = field->field_name;
int column_name_size = strlen(column_name);
@@ -3280,19 +3326,18 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
#endif
grn_obj_flags col_flags = GRN_OBJ_PERSISTENT;
- if (tmp_share->col_flags[i]) {
- col_flags |= mrn_parse_grn_column_create_flags(ha_thd(),
- ctx,
- tmp_share->col_flags[i],
- tmp_share->col_flags_length[i]);
- } else {
+ if (!find_column_flags(field, tmp_share, i, &col_flags)) {
col_flags |= GRN_OBJ_COLUMN_SCALAR;
}
- grn_builtin_type gtype = mrn_grn_type_from_field(ctx, field, false);
- if (tmp_share->col_type[i]) {
- col_type = grn_ctx_get(ctx, tmp_share->col_type[i], -1);
- } else {
- col_type = grn_ctx_at(ctx, gtype);
+
+ grn_obj *col_type;
+ {
+ int column_type_error_code = ER_CANT_CREATE_TABLE;
+ col_type = find_column_type(field, tmp_share, i, column_type_error_code);
+ if (!col_type) {
+ grn_obj_remove(ctx, table_obj);
+ DBUG_RETURN(column_type_error_code);
+ }
}
char *col_path = NULL; // we don't specify path
@@ -3445,17 +3490,11 @@ bool ha_mroonga::storage_create_foreign_key(TABLE *table,
DBUG_RETURN(false);
}
-#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS
table_list.init_one_table(mapper.db_name(),
strlen(mapper.db_name()),
mapper.mysql_table_name(),
strlen(mapper.mysql_table_name()),
mapper.mysql_table_name(), TL_WRITE);
-#else
- table_list.init_one_table(mapper.db_name(),
- mapper.mysql_table_name(),
- TL_WRITE);
-#endif
mrn_open_mutex_lock(table->s);
tmp_ref_table_share =
mrn_create_tmp_table_share(&table_list, ref_path, &error);
@@ -3572,16 +3611,16 @@ int ha_mroonga::storage_create_validate_index(TABLE *table)
/* checking if index is used for virtual columns */
uint n_keys = table->s->keys;
for (i = 0; i < n_keys; i++) {
- KEY key_info = table->s->key_info[i];
+ KEY *key_info = &(table->s->key_info[i]);
// must be single column key
- int key_parts = KEY_N_KEY_PARTS(&key_info);
+ int key_parts = KEY_N_KEY_PARTS(key_info);
if (key_parts != 1) {
continue;
}
- Field *field = key_info.key_part[0].field;
+ Field *field = key_info->key_part[0].field;
const char *column_name = field->field_name;
if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
- if (key_info.algorithm == HA_KEY_ALG_HASH) {
+ if (key_info->algorithm == HA_KEY_ALG_HASH) {
continue; // hash index is ok
}
GRN_LOG(ctx, GRN_LOG_ERROR, "only hash index can be defined for _id");
@@ -3660,8 +3699,7 @@ int ha_mroonga::storage_create_index_table(TABLE *table,
}
if (key_info->flags & HA_FULLTEXT) {
- grn_obj *tokenizer = find_tokenizer(tmp_share->key_parser[i],
- tmp_share->key_parser_length[i]);
+ grn_obj *tokenizer = find_tokenizer(key_info, tmp_share, i);
if (tokenizer) {
grn_info_type info_type = GRN_INFO_DEFAULT_TOKENIZER;
grn_obj_set_info(ctx, index_table, info_type, tokenizer);
@@ -3909,6 +3947,8 @@ int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
if (error) {
mrn_free_long_term_share(tmp_share->long_term_share);
tmp_share->long_term_share = NULL;
+ } else {
+ error = add_wrap_hton(tmp_share->table_name, tmp_share->hton);
}
mrn_free_share(tmp_share);
DBUG_RETURN(error);
@@ -3956,8 +3996,8 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked)
MRN_SET_WRAP_TABLE_KEY(this, table);
if (!is_clone)
{
- if (!(wrap_handler =
- share->hton->create(share->hton, table->s, &mem_root)))
+ wrap_handler = get_new_handler(table->s, &mem_root, share->hton);
+ if (!wrap_handler)
{
MRN_SET_BASE_SHARE_KEY(share, table->s);
MRN_SET_BASE_TABLE_KEY(this, table);
@@ -3969,19 +4009,13 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked)
base_key_info = NULL;
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
- wrap_handler->init();
#ifdef MRN_HANDLER_HAVE_SET_HA_SHARE_REF
wrap_handler->set_ha_share_ref(&table->s->ha_share);
#endif
error = wrap_handler->ha_open(table, name, mode, test_if_locked);
} else {
-#ifdef MRN_HANDLER_CLONE_NEED_NAME
if (!(wrap_handler = parent_for_clone->wrap_handler->clone(name,
mem_root_for_clone)))
-#else
- if (!(wrap_handler = parent_for_clone->wrap_handler->clone(
- mem_root_for_clone)))
-#endif
{
MRN_SET_BASE_SHARE_KEY(share, table->s);
MRN_SET_BASE_TABLE_KEY(this, table);
@@ -4047,12 +4081,12 @@ int ha_mroonga::wrapper_open_indexes(const char *name)
mrn::PathMapper mapper(name);
uint i = 0;
for (i = 0; i < n_keys; i++) {
- KEY key_info = table->s->key_info[i];
+ KEY *key_info = &(table->s->key_info[i]);
grn_index_tables[i] = NULL;
grn_index_columns[i] = NULL;
- if (!(wrapper_is_target_index(&key_info))) {
+ if (!(wrapper_is_target_index(key_info))) {
continue;
}
@@ -4060,7 +4094,7 @@ int ha_mroonga::wrapper_open_indexes(const char *name)
continue;
}
- mrn::IndexTableName index_table_name(mapper.table_name(), key_info.name);
+ mrn::IndexTableName index_table_name(mapper.table_name(), key_info->name);
grn_index_tables[i] = grn_ctx_get(ctx,
index_table_name.c_str(),
index_table_name.length());
@@ -4077,7 +4111,7 @@ int ha_mroonga::wrapper_open_indexes(const char *name)
strlen(INDEX_COLUMN_NAME));
if (!grn_index_columns[i]) {
/* just for backward compatibility before 1.0. */
- Field *field = key_info.key_part[0].field;
+ Field *field = key_info->key_part[0].field;
grn_index_columns[i] = grn_obj_column(ctx, grn_index_tables[i],
field->field_name,
strlen(field->field_name));
@@ -4337,10 +4371,10 @@ int ha_mroonga::storage_open_indexes(const char *name)
continue;
}
- KEY key_info = table->s->key_info[i];
- if (KEY_N_KEY_PARTS(&key_info) > 1) {
- KEY_PART_INFO *key_part = key_info.key_part;
- for (j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
+ KEY *key_info = &(table->s->key_info[i]);
+ if (KEY_N_KEY_PARTS(key_info) > 1) {
+ KEY_PART_INFO *key_part = key_info->key_part;
+ for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
bitmap_set_bit(&multiple_column_key_bitmap,
key_part[j].field->field_index);
}
@@ -4355,11 +4389,11 @@ int ha_mroonga::storage_open_indexes(const char *name)
if (ctx->rc == GRN_SUCCESS) {
grn_index_columns[i] = grn_obj_column(ctx,
grn_index_tables[i],
- key_info.name,
- strlen(key_info.name));
+ key_info->name,
+ strlen(key_info->name));
}
} else {
- mrn::IndexTableName index_table_name(mapper.table_name(), key_info.name);
+ mrn::IndexTableName index_table_name(mapper.table_name(), key_info->name);
grn_index_tables[i] = grn_ctx_get(ctx,
index_table_name.c_str(),
index_table_name.length());
@@ -4370,7 +4404,7 @@ int ha_mroonga::storage_open_indexes(const char *name)
strlen(INDEX_COLUMN_NAME));
if (!grn_index_columns[i] && ctx->rc == GRN_SUCCESS) {
/* just for backward compatibility before 1.0. */
- Field *field = key_info.key_part[0].field;
+ Field *field = key_info->key_part[0].field;
grn_index_columns[i] = grn_obj_column(ctx, grn_index_tables[i],
field->field_name,
strlen(field->field_name));
@@ -4504,40 +4538,20 @@ int ha_mroonga::close()
error = storage_close();
}
- if (is_temporary_table_name(share->table_name)) {
- TABLE_LIST table_list;
- TABLE_SHARE *tmp_table_share;
- int tmp_error;
- /* no need to decode */
- mrn::PathMapper mapper(share->table_name);
-#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS
- table_list.init_one_table(mapper.db_name(), strlen(mapper.db_name()),
- mapper.mysql_table_name(),
- strlen(mapper.mysql_table_name()),
- mapper.mysql_table_name(),
- TL_WRITE);
-#else
- table_list.init_one_table(mapper.db_name(), mapper.mysql_table_name(),
- TL_WRITE);
-#endif
- mrn_open_mutex_lock(NULL);
- tmp_table_share =
- mrn_create_tmp_table_share(&table_list, share->table_name, &tmp_error);
- mrn_open_mutex_unlock(NULL);
- if (!tmp_table_share) {
- error = tmp_error;
- } else if ((tmp_error = alter_share_add(share->table_name,
- tmp_table_share))) {
- error = tmp_error;
- mrn_open_mutex_lock(NULL);
- mrn_free_tmp_table_share(tmp_table_share);
- mrn_open_mutex_unlock(NULL);
- }
+ if (error != 0)
+ {
+ DBUG_RETURN(error);
}
+
+ error = add_wrap_hton(share->table_name, share->hton);
bitmap_free(&multiple_column_key_bitmap);
+ if (share->use_count == 1) {
+ mrn_free_long_term_share(share->long_term_share);
+ }
mrn_free_share(share);
share = NULL;
is_clone = false;
+
if (
thd &&
thd_sql_command(thd) == SQLCOM_FLUSH
@@ -4554,76 +4568,28 @@ int ha_mroonga::close()
DBUG_RETURN(error);
}
-int ha_mroonga::wrapper_delete_table(const char *name, MRN_SHARE *tmp_share,
+int ha_mroonga::wrapper_delete_table(const char *name,
+ handlerton *wrap_handlerton,
const char *table_name)
{
int error = 0;
- handler *hnd;
MRN_DBUG_ENTER_METHOD();
- MRN_SET_WRAP_SHARE_KEY(tmp_share, tmp_share->table_share);
- if (!(hnd =
- tmp_share->hton->create(tmp_share->hton, tmp_share->table_share,
- current_thd->mem_root)))
- {
- MRN_SET_BASE_SHARE_KEY(tmp_share, tmp_share->table_share);
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- }
- hnd->init();
- MRN_SET_BASE_SHARE_KEY(tmp_share, tmp_share->table_share);
- if ((error = hnd->ha_delete_table(name)))
+ handler *hnd = get_new_handler(NULL, current_thd->mem_root, wrap_handlerton);
+ if (!hnd)
{
- delete hnd;
- DBUG_RETURN(error);
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
- error = wrapper_delete_index(name, tmp_share, table_name);
-
+ error = hnd->ha_delete_table(name);
delete hnd;
- DBUG_RETURN(error);
-}
-
-int ha_mroonga::wrapper_delete_index(const char *name, MRN_SHARE *tmp_share,
- const char *table_name)
-{
- int error = 0;
- MRN_DBUG_ENTER_METHOD();
-
- error = ensure_database_open(name);
- if (error)
- DBUG_RETURN(error);
-
- error = mrn_change_encoding(ctx, system_charset_info);
- if (error)
- DBUG_RETURN(error);
- TABLE_SHARE *tmp_table_share = tmp_share->table_share;
-
- uint i;
- for (i = 0; i < tmp_table_share->keys; i++) {
- error = drop_index(tmp_share, i);
- if (error) {
- DBUG_RETURN(error);
- }
- }
-
- grn_obj *table = grn_ctx_get(ctx, table_name, strlen(table_name));
- if (!ctx->rc) {
- grn_obj_remove(ctx, table);
- }
- if (ctx->rc) {
- error = ER_CANT_OPEN_FILE;
- my_message(error, ctx->errbuf, MYF(0));
- DBUG_RETURN(error);
- }
DBUG_RETURN(error);
}
-int ha_mroonga::storage_delete_table(const char *name, MRN_SHARE *tmp_share,
- const char *table_name)
+int ha_mroonga::generic_delete_table(const char *name, const char *table_name)
{
int error = 0;
- TABLE_SHARE *tmp_table_share = tmp_share->table_share;
MRN_DBUG_ENTER_METHOD();
error = ensure_database_open(name);
@@ -4634,14 +4600,7 @@ int ha_mroonga::storage_delete_table(const char *name, MRN_SHARE *tmp_share,
if (error)
DBUG_RETURN(error);
- uint i;
- for (i = 0; i < tmp_table_share->keys; i++) {
- error = drop_index(tmp_share, i);
- if (error) {
- DBUG_RETURN(error);
- }
- }
-
+ error = drop_indexes(table_name);
grn_obj *table_obj = grn_ctx_get(ctx, table_name, strlen(table_name));
if (!ctx->rc) {
grn_obj_remove(ctx, table_obj);
@@ -4656,86 +4615,50 @@ int ha_mroonga::storage_delete_table(const char *name, MRN_SHARE *tmp_share,
int ha_mroonga::delete_table(const char *name)
{
+ MRN_DBUG_ENTER_METHOD();
+
int error = 0;
THD *thd = ha_thd();
- TABLE_LIST table_list;
- TABLE_SHARE *tmp_table_share = NULL;
- TABLE tmp_table;
- MRN_SHARE *tmp_share;
- st_mrn_alter_share *alter_share, *tmp_alter_share;
- MRN_DBUG_ENTER_METHOD();
+ handlerton *wrap_handlerton = NULL;
mrn::PathMapper mapper(name);
st_mrn_slot_data *slot_data = mrn_get_slot_data(thd, false);
- if (slot_data && slot_data->first_alter_share)
+ if (slot_data && slot_data->first_wrap_hton)
{
- tmp_alter_share = NULL;
- alter_share = slot_data->first_alter_share;
- while (alter_share)
+ st_mrn_wrap_hton *wrap_hton, *tmp_wrap_hton;
+ tmp_wrap_hton = NULL;
+ wrap_hton = slot_data->first_wrap_hton;
+ while (wrap_hton)
{
- if (!strcmp(alter_share->path, name))
+ if (!strcmp(wrap_hton->path, name))
{
/* found */
- tmp_table_share = alter_share->alter_share;
- if (tmp_alter_share)
- tmp_alter_share->next = alter_share->next;
+ wrap_handlerton = wrap_hton->hton;
+ if (tmp_wrap_hton)
+ tmp_wrap_hton->next = wrap_hton->next;
else
- slot_data->first_alter_share = alter_share->next;
- free(alter_share);
+ slot_data->first_wrap_hton = wrap_hton->next;
+ free(wrap_hton);
break;
}
- tmp_alter_share = alter_share;
- alter_share = alter_share->next;
+ tmp_wrap_hton = wrap_hton;
+ wrap_hton = wrap_hton->next;
}
}
- if (!tmp_table_share)
- {
-#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS
- table_list.init_one_table(mapper.db_name(), strlen(mapper.db_name()),
- mapper.mysql_table_name(),
- strlen(mapper.mysql_table_name()),
- mapper.mysql_table_name(),
- TL_WRITE);
-#else
- table_list.init_one_table(mapper.db_name(), mapper.mysql_table_name(),
- TL_WRITE);
-#endif
- mrn_open_mutex_lock(NULL);
- tmp_table_share = mrn_create_tmp_table_share(&table_list, name, &error);
- mrn_open_mutex_unlock(NULL);
- if (!tmp_table_share) {
- DBUG_RETURN(error);
- }
- }
- tmp_table.s = tmp_table_share;
-#ifdef WITH_PARTITION_STORAGE_ENGINE
- tmp_table.part_info = NULL;
-#endif
- if (!(tmp_share = mrn_get_share(name, &tmp_table, &error)))
+
+ if (wrap_handlerton)
{
- mrn_open_mutex_lock(NULL);
- mrn_free_tmp_table_share(tmp_table_share);
- mrn_open_mutex_unlock(NULL);
- DBUG_RETURN(error);
+ error = wrapper_delete_table(name, wrap_handlerton, mapper.table_name());
}
- if (tmp_share->wrapper_mode)
+ if (!error)
{
- error = wrapper_delete_table(name, tmp_share, mapper.table_name());
- } else {
- error = storage_delete_table(name, tmp_share, mapper.table_name());
+ error = generic_delete_table(name, mapper.table_name());
}
- if (!error) {
- mrn_free_long_term_share(tmp_share->long_term_share);
- tmp_share->long_term_share = NULL;
- }
- mrn_free_share(tmp_share);
- mrn_open_mutex_lock(NULL);
- mrn_free_tmp_table_share(tmp_table_share);
- mrn_open_mutex_unlock(NULL);
- if (is_temporary_table_name(name)) {
+ if (!error && is_temporary_table_name(name)) {
mrn_db_manager->drop(name);
}
+
DBUG_RETURN(error);
}
@@ -5331,9 +5254,9 @@ bool ha_mroonga::wrapper_have_target_index()
uint i;
uint n_keys = table->s->keys;
for (i = 0; i < n_keys; i++) {
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
- if (wrapper_is_target_index(&key_info)) {
+ if (wrapper_is_target_index(key_info)) {
have_target_index = true;
break;
}
@@ -5406,9 +5329,9 @@ int ha_mroonga::wrapper_write_row_index(uchar *buf)
uint i;
uint n_keys = table->s->keys;
for (i = 0; i < n_keys; i++) {
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
- if (!(wrapper_is_target_index(&key_info))) {
+ if (!(wrapper_is_target_index(key_info))) {
continue;
}
@@ -5418,8 +5341,8 @@ int ha_mroonga::wrapper_write_row_index(uchar *buf)
}
uint j;
- for (j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
- Field *field = key_info.key_part[j].field;
+ for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
+ Field *field = key_info->key_part[j].field;
if (field->is_null())
continue;
@@ -5481,7 +5404,8 @@ int ha_mroonga::storage_write_row(uchar *buf)
if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
push_warning_printf(thd, MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, MRN_GET_ERR_MSG(WARN_DATA_TRUNCATED),
+ WARN_DATA_TRUNCATED,
+ MRN_GET_ERR_MSG(WARN_DATA_TRUNCATED),
MRN_COLUMN_NAME_ID,
MRN_GET_CURRENT_ROW_FOR_WARNING(thd));
if (MRN_ABORT_ON_WARNING(thd)) {
@@ -5490,66 +5414,79 @@ int ha_mroonga::storage_write_row(uchar *buf)
}
}
- char *pkey;
- int pkey_size;
- uint pkey_nr;
- pkey_nr = table->s->primary_key;
- GRN_BULK_REWIND(&key_buffer);
- if (pkey_nr == MAX_INDEXES) {
- pkey = NULL;
- pkey_size = 0;
- } else {
- KEY key_info = table->key_info[pkey_nr];
- if (KEY_N_KEY_PARTS(&key_info) == 1) {
- Field *pkey_field = key_info.key_part[0].field;
- error = mrn_change_encoding(ctx, pkey_field->charset());
- if (error) {
- DBUG_RETURN(error);
- }
- generic_store_bulk(pkey_field, &key_buffer);
- pkey = GRN_TEXT_VALUE(&key_buffer);
- pkey_size = GRN_TEXT_LEN(&key_buffer);
- } else {
- mrn_change_encoding(ctx, NULL);
- uchar key[MRN_MAX_KEY_SIZE];
- key_copy(key, buf, &key_info, key_info.key_length);
- grn_bulk_space(ctx, &key_buffer, key_info.key_length);
- pkey = GRN_TEXT_VALUE(&key_buffer);
- storage_encode_multiple_column_key(&key_info,
- key, key_info.key_length,
- (uchar *)pkey, (uint *)&pkey_size);
+ uint pkey_nr = table->s->primary_key;
+
+ int added = 0;
+ {
+ mrn::Lock lock(&(share->record_mutex), have_unique_index());
+ if ((error = storage_write_row_unique_indexes(buf)))
+ {
+ DBUG_RETURN(error);
}
- }
+ unique_indexes_are_processed = true;
- if (grn_table->header.type != GRN_TABLE_NO_KEY && pkey_size == 0) {
- my_message(ER_ERROR_ON_WRITE, "primary key is empty", MYF(0));
- DBUG_RETURN(ER_ERROR_ON_WRITE);
- }
+ char *pkey;
+ int pkey_size;
+ GRN_BULK_REWIND(&key_buffer);
+ if (pkey_nr == MAX_INDEXES) {
+ pkey = NULL;
+ pkey_size = 0;
+ } else {
+ KEY *key_info = &(table->key_info[pkey_nr]);
+ if (KEY_N_KEY_PARTS(key_info) == 1) {
+ Field *pkey_field = key_info->key_part[0].field;
+ error = mrn_change_encoding(ctx, pkey_field->charset());
+ if (error) {
+ DBUG_RETURN(error);
+ }
+ generic_store_bulk(pkey_field, &key_buffer);
+ pkey = GRN_TEXT_VALUE(&key_buffer);
+ pkey_size = GRN_TEXT_LEN(&key_buffer);
+ } else {
+ mrn_change_encoding(ctx, NULL);
+ uchar key[MRN_MAX_KEY_SIZE];
+ key_copy(key, buf, key_info, key_info->key_length);
+ grn_bulk_reserve(ctx, &key_buffer, MRN_MAX_KEY_SIZE);
+ pkey = GRN_TEXT_VALUE(&key_buffer);
+ storage_encode_multiple_column_key(key_info,
+ key, key_info->key_length,
+ (uchar *)pkey, (uint *)&pkey_size);
+ }
+ }
- int added;
- record_id = grn_table_add(ctx, grn_table, pkey, pkey_size, &added);
- if (ctx->rc) {
- my_message(ER_ERROR_ON_WRITE, ctx->errbuf, MYF(0));
- DBUG_RETURN(ER_ERROR_ON_WRITE);
- }
- if (!added) {
- // duplicated error
- error = HA_ERR_FOUND_DUPP_KEY;
- memcpy(dup_ref, &record_id, sizeof(grn_id));
- dup_key = pkey_nr;
- if (!ignoring_duplicated_key) {
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "duplicated id on insert: update primary key: <%.*s>",
- pkey_size, pkey);
+ if (grn_table->header.type != GRN_TABLE_NO_KEY && pkey_size == 0) {
+ my_message(ER_ERROR_ON_WRITE, "primary key is empty", MYF(0));
+ DBUG_RETURN(ER_ERROR_ON_WRITE);
}
- DBUG_RETURN(error);
- }
- if ((error = storage_write_row_unique_indexes(buf)))
- {
- goto err;
+ record_id = grn_table_add(ctx, grn_table, pkey, pkey_size, &added);
+ if (ctx->rc) {
+ my_message(ER_ERROR_ON_WRITE, ctx->errbuf, MYF(0));
+ DBUG_RETURN(ER_ERROR_ON_WRITE);
+ }
+ if (!added) {
+ // duplicated error
+ error = HA_ERR_FOUND_DUPP_KEY;
+ memcpy(dup_ref, &record_id, sizeof(grn_id));
+ dup_key = pkey_nr;
+ if (!ignoring_duplicated_key) {
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "duplicated id on insert: update primary key: <%.*s>",
+ pkey_size, pkey);
+ }
+ uint j;
+ for (j = 0; j < table->s->keys; j++) {
+ if (j == pkey_nr) {
+ continue;
+ }
+ KEY *key_info = &table->key_info[j];
+ if (key_info->flags & HA_NOSAME) {
+ grn_table_delete_by_id(ctx, grn_index_tables[j], key_id[j]);
+ }
+ }
+ DBUG_RETURN(error);
+ }
}
- unique_indexes_are_processed = true;
grn_obj colbuf;
GRN_VOID_INIT(&colbuf);
@@ -5673,16 +5610,16 @@ int ha_mroonga::storage_write_row_multiple_column_index(uchar *buf,
key_info,
key_info->key_length);
GRN_BULK_REWIND(&encoded_key_buffer);
- grn_bulk_space(ctx, &encoded_key_buffer, key_info->key_length);
+ grn_bulk_reserve(ctx, &encoded_key_buffer, MRN_MAX_KEY_SIZE);
uint encoded_key_length;
storage_encode_multiple_column_key(key_info,
(uchar *)(GRN_TEXT_VALUE(&key_buffer)),
key_info->key_length,
(uchar *)(GRN_TEXT_VALUE(&encoded_key_buffer)),
&encoded_key_length);
+ grn_bulk_space(ctx, &encoded_key_buffer, encoded_key_length);
DBUG_PRINT("info", ("mroonga: key_length=%u", key_info->key_length));
DBUG_PRINT("info", ("mroonga: encoded_key_length=%u", encoded_key_length));
- DBUG_ASSERT(key_info->key_length >= encoded_key_length);
grn_rc rc;
rc = grn_column_index_update(ctx, index_column, record_id, 1, NULL,
@@ -5709,9 +5646,9 @@ int ha_mroonga::storage_write_row_multiple_column_indexes(uchar *buf,
continue;
}
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
- if (KEY_N_KEY_PARTS(&key_info) == 1 || (key_info.flags & HA_FULLTEXT)) {
+ if (KEY_N_KEY_PARTS(key_info) == 1 || (key_info->flags & HA_FULLTEXT)) {
continue;
}
@@ -5722,7 +5659,7 @@ int ha_mroonga::storage_write_row_multiple_column_indexes(uchar *buf,
if ((error = storage_write_row_multiple_column_index(buf,
record_id,
- &key_info,
+ key_info,
index_column)))
{
goto err;
@@ -5757,7 +5694,7 @@ int ha_mroonga::storage_write_row_unique_index(uchar *buf,
mrn_change_encoding(ctx, NULL);
uchar key[MRN_MAX_KEY_SIZE];
key_copy(key, buf, key_info, key_info->key_length);
- grn_bulk_space(ctx, &key_buffer, key_info->key_length);
+ grn_bulk_reserve(ctx, &key_buffer, MRN_MAX_KEY_SIZE);
ukey = GRN_TEXT_VALUE(&key_buffer);
storage_encode_multiple_column_key(key_info,
key, key_info->key_length,
@@ -5949,11 +5886,11 @@ int ha_mroonga::wrapper_update_row_index(const uchar *old_data, uchar *new_data)
}
mrn_change_encoding(ctx, NULL);
- KEY key_info = table->key_info[table_share->primary_key];
+ KEY *key_info = &(table->key_info[table_share->primary_key]);
GRN_BULK_REWIND(&key_buffer);
key_copy((uchar *)(GRN_TEXT_VALUE(&key_buffer)),
new_data,
- &key_info, key_info.key_length);
+ key_info, key_info->key_length);
int added;
grn_id new_record_id;
new_record_id = grn_table_add(ctx, grn_table,
@@ -5972,15 +5909,15 @@ int ha_mroonga::wrapper_update_row_index(const uchar *old_data, uchar *new_data)
grn_id old_record_id;
my_ptrdiff_t ptr_diff = PTR_BYTE_DIFF(old_data, table->record[0]);
- for (uint j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
- Field *field = key_info.key_part[j].field;
+ for (uint j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
+ Field *field = key_info->key_part[j].field;
field->move_field_offset(ptr_diff);
}
error = wrapper_get_record_id((uchar *)old_data, &old_record_id,
"failed to get old record ID "
"for updating from groonga");
- for (uint j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
- Field *field = key_info.key_part[j].field;
+ for (uint j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
+ Field *field = key_info->key_part[j].field;
field->move_field_offset(-ptr_diff);
}
if (error) {
@@ -5991,9 +5928,9 @@ int ha_mroonga::wrapper_update_row_index(const uchar *old_data, uchar *new_data)
uint i;
uint n_keys = table->s->keys;
for (i = 0; i < n_keys; i++) {
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
- if (!(wrapper_is_target_index(&key_info))) {
+ if (!(wrapper_is_target_index(key_info))) {
continue;
}
@@ -6004,8 +5941,8 @@ int ha_mroonga::wrapper_update_row_index(const uchar *old_data, uchar *new_data)
}
uint j;
- for (j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
- Field *field = key_info.key_part[j].field;
+ for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
+ Field *field = key_info->key_part[j].field;
generic_store_bulk(field, &new_value_buffer);
@@ -6086,6 +6023,7 @@ int ha_mroonga::storage_update_row(const uchar *old_data, uchar *new_data)
KEY *pkey_info = NULL;
storage_store_fields_for_prep_update(old_data, new_data, record_id);
{
+ mrn::Lock lock(&(share->record_mutex), have_unique_index());
mrn::DebugColumnAccess debug_column_access(table, table->read_set);
if ((error = storage_prepare_delete_row_unique_indexes(old_data,
record_id))) {
@@ -6233,9 +6171,9 @@ int ha_mroonga::storage_update_row_index(const uchar *old_data, uchar *new_data)
continue;
}
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
- if (KEY_N_KEY_PARTS(&key_info) == 1 || (key_info.flags & HA_FULLTEXT)) {
+ if (KEY_N_KEY_PARTS(key_info) == 1 || (key_info->flags & HA_FULLTEXT)) {
continue;
}
@@ -6246,42 +6184,44 @@ int ha_mroonga::storage_update_row_index(const uchar *old_data, uchar *new_data)
}
GRN_BULK_REWIND(&old_key);
- grn_bulk_space(ctx, &old_key, key_info.key_length);
- for (uint j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
- Field *field = key_info.key_part[j].field;
+ grn_bulk_space(ctx, &old_key, key_info->key_length);
+ for (uint j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
+ Field *field = key_info->key_part[j].field;
field->move_field_offset(ptr_diff);
}
key_copy((uchar *)(GRN_TEXT_VALUE(&old_key)),
(uchar *)old_data,
- &key_info,
- key_info.key_length);
- for (uint j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
- Field *field = key_info.key_part[j].field;
+ key_info,
+ key_info->key_length);
+ for (uint j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
+ Field *field = key_info->key_part[j].field;
field->move_field_offset(-ptr_diff);
}
GRN_BULK_REWIND(&old_encoded_key);
- grn_bulk_space(ctx, &old_encoded_key, key_info.key_length);
+ grn_bulk_reserve(ctx, &old_encoded_key, MRN_MAX_KEY_SIZE);
uint old_encoded_key_length;
- storage_encode_multiple_column_key(&key_info,
+ storage_encode_multiple_column_key(key_info,
(uchar *)(GRN_TEXT_VALUE(&old_key)),
- key_info.key_length,
+ key_info->key_length,
(uchar *)(GRN_TEXT_VALUE(&old_encoded_key)),
&old_encoded_key_length);
+ grn_bulk_space(ctx, &old_encoded_key, old_encoded_key_length);
GRN_BULK_REWIND(&new_key);
- grn_bulk_space(ctx, &new_key, key_info.key_length);
+ grn_bulk_space(ctx, &new_key, key_info->key_length);
key_copy((uchar *)(GRN_TEXT_VALUE(&new_key)),
(uchar *)new_data,
- &key_info,
- key_info.key_length);
+ key_info,
+ key_info->key_length);
GRN_BULK_REWIND(&new_encoded_key);
- grn_bulk_space(ctx, &new_encoded_key, key_info.key_length);
+ grn_bulk_reserve(ctx, &new_encoded_key, MRN_MAX_KEY_SIZE);
uint new_encoded_key_length;
- storage_encode_multiple_column_key(&key_info,
+ storage_encode_multiple_column_key(key_info,
(uchar *)(GRN_TEXT_VALUE(&new_key)),
- key_info.key_length,
+ key_info->key_length,
(uchar *)(GRN_TEXT_VALUE(&new_encoded_key)),
&new_encoded_key_length);
+ grn_bulk_space(ctx, &new_encoded_key, new_encoded_key_length);
grn_rc rc;
rc = grn_column_index_update(ctx, index_column, record_id, 1,
@@ -6436,9 +6376,9 @@ int ha_mroonga::wrapper_delete_row_index(const uchar *buf)
uint i;
uint n_keys = table->s->keys;
for (i = 0; i < n_keys; i++) {
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
- if (!(wrapper_is_target_index(&key_info))) {
+ if (!(wrapper_is_target_index(key_info))) {
continue;
}
@@ -6449,8 +6389,8 @@ int ha_mroonga::wrapper_delete_row_index(const uchar *buf)
}
uint j;
- for (j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
- Field *field = key_info.key_part[j].field;
+ for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
+ Field *field = key_info->key_part[j].field;
if (field->is_null())
continue;
@@ -6487,20 +6427,23 @@ int ha_mroonga::storage_delete_row(const uchar *buf)
}
storage_store_fields_for_prep_update(buf, NULL, record_id);
- if ((error = storage_prepare_delete_row_unique_indexes(buf, record_id))) {
- DBUG_RETURN(error);
- }
- mrn_change_encoding(ctx, NULL);
- grn_table_delete_by_id(ctx, grn_table, record_id);
- if (ctx->rc) {
- my_message(ER_ERROR_ON_WRITE, ctx->errbuf, MYF(0));
- DBUG_RETURN(ER_ERROR_ON_WRITE);
- }
- if (
- (error = storage_delete_row_index(buf)) ||
- (error = storage_delete_row_unique_indexes())
- ) {
- DBUG_RETURN(error);
+ {
+ mrn::Lock lock(&(share->record_mutex), have_unique_index());
+ if ((error = storage_prepare_delete_row_unique_indexes(buf, record_id))) {
+ DBUG_RETURN(error);
+ }
+ mrn_change_encoding(ctx, NULL);
+ grn_table_delete_by_id(ctx, grn_table, record_id);
+ if (ctx->rc) {
+ my_message(ER_ERROR_ON_WRITE, ctx->errbuf, MYF(0));
+ DBUG_RETURN(ER_ERROR_ON_WRITE);
+ }
+ if (
+ (error = storage_delete_row_index(buf)) ||
+ (error = storage_delete_row_unique_indexes())
+ ) {
+ DBUG_RETURN(error);
+ }
}
grn_db_touch(ctx, grn_ctx_db(ctx));
@@ -6526,9 +6469,9 @@ int ha_mroonga::storage_delete_row_index(const uchar *buf)
continue;
}
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
- if (KEY_N_KEY_PARTS(&key_info) == 1 || (key_info.flags & HA_FULLTEXT)) {
+ if (KEY_N_KEY_PARTS(key_info) == 1 || (key_info->flags & HA_FULLTEXT)) {
continue;
}
@@ -6539,19 +6482,20 @@ int ha_mroonga::storage_delete_row_index(const uchar *buf)
}
GRN_BULK_REWIND(&key);
- grn_bulk_space(ctx, &key, key_info.key_length);
+ grn_bulk_space(ctx, &key, key_info->key_length);
key_copy((uchar *)(GRN_TEXT_VALUE(&key)),
(uchar *)buf,
- &key_info,
- key_info.key_length);
+ key_info,
+ key_info->key_length);
GRN_BULK_REWIND(&encoded_key);
- grn_bulk_space(ctx, &encoded_key, key_info.key_length);
+ grn_bulk_reserve(ctx, &encoded_key, MRN_MAX_KEY_SIZE);
uint encoded_key_length;
- storage_encode_multiple_column_key(&key_info,
+ storage_encode_multiple_column_key(key_info,
(uchar *)(GRN_TEXT_VALUE(&key)),
- key_info.key_length,
+ key_info->key_length,
(uchar *)(GRN_TEXT_VALUE(&encoded_key)),
&encoded_key_length);
+ grn_bulk_space(ctx, &encoded_key, encoded_key_length);
grn_rc rc;
rc = grn_column_index_update(ctx, index_column, record_id, 1,
@@ -6627,7 +6571,7 @@ int ha_mroonga::storage_prepare_delete_row_unique_index(const uchar *buf,
mrn_change_encoding(ctx, NULL);
uchar key[MRN_MAX_KEY_SIZE];
key_copy(key, (uchar *) buf, key_info, key_info->key_length);
- grn_bulk_space(ctx, &key_buffer, key_info->key_length);
+ grn_bulk_reserve(ctx, &key_buffer, MRN_MAX_KEY_SIZE);
ukey = GRN_TEXT_VALUE(&key_buffer);
storage_encode_multiple_column_key(key_info,
key, key_info->key_length,
@@ -6737,8 +6681,8 @@ ha_rows ha_mroonga::wrapper_records_in_range(uint key_nr, key_range *range_min,
{
ha_rows row_count;
MRN_DBUG_ENTER_METHOD();
- KEY key_info = table->s->key_info[key_nr];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->s->key_info[key_nr]);
+ if (mrn_is_geo_key(key_info)) {
row_count = generic_records_in_range_geo(key_nr, range_min, range_max);
} else {
MRN_SET_WRAP_SHARE_KEY(share, table->s);
@@ -6760,8 +6704,8 @@ ha_rows ha_mroonga::storage_records_in_range(uint key_nr, key_range *range_min,
uchar *key_min = NULL, *key_max = NULL;
uchar key_min_entity[MRN_MAX_KEY_SIZE];
uchar key_max_entity[MRN_MAX_KEY_SIZE];
- KEY key_info = table->s->key_info[key_nr];
- bool is_multiple_column_index = KEY_N_KEY_PARTS(&key_info) > 1;
+ KEY *key_info = &(table->s->key_info[key_nr]);
+ bool is_multiple_column_index = KEY_N_KEY_PARTS(key_info) > 1;
if (is_multiple_column_index) {
mrn_change_encoding(ctx, NULL);
@@ -6770,24 +6714,23 @@ ha_rows ha_mroonga::storage_records_in_range(uint key_nr, key_range *range_min,
memcmp(range_min->key, range_max->key, range_min->length) == 0) {
flags |= GRN_CURSOR_PREFIX;
key_min = key_min_entity;
- storage_encode_multiple_column_key(&key_info,
+ storage_encode_multiple_column_key(key_info,
range_min->key, range_min->length,
key_min, &size_min);
} else {
key_min = key_min_entity;
key_max = key_max_entity;
- storage_encode_multiple_column_key_range(&key_info,
+ storage_encode_multiple_column_key_range(key_info,
range_min, range_max,
key_min, &size_min,
key_max, &size_max);
}
- } else if (mrn_is_geo_key(&key_info)) {
- mrn_change_encoding(ctx, key_info.key_part->field->charset());
+ } else if (mrn_is_geo_key(key_info)) {
+ mrn_change_encoding(ctx, key_info->key_part->field->charset());
row_count = generic_records_in_range_geo(key_nr, range_min, range_max);
DBUG_RETURN(row_count);
} else {
- KEY_PART_INFO key_part = key_info.key_part[0];
- Field *field = key_part.field;
+ Field *field = key_info->key_part[0].field;
const char *column_name = field->field_name;
mrn_change_encoding(ctx, field->charset());
@@ -6909,12 +6852,12 @@ ha_rows ha_mroonga::records_in_range(uint key_nr, key_range *range_min, key_rang
int ha_mroonga::wrapper_index_init(uint idx, bool sorted)
{
- int error = 0;
- KEY key_info = table->s->key_info[idx];
MRN_DBUG_ENTER_METHOD();
+ int error = 0;
+ KEY *key_info = &(table->s->key_info[idx]);
MRN_SET_WRAP_SHARE_KEY(share, table->s);
MRN_SET_WRAP_TABLE_KEY(this, table);
- if (!mrn_is_geo_key(&key_info) && key_info.algorithm != HA_KEY_ALG_FULLTEXT)
+ if (!mrn_is_geo_key(key_info) && key_info->algorithm != HA_KEY_ALG_FULLTEXT)
{
error = wrap_handler->ha_index_init(share->wrap_key_nr[idx], sorted);
} else {
@@ -6985,8 +6928,8 @@ int ha_mroonga::wrapper_index_read_map(uchar *buf, const uchar *key,
{
int error = 0;
MRN_DBUG_ENTER_METHOD();
- KEY key_info = table->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
clear_cursor_geo();
error = generic_geo_open_cursor(key, find_flag);
if (!error) {
@@ -7019,7 +6962,7 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
int error = 0;
uint key_nr = active_index;
- KEY key_info = table->key_info[key_nr];
+ KEY *key_info = &(table->key_info[key_nr]);
int flags = 0;
uint size_min = 0, size_max = 0;
uchar *key_min = NULL, *key_max = NULL;
@@ -7030,7 +6973,7 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
clear_cursor_geo();
clear_empty_value_records();
- bool is_multiple_column_index = KEY_N_KEY_PARTS(&key_info) > 1;
+ bool is_multiple_column_index = KEY_N_KEY_PARTS(key_info) > 1;
if (is_multiple_column_index) {
mrn_change_encoding(ctx, NULL);
uint key_length =
@@ -7039,17 +6982,17 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
("mroonga: multiple column index: "
"search key length=<%u>, "
"multiple column index key length=<%u>",
- key_length, key_info.key_length));
- if (key_length == key_info.key_length) {
+ key_length, key_info->key_length));
+ if (key_length == key_info->key_length) {
if (find_flag == HA_READ_BEFORE_KEY ||
find_flag == HA_READ_PREFIX_LAST_OR_PREV) {
key_max = key_max_entity;
- storage_encode_multiple_column_key(&key_info,
+ storage_encode_multiple_column_key(key_info,
key, key_length,
key_max, &size_max);
} else {
key_min = key_min_entity;
- storage_encode_multiple_column_key(&key_info,
+ storage_encode_multiple_column_key(key_info,
key, key_length,
key_min, &size_min);
if (find_flag == HA_READ_KEY_EXACT) {
@@ -7060,12 +7003,12 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
} else {
flags |= GRN_CURSOR_PREFIX;
key_min = key_min_entity;
- storage_encode_multiple_column_key(&key_info,
+ storage_encode_multiple_column_key(key_info,
key, key_length,
key_min, &size_min);
}
- } else if (mrn_is_geo_key(&key_info)) {
- error = mrn_change_encoding(ctx, key_info.key_part->field->charset());
+ } else if (mrn_is_geo_key(key_info)) {
+ error = mrn_change_encoding(ctx, key_info->key_part->field->charset());
if (error)
DBUG_RETURN(error);
error = generic_geo_open_cursor(key, find_flag);
@@ -7074,8 +7017,7 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
}
DBUG_RETURN(error);
} else {
- KEY_PART_INFO key_part = key_info.key_part[0];
- Field *field = key_part.field;
+ Field *field = key_info->key_part[0].field;
error = mrn_change_encoding(ctx, field->charset());
if (error)
DBUG_RETURN(error);
@@ -7150,7 +7092,7 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
GRN_EXPR_CREATE_FOR_QUERY(ctx, grn_table,
expression, expression_variable);
grn_obj *target_column =
- grn_columns[key_info.key_part->field->field_index];
+ grn_columns[key_info->key_part->field->field_index];
grn_expr_append_const(ctx, expression, target_column, GRN_OP_GET_VALUE, 1);
grn_obj empty_value;
GRN_TEXT_INIT(&empty_value, 0);
@@ -7229,7 +7171,7 @@ int ha_mroonga::storage_index_read_last_map(uchar *buf, const uchar *key,
{
MRN_DBUG_ENTER_METHOD();
uint key_nr = active_index;
- KEY key_info = table->key_info[key_nr];
+ KEY *key_info = &(table->key_info[key_nr]);
int flags = GRN_CURSOR_DESCENDING, error;
uint size_min = 0, size_max = 0;
@@ -7238,19 +7180,18 @@ int ha_mroonga::storage_index_read_last_map(uchar *buf, const uchar *key,
clear_cursor();
- bool is_multiple_column_index = KEY_N_KEY_PARTS(&key_info) > 1;
+ bool is_multiple_column_index = KEY_N_KEY_PARTS(key_info) > 1;
if (is_multiple_column_index) {
mrn_change_encoding(ctx, NULL);
flags |= GRN_CURSOR_PREFIX;
uint key_length =
mrn_calculate_key_len(table, active_index, key, keypart_map);
key_min = key_min_entity;
- storage_encode_multiple_column_key(&key_info,
+ storage_encode_multiple_column_key(key_info,
key, key_length,
key_min, &size_min);
} else {
- KEY_PART_INFO key_part = key_info.key_part[0];
- Field *field = key_part.field;
+ Field *field = key_info->key_part[0].field;
error = mrn_change_encoding(ctx, field->charset());
if (error)
DBUG_RETURN(error);
@@ -7308,8 +7249,8 @@ int ha_mroonga::wrapper_index_next(uchar *buf)
{
int error = 0;
MRN_DBUG_ENTER_METHOD();
- KEY key_info = table->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
error = wrapper_get_next_geo_record(buf);
} else {
MRN_SET_WRAP_SHARE_KEY(share, table->s);
@@ -7351,8 +7292,8 @@ int ha_mroonga::wrapper_index_prev(uchar *buf)
{
int error = 0;
MRN_DBUG_ENTER_METHOD();
- KEY key_info = table->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
error = wrapper_get_next_geo_record(buf);
} else {
MRN_SET_WRAP_SHARE_KEY(share, table->s);
@@ -7525,8 +7466,8 @@ int ha_mroonga::wrapper_index_next_same(uchar *buf, const uchar *key,
{
MRN_DBUG_ENTER_METHOD();
int error = 0;
- KEY key_info = table->s->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->s->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
error = wrapper_get_next_geo_record(buf);
} else {
MRN_SET_WRAP_SHARE_KEY(share, table->s);
@@ -7571,8 +7512,8 @@ int ha_mroonga::wrapper_read_range_first(const key_range *start_key,
{
int error = 0;
MRN_DBUG_ENTER_METHOD();
- KEY key_info = table->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
clear_cursor_geo();
error = generic_geo_open_cursor(start_key->key, start_key->flag);
if (!error) {
@@ -7603,11 +7544,11 @@ int ha_mroonga::storage_read_range_first(const key_range *start_key,
uchar *key_min = NULL, *key_max = NULL;
uchar key_min_entity[MRN_MAX_KEY_SIZE];
uchar key_max_entity[MRN_MAX_KEY_SIZE];
- KEY key_info = table->s->key_info[active_index];
+ KEY *key_info = &(table->s->key_info[active_index]);
clear_cursor();
- bool is_multiple_column_index = KEY_N_KEY_PARTS(&key_info) > 1;
+ bool is_multiple_column_index = KEY_N_KEY_PARTS(key_info) > 1;
if (is_multiple_column_index) {
mrn_change_encoding(ctx, NULL);
if (start_key && end_key &&
@@ -7615,13 +7556,13 @@ int ha_mroonga::storage_read_range_first(const key_range *start_key,
memcmp(start_key->key, end_key->key, start_key->length) == 0) {
flags |= GRN_CURSOR_PREFIX;
key_min = key_min_entity;
- storage_encode_multiple_column_key(&key_info,
+ storage_encode_multiple_column_key(key_info,
start_key->key, start_key->length,
key_min, &size_min);
} else {
key_min = key_min_entity;
key_max = key_max_entity;
- storage_encode_multiple_column_key_range(&key_info,
+ storage_encode_multiple_column_key_range(key_info,
start_key, end_key,
key_min, &size_min,
key_max, &size_max);
@@ -7633,8 +7574,7 @@ int ha_mroonga::storage_read_range_first(const key_range *start_key,
}
}
} else {
- KEY_PART_INFO key_part = key_info.key_part[0];
- Field *field = key_part.field;
+ Field *field = key_info->key_part[0].field;
const char *column_name = field->field_name;
error = mrn_change_encoding(ctx, field->charset());
if (error)
@@ -7742,8 +7682,8 @@ int ha_mroonga::wrapper_read_range_next()
{
int error = 0;
MRN_DBUG_ENTER_METHOD();
- KEY key_info = table->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
error = wrapper_get_next_geo_record(table->record[0]);
DBUG_RETURN(error);
}
@@ -8082,7 +8022,7 @@ grn_rc ha_mroonga::generic_ft_init_ext_prepare_expression_in_boolean_mode(
bool parsed = false;
bool done = false;
keyword++;
- keyword_length++;
+ keyword_length--;
while (!done) {
uint consumed_keyword_length = 0;
switch (keyword[0]) {
@@ -8283,12 +8223,11 @@ FT_INFO *ha_mroonga::generic_ft_init_ext(uint flags, uint key_nr, String *key)
check_count_skip(0, 0, true);
mrn_change_encoding(ctx, system_charset_info);
- grn_operator operation = GRN_OP_AND;
+ grn_operator operation = GRN_OP_OR;
if (!matched_record_keys) {
matched_record_keys = grn_table_create(ctx, NULL, 0, NULL,
GRN_OBJ_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC,
grn_table, 0);
- operation = GRN_OP_OR;
}
grn_table_sort_key *sort_keys = NULL;
@@ -8317,6 +8256,24 @@ FT_INFO *ha_mroonga::generic_ft_init_ext(uint flags, uint key_nr, String *key)
matched_record_keys);
grn_table_sort(ctx, matched_record_keys, 0, static_cast<int>(limit),
sorted_result, sort_keys, n_sort_keys);
+ } else if (flags & FT_SORTED) {
+ grn_table_sort_key score_sort_key;
+ score_sort_key.key = grn_obj_column(ctx,
+ matched_record_keys,
+ MRN_COLUMN_NAME_SCORE,
+ strlen(MRN_COLUMN_NAME_SCORE));
+ score_sort_key.offset = 0;
+ score_sort_key.flags = GRN_TABLE_SORT_DESC;
+ if (sorted_result) {
+ grn_obj_unlink(ctx, sorted_result);
+ }
+ sorted_result = grn_table_create(ctx, NULL,
+ 0, NULL,
+ GRN_OBJ_TABLE_NO_KEY, NULL,
+ matched_record_keys);
+ grn_table_sort(ctx, matched_record_keys, 0, -1,
+ sorted_result, &score_sort_key, 1);
+ grn_obj_unlink(ctx, score_sort_key.key);
}
if (sort_keys) {
for (int i = 0; i < n_sort_keys; i++) {
@@ -8586,6 +8543,26 @@ ulonglong ha_mroonga::file_size(const char *path)
}
}
+bool ha_mroonga::have_unique_index()
+{
+ MRN_DBUG_ENTER_METHOD();
+
+ uint n_keys = table->s->keys;
+
+ for (uint i = 0; i < n_keys; i++) {
+ if (i == table->s->primary_key) {
+ continue;
+ }
+
+ KEY *key_info = &(table->key_info[i]);
+ if (key_info->flags & HA_NOSAME) {
+ DBUG_RETURN(true);
+ }
+ }
+
+ DBUG_RETURN(false);
+}
+
void ha_mroonga::push_warning_unsupported_spatial_index_search(enum ha_rkey_function flag)
{
char search_name[MRN_BUFFER_SIZE];
@@ -8712,27 +8689,27 @@ void ha_mroonga::clear_indexes()
DBUG_VOID_RETURN;
}
-int ha_mroonga::alter_share_add(const char *path, TABLE_SHARE *table_share)
+int ha_mroonga::add_wrap_hton(const char *path, handlerton *wrap_handlerton)
{
MRN_DBUG_ENTER_METHOD();
st_mrn_slot_data *slot_data = mrn_get_slot_data(ha_thd(), true);
if (!slot_data)
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- st_mrn_alter_share *alter_share =
- (st_mrn_alter_share *)malloc(sizeof(st_mrn_alter_share));
- if (!alter_share)
+ st_mrn_wrap_hton *wrap_hton =
+ (st_mrn_wrap_hton *)malloc(sizeof(st_mrn_wrap_hton));
+ if (!wrap_hton)
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- alter_share->next = NULL;
- strcpy(alter_share->path, path);
- alter_share->alter_share = table_share;
- if (slot_data->first_alter_share)
+ wrap_hton->next = NULL;
+ strcpy(wrap_hton->path, path);
+ wrap_hton->hton = wrap_handlerton;
+ if (slot_data->first_wrap_hton)
{
- st_mrn_alter_share *tmp_alter_share = slot_data->first_alter_share;
- while (tmp_alter_share->next)
- tmp_alter_share = tmp_alter_share->next;
- tmp_alter_share->next = alter_share;
+ st_mrn_wrap_hton *tmp_wrap_hton = slot_data->first_wrap_hton;
+ while (tmp_wrap_hton->next)
+ tmp_wrap_hton = tmp_wrap_hton->next;
+ tmp_wrap_hton->next = wrap_hton;
} else {
- slot_data->first_alter_share = alter_share;
+ slot_data->first_wrap_hton = wrap_hton;
}
DBUG_RETURN(0);
}
@@ -8848,6 +8825,320 @@ int ha_mroonga::drop_index(MRN_SHARE *target_share, uint key_index)
DBUG_RETURN(error);
}
+int ha_mroonga::drop_indexes_normal(const char *table_name, grn_obj *table)
+{
+ MRN_DBUG_ENTER_METHOD();
+
+ int error = 0;
+
+ grn_hash *columns_raw = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY);
+ mrn::SmartGrnObj columns(ctx, reinterpret_cast<grn_obj *>(columns_raw));
+ if (!columns.get()) {
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "failed to allocate columns buffer: <%s>: <%s>",
+ table_name, ctx->errbuf);
+ error = HA_ERR_OUT_OF_MEM;
+ my_message(ER_ERROR_ON_WRITE, error_message, MYF(0));
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message);
+ DBUG_RETURN(error);
+ }
+
+ grn_table_columns(ctx, table, "", 0, columns.get());
+ grn_table_cursor *cursor = grn_table_cursor_open(ctx,
+ columns.get(),
+ NULL, 0,
+ NULL, 0,
+ 0, -1,
+ 0);
+ if (!cursor) {
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "failed to allocate columns cursor: <%s>: <%s>",
+ table_name, ctx->errbuf);
+ error = HA_ERR_OUT_OF_MEM;
+ my_message(ER_ERROR_ON_WRITE, error_message, MYF(0));
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message);
+ DBUG_RETURN(error);
+ }
+
+ while (grn_table_cursor_next(ctx, cursor) != GRN_ID_NIL) {
+ void *key;
+ grn_table_cursor_get_key(ctx, cursor, &key);
+ grn_id *id = reinterpret_cast<grn_id *>(key);
+ mrn::SmartGrnObj column(ctx, grn_ctx_at(ctx, *id));
+ if (!column.get()) {
+ continue;
+ }
+
+ grn_operator index_operators[] = {
+ GRN_OP_EQUAL,
+ GRN_OP_MATCH,
+ GRN_OP_LESS,
+ GRN_OP_REGEXP
+ };
+ size_t n_index_operators = sizeof(index_operators) / sizeof(grn_operator);
+ for (size_t i = 0; i < n_index_operators; i++) {
+ grn_index_datum index_datum;
+ while (grn_column_find_index_data(ctx,
+ column.get(),
+ index_operators[i],
+ &index_datum,
+ 1) > 0) {
+ grn_id index_table_id = index_datum.index->header.domain;
+ mrn::SmartGrnObj index_table(ctx, grn_ctx_at(ctx, index_table_id));
+ char index_table_name[GRN_TABLE_MAX_KEY_SIZE];
+ int index_table_name_length;
+ index_table_name_length = grn_obj_name(ctx, index_table.get(),
+ index_table_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ if (mrn::IndexTableName::is_custom_name(table_name,
+ strlen(table_name),
+ index_table_name,
+ index_table_name_length)) {
+ char index_column_name[GRN_TABLE_MAX_KEY_SIZE];
+ int index_column_name_length;
+ index_column_name_length = grn_obj_name(ctx,
+ index_datum.index,
+ index_column_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ grn_rc rc = grn_obj_remove(ctx, index_datum.index);
+ if (rc != GRN_SUCCESS) {
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "failed to drop index column: <%.*s>: <%s>",
+ index_column_name_length, index_column_name,
+ ctx->errbuf);
+ error = ER_ERROR_ON_WRITE;
+ my_message(error, error_message, MYF(0));
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message);
+ }
+ } else {
+ grn_rc rc = grn_obj_remove(ctx, index_table.get());
+ if (rc == GRN_SUCCESS) {
+ index_table.release();
+ } else {
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "failed to drop index table: <%.*s>: <%s>",
+ index_table_name_length, index_table_name,
+ ctx->errbuf);
+ error = ER_ERROR_ON_WRITE;
+ my_message(error, error_message, MYF(0));
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message);
+ }
+ }
+
+ if (error != 0) {
+ break;
+ }
+ }
+
+ if (error != 0) {
+ break;
+ }
+ }
+
+ if (error != 0) {
+ break;
+ }
+ }
+
+ grn_table_cursor_close(ctx, cursor);
+
+ DBUG_RETURN(error);
+}
+
+int ha_mroonga::drop_indexes_multiple(const char *table_name, grn_obj *table)
+{
+ MRN_DBUG_ENTER_METHOD();
+
+ int error = 0;
+
+ char index_table_name_prefix[GRN_TABLE_MAX_KEY_SIZE];
+ snprintf(index_table_name_prefix, GRN_TABLE_MAX_KEY_SIZE,
+ "%s%s", table_name, mrn::IndexTableName::SEPARATOR);
+ grn_table_cursor *cursor =
+ grn_table_cursor_open(ctx,
+ grn_ctx_db(ctx),
+ index_table_name_prefix,
+ strlen(index_table_name_prefix),
+ NULL, 0,
+ 0, -1,
+ GRN_CURSOR_PREFIX);
+ if (!cursor) {
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "failed to allocate index tables cursor: <%s>: <%s>",
+ table_name, ctx->errbuf);
+ error = HA_ERR_OUT_OF_MEM;
+ my_message(ER_ERROR_ON_WRITE, error_message, MYF(0));
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message);
+ DBUG_RETURN(error);
+ }
+
+ grn_id table_id = grn_obj_id(ctx, table);
+ grn_id id;
+ while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
+ mrn::SmartGrnObj object(ctx, grn_ctx_at(ctx, id));
+ if (!object.get()) {
+ continue;
+ }
+ if (!grn_obj_is_table(ctx, object.get())) {
+ continue;
+ }
+
+ char multiple_column_index_table_name[GRN_TABLE_MAX_KEY_SIZE];
+ int multiple_column_index_table_name_length;
+ multiple_column_index_table_name_length =
+ grn_obj_name(ctx,
+ object.get(),
+ multiple_column_index_table_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+
+ char multiple_column_index_name[GRN_TABLE_MAX_KEY_SIZE];
+ snprintf(multiple_column_index_name, GRN_TABLE_MAX_KEY_SIZE,
+ "%.*s.%s",
+ multiple_column_index_table_name_length,
+ multiple_column_index_table_name,
+ INDEX_COLUMN_NAME);
+ mrn::SmartGrnObj index_column(ctx, multiple_column_index_name);
+ if (!index_column.get()) {
+ continue;
+ }
+
+ if (grn_obj_get_range(ctx, index_column.get()) != table_id) {
+ continue;
+ }
+
+ grn_rc rc = grn_obj_remove(ctx, object.get());
+ if (rc == GRN_SUCCESS) {
+ object.release();
+ index_column.release();
+ } else {
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "failed to drop multiple column index table: <%.*s>: <%s>",
+ multiple_column_index_table_name_length,
+ multiple_column_index_table_name,
+ ctx->errbuf);
+ error = ER_ERROR_ON_WRITE;
+ my_message(error, error_message, MYF(0));
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message);
+ break;
+ }
+ }
+
+ grn_table_cursor_close(ctx, cursor);
+
+ DBUG_RETURN(error);
+}
+
+int ha_mroonga::drop_indexes(const char *table_name)
+{
+ MRN_DBUG_ENTER_METHOD();
+ int error = 0;
+
+ mrn::SmartGrnObj table(ctx, table_name);
+ if (!table.get()) {
+ DBUG_RETURN(0);
+ }
+
+ error = drop_indexes_normal(table_name, table.get());
+ if (error == 0) {
+ error = drop_indexes_multiple(table_name, table.get());
+ }
+
+ DBUG_RETURN(error);
+}
+
+bool ha_mroonga::find_column_flags(Field *field, MRN_SHARE *mrn_share, int i,
+ grn_obj_flags *column_flags)
+{
+ MRN_DBUG_ENTER_METHOD();
+ bool found = false;
+
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ {
+ const char *names = field->option_struct->flags;
+ if (names) {
+ found = mrn_parse_grn_column_create_flags(ha_thd(),
+ ctx,
+ names,
+ strlen(names),
+ column_flags);
+ DBUG_RETURN(found);
+ }
+ }
+#endif
+
+ if (mrn_share->col_flags[i]) {
+ found = mrn_parse_grn_column_create_flags(ha_thd(),
+ ctx,
+ mrn_share->col_flags[i],
+ mrn_share->col_flags_length[i],
+ column_flags);
+ DBUG_RETURN(found);
+ }
+
+ DBUG_RETURN(found);
+}
+
+grn_obj *ha_mroonga::find_column_type(Field *field, MRN_SHARE *mrn_share, int i,
+ int error_code)
+{
+ MRN_DBUG_ENTER_METHOD();
+
+ const char *grn_type_name = NULL;
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ grn_type_name = field->option_struct->groonga_type;
+#endif
+ if (!grn_type_name) {
+ grn_type_name = mrn_share->col_type[i];
+ }
+
+ grn_obj *type = NULL;
+ if (grn_type_name) {
+ type = grn_ctx_get(ctx, grn_type_name, -1);
+ if (!type) {
+ char error_message[MRN_BUFFER_SIZE];
+ snprintf(error_message, MRN_BUFFER_SIZE,
+ "unknown custom Groonga type name for <%s> column: <%s>",
+ field->field_name, grn_type_name);
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message);
+ my_message(error_code, error_message, MYF(0));
+
+ DBUG_RETURN(NULL);
+ }
+ } else {
+ grn_builtin_type grn_type_id = mrn_grn_type_from_field(ctx, field, false);
+ type = grn_ctx_at(ctx, grn_type_id);
+ }
+
+ DBUG_RETURN(type);
+}
+
+grn_obj *ha_mroonga::find_tokenizer(KEY *key, MRN_SHARE *mrn_share, int i)
+{
+ MRN_DBUG_ENTER_METHOD();
+ grn_obj *tokenizer;
+ const char *tokenizer_name = NULL;
+ uint tokenizer_name_length = 0;
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ if (key->option_struct->tokenizer) {
+ tokenizer_name = key->option_struct->tokenizer;
+ tokenizer_name_length = strlen(tokenizer_name);
+ }
+#endif
+ if (!tokenizer_name) {
+ tokenizer_name = mrn_share->key_tokenizer[i];
+ tokenizer_name_length = mrn_share->key_tokenizer_length[i];
+ }
+ tokenizer = find_tokenizer(tokenizer_name, tokenizer_name_length);
+ DBUG_RETURN(tokenizer);
+}
+
grn_obj *ha_mroonga::find_tokenizer(const char *name, int name_length)
{
MRN_DBUG_ENTER_METHOD();
@@ -8862,92 +9153,137 @@ grn_obj *ha_mroonga::find_tokenizer(const char *name, int name_length)
if (!tokenizer) {
char message[MRN_BUFFER_SIZE];
sprintf(message,
- "specified fulltext parser <%.*s> doesn't exist. "
- "default fulltext parser <%s> is used instead.",
+ "specified tokenizer for fulltext index <%.*s> doesn't exist. "
+ "The default tokenizer for fulltext index <%s> is used instead.",
name_length, name,
- MRN_PARSER_DEFAULT);
+ MRN_DEFAULT_TOKENIZER);
push_warning(ha_thd(),
MRN_SEVERITY_WARNING, ER_UNSUPPORTED_EXTENSION,
message);
tokenizer = grn_ctx_get(ctx,
- MRN_PARSER_DEFAULT,
- strlen(MRN_PARSER_DEFAULT));
+ MRN_DEFAULT_TOKENIZER,
+ strlen(MRN_DEFAULT_TOKENIZER));
}
if (!tokenizer) {
push_warning(ha_thd(),
MRN_SEVERITY_WARNING, ER_UNSUPPORTED_EXTENSION,
- "couldn't find fulltext parser. "
- "Bigram fulltext parser is used instead.");
+ "couldn't find tokenizer for fulltext index. "
+ "Bigram tokenizer is used instead.");
tokenizer = grn_ctx_at(ctx, GRN_DB_BIGRAM);
}
DBUG_RETURN(tokenizer);
}
-grn_obj *ha_mroonga::find_normalizer(KEY *key_info)
+grn_obj *ha_mroonga::find_normalizer(KEY *key)
+{
+ MRN_DBUG_ENTER_METHOD();
+
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ if (key->option_struct->normalizer) {
+ grn_obj *normalizer = find_normalizer(key,
+ key->option_struct->normalizer);
+ DBUG_RETURN(normalizer);
+ }
+#endif
+
+ if (key->comment.length > 0) {
+ mrn::ParametersParser parser(key->comment.str,
+ key->comment.length);
+ parser.parse();
+ grn_obj *normalizer = find_normalizer(key, parser["normalizer"]);
+ DBUG_RETURN(normalizer);
+ }
+
+ grn_obj *normalizer = find_normalizer(key, NULL);
+ DBUG_RETURN(normalizer);
+}
+
+grn_obj *ha_mroonga::find_normalizer(KEY *key, const char *name)
{
MRN_DBUG_ENTER_METHOD();
+
grn_obj *normalizer = NULL;
bool use_normalizer = true;
-#if MYSQL_VERSION_ID >= 50500
- if (key_info->comment.length > 0) {
- mrn::ParametersParser parser(key_info->comment.str,
- key_info->comment.length);
- parser.parse();
- const char *normalizer_name = parser["normalizer"];
- if (normalizer_name) {
- if (strcmp(normalizer_name, "none") == 0) {
- use_normalizer = false;
- } else {
- normalizer = grn_ctx_get(ctx, normalizer_name, -1);
- }
+ if (name) {
+ if (strcmp(name, "none") == 0) {
+ use_normalizer = false;
+ } else {
+ normalizer = grn_ctx_get(ctx, name, -1);
}
}
-#endif
if (use_normalizer && !normalizer) {
- Field *field = key_info->key_part[0].field;
+ Field *field = key->key_part[0].field;
mrn::FieldNormalizer field_normalizer(ctx, ha_thd(), field);
normalizer = field_normalizer.find_grn_normalizer();
}
+
DBUG_RETURN(normalizer);
}
-bool ha_mroonga::find_index_column_flags(KEY *key_info, grn_obj_flags *index_column_flags)
+bool ha_mroonga::find_index_column_flags(KEY *key, grn_obj_flags *index_column_flags)
{
MRN_DBUG_ENTER_METHOD();
bool found = false;
-#if MYSQL_VERSION_ID >= 50500
- if (key_info->comment.length > 0) {
- mrn::ParametersParser parser(key_info->comment.str,
- key_info->comment.length);
- parser.parse();
- const char *names = parser["index_flags"];
+
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ {
+ const char *names = key->option_struct->flags;
if (names) {
found = mrn_parse_grn_index_column_flags(ha_thd(),
ctx,
names,
strlen(names),
index_column_flags);
+ DBUG_RETURN(found);
}
}
#endif
+
+ if (key->comment.length > 0) {
+ mrn::ParametersParser parser(key->comment.str,
+ key->comment.length);
+ parser.parse();
+ const char *names = parser["flags"];
+ if (!names) {
+ // Deprecated. It's for backward compatibility.
+ names = parser["index_flags"];
+ }
+ if (names) {
+ found = mrn_parse_grn_index_column_flags(ha_thd(),
+ ctx,
+ names,
+ strlen(names),
+ index_column_flags);
+ }
+ }
+
DBUG_RETURN(found);
}
-bool ha_mroonga::find_token_filters(KEY *key_info, grn_obj *token_filters)
+bool ha_mroonga::find_token_filters(KEY *key, grn_obj *token_filters)
{
MRN_DBUG_ENTER_METHOD();
bool found = false;
-#if MYSQL_VERSION_ID >= 50500
- if (key_info->comment.length > 0) {
- mrn::ParametersParser parser(key_info->comment.str,
- key_info->comment.length);
+
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ if (key->option_struct->token_filters) {
+ found = find_token_filters_fill(token_filters,
+ key->option_struct->token_filters,
+ strlen(key->option_struct->token_filters));
+ DBUG_RETURN(found);
+ }
+#endif
+
+ if (key->comment.length > 0) {
+ mrn::ParametersParser parser(key->comment.str,
+ key->comment.length);
parser.parse();
const char *names = parser["token_filters"];
if (names) {
found = find_token_filters_fill(token_filters, names, strlen(names));
}
}
-#endif
+
DBUG_RETURN(found);
}
@@ -9356,8 +9692,8 @@ void ha_mroonga::check_count_skip(key_part_map start_key_part_map,
} else {
DBUG_PRINT("info", ("mroonga: count skip: without fulltext"));
uint key_nr = active_index;
- KEY key_info = table->key_info[key_nr];
- KEY_PART_INFO *key_part = key_info.key_part;
+ KEY *key_info = &(table->key_info[key_nr]);
+ KEY_PART_INFO *key_part = key_info->key_part;
for (where = MRN_SELECT_LEX_GET_WHERE_COND(select_lex);
where;
where = where->next) {
@@ -9386,17 +9722,17 @@ void ha_mroonga::check_count_skip(key_part_map start_key_part_map,
if (field->table != table)
break;
uint j;
- for (j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
+ for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
if (key_part[j].field == field)
{
if (!(start_key_part_map >> j) && !(end_key_part_map >> j))
- j = KEY_N_KEY_PARTS(&key_info);
+ j = KEY_N_KEY_PARTS(key_info);
else
i++;
break;
}
}
- if (j >= KEY_N_KEY_PARTS(&key_info))
+ if (j >= KEY_N_KEY_PARTS(key_info))
break;
}
if (i >= select_lex->select_n_where_fields)
@@ -9864,8 +10200,12 @@ int ha_mroonga::generic_store_bulk_datetime(Field *field, grn_obj *buf)
long long int time = time_converter.mysql_time_to_grn_time(&mysql_time,
&truncated);
if (truncated) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0);
GRN_TIME_SET(ctx, buf, time);
@@ -9896,8 +10236,12 @@ int ha_mroonga::generic_store_bulk_year(Field *field, grn_obj *buf)
mrn::TimeConverter time_converter;
long long int time = time_converter.tm_to_grn_time(&date, usec, &truncated);
if (truncated) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0);
GRN_TIME_SET(ctx, buf, time);
@@ -9917,8 +10261,12 @@ int ha_mroonga::generic_store_bulk_datetime2(Field *field, grn_obj *buf)
long long int time = time_converter.mysql_time_to_grn_time(&mysql_time,
&truncated);
if (truncated) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0);
GRN_TIME_SET(ctx, buf, time);
@@ -9938,8 +10286,12 @@ int ha_mroonga::generic_store_bulk_time2(Field *field, grn_obj *buf)
long long int time = time_converter.mysql_time_to_grn_time(&mysql_time,
&truncated);
if (truncated) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0);
GRN_TIME_SET(ctx, buf, time);
@@ -9959,8 +10311,12 @@ int ha_mroonga::generic_store_bulk_new_date(Field *field, grn_obj *buf)
long long int time = time_converter.mysql_time_to_grn_time(&mysql_date,
&truncated);
if (truncated) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0);
GRN_TIME_SET(ctx, buf, time);
@@ -10628,8 +10984,8 @@ void ha_mroonga::storage_store_fields(uchar *buf, grn_id record_id)
const char *column_name = field->field_name;
if (ignoring_no_key_columns) {
- KEY key_info = table->s->key_info[active_index];
- if (strcmp(key_info.key_part[0].field->field_name, column_name)) {
+ KEY *key_info = &(table->s->key_info[active_index]);
+ if (strcmp(key_info->key_part[0].field->field_name, column_name)) {
continue;
}
}
@@ -10831,8 +11187,12 @@ int ha_mroonga::storage_encode_key_timestamp(Field *field, const uchar *key,
mrn::TimeConverter time_converter;
time = time_converter.mysql_time_to_grn_time(&mysql_time, &truncated);
if (truncated) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
memcpy(buf, &time, 8);
*size = 8;
@@ -10878,8 +11238,12 @@ int ha_mroonga::storage_encode_key_time(Field *field, const uchar *key,
mrn::TimeConverter time_converter;
time = time_converter.mysql_time_to_grn_time(&mysql_time, &truncated);
if (truncated) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
#else
int mysql_time = (int)sint3korr(key);
@@ -10913,8 +11277,12 @@ int ha_mroonga::storage_encode_key_year(Field *field, const uchar *key,
long long int time = time_converter.tm_to_grn_time(&datetime, usec,
&truncated);
if (truncated) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
memcpy(buf, &time, 8);
*size = 8;
@@ -10962,8 +11330,12 @@ int ha_mroonga::storage_encode_key_datetime(Field *field, const uchar *key,
time = time_converter.tm_to_grn_time(&date, usec, &truncated);
}
if (truncated) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
memcpy(buf, &time, 8);
*size = 8;
@@ -10988,8 +11360,12 @@ int ha_mroonga::storage_encode_key_timestamp2(Field *field, const uchar *key,
long long int grn_time = time_converter.mysql_time_to_grn_time(&mysql_time,
&truncated);
if (truncated) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
memcpy(buf, &grn_time, 8);
*size = 8;
@@ -11015,8 +11391,12 @@ int ha_mroonga::storage_encode_key_datetime2(Field *field, const uchar *key,
long long int grn_time = time_converter.mysql_time_to_grn_time(&mysql_time,
&truncated);
if (truncated) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
memcpy(buf, &grn_time, 8);
*size = 8;
@@ -11042,8 +11422,12 @@ int ha_mroonga::storage_encode_key_time2(Field *field, const uchar *key,
long long int grn_time = time_converter.mysql_time_to_grn_time(&mysql_time,
&truncated);
if (truncated) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
memcpy(buf, &grn_time, 8);
*size = 8;
@@ -11212,8 +11596,12 @@ int ha_mroonga::storage_encode_key(Field *field, const uchar *key,
long long int time = time_converter.tm_to_grn_time(&date, usec,
&truncated);
if (truncated) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
memcpy(buf, &time, 8);
*size = 8;
@@ -11381,12 +11769,11 @@ int ha_mroonga::reset()
replacing_ = false;
written_by_row_based_binlog = 0;
mrn_lock_type = F_UNLCK;
- mrn_clear_alter_share(thd);
+ mrn_clear_slot_data(thd);
current_ft_item = NULL;
DBUG_RETURN(error);
}
-#ifdef MRN_HANDLER_CLONE_NEED_NAME
handler *ha_mroonga::wrapper_clone(const char *name, MEM_ROOT *mem_root)
{
handler *cloned_handler;
@@ -11426,47 +11813,6 @@ handler *ha_mroonga::clone(const char *name, MEM_ROOT *mem_root)
}
DBUG_RETURN(cloned_handler);
}
-#else
-handler *ha_mroonga::wrapper_clone(MEM_ROOT *mem_root)
-{
- handler *cloned_handler;
- MRN_DBUG_ENTER_METHOD();
- if (!(cloned_handler = get_new_handler(table->s, mem_root,
- table->s->db_type())))
- DBUG_RETURN(NULL);
- ((ha_mroonga *) cloned_handler)->is_clone = true;
- ((ha_mroonga *) cloned_handler)->parent_for_clone = this;
- ((ha_mroonga *) cloned_handler)->mem_root_for_clone = mem_root;
- if (cloned_handler->ha_open(table, table->s->normalized_path.str,
- table->db_stat, HA_OPEN_IGNORE_IF_LOCKED))
- {
- delete cloned_handler;
- DBUG_RETURN(NULL);
- }
- DBUG_RETURN(cloned_handler);
-}
-
-handler *ha_mroonga::storage_clone(MEM_ROOT *mem_root)
-{
- MRN_DBUG_ENTER_METHOD();
- handler *cloned_handler;
- cloned_handler = handler::clone(mem_root);
- DBUG_RETURN(cloned_handler);
-}
-
-handler *ha_mroonga::clone(MEM_ROOT *mem_root)
-{
- MRN_DBUG_ENTER_METHOD();
- handler *cloned_handler;
- if (share->wrapper_mode)
- {
- cloned_handler = wrapper_clone(mem_root);
- } else {
- cloned_handler = storage_clone(mem_root);
- }
- DBUG_RETURN(cloned_handler);
-}
-#endif
uint8 ha_mroonga::wrapper_table_cache_type()
{
@@ -11511,8 +11857,8 @@ ha_rows ha_mroonga::wrapper_multi_range_read_info_const(uint keyno,
{
MRN_DBUG_ENTER_METHOD();
ha_rows rows;
- KEY key_info = table->key_info[keyno];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[keyno]);
+ if (mrn_is_geo_key(key_info)) {
rows = handler::multi_range_read_info_const(keyno, seq, seq_init_param,
n_ranges, bufsz, flags, cost);
DBUG_RETURN(rows);
@@ -11577,8 +11923,8 @@ ha_rows ha_mroonga::wrapper_multi_range_read_info(uint keyno, uint n_ranges,
{
MRN_DBUG_ENTER_METHOD();
ha_rows rows;
- KEY key_info = table->key_info[keyno];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[keyno]);
+ if (mrn_is_geo_key(key_info)) {
rows = handler::multi_range_read_info(keyno, n_ranges, keys,
#ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS
key_parts,
@@ -11651,8 +11997,8 @@ int ha_mroonga::wrapper_multi_range_read_init(RANGE_SEQ_IF *seq,
{
MRN_DBUG_ENTER_METHOD();
int error = 0;
- KEY key_info = table->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
error = handler::multi_range_read_init(seq, seq_init_param,
n_ranges, mode, buf);
DBUG_RETURN(error);
@@ -11700,8 +12046,8 @@ int ha_mroonga::wrapper_multi_range_read_next(range_id_t *range_info)
{
MRN_DBUG_ENTER_METHOD();
int error = 0;
- KEY key_info = table->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
error = handler::multi_range_read_next(range_info);
DBUG_RETURN(error);
}
@@ -11743,8 +12089,8 @@ int ha_mroonga::wrapper_read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
{
int error = 0;
MRN_DBUG_ENTER_METHOD();
- KEY key_info = table->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
error = handler::read_multi_range_first(found_range_p, ranges,
range_count, sorted, buffer);
DBUG_RETURN(error);
@@ -11795,8 +12141,8 @@ int ha_mroonga::wrapper_read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
{
int error = 0;
MRN_DBUG_ENTER_METHOD();
- KEY key_info = table->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
error = handler::read_multi_range_next(found_range_p);
DBUG_RETURN(error);
}
@@ -11970,9 +12316,9 @@ int ha_mroonga::wrapper_delete_all_rows()
uint i;
uint n_keys = table->s->keys;
for (i = 0; i < n_keys; i++) {
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
- if (!(wrapper_is_target_index(&key_info))) {
+ if (!(wrapper_is_target_index(key_info))) {
continue;
}
@@ -12016,7 +12362,6 @@ int ha_mroonga::delete_all_rows()
DBUG_RETURN(error);
}
-#ifdef MRN_HANDLER_HAVE_TRUNCATE
int ha_mroonga::wrapper_truncate()
{
int error = 0;
@@ -12033,7 +12378,6 @@ int ha_mroonga::wrapper_truncate()
DBUG_RETURN(error);
}
-#endif
int ha_mroonga::wrapper_truncate_index()
{
@@ -12055,9 +12399,9 @@ int ha_mroonga::wrapper_truncate_index()
uint i;
uint n_keys = table->s->keys;
for (i = 0; i < n_keys; i++) {
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
- if (!(wrapper_is_target_index(&key_info))) {
+ if (!(wrapper_is_target_index(key_info))) {
continue;
}
@@ -12130,11 +12474,11 @@ int ha_mroonga::storage_truncate_index()
continue;
}
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
if (
- !(key_info.flags & HA_NOSAME) &&
- (KEY_N_KEY_PARTS(&key_info) == 1 || (key_info.flags & HA_FULLTEXT))
+ !(key_info->flags & HA_NOSAME) &&
+ (KEY_N_KEY_PARTS(key_info) == 1 || (key_info->flags & HA_FULLTEXT))
) {
continue;
}
@@ -12155,7 +12499,6 @@ err:
DBUG_RETURN(error);
}
-#ifdef MRN_HANDLER_HAVE_TRUNCATE
int ha_mroonga::truncate()
{
MRN_DBUG_ENTER_METHOD();
@@ -12168,7 +12511,6 @@ int ha_mroonga::truncate()
}
DBUG_RETURN(error);
}
-#endif
double ha_mroonga::wrapper_scan_time()
{
@@ -12207,8 +12549,8 @@ double ha_mroonga::wrapper_read_time(uint index, uint ranges, ha_rows rows)
double res;
MRN_DBUG_ENTER_METHOD();
if (index < MAX_KEY) {
- KEY key_info = table->key_info[index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[index]);
+ if (mrn_is_geo_key(key_info)) {
res = handler::read_time(index, ranges, rows);
DBUG_RETURN(res);
}
@@ -12387,16 +12729,14 @@ int ha_mroonga::wrapper_rename_table(const char *from, const char *to,
int error = 0;
handler *hnd;
MRN_DBUG_ENTER_METHOD();
- MRN_SET_WRAP_SHARE_KEY(tmp_share, tmp_share->table_share);
- if (!(hnd =
- tmp_share->hton->create(tmp_share->hton, tmp_share->table_share,
- current_thd->mem_root)))
+
+ hnd = get_new_handler(tmp_share->table_share,
+ current_thd->mem_root,
+ tmp_share->hton);
+ if (!hnd)
{
- MRN_SET_BASE_SHARE_KEY(tmp_share, tmp_share->table_share);
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
- hnd->init();
- MRN_SET_BASE_SHARE_KEY(tmp_share, tmp_share->table_share);
if ((error = hnd->ha_rename_table(from, to)))
{
@@ -12610,17 +12950,11 @@ int ha_mroonga::rename_table(const char *from, const char *to)
if (strcmp(from_mapper.db_name(), to_mapper.db_name()))
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
-#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS
table_list.init_one_table(from_mapper.db_name(),
strlen(from_mapper.db_name()),
from_mapper.mysql_table_name(),
strlen(from_mapper.mysql_table_name()),
from_mapper.mysql_table_name(), TL_WRITE);
-#else
- table_list.init_one_table(from_mapper.db_name(),
- from_mapper.mysql_table_name(),
- TL_WRITE);
-#endif
mrn_open_mutex_lock(NULL);
tmp_table_share = mrn_create_tmp_table_share(&table_list, from, &error);
mrn_open_mutex_unlock(NULL);
@@ -12650,21 +12984,20 @@ int ha_mroonga::rename_table(const char *from, const char *to)
to_mapper.table_name());
}
+ if (!error && to_mapper.table_name()[0] == '#') {
+ error = add_wrap_hton(to, tmp_share->hton);
+ } else if (error && from_mapper.table_name()[0] == '#') {
+ add_wrap_hton(from, tmp_share->hton);
+ }
if (!error) {
mrn_free_long_term_share(tmp_share->long_term_share);
tmp_share->long_term_share = NULL;
}
mrn_free_share(tmp_share);
- if (!error && to_mapper.table_name()[0] == '#') {
- if ((error = alter_share_add(to, tmp_table_share)))
- DBUG_RETURN(error);
- } else if (error && from_mapper.table_name()[0] == '#') {
- alter_share_add(from, tmp_table_share);
- } else {
- mrn_open_mutex_lock(NULL);
- mrn_free_tmp_table_share(tmp_table_share);
- mrn_open_mutex_unlock(NULL);
- }
+ mrn_open_mutex_lock(NULL);
+ mrn_free_tmp_table_share(tmp_table_share);
+ mrn_open_mutex_unlock(NULL);
+
DBUG_RETURN(error);
}
@@ -13669,6 +14002,7 @@ enum_alter_inplace_result ha_mroonga::wrapper_check_if_supported_inplace_alter(
}
memcpy(wrap_altered_table, altered_table, sizeof(TABLE));
memcpy(wrap_altered_table_share, altered_table->s, sizeof(TABLE_SHARE));
+ mrn_init_sql_alloc(ha_thd(), &(wrap_altered_table_share->mem_root));
n_keys = ha_alter_info->index_drop_count;
for (i = 0; i < n_keys; ++i) {
@@ -13785,6 +14119,25 @@ bool ha_mroonga::wrapper_prepare_inplace_alter_table(
if (!alter_handler_flags) {
DBUG_RETURN(false);
}
+
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ int error = 0;
+ MRN_SHARE *tmp_share;
+ tmp_share = mrn_get_share(altered_table->s->table_name.str,
+ altered_table,
+ &error);
+ if (error != 0) {
+ DBUG_RETURN(true);
+ }
+
+ if (parse_engine_table_options(ha_thd(),
+ tmp_share->hton,
+ wrap_altered_table->s)) {
+ mrn_free_share(tmp_share);
+ DBUG_RETURN(true);
+ }
+#endif
+
MRN_SET_WRAP_ALTER_KEY(this, ha_alter_info);
MRN_SET_WRAP_SHARE_KEY(share, table->s);
MRN_SET_WRAP_TABLE_KEY(this, table);
@@ -13793,6 +14146,11 @@ bool ha_mroonga::wrapper_prepare_inplace_alter_table(
MRN_SET_BASE_ALTER_KEY(this, ha_alter_info);
MRN_SET_BASE_SHARE_KEY(share, table->s);
MRN_SET_BASE_TABLE_KEY(this, table);
+
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ mrn_free_share(tmp_share);
+#endif
+
DBUG_RETURN(result);
}
@@ -13857,8 +14215,8 @@ bool ha_mroonga::wrapper_inplace_alter_table(
ha_alter_info->key_count);
MRN_SHARE *tmp_share;
TABLE_SHARE tmp_table_share;
- char **key_parser;
- uint *key_parser_length;
+ char **key_tokenizer;
+ uint *key_tokenizer_length;
KEY *p_key_info = &table->key_info[table_share->primary_key];
bool need_fill_index = false;
memset(index_tables, 0, sizeof(grn_obj *) * ha_alter_info->key_count);
@@ -13868,8 +14226,8 @@ bool ha_mroonga::wrapper_inplace_alter_table(
if (!(tmp_share = (MRN_SHARE *)
mrn_my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
&tmp_share, sizeof(*tmp_share),
- &key_parser, sizeof(char *) * (tmp_table_share.keys),
- &key_parser_length, sizeof(uint) * (tmp_table_share.keys),
+ &key_tokenizer, sizeof(char *) * (tmp_table_share.keys),
+ &key_tokenizer_length, sizeof(uint) * (tmp_table_share.keys),
NullS))
) {
MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables);
@@ -13880,8 +14238,8 @@ bool ha_mroonga::wrapper_inplace_alter_table(
tmp_share->table_share = &tmp_table_share;
tmp_share->index_table = NULL;
tmp_share->index_table_length = NULL;
- tmp_share->key_parser = key_parser;
- tmp_share->key_parser_length = key_parser_length;
+ tmp_share->key_tokenizer = key_tokenizer;
+ tmp_share->key_tokenizer_length = key_tokenizer_length;
bitmap_clear_all(table->read_set);
mrn_set_bitmap_by_key(table->read_set, p_key_info);
n_keys = ha_alter_info->index_add_count;
@@ -13939,14 +14297,32 @@ bool ha_mroonga::wrapper_inplace_alter_table(
bitmap_set_all(table->read_set);
if (!error && alter_handler_flags) {
- MRN_SET_WRAP_ALTER_KEY(this, ha_alter_info);
- MRN_SET_WRAP_SHARE_KEY(share, table->s);
- MRN_SET_WRAP_TABLE_KEY(this, table);
- result = wrap_handler->ha_inplace_alter_table(wrap_altered_table,
- ha_alter_info);
- MRN_SET_BASE_ALTER_KEY(this, ha_alter_info);
- MRN_SET_BASE_SHARE_KEY(share, table->s);
- MRN_SET_BASE_TABLE_KEY(this, table);
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ {
+ MRN_SHARE *alter_tmp_share;
+ alter_tmp_share = mrn_get_share(altered_table->s->table_name.str,
+ altered_table,
+ &error);
+ if (alter_tmp_share) {
+ if (parse_engine_table_options(ha_thd(),
+ alter_tmp_share->hton,
+ wrap_altered_table->s)) {
+ error = MRN_GET_ERROR_NUMBER;
+ }
+ mrn_free_share(alter_tmp_share);
+ }
+ }
+#endif
+ if (!error) {
+ MRN_SET_WRAP_ALTER_KEY(this, ha_alter_info);
+ MRN_SET_WRAP_SHARE_KEY(share, table->s);
+ MRN_SET_WRAP_TABLE_KEY(this, table);
+ result = wrap_handler->ha_inplace_alter_table(wrap_altered_table,
+ ha_alter_info);
+ MRN_SET_BASE_ALTER_KEY(this, ha_alter_info);
+ MRN_SET_BASE_SHARE_KEY(share, table->s);
+ MRN_SET_BASE_TABLE_KEY(this, table);
+ }
}
if (result || error)
@@ -13954,8 +14330,7 @@ bool ha_mroonga::wrapper_inplace_alter_table(
n_keys = ha_alter_info->index_add_count;
for (i = 0; i < n_keys; ++i) {
uint key_pos = ha_alter_info->index_add_buffer[i];
- KEY *key =
- &altered_table->key_info[key_pos];
+ KEY *key = &altered_table->key_info[key_pos];
if (!(key->flags & HA_FULLTEXT || mrn_is_geo_key(key))) {
continue;
}
@@ -14007,8 +14382,8 @@ bool ha_mroonga::storage_inplace_alter_table_index(
ha_alter_info->key_count);
MRN_SHARE *tmp_share;
TABLE_SHARE tmp_table_share;
- char **index_table, **key_parser, **col_flags, **col_type;
- uint *index_table_length, *key_parser_length, *col_flags_length, *col_type_length;
+ char **index_table, **key_tokenizer, **col_flags, **col_type;
+ uint *index_table_length, *key_tokenizer_length, *col_flags_length, *col_type_length;
bool have_multiple_column_index = false;
memset(index_tables, 0, sizeof(grn_obj *) * ha_alter_info->key_count);
memset(index_columns, 0, sizeof(grn_obj *) * ha_alter_info->key_count);
@@ -14019,8 +14394,8 @@ bool ha_mroonga::storage_inplace_alter_table_index(
&tmp_share, sizeof(*tmp_share),
&index_table, sizeof(char *) * tmp_table_share.keys,
&index_table_length, sizeof(uint) * tmp_table_share.keys,
- &key_parser, sizeof(char *) * tmp_table_share.keys,
- &key_parser_length, sizeof(uint) * tmp_table_share.keys,
+ &key_tokenizer, sizeof(char *) * tmp_table_share.keys,
+ &key_tokenizer_length, sizeof(uint) * tmp_table_share.keys,
&col_flags, sizeof(char *) * tmp_table_share.fields,
&col_flags_length, sizeof(uint) * tmp_table_share.fields,
&col_type, sizeof(char *) * tmp_table_share.fields,
@@ -14035,8 +14410,8 @@ bool ha_mroonga::storage_inplace_alter_table_index(
tmp_share->table_share = &tmp_table_share;
tmp_share->index_table = index_table;
tmp_share->index_table_length = index_table_length;
- tmp_share->key_parser = key_parser;
- tmp_share->key_parser_length = key_parser_length;
+ tmp_share->key_tokenizer = key_tokenizer;
+ tmp_share->key_tokenizer_length = key_tokenizer_length;
tmp_share->col_flags = col_flags;
tmp_share->col_flags_length = col_flags_length;
tmp_share->col_type = col_type;
@@ -14145,8 +14520,8 @@ bool ha_mroonga::storage_inplace_alter_table_add_column(
MRN_SHARE *tmp_share;
TABLE_SHARE tmp_table_share;
- char **index_table, **key_parser, **col_flags, **col_type;
- uint *index_table_length, *key_parser_length, *col_flags_length, *col_type_length;
+ char **index_table, **key_tokenizer, **col_flags, **col_type;
+ uint *index_table_length, *key_tokenizer_length, *col_flags_length, *col_type_length;
tmp_table_share.keys = 0;
tmp_table_share.fields = altered_table->s->fields;
tmp_share = (MRN_SHARE *)mrn_my_multi_malloc(
@@ -14154,8 +14529,8 @@ bool ha_mroonga::storage_inplace_alter_table_add_column(
&tmp_share, sizeof(*tmp_share),
&index_table, sizeof(char *) * tmp_table_share.keys,
&index_table_length, sizeof(uint) * tmp_table_share.keys,
- &key_parser, sizeof(char *) * tmp_table_share.keys,
- &key_parser_length, sizeof(uint) * tmp_table_share.keys,
+ &key_tokenizer, sizeof(char *) * tmp_table_share.keys,
+ &key_tokenizer_length, sizeof(uint) * tmp_table_share.keys,
&col_flags, sizeof(char *) * tmp_table_share.fields,
&col_flags_length, sizeof(uint) * tmp_table_share.fields,
&col_type, sizeof(char *) * tmp_table_share.fields,
@@ -14169,8 +14544,8 @@ bool ha_mroonga::storage_inplace_alter_table_add_column(
tmp_share->table_share = &tmp_table_share;
tmp_share->index_table = index_table;
tmp_share->index_table_length = index_table_length;
- tmp_share->key_parser = key_parser;
- tmp_share->key_parser_length = key_parser_length;
+ tmp_share->key_tokenizer = key_tokenizer;
+ tmp_share->key_tokenizer_length = key_tokenizer_length;
tmp_share->col_flags = col_flags;
tmp_share->col_flags_length = col_flags_length;
tmp_share->col_type = col_type;
@@ -14187,7 +14562,6 @@ bool ha_mroonga::storage_inplace_alter_table_add_column(
continue;
}
- grn_obj *col_type;
Field *field = altered_table->s->field[i];
const char *column_name = field->field_name;
int column_name_size = strlen(column_name);
@@ -14199,20 +14573,19 @@ bool ha_mroonga::storage_inplace_alter_table_add_column(
}
grn_obj_flags col_flags = GRN_OBJ_PERSISTENT;
- if (tmp_share->col_flags[i]) {
- col_flags |= mrn_parse_grn_column_create_flags(ha_thd(),
- ctx,
- tmp_share->col_flags[i],
- tmp_share->col_flags_length[i]);
- } else {
+ if (!find_column_flags(field, tmp_share, i, &col_flags)) {
col_flags |= GRN_OBJ_COLUMN_SCALAR;
}
- grn_builtin_type gtype = mrn_grn_type_from_field(ctx, field, false);
- if (tmp_share->col_type[i]) {
- col_type = grn_ctx_get(ctx, tmp_share->col_type[i], -1);
- } else {
- col_type = grn_ctx_at(ctx, gtype);
+ grn_obj *col_type;
+ {
+ int column_type_error_code = ER_WRONG_FIELD_SPEC;
+ col_type = find_column_type(field, tmp_share, i, column_type_error_code);
+ if (!col_type) {
+ error = column_type_error_code;
+ have_error = true;
+ break;
+ }
}
char *col_path = NULL; // we don't specify path
@@ -14418,6 +14791,7 @@ bool ha_mroonga::wrapper_commit_inplace_alter_table(
bool result;
MRN_DBUG_ENTER_METHOD();
if (!alter_handler_flags) {
+ free_root(&(wrap_altered_table_share->mem_root), MYF(0));
my_free(alter_key_info_buffer);
alter_key_info_buffer = NULL;
DBUG_RETURN(false);
@@ -14431,6 +14805,7 @@ bool ha_mroonga::wrapper_commit_inplace_alter_table(
MRN_SET_BASE_ALTER_KEY(this, ha_alter_info);
MRN_SET_BASE_SHARE_KEY(share, table->s);
MRN_SET_BASE_TABLE_KEY(this, table);
+ free_root(&(wrap_altered_table_share->mem_root), MYF(0));
my_free(alter_key_info_buffer);
alter_key_info_buffer = NULL;
DBUG_RETURN(result);
@@ -14538,8 +14913,8 @@ int ha_mroonga::wrapper_add_index(TABLE *table_arg, KEY *key_info,
THD *thd = ha_thd();
MRN_SHARE *tmp_share;
TABLE_SHARE tmp_table_share;
- char **key_parser;
- uint *key_parser_length;
+ char **key_tokenizer;
+ uint *key_tokenizer_length;
MRN_DBUG_ENTER_METHOD();
if (!(wrap_alter_key_info = (KEY *) mrn_my_malloc(sizeof(KEY) * num_of_keys,
MYF(MY_WME)))) {
@@ -14553,8 +14928,8 @@ int ha_mroonga::wrapper_add_index(TABLE *table_arg, KEY *key_info,
if (!(tmp_share = (MRN_SHARE *)
mrn_my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
&tmp_share, sizeof(*tmp_share),
- &key_parser, sizeof(char *) * (n_keys + num_of_keys),
- &key_parser_length, sizeof(uint) * (n_keys + num_of_keys),
+ &key_tokenizer, sizeof(char *) * (n_keys + num_of_keys),
+ &key_tokenizer_length, sizeof(uint) * (n_keys + num_of_keys),
NullS))
) {
MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables);
@@ -14565,8 +14940,8 @@ int ha_mroonga::wrapper_add_index(TABLE *table_arg, KEY *key_info,
tmp_share->table_share = &tmp_table_share;
tmp_share->index_table = NULL;
tmp_share->index_table_length = NULL;
- tmp_share->key_parser = key_parser;
- tmp_share->key_parser_length = key_parser_length;
+ tmp_share->key_tokenizer = key_tokenizer;
+ tmp_share->key_tokenizer_length = key_tokenizer_length;
tmp_share->col_flags = NULL;
tmp_share->col_type = NULL;
#ifdef MRN_HANDLER_HAVE_FINAL_ADD_INDEX
@@ -14677,8 +15052,8 @@ int ha_mroonga::storage_add_index(TABLE *table_arg, KEY *key_info,
MRN_ALLOCATE_VARIABLE_LENGTH_ARRAYS(grn_obj *, index_columns, num_of_keys + n_keys);
MRN_SHARE *tmp_share;
TABLE_SHARE tmp_table_share;
- char **index_table, **key_parser, **col_flags, **col_type;
- uint *index_table_length, *key_parser_length, *col_flags_length, *col_type_length;
+ char **index_table, **key_tokenizer, **col_flags, **col_type;
+ uint *index_table_length, *key_tokenizer_length, *col_flags_length, *col_type_length;
bool have_multiple_column_index = false;
MRN_DBUG_ENTER_METHOD();
@@ -14689,8 +15064,8 @@ int ha_mroonga::storage_add_index(TABLE *table_arg, KEY *key_info,
&tmp_share, sizeof(*tmp_share),
&index_table, sizeof(char*) * tmp_table_share.keys,
&index_table_length, sizeof(uint) * tmp_table_share.keys,
- &key_parser, sizeof(char *) * tmp_table_share.keys,
- &key_parser_length, sizeof(uint) * tmp_table_share.keys,
+ &key_tokenizer, sizeof(char *) * tmp_table_share.keys,
+ &key_tokenizer_length, sizeof(uint) * tmp_table_share.keys,
&col_flags, sizeof(char *) * tmp_table_share.fields,
&col_flags_length, sizeof(uint) * tmp_table_share.fields,
&col_type, sizeof(char *) * tmp_table_share.fields,
@@ -14705,8 +15080,8 @@ int ha_mroonga::storage_add_index(TABLE *table_arg, KEY *key_info,
tmp_share->table_share = &tmp_table_share;
tmp_share->index_table = index_table;
tmp_share->index_table_length = index_table_length;
- tmp_share->key_parser = key_parser;
- tmp_share->key_parser_length = key_parser_length;
+ tmp_share->key_tokenizer = key_tokenizer;
+ tmp_share->key_tokenizer_length = key_tokenizer_length;
tmp_share->col_flags = col_flags;
tmp_share->col_flags_length = col_flags_length;
tmp_share->col_type = col_type;
@@ -15238,11 +15613,11 @@ int ha_mroonga::reset_auto_increment(ulonglong value)
void ha_mroonga::set_pk_bitmap()
{
- KEY key_info = table->key_info[table_share->primary_key];
- uint j;
MRN_DBUG_ENTER_METHOD();
- for (j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
- Field *field = key_info.key_part[j].field;
+ KEY *key_info = &(table->key_info[table_share->primary_key]);
+ uint j;
+ for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
+ Field *field = key_info->key_part[j].field;
bitmap_set_bit(table->read_set, field->field_index);
}
DBUG_VOID_RETURN;
@@ -15556,17 +15931,11 @@ char *ha_mroonga::storage_get_foreign_key_create_info()
build_table_filename(ref_path, sizeof(ref_path) - 1,
table_share->db.str, ref_table_buff, "", 0);
DBUG_PRINT("info", ("mroonga: ref_path=%s", ref_path));
-#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS
table_list.init_one_table(table_share->db.str,
table_share->db.length,
ref_table_buff,
ref_table_name_length,
ref_table_buff, TL_WRITE);
-#else
- table_list.init_one_table(table_share->db.str,
- ref_table_buff,
- TL_WRITE);
-#endif
mrn_open_mutex_lock(table_share);
tmp_ref_table_share =
mrn_create_tmp_table_share(&table_list, ref_path, &error);
@@ -15768,17 +16137,11 @@ int ha_mroonga::storage_get_foreign_key_list(THD *thd,
build_table_filename(ref_path, sizeof(ref_path) - 1,
table_share->db.str, ref_table_buff, "", 0);
DBUG_PRINT("info", ("mroonga: ref_path=%s", ref_path));
-#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS
table_list.init_one_table(table_share->db.str,
table_share->db.length,
ref_table_buff,
ref_table_name_length,
ref_table_buff, TL_WRITE);
-#else
- table_list.init_one_table(table_share->db.str,
- ref_table_buff,
- TL_WRITE);
-#endif
mrn_open_mutex_lock(table_share);
tmp_ref_table_share =
mrn_create_tmp_table_share(&table_list, ref_path, &error);
@@ -15831,7 +16194,6 @@ int ha_mroonga::get_foreign_key_list(THD *thd,
DBUG_RETURN(res);
}
-#ifdef MRN_HANDLER_HAVE_GET_PARENT_FOREIGN_KEY_LIST
int ha_mroonga::wrapper_get_parent_foreign_key_list(THD *thd,
List<FOREIGN_KEY_INFO> *f_key_list)
{
@@ -15866,7 +16228,6 @@ int ha_mroonga::get_parent_foreign_key_list(THD *thd,
}
DBUG_RETURN(res);
}
-#endif
uint ha_mroonga::wrapper_referenced_by_foreign_key()
{
diff --git a/storage/mroonga/ha_mroonga.hpp b/storage/mroonga/ha_mroonga.hpp
index 78d5c3d2465..37059210dd1 100644
--- a/storage/mroonga/ha_mroonga.hpp
+++ b/storage/mroonga/ha_mroonga.hpp
@@ -33,18 +33,11 @@ extern "C" {
#include <groonga.h>
#include "mrn_mysql_compat.h"
-#if (MYSQL_VERSION_ID >= 50603) || \
- (MYSQL_VERSION_ID >= 50513 && MYSQL_VERSION_ID < 50600) || \
- (MYSQL_VERSION_ID >= 50158 && MYSQL_VERSION_ID < 50500)
-# define MRN_HANDLER_CLONE_NEED_NAME 1
-#endif
-
#if (MYSQL_VERSION_ID >= 50514 && MYSQL_VERSION_ID < 50600)
# define MRN_HANDLER_HAVE_FINAL_ADD_INDEX 1
#endif
-#if (MYSQL_VERSION_ID >= 50603) || \
- (defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 50209)
+#if (MYSQL_VERSION_ID >= 50603) || defined(MRN_MARIADB_P)
# define MRN_HANDLER_HAVE_HA_RND_NEXT 1
# define MRN_HANDLER_HAVE_HA_RND_POS 1
# define MRN_HANDLER_HAVE_HA_INDEX_READ_MAP 1
@@ -56,8 +49,7 @@ extern "C" {
# define MRN_HANDLER_HAVE_HA_INDEX_NEXT_SAME 1
#endif
-#if (MYSQL_VERSION_ID >= 50604) || \
- (defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 50302)
+#if (MYSQL_VERSION_ID >= 50604) || defined(MRN_MARIADB_P)
# define MRN_HANDLER_HAVE_HA_CLOSE 1
# define MRN_HANDLER_HAVE_MULTI_RANGE_READ 1
#endif
@@ -77,15 +69,10 @@ extern "C" {
# endif
#endif
-#if (defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 50302)
+#ifdef MRN_MARIADB_P
# define MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS
#endif
-#if MYSQL_VERSION_ID >= 50500
-# define MRN_HANDLER_HAVE_TRUNCATE
-# define MRN_HANDLER_HAVE_GET_PARENT_FOREIGN_KEY_LIST
-#endif
-
#if MYSQL_VERSION_ID < 50600
# define MRN_HANDLER_HAVE_GET_TABLESPACE_NAME
#endif
@@ -94,10 +81,6 @@ extern "C" {
# define MRN_HANDLER_HAVE_SET_HA_SHARE_REF
#endif
-#if MYSQL_VERSION_ID >= 50500
-# define MRN_TABLE_LIST_INIT_REQUIRE_ALIAS
-#endif
-
#if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P)
# define MRN_BIG_TABLES
#elif defined(BIG_TABLES)
@@ -110,17 +93,10 @@ extern "C" {
# define MRN_HA_ROWS_FORMAT "lu"
#endif
-#if (MYSQL_VERSION_ID < 50519) || \
- defined(MRN_MARIADB_P) || \
- (50600 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID < 50604)
+#ifdef MRN_MARIADB_P
# define MRN_NEED_FREE_STRING_MEMALLOC_PLUGIN_VAR
#endif
-#if MYSQL_VERSION_ID >= 50500
-# define MRN_HAVE_HA_EXTRA_ADD_CHILDREN_LIST
-# define MRN_HAVE_HA_EXTRA_IS_ATTACHED_CHILDREN
-#endif
-
#ifdef MRN_MARIADB_P
# define MRN_HAVE_HA_EXTRA_DETACH_CHILD
# define MRN_HAVE_HA_EXTRA_PREPARE_FOR_FORCED_CLOSE
@@ -147,10 +123,6 @@ extern "C" {
# define MRN_FIELD_STORE_TIME_NEED_TYPE
#endif
-#if MYSQL_VERSION_ID < 50500
-# define MRN_HAVE_TL_WRITE_ALLOW_READ
-#endif
-
#if MYSQL_VERSION_ID < 50706 || defined(MRN_MARIADB_P)
# define MRN_HAVE_TL_WRITE_DELAYED
#endif
@@ -159,9 +131,7 @@ extern "C" {
# define MRN_HAVE_TL_WRITE_CONCURRENT_DEFAULT
#endif
-#if (defined(MRN_MARIADB_P) && \
- ((MYSQL_VERSION_ID >= 50306 && MYSQL_VERSION_ID < 50500) || \
- MYSQL_VERSION_ID >= 50523))
+#ifdef MRN_MARIADB_P
# define MRN_HANDLER_AUTO_REPAIR_HAVE_ERROR
#endif
@@ -191,6 +161,9 @@ extern "C" {
#if (defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 100010)
# define MRN_HAVE_TDC_LOCK_TABLE_SHARE
+# if MYSQL_VERSION_ID >= 100100
+# define MRN_TABLE_SHARE_TDC_IS_POINTER
+# endif
#endif
#ifdef MRN_MARIADB_P
@@ -256,6 +229,22 @@ struct st_mrn_ft_info
ha_mroonga *mroonga;
};
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+struct ha_field_option_struct
+{
+ const char *groonga_type;
+ const char *flags;
+};
+
+struct ha_index_option_struct
+{
+ const char *tokenizer;
+ const char *normalizer;
+ const char *token_filters;
+ const char *flags;
+};
+#endif
+
/* handler class */
class ha_mroonga: public handler
{
@@ -446,11 +435,7 @@ public:
int reset();
-#ifdef MRN_HANDLER_CLONE_NEED_NAME
handler *clone(const char *name, MEM_ROOT *mem_root);
-#else
- handler *clone(MEM_ROOT *mem_root);
-#endif
uint8 table_cache_type();
#ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ
ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
@@ -481,9 +466,7 @@ public:
#endif
int end_bulk_insert();
int delete_all_rows();
-#ifdef MRN_HANDLER_HAVE_TRUNCATE
int truncate();
-#endif // MRN_HANDLER_HAVE_TRUNCATE
double scan_time();
double read_time(uint index, uint ranges, ha_rows rows);
const key_map *keys_to_use_for_scanning();
@@ -567,9 +550,7 @@ protected:
#endif
bool can_switch_engines();
int get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list);
-#ifdef MRN_HANDLER_HAVE_GET_PARENT_FOREIGN_KEY_LIST
int get_parent_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list);
-#endif
uint referenced_by_foreign_key();
void init_table_handle_for_HANDLER();
void free_foreign_key_create_info(char* str);
@@ -597,6 +578,8 @@ private:
void mkdir_p(const char *directory);
ulonglong file_size(const char *path);
+ bool have_unique_index();
+
void push_warning_unsupported_spatial_index_search(enum ha_rkey_function flag);
void clear_cursor();
void clear_cursor_geo();
@@ -604,14 +587,23 @@ private:
void clear_search_result();
void clear_search_result_geo();
void clear_indexes();
- int alter_share_add(const char *path, TABLE_SHARE *table_share);
+ int add_wrap_hton(const char *path, handlerton *wrap_handlerton);
void remove_related_files(const char *base_path);
void remove_grn_obj_force(const char *name);
int drop_index(MRN_SHARE *target_share, uint key_index);
+ int drop_indexes_normal(const char *table_name, grn_obj *table);
+ int drop_indexes_multiple(const char *table_name, grn_obj *table);
+ int drop_indexes(const char *table_name);
+ bool find_column_flags(Field *field, MRN_SHARE *mrn_share, int i,
+ grn_obj_flags *column_flags);
+ grn_obj *find_column_type(Field *field, MRN_SHARE *mrn_share, int i,
+ int error_code);
+ grn_obj *find_tokenizer(KEY *key, MRN_SHARE *mrn_share, int i);
grn_obj *find_tokenizer(const char *name, int name_length);
- grn_obj *find_normalizer(KEY *key_info);
- bool find_index_column_flags(KEY *key_info, grn_obj_flags *index_column_flags);
- bool find_token_filters(KEY *key_info, grn_obj *token_filters);
+ grn_obj *find_normalizer(KEY *key);
+ grn_obj *find_normalizer(KEY *key, const char *name);
+ bool find_index_column_flags(KEY *key, grn_obj_flags *index_column_flags);
+ bool find_token_filters(KEY *key, grn_obj *token_filters);
bool find_token_filters_put(grn_obj *token_filters,
const char *token_filter_name,
int token_filter_name_length);
@@ -788,12 +780,9 @@ private:
int close_databases();
int ensure_database_open(const char *name);
int ensure_database_remove(const char *name);
- int wrapper_delete_table(const char *name, MRN_SHARE *tmp_share,
- const char *table_name);
- int wrapper_delete_index(const char *name, MRN_SHARE *tmp_share,
- const char *table_name);
- int storage_delete_table(const char *name, MRN_SHARE *tmp_share,
+ int wrapper_delete_table(const char *name, handlerton *wrap_handlerton,
const char *table_name);
+ int generic_delete_table(const char *name, const char *table_name);
int wrapper_open(const char *name, int mode, uint test_if_locked);
int wrapper_open_indexes(const char *name);
int storage_open(const char *name, int mode, uint test_if_locked);
@@ -987,13 +976,8 @@ private:
void storage_cond_pop();
bool wrapper_get_error_message(int error, String *buf);
bool storage_get_error_message(int error, String *buf);
-#ifdef MRN_HANDLER_CLONE_NEED_NAME
handler *wrapper_clone(const char *name, MEM_ROOT *mem_root);
handler *storage_clone(const char *name, MEM_ROOT *mem_root);
-#else
- handler *wrapper_clone(MEM_ROOT *mem_root);
- handler *storage_clone(MEM_ROOT *mem_root);
-#endif
uint8 wrapper_table_cache_type();
uint8 storage_table_cache_type();
#ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ
@@ -1049,9 +1033,7 @@ private:
const char *function_name);
int wrapper_delete_all_rows();
int storage_delete_all_rows();
-#ifdef MRN_HANDLER_HAVE_TRUNCATE
int wrapper_truncate();
-#endif // MRN_HANDLER_HAVE_TRUNCATE
int wrapper_truncate_index();
int storage_truncate();
int storage_truncate_index();
@@ -1216,10 +1198,8 @@ private:
bool storage_can_switch_engines();
int wrapper_get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list);
int storage_get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list);
-#ifdef MRN_HANDLER_HAVE_GET_PARENT_FOREIGN_KEY_LIST
int wrapper_get_parent_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list);
int storage_get_parent_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list);
-#endif
uint wrapper_referenced_by_foreign_key();
uint storage_referenced_by_foreign_key();
void wrapper_init_table_handle_for_HANDLER();
diff --git a/storage/mroonga/lib/mrn_condition_converter.cpp b/storage/mroonga/lib/mrn_condition_converter.cpp
index 1bfae1d4f8a..1527a546938 100644
--- a/storage/mroonga/lib/mrn_condition_converter.cpp
+++ b/storage/mroonga/lib/mrn_condition_converter.cpp
@@ -17,10 +17,6 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "mrn_condition_converter.hpp"
#include "mrn_time_converter.hpp"
#include "mrn_smart_grn_obj.hpp"
diff --git a/storage/mroonga/lib/mrn_condition_converter.hpp b/storage/mroonga/lib/mrn_condition_converter.hpp
index bb85f5cdef5..3a7fbd048dc 100644
--- a/storage/mroonga/lib/mrn_condition_converter.hpp
+++ b/storage/mroonga/lib/mrn_condition_converter.hpp
@@ -20,11 +20,12 @@
#ifndef MRN_CONDITION_CONVERTER_HPP_
#define MRN_CONDITION_CONVERTER_HPP_
-#include <groonga.h>
#include <mrn_mysql_compat.h>
#include <item_cmpfunc.h>
+#include <groonga.h>
+
namespace mrn {
class ConditionConverter {
public:
diff --git a/storage/mroonga/lib/mrn_database_manager.cpp b/storage/mroonga/lib/mrn_database_manager.cpp
index 365f47337fa..753d1551ff4 100644
--- a/storage/mroonga/lib/mrn_database_manager.cpp
+++ b/storage/mroonga/lib/mrn_database_manager.cpp
@@ -2,7 +2,7 @@
/*
Copyright(C) 2010 Tetsuro IKEDA
Copyright(C) 2010-2013 Kentoku SHIBA
- Copyright(C) 2011-2014 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -126,13 +126,12 @@ namespace mrn {
mapper.db_name(), strlen(mapper.db_name()),
&db_address, NULL);
memcpy(db_address, db, sizeof(grn_obj *));
+ error = ensure_normalizers_registered(*db);
} else {
memcpy(db, db_address, sizeof(grn_obj *));
grn_ctx_use(ctx_, *db);
}
- error = ensure_normalizers_registered(*db);
-
DBUG_RETURN(error);
}
@@ -313,18 +312,18 @@ namespace mrn {
int error = 0;
#ifdef WITH_GROONGA_NORMALIZER_MYSQL
{
+# ifdef MRN_GROONGA_NORMALIZER_MYSQL_EMBEDDED
+ GRN_PLUGIN_IMPL_NAME_TAGGED(init, normalizers_mysql)(ctx_);
+ GRN_PLUGIN_IMPL_NAME_TAGGED(register, normalizers_mysql)(ctx_);
+# else
grn_obj *mysql_normalizer;
mysql_normalizer = grn_ctx_get(ctx_, "NormalizerMySQLGeneralCI", -1);
if (mysql_normalizer) {
grn_obj_unlink(ctx_, mysql_normalizer);
} else {
-# ifdef MRN_GROONGA_NORMALIZER_MYSQL_EMBED
- GRN_PLUGIN_IMPL_NAME_TAGGED(init, normalizers_mysql)(ctx_);
- GRN_PLUGIN_IMPL_NAME_TAGGED(register, normalizers_mysql)(ctx_);
-# else
grn_plugin_register(ctx_, GROONGA_NORMALIZER_MYSQL_PLUGIN_NAME);
-# endif
}
+# endif
}
#endif
diff --git a/storage/mroonga/lib/mrn_database_repairer.cpp b/storage/mroonga/lib/mrn_database_repairer.cpp
index 151330c9999..f04c027f8bb 100644
--- a/storage/mroonga/lib/mrn_database_repairer.cpp
+++ b/storage/mroonga/lib/mrn_database_repairer.cpp
@@ -233,7 +233,7 @@ namespace mrn {
bool *succeeded = static_cast<bool *>(user_data);
if (grn_db_recover(ctx_, db) != GRN_SUCCESS) {
push_warning_printf(thd_,
- Sql_condition::WARN_LEVEL_WARN,
+ MRN_SEVERITY_WARNING,
ER_NOT_KEYFILE,
"mroonga: repair: "
"Failed to recover database: <%s>: <%s>",
diff --git a/storage/mroonga/lib/mrn_encoding.cpp b/storage/mroonga/lib/mrn_encoding.cpp
index 35b8909fba2..f6f66758b2f 100644
--- a/storage/mroonga/lib/mrn_encoding.cpp
+++ b/storage/mroonga/lib/mrn_encoding.cpp
@@ -18,7 +18,6 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <mrn_mysql.h>
#include <mrn_err.h>
#include "mrn_encoding.hpp"
diff --git a/storage/mroonga/lib/mrn_encoding.hpp b/storage/mroonga/lib/mrn_encoding.hpp
index b29b44d967e..9c3a65da0f1 100644
--- a/storage/mroonga/lib/mrn_encoding.hpp
+++ b/storage/mroonga/lib/mrn_encoding.hpp
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -20,11 +20,11 @@
#ifndef MRN_ENCODING_HPP_
#define MRN_ENCODING_HPP_
-#include <groonga.h>
-
#include <mrn_mysql.h>
#include <mrn_mysql_compat.h>
+#include <groonga.h>
+
namespace mrn {
namespace encoding {
void init(void);
diff --git a/storage/mroonga/lib/mrn_field_normalizer.cpp b/storage/mroonga/lib/mrn_field_normalizer.cpp
index f0b9d921599..d5b0b3ff43e 100644
--- a/storage/mroonga/lib/mrn_field_normalizer.cpp
+++ b/storage/mroonga/lib/mrn_field_normalizer.cpp
@@ -17,8 +17,6 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <mrn_mysql.h>
-
#include "mrn_field_normalizer.hpp"
#include "mrn_encoding.hpp"
diff --git a/storage/mroonga/lib/mrn_field_normalizer.hpp b/storage/mroonga/lib/mrn_field_normalizer.hpp
index 5fd8974ce5b..3a855693481 100644
--- a/storage/mroonga/lib/mrn_field_normalizer.hpp
+++ b/storage/mroonga/lib/mrn_field_normalizer.hpp
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -20,11 +20,11 @@
#ifndef MRN_FIELD_NORMALIZER_HPP_
#define MRN_FIELD_NORMALIZER_HPP_
-#include <groonga.h>
-
#include <mrn_mysql.h>
#include <mrn_mysql_compat.h>
+#include <groonga.h>
+
namespace mrn {
class FieldNormalizer {
public:
diff --git a/storage/mroonga/lib/mrn_index_table_name.cpp b/storage/mroonga/lib/mrn_index_table_name.cpp
index 93f4ff8f8fd..a4a687c7996 100644
--- a/storage/mroonga/lib/mrn_index_table_name.cpp
+++ b/storage/mroonga/lib/mrn_index_table_name.cpp
@@ -26,6 +26,32 @@
#define MRN_CLASS_NAME "mrn::IndexTableName"
namespace mrn {
+ const char *IndexTableName::SEPARATOR = "-";
+
+ bool IndexTableName::is_custom_name(const char *table_name,
+ size_t table_name_length,
+ const char *index_table_name,
+ size_t index_table_name_length)
+ {
+ MRN_DBUG_ENTER_METHOD();
+
+ if (index_table_name_length <= (table_name_length + strlen(SEPARATOR))) {
+ DBUG_RETURN(true);
+ }
+
+ if (strncmp(table_name, index_table_name, table_name_length) != 0) {
+ DBUG_RETURN(true);
+ }
+
+ if (strncmp(SEPARATOR,
+ index_table_name + table_name_length,
+ strlen(SEPARATOR)) != 0) {
+ DBUG_RETURN(true);
+ }
+
+ DBUG_RETURN(false);
+ }
+
IndexTableName::IndexTableName(const char *table_name,
const char *mysql_index_name)
: table_name_(table_name),
@@ -38,7 +64,10 @@ namespace mrn {
mysql_index_name_multibyte,
mysql_index_name_multibyte + strlen(mysql_index_name_));
snprintf(name_, MRN_MAX_KEY_SIZE,
- "%s-%s", table_name_, encoded_mysql_index_name_multibyte);
+ "%s%s%s",
+ table_name_,
+ SEPARATOR,
+ encoded_mysql_index_name_multibyte);
length_ = strlen(name_);
}
diff --git a/storage/mroonga/lib/mrn_index_table_name.hpp b/storage/mroonga/lib/mrn_index_table_name.hpp
index 4ac4bfe087b..c4f16228610 100644
--- a/storage/mroonga/lib/mrn_index_table_name.hpp
+++ b/storage/mroonga/lib/mrn_index_table_name.hpp
@@ -26,6 +26,13 @@
namespace mrn {
class IndexTableName {
public:
+ static const char *SEPARATOR;
+
+ static bool is_custom_name(const char *table_name,
+ size_t table_name_length,
+ const char *index_table_name,
+ size_t index_table_name_length);
+
IndexTableName(const char *table_name, const char *mysql_index_name);
const char *c_str();
size_t length();
diff --git a/storage/mroonga/lib/mrn_lock.cpp b/storage/mroonga/lib/mrn_lock.cpp
index 3340149b237..f518bca9af3 100644
--- a/storage/mroonga/lib/mrn_lock.cpp
+++ b/storage/mroonga/lib/mrn_lock.cpp
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -20,12 +20,17 @@
#include "mrn_lock.hpp"
namespace mrn {
- Lock::Lock(mysql_mutex_t *mutex)
- : mutex_(mutex) {
- mysql_mutex_lock(mutex_);
+ Lock::Lock(mysql_mutex_t *mutex, bool execute)
+ : mutex_(mutex),
+ execute_(execute) {
+ if (execute_) {
+ mysql_mutex_lock(mutex_);
+ }
}
Lock::~Lock() {
- mysql_mutex_unlock(mutex_);
+ if (execute_) {
+ mysql_mutex_unlock(mutex_);
+ }
}
}
diff --git a/storage/mroonga/lib/mrn_lock.hpp b/storage/mroonga/lib/mrn_lock.hpp
index 08e47b39c58..2ec71370fa1 100644
--- a/storage/mroonga/lib/mrn_lock.hpp
+++ b/storage/mroonga/lib/mrn_lock.hpp
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -26,10 +26,11 @@
namespace mrn {
class Lock {
public:
- Lock(mysql_mutex_t *mutex);
+ Lock(mysql_mutex_t *mutex, bool execute=true);
~Lock();
private:
mysql_mutex_t *mutex_;
+ bool execute_;
};
}
diff --git a/storage/mroonga/lib/mrn_multiple_column_key_codec.cpp b/storage/mroonga/lib/mrn_multiple_column_key_codec.cpp
index 1e55636f1bc..c7ef9dd5851 100644
--- a/storage/mroonga/lib/mrn_multiple_column_key_codec.cpp
+++ b/storage/mroonga/lib/mrn_multiple_column_key_codec.cpp
@@ -23,6 +23,7 @@
#include "mrn_multiple_column_key_codec.hpp"
#include "mrn_field_normalizer.hpp"
#include "mrn_smart_grn_obj.hpp"
+#include "mrn_time_converter.hpp"
#include "mrn_value_decoder.hpp"
// for debug
@@ -36,6 +37,13 @@
uint8 *key_ = (uint8 *)(key); \
while (size_--) { *buf_++ = *key_++; } \
}
+#define mrn_byte_order_network_to_host(buf, key, size) \
+{ \
+ uint32 size_ = (uint32)(size); \
+ uint8 *buf_ = (uint8 *)(buf); \
+ uint8 *key_ = (uint8 *)(key); \
+ while (size_) { *buf_++ = *key_++; size_--; } \
+}
#else /* WORDS_BIGENDIAN */
#define mrn_byte_order_host_to_network(buf, key, size) \
{ \
@@ -44,6 +52,13 @@
uint8 *key_ = (uint8 *)(key) + size_; \
while (size_--) { *buf_++ = *(--key_); } \
}
+#define mrn_byte_order_network_to_host(buf, key, size) \
+{ \
+ uint32 size_ = (uint32)(size); \
+ uint8 *buf_ = (uint8 *)(buf); \
+ uint8 *key_ = (uint8 *)(key) + size_; \
+ while (size_) { *buf_++ = *(--key_); size_--; } \
+}
#endif /* WORDS_BIGENDIAN */
namespace mrn {
@@ -87,6 +102,7 @@ namespace mrn {
DataType data_type = TYPE_UNKNOWN;
uint data_size = 0;
get_key_info(key_part, &data_type, &data_size);
+ uint grn_key_data_size = data_size;
switch (data_type) {
case TYPE_UNKNOWN:
@@ -97,26 +113,17 @@ namespace mrn {
case TYPE_LONG_LONG_NUMBER:
{
long long int long_long_value = 0;
- switch (data_size) {
- case 3:
- long_long_value = (long long int)sint3korr(current_mysql_key);
- break;
- case 8:
- long_long_value = (long long int)sint8korr(current_mysql_key);
- break;
- }
- mrn_byte_order_host_to_network(current_grn_key, &long_long_value,
- data_size);
- *((uint8 *)(current_grn_key)) ^= 0x80;
+ long_long_value = sint8korr(current_mysql_key);
+ encode_long_long_int(long_long_value, current_grn_key);
}
break;
case TYPE_NUMBER:
- mrn_byte_order_host_to_network(current_grn_key, current_mysql_key, data_size);
{
- Field_num *number_field = (Field_num *)field;
- if (!number_field->unsigned_flag) {
- *((uint8 *)(current_grn_key)) ^= 0x80;
- }
+ Field_num *number_field = static_cast<Field_num *>(field);
+ encode_number(current_mysql_key,
+ data_size,
+ !number_field->unsigned_flag,
+ current_grn_key);
}
break;
case TYPE_FLOAT:
@@ -133,6 +140,44 @@ namespace mrn {
encode_double(value, data_size, current_grn_key);
}
break;
+ case TYPE_DATETIME:
+ {
+ long long int mysql_datetime;
+#ifdef WORDS_BIGENDIAN
+ if (field->table && field->table->s->db_low_byte_first) {
+ mysql_datetime = sint8korr(current_mysql_key);
+ } else
+#endif
+ {
+ value_decoder::decode(&mysql_datetime, current_mysql_key);
+ }
+ TimeConverter time_converter;
+ bool truncated;
+ long long int grn_time =
+ time_converter.mysql_datetime_to_grn_time(mysql_datetime,
+ &truncated);
+ encode_long_long_int(grn_time, current_grn_key);
+ }
+ break;
+#ifdef MRN_HAVE_MYSQL_TYPE_DATETIME2
+ case TYPE_DATETIME2:
+ {
+ Field_datetimef *datetimef_field =
+ static_cast<Field_datetimef *>(field);
+ long long int mysql_datetime_packed =
+ my_datetime_packed_from_binary(current_mysql_key,
+ datetimef_field->decimals());
+ MYSQL_TIME mysql_time;
+ TIME_from_longlong_datetime_packed(&mysql_time, mysql_datetime_packed);
+ TimeConverter time_converter;
+ bool truncated;
+ long long int grn_time =
+ time_converter.mysql_time_to_grn_time(&mysql_time, &truncated);
+ grn_key_data_size = 8;
+ encode_long_long_int(grn_time, current_grn_key);
+ }
+ break;
+#endif
case TYPE_BYTE_SEQUENCE:
memcpy(current_grn_key, current_mysql_key, data_size);
break;
@@ -140,7 +185,8 @@ namespace mrn {
encode_reverse(current_mysql_key, data_size, current_grn_key);
break;
case TYPE_BYTE_BLOB:
- encode_blob(field, current_mysql_key, current_grn_key, &data_size);
+ encode_blob(current_mysql_key, &data_size, field, current_grn_key);
+ grn_key_data_size = data_size;
break;
}
@@ -149,8 +195,8 @@ namespace mrn {
}
current_mysql_key += data_size;
- current_grn_key += data_size;
- *grn_key_length += data_size;
+ current_grn_key += grn_key_data_size;
+ *grn_key_length += grn_key_data_size;
}
DBUG_RETURN(error);
@@ -185,6 +231,7 @@ namespace mrn {
DataType data_type = TYPE_UNKNOWN;
uint data_size = 0;
get_key_info(key_part, &data_type, &data_size);
+ uint grn_key_data_size = data_size;
switch (data_type) {
case TYPE_UNKNOWN:
@@ -194,43 +241,68 @@ namespace mrn {
break;
case TYPE_LONG_LONG_NUMBER:
{
- long long int long_long_value = 0;
- switch (data_size) {
- case 3:
- long_long_value = (long long int)sint3korr(current_grn_key);
- break;
- case 8:
- long_long_value = (long long int)sint8korr(current_grn_key);
- break;
- }
- *((uint8 *)(&long_long_value)) ^= 0x80;
- mrn_byte_order_host_to_network(current_mysql_key, &long_long_value,
- data_size);
+ long long int value;
+ decode_long_long_int(current_grn_key, &value);
+ int8store(current_mysql_key, value);
}
break;
case TYPE_NUMBER:
{
- uchar buffer[8];
- memcpy(buffer, current_grn_key, data_size);
- Field_num *number_field = (Field_num *)field;
- if (!number_field->unsigned_flag) {
- buffer[0] ^= 0x80;
- }
- mrn_byte_order_host_to_network(current_mysql_key, buffer,
- data_size);
+ Field_num *number_field = static_cast<Field_num *>(field);
+ decode_number(current_grn_key,
+ grn_key_data_size,
+ !number_field->unsigned_flag,
+ current_mysql_key);
}
break;
case TYPE_FLOAT:
- decode_float(current_grn_key, current_mysql_key, data_size);
+ decode_float(current_grn_key, grn_key_data_size, current_mysql_key);
break;
case TYPE_DOUBLE:
- decode_double(current_grn_key, current_mysql_key, data_size);
+ decode_double(current_grn_key, grn_key_data_size, current_mysql_key);
+ break;
+ case TYPE_DATETIME:
+ {
+ long long int grn_time;
+ decode_long_long_int(current_grn_key, &grn_time);
+ TimeConverter time_converter;
+ long long int mysql_datetime =
+ time_converter.grn_time_to_mysql_datetime(grn_time);
+#ifdef WORDS_BIGENDIAN
+ if (field->table && field->table->s->db_low_byte_first) {
+ int8store(current_mysql_key, mysql_datetime);
+ } else
+#endif
+ {
+ longlongstore(current_mysql_key, mysql_datetime);
+ }
+ }
+ break;
+#ifdef MRN_HAVE_MYSQL_TYPE_DATETIME2
+ case TYPE_DATETIME2:
+ {
+ Field_datetimef *datetimef_field =
+ static_cast<Field_datetimef *>(field);
+ long long int grn_time;
+ grn_key_data_size = 8;
+ decode_long_long_int(current_grn_key, &grn_time);
+ TimeConverter time_converter;
+ MYSQL_TIME mysql_time;
+ mysql_time.time_type = MYSQL_TIMESTAMP_DATETIME;
+ time_converter.grn_time_to_mysql_time(grn_time, &mysql_time);
+ long long int mysql_datetime_packed =
+ TIME_to_longlong_datetime_packed(&mysql_time);
+ my_datetime_packed_to_binary(mysql_datetime_packed,
+ current_mysql_key,
+ datetimef_field->decimals());
+ }
break;
+#endif
case TYPE_BYTE_SEQUENCE:
- memcpy(current_mysql_key, current_grn_key, data_size);
+ memcpy(current_mysql_key, current_grn_key, grn_key_data_size);
break;
case TYPE_BYTE_REVERSE:
- decode_reverse(current_grn_key, current_mysql_key, data_size);
+ decode_reverse(current_grn_key, grn_key_data_size, current_mysql_key);
break;
case TYPE_BYTE_BLOB:
memcpy(current_mysql_key,
@@ -240,6 +312,7 @@ namespace mrn {
current_grn_key,
data_size);
data_size += HA_KEY_BLOB_LENGTH;
+ grn_key_data_size = data_size;
break;
}
@@ -247,7 +320,7 @@ namespace mrn {
break;
}
- current_grn_key += data_size;
+ current_grn_key += grn_key_data_size;
current_mysql_key += data_size;
*mysql_key_length += data_size;
}
@@ -275,10 +348,19 @@ namespace mrn {
DataType data_type = TYPE_UNKNOWN;
uint data_size = 0;
get_key_info(key_part, &data_type, &data_size);
- total_size += data_size;
- if (data_type == TYPE_BYTE_BLOB) {
- total_size += HA_KEY_BLOB_LENGTH;
+ switch (data_type) {
+#ifdef MRN_HAVE_MYSQL_TYPE_DATETIME2
+ case TYPE_DATETIME2:
+ data_size = 8;
+ break;
+#endif
+ case TYPE_BYTE_BLOB:
+ data_size += HA_KEY_BLOB_LENGTH;
+ break;
+ default:
+ break;
}
+ total_size += data_size;
}
DBUG_RETURN(total_size);
@@ -331,10 +413,22 @@ namespace mrn {
*data_size = 1;
break;
case MYSQL_TYPE_TIMESTAMP:
+ DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_TIMESTAMP"));
+ *data_type = TYPE_BYTE_REVERSE;
+ *data_size = key_part->length;
+ break;
case MYSQL_TYPE_DATE:
+ DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_DATE"));
+ *data_type = TYPE_BYTE_REVERSE;
+ *data_size = key_part->length;
+ break;
case MYSQL_TYPE_DATETIME:
- case MYSQL_TYPE_NEWDATE:
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_DATETIME"));
+ *data_type = TYPE_DATETIME;
+ *data_size = key_part->length;
+ break;
+ case MYSQL_TYPE_NEWDATE:
+ DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_NEWDATE"));
*data_type = TYPE_BYTE_REVERSE;
*data_size = key_part->length;
break;
@@ -350,7 +444,7 @@ namespace mrn {
break;
case MYSQL_TYPE_TIME:
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_TIME"));
- *data_type = TYPE_LONG_LONG_NUMBER;
+ *data_type = TYPE_NUMBER;
*data_size = 3;
break;
case MYSQL_TYPE_VARCHAR:
@@ -374,7 +468,7 @@ namespace mrn {
#ifdef MRN_HAVE_MYSQL_TYPE_DATETIME2
case MYSQL_TYPE_DATETIME2:
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_DATETIME2"));
- *data_type = TYPE_BYTE_SEQUENCE;
+ *data_type = TYPE_DATETIME2;
*data_size = key_part->length;
break;
#endif
@@ -428,77 +522,127 @@ namespace mrn {
DBUG_VOID_RETURN;
}
- void MultipleColumnKeyCodec::encode_float(volatile float value, uint data_size,
+ void MultipleColumnKeyCodec::encode_number(const uchar *mysql_key,
+ uint mysql_key_size,
+ bool is_signed,
+ uchar *grn_key) {
+ MRN_DBUG_ENTER_METHOD();
+ mrn_byte_order_host_to_network(grn_key, mysql_key, mysql_key_size);
+ if (is_signed) {
+ grn_key[0] ^= 0x80;
+ }
+ DBUG_VOID_RETURN;
+ }
+
+ void MultipleColumnKeyCodec::decode_number(const uchar *grn_key,
+ uint grn_key_size,
+ bool is_signed,
+ uchar *mysql_key) {
+ MRN_DBUG_ENTER_METHOD();
+ uchar buffer[8];
+ memcpy(buffer, grn_key, grn_key_size);
+ if (is_signed) {
+ buffer[0] ^= 0x80;
+ }
+ mrn_byte_order_network_to_host(mysql_key, buffer, grn_key_size);
+ DBUG_VOID_RETURN;
+ }
+
+ void MultipleColumnKeyCodec::encode_long_long_int(volatile long long int value,
+ uchar *grn_key) {
+ MRN_DBUG_ENTER_METHOD();
+ uint value_size = 8;
+ mrn_byte_order_host_to_network(grn_key, &value, value_size);
+ grn_key[0] ^= 0x80;
+ DBUG_VOID_RETURN;
+ }
+
+ void MultipleColumnKeyCodec::decode_long_long_int(const uchar *grn_key,
+ long long int *value) {
+ MRN_DBUG_ENTER_METHOD();
+ uint grn_key_size = 8;
+ uchar buffer[8];
+ memcpy(buffer, grn_key, grn_key_size);
+ buffer[0] ^= 0x80;
+ mrn_byte_order_network_to_host(value, buffer, grn_key_size);
+ DBUG_VOID_RETURN;
+ }
+
+ void MultipleColumnKeyCodec::encode_float(volatile float value,
+ uint value_size,
uchar *grn_key) {
MRN_DBUG_ENTER_METHOD();
- int n_bits = (data_size * 8 - 1);
+ int n_bits = (value_size * 8 - 1);
volatile int *int_value_pointer = (int *)(&value);
int int_value = *int_value_pointer;
int_value ^= ((int_value >> n_bits) | (1 << n_bits));
- mrn_byte_order_host_to_network(grn_key, &int_value, data_size);
+ mrn_byte_order_host_to_network(grn_key, &int_value, value_size);
DBUG_VOID_RETURN;
}
void MultipleColumnKeyCodec::decode_float(const uchar *grn_key,
- uchar *mysql_key,
- uint data_size) {
+ uint grn_key_size,
+ uchar *mysql_key) {
MRN_DBUG_ENTER_METHOD();
int int_value;
- mrn_byte_order_host_to_network(&int_value, grn_key, data_size);
- int max_bit = (data_size * 8 - 1);
+ mrn_byte_order_network_to_host(&int_value, grn_key, grn_key_size);
+ int max_bit = (grn_key_size * 8 - 1);
*((int *)mysql_key) =
int_value ^ (((int_value ^ (1 << max_bit)) >> max_bit) |
(1 << max_bit));
DBUG_VOID_RETURN;
}
- void MultipleColumnKeyCodec::encode_double(volatile double value, uint data_size,
+ void MultipleColumnKeyCodec::encode_double(volatile double value,
+ uint value_size,
uchar *grn_key) {
MRN_DBUG_ENTER_METHOD();
- int n_bits = (data_size * 8 - 1);
+ int n_bits = (value_size * 8 - 1);
volatile long long int *long_long_value_pointer = (long long int *)(&value);
volatile long long int long_long_value = *long_long_value_pointer;
long_long_value ^= ((long_long_value >> n_bits) | (1LL << n_bits));
- mrn_byte_order_host_to_network(grn_key, &long_long_value, data_size);
+ mrn_byte_order_host_to_network(grn_key, &long_long_value, value_size);
DBUG_VOID_RETURN;
}
void MultipleColumnKeyCodec::decode_double(const uchar *grn_key,
- uchar *mysql_key,
- uint data_size) {
+ uint grn_key_size,
+ uchar *mysql_key) {
MRN_DBUG_ENTER_METHOD();
long long int long_long_value;
- mrn_byte_order_host_to_network(&long_long_value, grn_key, data_size);
- int max_bit = (data_size * 8 - 1);
+ mrn_byte_order_network_to_host(&long_long_value, grn_key, grn_key_size);
+ int max_bit = (grn_key_size * 8 - 1);
*((long long int *)mysql_key) =
long_long_value ^ (((long_long_value ^ (1LL << max_bit)) >> max_bit) |
(1LL << max_bit));
DBUG_VOID_RETURN;
}
- void MultipleColumnKeyCodec::encode_reverse(const uchar *mysql_key, uint data_size,
+ void MultipleColumnKeyCodec::encode_reverse(const uchar *mysql_key,
+ uint mysql_key_size,
uchar *grn_key) {
MRN_DBUG_ENTER_METHOD();
- for (uint i = 0; i < data_size; i++) {
- grn_key[i] = mysql_key[data_size - i - 1];
+ for (uint i = 0; i < mysql_key_size; i++) {
+ grn_key[i] = mysql_key[mysql_key_size - i - 1];
}
DBUG_VOID_RETURN;
}
void MultipleColumnKeyCodec::decode_reverse(const uchar *grn_key,
- uchar *mysql_key,
- uint data_size) {
+ uint grn_key_size,
+ uchar *mysql_key) {
MRN_DBUG_ENTER_METHOD();
- for (uint i = 0; i < data_size; i++) {
- mysql_key[i] = grn_key[data_size - i - 1];
+ for (uint i = 0; i < grn_key_size; i++) {
+ mysql_key[i] = grn_key[grn_key_size - i - 1];
}
DBUG_VOID_RETURN;
}
- void MultipleColumnKeyCodec::encode_blob(Field *field,
- const uchar *mysql_key,
- uchar *grn_key,
- uint *data_size) {
+ void MultipleColumnKeyCodec::encode_blob(const uchar *mysql_key,
+ uint *mysql_key_size,
+ Field *field,
+ uchar *grn_key) {
+ MRN_DBUG_ENTER_METHOD();
FieldNormalizer normalizer(ctx_, thread_, field);
if (normalizer.should_normalize()) {
#if HA_KEY_BLOB_LENGTH != 2
@@ -517,15 +661,15 @@ namespace mrn {
uint16 new_blob_data_length;
if (normalized_length <= UINT_MAX16) {
memcpy(grn_key, normalized, normalized_length);
- if (normalized_length < *data_size) {
+ if (normalized_length < *mysql_key_size) {
memset(grn_key + normalized_length,
- '\0', *data_size - normalized_length);
+ '\0', *mysql_key_size - normalized_length);
}
new_blob_data_length = normalized_length;
} else {
push_warning_printf(thread_,
MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED,
+ MRN_ERROR_CODE_DATA_TRUNCATE(thread_),
"normalized data truncated "
"for multiple column index: "
"normalized-data-size: <%u> "
@@ -539,11 +683,14 @@ namespace mrn {
memcpy(grn_key, normalized, blob_data_length);
new_blob_data_length = blob_data_length;
}
- memcpy(grn_key + *data_size, &new_blob_data_length, HA_KEY_BLOB_LENGTH);
+ memcpy(grn_key + *mysql_key_size,
+ &new_blob_data_length,
+ HA_KEY_BLOB_LENGTH);
} else {
- memcpy(grn_key + *data_size, mysql_key, HA_KEY_BLOB_LENGTH);
- memcpy(grn_key, mysql_key + HA_KEY_BLOB_LENGTH, *data_size);
+ memcpy(grn_key + *mysql_key_size, mysql_key, HA_KEY_BLOB_LENGTH);
+ memcpy(grn_key, mysql_key + HA_KEY_BLOB_LENGTH, *mysql_key_size);
}
- *data_size += HA_KEY_BLOB_LENGTH;
+ *mysql_key_size += HA_KEY_BLOB_LENGTH;
+ DBUG_VOID_RETURN;
}
}
diff --git a/storage/mroonga/lib/mrn_multiple_column_key_codec.hpp b/storage/mroonga/lib/mrn_multiple_column_key_codec.hpp
index fc6ae285357..2b3f935d4e4 100644
--- a/storage/mroonga/lib/mrn_multiple_column_key_codec.hpp
+++ b/storage/mroonga/lib/mrn_multiple_column_key_codec.hpp
@@ -44,6 +44,10 @@ namespace mrn {
TYPE_NUMBER,
TYPE_FLOAT,
TYPE_DOUBLE,
+ TYPE_DATETIME,
+#ifdef MRN_HAVE_MYSQL_TYPE_DATETIME2
+ TYPE_DATETIME2,
+#endif
TYPE_BYTE_SEQUENCE,
TYPE_BYTE_REVERSE,
TYPE_BYTE_BLOB
@@ -56,14 +60,40 @@ namespace mrn {
void get_key_info(KEY_PART_INFO *key_part,
DataType *data_type, uint *data_size);
- void encode_float(volatile float value, uint data_size, uchar *grn_key);
- void decode_float(const uchar *grn_key, uchar *mysql_key, uint data_size);
- void encode_double(volatile double value, uint data_size, uchar *grn_key);
- void decode_double(const uchar *grn_key, uchar *mysql_key, uint data_size);
- void encode_reverse(const uchar *mysql_key, uint data_size, uchar *grn_key);
- void decode_reverse(const uchar *grn_key, uchar *mysql_key, uint data_size);
- void encode_blob(Field *field,
- const uchar *mysql_key, uchar *grn_key, uint *data_size);
+ void encode_number(const uchar *mysql_key,
+ uint mysql_key_size,
+ bool is_signed,
+ uchar *grn_key);
+ void decode_number(const uchar *grn_key,
+ uint grn_key_size,
+ bool is_signed,
+ uchar *mysql_key);
+ void encode_long_long_int(volatile long long int value,
+ uchar *grn_key);
+ void decode_long_long_int(const uchar *grn_key,
+ long long int *value);
+ void encode_float(volatile float value,
+ uint value_size,
+ uchar *grn_key);
+ void decode_float(const uchar *grn_key,
+ uint grn_key_size,
+ uchar *mysql_key);
+ void encode_double(volatile double value,
+ uint value_size,
+ uchar *grn_key);
+ void decode_double(const uchar *grn_key,
+ uint grn_key_size,
+ uchar *mysql_key);
+ void encode_reverse(const uchar *mysql_key,
+ uint mysql_key_size,
+ uchar *grn_key);
+ void decode_reverse(const uchar *grn_key,
+ uint grn_key_size,
+ uchar *mysql_key);
+ void encode_blob(const uchar *mysql_key,
+ uint *mysql_key_size,
+ Field *field,
+ uchar *grn_key);
};
}
diff --git a/storage/mroonga/lib/mrn_mysqlservices.cpp b/storage/mroonga/lib/mrn_mysqlservices.cpp
index 9c7af9acfe0..693aa8607c3 100644
--- a/storage/mroonga/lib/mrn_mysqlservices.cpp
+++ b/storage/mroonga/lib/mrn_mysqlservices.cpp
@@ -17,10 +17,6 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include <mrn_mysql.h>
#include <mrn_mysql_compat.h>
diff --git a/storage/mroonga/lib/mrn_smart_grn_obj.cpp b/storage/mroonga/lib/mrn_smart_grn_obj.cpp
index 9dbae6528f9..40ea9cb079c 100644
--- a/storage/mroonga/lib/mrn_smart_grn_obj.cpp
+++ b/storage/mroonga/lib/mrn_smart_grn_obj.cpp
@@ -50,4 +50,10 @@ namespace mrn {
grn_obj *SmartGrnObj::get() {
return obj_;
}
+
+ grn_obj *SmartGrnObj::release() {
+ grn_obj *obj = obj_;
+ obj_ = NULL;
+ return obj;
+ }
}
diff --git a/storage/mroonga/lib/mrn_smart_grn_obj.hpp b/storage/mroonga/lib/mrn_smart_grn_obj.hpp
index c9c86f3e46e..0a44a6ac9db 100644
--- a/storage/mroonga/lib/mrn_smart_grn_obj.hpp
+++ b/storage/mroonga/lib/mrn_smart_grn_obj.hpp
@@ -33,6 +33,7 @@ namespace mrn {
~SmartGrnObj();
grn_obj *get();
+ grn_obj *release();
};
}
diff --git a/storage/mroonga/lib/mrn_time_converter.cpp b/storage/mroonga/lib/mrn_time_converter.cpp
index 63b2e53766d..3c6821c8d11 100644
--- a/storage/mroonga/lib/mrn_time_converter.cpp
+++ b/storage/mroonga/lib/mrn_time_converter.cpp
@@ -1,7 +1,7 @@
/* -*- c-basic-offset: 2 -*- */
/*
Copyright(C) 2010-2013 Kentoku SHIBA
- Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -18,10 +18,6 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "mrn_time_converter.hpp"
#ifdef min
@@ -257,4 +253,43 @@ namespace mrn {
}
DBUG_VOID_RETURN;
}
+
+ long long int TimeConverter::mysql_datetime_to_grn_time(long long int mysql_datetime,
+ bool *truncated) {
+ MRN_DBUG_ENTER_METHOD();
+
+ MYSQL_TIME mysql_time;
+ mysql_time.time_type = MYSQL_TIMESTAMP_DATETIME;
+ mysql_time.neg = 0;
+ mysql_time.second_part = 0;
+ mysql_time.second = (mysql_datetime % 100);
+ mysql_time.minute = (mysql_datetime / 100 % 100);
+ mysql_time.hour = (mysql_datetime / 10000 % 100);
+ mysql_time.day = (mysql_datetime / 1000000 % 100);
+ mysql_time.month = (mysql_datetime / 100000000 % 100);
+ mysql_time.year = (mysql_datetime / 10000000000LL % 10000);
+
+ long long int grn_time = mysql_time_to_grn_time(&mysql_time, truncated);
+
+ DBUG_RETURN(grn_time);
+ }
+
+ long long int TimeConverter::grn_time_to_mysql_datetime(long long int grn_time) {
+ MRN_DBUG_ENTER_METHOD();
+
+ MYSQL_TIME mysql_time;
+ mysql_time.time_type = MYSQL_TIMESTAMP_DATETIME;
+
+ grn_time_to_mysql_time(grn_time, &mysql_time);
+
+ long long int mysql_datetime =
+ (mysql_time.second * 1) +
+ (mysql_time.minute * 100) +
+ (mysql_time.hour * 10000) +
+ (mysql_time.day * 1000000) +
+ (mysql_time.month * 100000000) +
+ (mysql_time.year * 10000000000LL);
+
+ DBUG_RETURN(mysql_datetime);
+ }
}
diff --git a/storage/mroonga/lib/mrn_time_converter.hpp b/storage/mroonga/lib/mrn_time_converter.hpp
index c5c69a0a8ad..9d297f92e59 100644
--- a/storage/mroonga/lib/mrn_time_converter.hpp
+++ b/storage/mroonga/lib/mrn_time_converter.hpp
@@ -1,7 +1,7 @@
/* -*- c-basic-offset: 2 -*- */
/*
Copyright(C) 2010-2013 Kentoku SHIBA
- Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -21,9 +21,10 @@
#ifndef MRN_TIME_CONVERTER_HPP_
#define MRN_TIME_CONVERTER_HPP_
-#include <groonga.h>
#include <mrn_mysql_compat.h>
+#include <groonga.h>
+
namespace mrn {
class TimeConverter {
public:
@@ -34,10 +35,13 @@ namespace mrn {
long long int mysql_time_to_grn_time(MYSQL_TIME *mysql_time,
bool *truncated);
+ long long int mysql_datetime_to_grn_time(long long int mysql_datetime,
+ bool *truncated);
long long int tm_to_grn_time(struct tm *time, int usec, bool *truncated);
void grn_time_to_mysql_time(long long int grn_time, MYSQL_TIME *mysql_time);
+ long long int grn_time_to_mysql_datetime(long long int grn_time);
private:
time_t tm_to_time_gm(struct tm *time, bool *truncated);
diff --git a/storage/mroonga/lib/mrn_value_decoder.cpp b/storage/mroonga/lib/mrn_value_decoder.cpp
index 8356789915f..c01b01718b1 100644
--- a/storage/mroonga/lib/mrn_value_decoder.cpp
+++ b/storage/mroonga/lib/mrn_value_decoder.cpp
@@ -60,5 +60,16 @@ namespace mrn {
#endif
DBUG_VOID_RETURN;
}
+ void decode(long long int *dest, const uchar *source) {
+ MRN_DBUG_ENTER_FUNCTION();
+#ifdef MRN_DEST_IS_POINTER
+ longlongget(dest, source);
+#else
+ long long int value;
+ longlongget(value, source);
+ *dest = value;
+#endif
+ DBUG_VOID_RETURN;
+ }
}
}
diff --git a/storage/mroonga/lib/mrn_value_decoder.hpp b/storage/mroonga/lib/mrn_value_decoder.hpp
index 8a48de0b003..fe651f574f0 100644
--- a/storage/mroonga/lib/mrn_value_decoder.hpp
+++ b/storage/mroonga/lib/mrn_value_decoder.hpp
@@ -27,6 +27,7 @@ namespace mrn {
void decode(uint16 *dest, const uchar *source);
void decode(float *dest, const uchar *source);
void decode(double *dest, const uchar *source);
+ void decode(long long int *dest, const uchar *source);
}
}
diff --git a/storage/mroonga/mrn_constants.hpp b/storage/mroonga/mrn_constants.hpp
index 5bc6da6b9b6..b11ebe8bd93 100644
--- a/storage/mroonga/mrn_constants.hpp
+++ b/storage/mroonga/mrn_constants.hpp
@@ -42,8 +42,8 @@
#define MRN_COLUMN_NAME_ID "_id"
#define MRN_COLUMN_NAME_KEY "_key"
#define MRN_COLUMN_NAME_SCORE "_score"
-#ifndef MRN_PARSER_DEFAULT
-# define MRN_PARSER_DEFAULT "TokenBigram"
+#ifndef MRN_DEFAULT_TOKENIZER
+# define MRN_DEFAULT_TOKENIZER "TokenBigram"
#endif
#endif /* MRN_CONSTANTS_HPP_ */
diff --git a/storage/mroonga/mrn_err.h b/storage/mroonga/mrn_err.h
index cd4515a034e..d109f87bb48 100644
--- a/storage/mroonga/mrn_err.h
+++ b/storage/mroonga/mrn_err.h
@@ -1,4 +1,6 @@
-/* Copyright(C) 2011 Kentoku SHIBA
+/*
+ Copyright(C) 2011 Kentoku SHIBA
+ Copyright(C) 2014-2015 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -33,7 +35,7 @@
"The column flag '%-.64s' is unsupported. It is ignored"
#define ER_MRN_INVALID_COLUMN_FLAG_NUM 16507
#define ER_MRN_INVALID_COLUMN_FLAG_STR \
- "The column flag '%-.64s' is invalid. '%-64s' is used instead"
+ "The column flag '%-.64s' is invalid. It is ignored"
#define ER_MRN_INVALID_INDEX_FLAG_NUM 16508
#define ER_MRN_INVALID_INDEX_FLAG_STR \
"The index flag '%-.64s' is invalid. It is ignored"
diff --git a/storage/mroonga/mrn_mysql_compat.h b/storage/mroonga/mrn_mysql_compat.h
index a717220a35c..660c72b4d25 100644
--- a/storage/mroonga/mrn_mysql_compat.h
+++ b/storage/mroonga/mrn_mysql_compat.h
@@ -33,20 +33,11 @@
#endif
#if defined(MRN_MARIADB_P)
-# if MYSQL_VERSION_ID >= 50302 && MYSQL_VERSION_ID < 100000
+# if MYSQL_VERSION_ID < 100000
typedef COST_VECT Cost_estimate;
# endif
#endif
-#if MYSQL_VERSION_ID >= 50516
-# define MRN_PLUGIN_HAVE_FLAGS 1
-#endif
-
-// for MySQL < 5.5
-#ifndef MY_ALL_CHARSETS_SIZE
-# define MY_ALL_CHARSETS_SIZE 256
-#endif
-
#ifndef MRN_MARIADB_P
typedef char *range_id_t;
#endif
@@ -79,9 +70,11 @@
#if MYSQL_VERSION_ID >= 50607
# if MYSQL_VERSION_ID >= 100007 && defined(MRN_MARIADB_P)
# define MRN_GET_ERROR_MESSAGE thd_get_error_message(current_thd)
+# define MRN_GET_ERROR_NUMBER thd_get_error_number(current_thd)
# define MRN_GET_CURRENT_ROW_FOR_WARNING(thd) thd_get_error_row(thd)
# else
# define MRN_GET_ERROR_MESSAGE current_thd->get_stmt_da()->message()
+# define MRN_GET_ERROR_NUMBER current_thd->get_stmt_da()->sql_errno()
# if MYSQL_VERSION_ID >= 50706
# define MRN_GET_CURRENT_ROW_FOR_WARNING(thd) \
thd->get_stmt_da()->current_row_for_condition()
@@ -91,20 +84,16 @@
# endif
# endif
#else
-# if MYSQL_VERSION_ID >= 50500
-# define MRN_GET_ERROR_MESSAGE current_thd->stmt_da->message()
-# define MRN_GET_CURRENT_ROW_FOR_WARNING(thd) thd->warning_info->current_row_for_warning()
-# else
-# define MRN_GET_ERROR_MESSAGE current_thd->main_da.message()
-# define MRN_GET_CURRENT_ROW_FOR_WARNING(thd) thd->row_count
-# endif
+# define MRN_GET_ERROR_MESSAGE current_thd->stmt_da->message()
+# define MRN_GET_ERROR_NUMBER current_thd->stmt_da->sql_errno()
+# define MRN_GET_CURRENT_ROW_FOR_WARNING(thd) thd->warning_info->current_row_for_warning()
#endif
#if MYSQL_VERSION_ID >= 50607 && !defined(MRN_MARIADB_P)
# define MRN_ITEM_HAVE_ITEM_NAME
#endif
-#if MYSQL_VERSION_ID >= 50500 && MYSQL_VERSION_ID < 100000
+#if MYSQL_VERSION_ID < 100000
# define MRN_HAVE_TABLE_DEF_CACHE
#endif
@@ -124,10 +113,6 @@
# define MRN_TABLE_SHARE_HAVE_LOCK_SHARE
#endif
-#if MYSQL_VERSION_ID >= 50404
-# define MRN_TABLE_SHARE_HAVE_LOCK_HA_DATA
-#endif
-
#ifndef TIME_FUZZY_DATE
/* For MariaDB 10. */
# ifdef TIME_FUZZY_DATES
@@ -217,4 +202,42 @@
# define MRN_FORMAT_STRING_LENGTH "u"
#endif
+#ifdef MRN_MARIADB_P
+# define MRN_SUPPORT_CUSTOM_OPTIONS
+#endif
+
+#if defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 100000
+# if MYSQL_VERSION_ID >= 100104
+# define mrn_init_sql_alloc(thd, mem_root) \
+ init_sql_alloc(mem_root, \
+ TABLE_ALLOC_BLOCK_SIZE, \
+ 0, \
+ MYF(thd->slave_thread ? 0 : MY_THREAD_SPECIFIC))
+# else
+# define mrn_init_sql_alloc(thd, mem_root) \
+ init_sql_alloc(mem_root, \
+ TABLE_ALLOC_BLOCK_SIZE, \
+ 0, \
+ MYF(0))
+# endif
+#else
+# define mrn_init_sql_alloc(thd, mem_root) \
+ init_sql_alloc(mem_root, \
+ TABLE_ALLOC_BLOCK_SIZE, \
+ 0)
+#endif
+
+#ifdef MRN_MARIADB_P
+# define MRN_ABORT_ON_WARNING(thd) thd->abort_on_warning
+#else
+# if MYSQL_VERSION_ID >= 50706
+# define MRN_ABORT_ON_WARNING(thd) false
+# else
+# define MRN_ABORT_ON_WARNING(thd) thd->abort_on_warning
+# endif
+#endif
+
+#define MRN_ERROR_CODE_DATA_TRUNCATE(thd) \
+ (MRN_ABORT_ON_WARNING(thd) ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED)
+
#endif /* MRN_MYSQL_COMPAT_H_ */
diff --git a/storage/mroonga/mrn_table.cpp b/storage/mroonga/mrn_table.cpp
index 890d21a415b..af07dc09cf3 100644
--- a/storage/mroonga/mrn_table.cpp
+++ b/storage/mroonga/mrn_table.cpp
@@ -35,10 +35,18 @@
#include "mrn_variables.hpp"
#include <mrn_lock.hpp>
-#if MYSQL_VERSION_ID >= 50603
-# define MRN_HA_RESOLVE_BY_NAME(name) ha_resolve_by_name(NULL, (name), TRUE)
+#ifdef MRN_MARIADB_P
+# if MYSQL_VERSION_ID >= 100100
+# define MRN_HA_RESOLVE_BY_NAME(name) ha_resolve_by_name(NULL, (name), TRUE)
+# else
+# define MRN_HA_RESOLVE_BY_NAME(name) ha_resolve_by_name(NULL, (name))
+# endif
#else
-# define MRN_HA_RESOLVE_BY_NAME(name) ha_resolve_by_name(NULL, (name))
+# if MYSQL_VERSION_ID >= 50603
+# define MRN_HA_RESOLVE_BY_NAME(name) ha_resolve_by_name(NULL, (name), TRUE)
+# else
+# define MRN_HA_RESOLVE_BY_NAME(name) ha_resolve_by_name(NULL, (name))
+# endif
#endif
#if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P)
@@ -68,9 +76,7 @@ extern "C" {
# ifdef MRN_TABLE_SHARE_HAVE_LOCK_SHARE
extern PSI_mutex_key *mrn_table_share_lock_share;
# endif
-# ifdef MRN_TABLE_SHARE_HAVE_LOCK_HA_DATA
extern PSI_mutex_key *mrn_table_share_lock_ha_data;
-# endif
# endif
extern PSI_mutex_key mrn_share_mutex_key;
extern PSI_mutex_key mrn_long_term_share_auto_inc_mutex_key;
@@ -80,7 +86,7 @@ extern HASH mrn_open_tables;
extern mysql_mutex_t mrn_open_tables_mutex;
extern HASH mrn_long_term_share;
extern mysql_mutex_t mrn_long_term_share_mutex;
-extern char *mrn_default_parser;
+extern char *mrn_default_tokenizer;
extern char *mrn_default_wrapper_engine;
extern handlerton *mrn_hton_ptr;
extern HASH mrn_allocated_thds;
@@ -333,8 +339,8 @@ int mrn_parse_table_param(MRN_SHARE *share, TABLE *table)
for (i = 2; i > 0; i--)
#endif
{
- const char *params_string_value;
- uint params_string_length;
+ const char *params_string_value = NULL;
+ uint params_string_length = 0;
switch (i)
{
#ifdef WITH_PARTITION_STORAGE_ENGINE
@@ -515,16 +521,16 @@ int mrn_add_index_param(MRN_SHARE *share, KEY *key_info, int i)
#if MYSQL_VERSION_ID >= 50500
if (key_info->comment.length == 0)
{
- if (share->key_parser[i]) {
- my_free(share->key_parser[i]);
+ if (share->key_tokenizer[i]) {
+ my_free(share->key_tokenizer[i]);
}
- if (
- !(share->key_parser[i] = mrn_my_strdup(mrn_default_parser, MYF(MY_WME)))
- ) {
+ share->key_tokenizer[i] = mrn_my_strdup(mrn_default_tokenizer, MYF(MY_WME));
+ if (!share->key_tokenizer[i]) {
error = HA_ERR_OUT_OF_MEM;
goto error;
}
- share->key_parser_length[i] = strlen(share->key_parser[i]);
+ share->key_tokenizer_length[i] = strlen(share->key_tokenizer[i]);
+
DBUG_RETURN(0);
}
DBUG_PRINT("info", ("mroonga create comment string"));
@@ -572,21 +578,23 @@ int mrn_add_index_param(MRN_SHARE *share, KEY *key_info, int i)
MRN_PARAM_STR_LIST("table", index_table, i);
break;
case 6:
- MRN_PARAM_STR_LIST("parser", key_parser, i);
+ MRN_PARAM_STR_LIST("parser", key_tokenizer, i);
+ break;
+ case 9:
+ MRN_PARAM_STR_LIST("tokenizer", key_tokenizer, i);
break;
default:
break;
}
}
#endif
- if (!share->key_parser[i]) {
- if (
- !(share->key_parser[i] = mrn_my_strdup(mrn_default_parser, MYF(MY_WME)))
- ) {
+ if (!share->key_tokenizer[i]) {
+ share->key_tokenizer[i] = mrn_my_strdup(mrn_default_tokenizer, MYF(MY_WME));
+ if (!share->key_tokenizer[i]) {
error = HA_ERR_OUT_OF_MEM;
goto error;
}
- share->key_parser_length[i] = strlen(share->key_parser[i]);
+ share->key_tokenizer_length[i] = strlen(share->key_tokenizer[i]);
}
if (param_string)
@@ -687,6 +695,9 @@ int mrn_add_column_param(MRN_SHARE *share, Field *field, int i)
case 5:
MRN_PARAM_STR_LIST("flags", col_flags, i);
break;
+ case 12:
+ MRN_PARAM_STR_LIST("groonga_type", col_type, i);
+ break;
default:
break;
}
@@ -741,8 +752,8 @@ int mrn_free_share_alloc(
{
if (share->index_table && share->index_table[i])
my_free(share->index_table[i]);
- if (share->key_parser[i])
- my_free(share->key_parser[i]);
+ if (share->key_tokenizer[i])
+ my_free(share->key_tokenizer[i]);
}
for (i = 0; i < share->table_share->fields; i++)
{
@@ -817,9 +828,9 @@ error_alloc_long_term_share:
MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error)
{
MRN_SHARE *share;
- char *tmp_name, **index_table, **key_parser, **col_flags, **col_type;
+ char *tmp_name, **index_table, **key_tokenizer, **col_flags, **col_type;
uint length, *wrap_key_nr, *index_table_length;
- uint *key_parser_length, *col_flags_length, *col_type_length, i, j;
+ uint *key_tokenizer_length, *col_flags_length, *col_type_length, i, j;
KEY *wrap_key_info;
TABLE_SHARE *wrap_table_share;
MRN_DBUG_ENTER_FUNCTION();
@@ -834,8 +845,8 @@ MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error)
&tmp_name, length + 1,
&index_table, sizeof(char *) * table->s->keys,
&index_table_length, sizeof(uint) * table->s->keys,
- &key_parser, sizeof(char *) * table->s->keys,
- &key_parser_length, sizeof(uint) * table->s->keys,
+ &key_tokenizer, sizeof(char *) * table->s->keys,
+ &key_tokenizer_length, sizeof(uint) * table->s->keys,
&col_flags, sizeof(char *) * table->s->fields,
&col_flags_length, sizeof(uint) * table->s->fields,
&col_type, sizeof(char *) * table->s->fields,
@@ -853,8 +864,8 @@ MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error)
share->table_name = tmp_name;
share->index_table = index_table;
share->index_table_length = index_table_length;
- share->key_parser = key_parser;
- share->key_parser_length = key_parser_length;
+ share->key_tokenizer = key_tokenizer;
+ share->key_tokenizer_length = key_tokenizer_length;
share->col_flags = col_flags;
share->col_flags_length = col_flags_length;
share->col_type = col_type;
@@ -903,6 +914,7 @@ MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error)
share->wrap_primary_key = MAX_KEY;
}
memcpy(wrap_table_share, table->s, sizeof(*wrap_table_share));
+ mrn_init_sql_alloc(current_thd, &(wrap_table_share->mem_root));
wrap_table_share->keys = share->wrap_keys;
wrap_table_share->key_info = share->wrap_key_info;
wrap_table_share->primary_key = share->wrap_primary_key;
@@ -917,20 +929,18 @@ MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error)
&(wrap_table_share->LOCK_share), MY_MUTEX_INIT_SLOW);
# endif
#endif
-#ifdef MRN_TABLE_SHARE_HAVE_LOCK_HA_DATA
-# ifdef WIN32
+#ifdef WIN32
mysql_mutex_init(*mrn_table_share_lock_ha_data,
&(wrap_table_share->LOCK_ha_data), MY_MUTEX_INIT_FAST);
-# else
+#else
mysql_mutex_init(key_TABLE_SHARE_LOCK_ha_data,
&(wrap_table_share->LOCK_ha_data), MY_MUTEX_INIT_FAST);
-# endif
#endif
share->wrap_table_share = wrap_table_share;
}
if (mysql_mutex_init(mrn_share_mutex_key,
- &share->mutex,
+ &share->record_mutex,
MY_MUTEX_INIT_FAST) != 0)
{
*error = HA_ERR_OUT_OF_MEM;
@@ -953,7 +963,7 @@ MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error)
error_hash_insert:
error_get_long_term_share:
- mysql_mutex_destroy(&share->mutex);
+ mysql_mutex_destroy(&share->record_mutex);
error_init_mutex:
error_parse_table_param:
mrn_free_share_alloc(share);
@@ -973,14 +983,13 @@ int mrn_free_share(MRN_SHARE *share)
plugin_unlock(NULL, share->plugin);
mrn_free_share_alloc(share);
thr_lock_delete(&share->lock);
- mysql_mutex_destroy(&share->mutex);
+ mysql_mutex_destroy(&share->record_mutex);
if (share->wrapper_mode) {
#ifdef MRN_TABLE_SHARE_HAVE_LOCK_SHARE
mysql_mutex_destroy(&(share->wrap_table_share->LOCK_share));
#endif
-#ifdef MRN_TABLE_SHARE_HAVE_LOCK_HA_DATA
mysql_mutex_destroy(&(share->wrap_table_share->LOCK_ha_data));
-#endif
+ free_root(&(share->wrap_table_share->mem_root), MYF(0));
}
my_free(share);
}
@@ -1114,7 +1123,7 @@ st_mrn_slot_data *mrn_get_slot_data(THD *thd, bool can_create)
if (slot_data == NULL) {
slot_data = (st_mrn_slot_data*) malloc(sizeof(st_mrn_slot_data));
slot_data->last_insert_record_id = GRN_ID_NIL;
- slot_data->first_alter_share = NULL;
+ slot_data->first_wrap_hton = NULL;
slot_data->alter_create_info = NULL;
slot_data->disable_keys_create_info = NULL;
slot_data->alter_connect_string = NULL;
@@ -1132,22 +1141,21 @@ st_mrn_slot_data *mrn_get_slot_data(THD *thd, bool can_create)
DBUG_RETURN(slot_data);
}
-void mrn_clear_alter_share(THD *thd)
+void mrn_clear_slot_data(THD *thd)
{
MRN_DBUG_ENTER_FUNCTION();
st_mrn_slot_data *slot_data = mrn_get_slot_data(thd, FALSE);
if (slot_data) {
- if (slot_data->first_alter_share) {
- st_mrn_alter_share *tmp_alter_share;
- st_mrn_alter_share *alter_share = slot_data->first_alter_share;
- while (alter_share)
+ if (slot_data->first_wrap_hton) {
+ st_mrn_wrap_hton *tmp_wrap_hton;
+ st_mrn_wrap_hton *wrap_hton = slot_data->first_wrap_hton;
+ while (wrap_hton)
{
- tmp_alter_share = alter_share->next;
- mrn_free_tmp_table_share(alter_share->alter_share);
- free(alter_share);
- alter_share = tmp_alter_share;
+ tmp_wrap_hton = wrap_hton->next;
+ free(wrap_hton);
+ wrap_hton = tmp_wrap_hton;
}
- slot_data->first_alter_share = NULL;
+ slot_data->first_wrap_hton = NULL;
}
slot_data->alter_create_info = NULL;
slot_data->disable_keys_create_info = NULL;
diff --git a/storage/mroonga/mrn_table.hpp b/storage/mroonga/mrn_table.hpp
index 9118455b53d..0066fc23f08 100644
--- a/storage/mroonga/mrn_table.hpp
+++ b/storage/mroonga/mrn_table.hpp
@@ -1,7 +1,7 @@
/* -*- c-basic-offset: 2 -*- */
/*
Copyright(C) 2011-2013 Kentoku SHIBA
- Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -43,7 +43,7 @@ typedef struct st_mroonga_share
char *table_name;
uint table_name_length;
uint use_count;
- mysql_mutex_t mutex;
+ mysql_mutex_t record_mutex;
THR_LOCK lock;
TABLE_SHARE *table_share;
TABLE_SHARE *wrap_table_share;
@@ -60,11 +60,11 @@ typedef struct st_mroonga_share
plugin_ref plugin;
handlerton *hton;
char **index_table;
- char **key_parser;
+ char **key_tokenizer;
char **col_flags;
char **col_type;
uint *index_table_length;
- uint *key_parser_length;
+ uint *key_tokenizer_length;
uint *col_flags_length;
uint *col_type_length;
uint *wrap_key_nr;
@@ -78,17 +78,17 @@ typedef struct st_mroonga_share
bool disable_keys;
} MRN_SHARE;
-struct st_mrn_alter_share
+struct st_mrn_wrap_hton
{
char path[FN_REFLEN + 1];
- TABLE_SHARE *alter_share;
- st_mrn_alter_share *next;
+ handlerton *hton;
+ st_mrn_wrap_hton *next;
};
struct st_mrn_slot_data
{
grn_id last_insert_record_id;
- st_mrn_alter_share *first_alter_share;
+ st_mrn_wrap_hton *first_wrap_hton;
HA_CREATE_INFO *alter_create_info;
HA_CREATE_INFO *disable_keys_create_info;
char *alter_connect_string;
@@ -167,7 +167,7 @@ void mrn_free_tmp_table_share(TABLE_SHARE *table_share);
KEY *mrn_create_key_info_for_table(MRN_SHARE *share, TABLE *table, int *error);
void mrn_set_bitmap_by_key(MY_BITMAP *map, KEY *key_info);
st_mrn_slot_data *mrn_get_slot_data(THD *thd, bool can_create);
-void mrn_clear_alter_share(THD *thd);
+void mrn_clear_slot_data(THD *thd);
#ifdef __cplusplus
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_embedded.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_embedded.inc
new file mode 100644
index 00000000000..02c21ff32c6
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_embedded.inc
@@ -0,0 +1,19 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--disable_query_log
+let $libgroonga_embedded = `SELECT @@mroonga_libgroonga_embedded;`;
+--enable_query_log
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_groonga_plugin_register.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_groonga_plugin_register.inc
new file mode 100644
index 00000000000..414eb1702de
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_groonga_plugin_register.inc
@@ -0,0 +1,22 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/check_libgroonga_embedded.inc
+
+if ($libgroonga_embedded) {
+ --source ../../include/mroonga/have_mroonga_deinit.inc
+ skip "This test requires plugin_register of Groonga. libgroonga embedded build doesn't support it.";
+}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_fulltext_index_comment.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mariadb.inc
index e8c79936cc6..24c65a61dd9 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_fulltext_index_comment.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mariadb.inc
@@ -1,4 +1,4 @@
-# Copyright(C) 2012 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -14,12 +14,8 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
---source ../../include/mroonga/check_version.inc
+--source ../../include/mroonga/check_mariadb.inc
-if ($version_55_or_later) {
- let $fulltext_index_comment = 1;
-}
-
-if (!$fulltext_index_comment) {
- skip Fulltext index comment is available in version 5.5 or later;
+if (!$mariadb) {
+ skip This test is for MariaDB;
}
diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga.inc
index 2ebec2df8c4..cd17adebfe9 100644
--- a/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga.inc
+++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/have_mroonga.inc
@@ -38,6 +38,9 @@ if (!$have_default_storage_engine_variable) {
let have_default_tmp_storage_engine_variable=`SELECT 1 FROM information_schema.global_variables WHERE variable_name = "default_tmp_storage_engine"`;
if ($have_default_tmp_storage_engine_variable) {
let original_default_tmp_storage_engine=`SELECT variable_value FROM information_schema.global_variables WHERE variable_name = "default_tmp_storage_engine"`;
+ if (!$original_default_tmp_storage_engine) {
+ let original_default_tmp_storage_engine=NULL;
+ }
set default_tmp_storage_engine=Mroonga;
}
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_with_flags.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_comment.result
index e441df32c92..e441df32c92 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_with_flags.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_comment.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_parameter.result
new file mode 100644
index 00000000000..6f2a1870ac7
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_flags_parameter.result
@@ -0,0 +1,17 @@
+CREATE TABLE tags (
+id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
+) DEFAULT CHARSET=utf8;
+ALTER TABLE tags ADD COLUMN name VARCHAR(64) FLAGS='COLUMN_VECTOR';
+SHOW CREATE TABLE tags;
+Table Create Table
+tags CREATE TABLE `tags` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `name` varchar(64) DEFAULT NULL `FLAGS`='COLUMN_VECTOR',
+ PRIMARY KEY (`id`)
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+SELECT mroonga_command("dump --dump_plugins no");
+mroonga_command("dump --dump_plugins no")
+table_create tags TABLE_PAT_KEY UInt32
+column_create tags id COLUMN_SCALAR UInt32
+column_create tags name COLUMN_VECTOR ShortText
+DROP TABLE tags;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_comment.result
new file mode 100644
index 00000000000..0bd8985f2e8
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_comment.result
@@ -0,0 +1,18 @@
+CREATE TABLE tags (
+id INT UNSIGNED PRIMARY KEY
+) DEFAULT CHARSET=utf8;
+CREATE TABLE bugs (
+id INT UNSIGNED PRIMARY KEY
+) DEFAULT CHARSET=utf8;
+ALTER TABLE bugs ADD COLUMN name VARCHAR(64) COMMENT 'groonga_type "tags"';
+SELECT mroonga_command("dump --dump_plugins no");
+mroonga_command("dump --dump_plugins no")
+table_create tags TABLE_PAT_KEY UInt32
+column_create tags id COLUMN_SCALAR UInt32
+
+table_create bugs TABLE_PAT_KEY UInt32
+column_create bugs id COLUMN_SCALAR UInt32
+
+column_create bugs name COLUMN_SCALAR tags
+DROP TABLE bugs;
+DROP TABLE tags;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_parameter.result
new file mode 100644
index 00000000000..fe484372999
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_groonga_type_parameter.result
@@ -0,0 +1,26 @@
+CREATE TABLE tags (
+id INT UNSIGNED PRIMARY KEY
+) DEFAULT CHARSET=utf8;
+CREATE TABLE bugs (
+id INT UNSIGNED PRIMARY KEY
+) DEFAULT CHARSET=utf8;
+ALTER TABLE bugs ADD COLUMN name VARCHAR(64) GROONGA_TYPE='tags';
+SHOW CREATE TABLE bugs;
+Table Create Table
+bugs CREATE TABLE `bugs` (
+ `id` int(10) unsigned NOT NULL,
+ `name` varchar(64) DEFAULT NULL `GROONGA_TYPE`='tags',
+ PRIMARY KEY (`id`),
+ CONSTRAINT `name` FOREIGN KEY (`name`) REFERENCES `test`.`tags` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+SELECT mroonga_command("dump --dump_plugins no");
+mroonga_command("dump --dump_plugins no")
+table_create tags TABLE_PAT_KEY UInt32
+column_create tags id COLUMN_SCALAR UInt32
+
+table_create bugs TABLE_PAT_KEY UInt32
+column_create bugs id COLUMN_SCALAR UInt32
+
+column_create bugs name COLUMN_SCALAR tags
+DROP TABLE bugs;
+DROP TABLE tags;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_with_type.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_type_comment.result
index b4c3044c7d5..b4c3044c7d5 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_with_type.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_column_type_comment.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_index_token_filters_one_token_filter.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_index_token_filters_one_token_filter.result
index 21784decb88..65e608dddeb 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_index_token_filters_one_token_filter.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_index_token_filters_one_token_filter.result
@@ -1,5 +1,5 @@
-SELECT mroonga_command("register token_filters/stop_word");
-mroonga_command("register token_filters/stop_word")
+SELECT mroonga_command("plugin_register token_filters/stop_word");
+mroonga_command("plugin_register token_filters/stop_word")
true
SET NAMES utf8;
CREATE TABLE memos (
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_token_filter.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_token_filter.result
index 1c96236230b..60d302cc6a5 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_token_filter.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_change_token_filter.result
@@ -1,5 +1,5 @@
-SELECT mroonga_command("register token_filters/stop_word");
-mroonga_command("register token_filters/stop_word")
+SELECT mroonga_command("plugin_register token_filters/stop_word");
+mroonga_command("plugin_register token_filters/stop_word")
true
CREATE TABLE terms (
term VARCHAR(64) NOT NULL PRIMARY KEY,
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_date_strict.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_date_strict.result
new file mode 100644
index 00000000000..c4d73e2f57d
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_datetime_zero_date_strict.result
@@ -0,0 +1,23 @@
+DROP TABLE IF EXISTS timestamps;
+CREATE TABLE timestamps (
+id INT PRIMARY KEY AUTO_INCREMENT,
+create_dt DATETIME
+) DEFAULT CHARSET UTF8;
+SHOW CREATE TABLE timestamps;
+Table Create Table
+timestamps CREATE TABLE `timestamps` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `create_dt` datetime DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+SET sql_mode='STRICT_TRANS_TABLES';
+INSERT INTO timestamps (create_dt) VALUES ("0000-00-00 00:00:00");
+ERROR 22003: Out of range value for column 'create_dt' at row 1
+SET sql_mode=default;
+SELECT * FROM timestamps;
+id create_dt
+INSERT INTO timestamps (create_dt) VALUES ("2015-06-17 00:00:00");
+SELECT * FROM timestamps;
+id create_dt
+2 2015-06-17 00:00:00
+DROP TABLE timestamps;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_vector.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_flags_comment.result
index af3c19e9bb0..af3c19e9bb0 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_vector.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_flags_comment.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_flags_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_flags_parameter.result
new file mode 100644
index 00000000000..9e089e53f49
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_flags_parameter.result
@@ -0,0 +1,17 @@
+CREATE TABLE bugs (
+id INT UNSIGNED PRIMARY KEY,
+tags TEXT FLAGS='COLUMN_VECTOR'
+) DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE bugs;
+Table Create Table
+bugs CREATE TABLE `bugs` (
+ `id` int(10) unsigned NOT NULL,
+ `tags` text `FLAGS`='COLUMN_VECTOR',
+ PRIMARY KEY (`id`)
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+SELECT mroonga_command("dump --dump_plugins no");
+mroonga_command("dump --dump_plugins no")
+table_create bugs TABLE_PAT_KEY UInt32
+column_create bugs id COLUMN_SCALAR UInt32
+column_create bugs tags COLUMN_VECTOR LongText
+DROP TABLE bugs;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_comment.result
new file mode 100644
index 00000000000..5e5980ac62b
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_comment.result
@@ -0,0 +1,18 @@
+CREATE TABLE tags (
+name VARCHAR(64) PRIMARY KEY
+) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+CREATE TABLE bugs (
+id INT UNSIGNED PRIMARY KEY,
+tag VARCHAR(64) COMMENT 'groonga_type "tags"'
+) DEFAULT CHARSET=utf8;
+SELECT mroonga_command("dump --dump_plugins no");
+mroonga_command("dump --dump_plugins no")
+table_create tags TABLE_PAT_KEY ShortText
+column_create tags name COLUMN_SCALAR ShortText
+
+table_create bugs TABLE_PAT_KEY UInt32
+column_create bugs id COLUMN_SCALAR UInt32
+
+column_create bugs tag COLUMN_SCALAR tags
+DROP TABLE bugs;
+DROP TABLE tags;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_nonexistent.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_nonexistent.result
new file mode 100644
index 00000000000..99dc30aaa02
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_nonexistent.result
@@ -0,0 +1,6 @@
+DROP TABLE IF EXISTS bugs;
+CREATE TABLE bugs (
+id INT UNSIGNED PRIMARY KEY,
+tag VARCHAR(64) COMMENT 'groonga_type "Nonexistent"'
+) DEFAULT CHARSET=utf8mb4;
+ERROR HY000: unknown custom Groonga type name for <tag> column: <Nonexistent>
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_parameter.result
new file mode 100644
index 00000000000..24941f043c7
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_groonga_type_parameter.result
@@ -0,0 +1,26 @@
+CREATE TABLE tags (
+name VARCHAR(64) PRIMARY KEY
+) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+CREATE TABLE bugs (
+id INT UNSIGNED PRIMARY KEY,
+tag VARCHAR(64) GROONGA_TYPE='tags'
+) DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE bugs;
+Table Create Table
+bugs CREATE TABLE `bugs` (
+ `id` int(10) unsigned NOT NULL,
+ `tag` varchar(64) DEFAULT NULL `GROONGA_TYPE`='tags',
+ PRIMARY KEY (`id`),
+ CONSTRAINT `tag` FOREIGN KEY (`tag`) REFERENCES `test`.`tags` (`name`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+SELECT mroonga_command("dump --dump_plugins no");
+mroonga_command("dump --dump_plugins no")
+table_create tags TABLE_PAT_KEY ShortText
+column_create tags name COLUMN_SCALAR ShortText
+
+table_create bugs TABLE_PAT_KEY UInt32
+column_create bugs id COLUMN_SCALAR UInt32
+
+column_create bugs tag COLUMN_SCALAR tags
+DROP TABLE bugs;
+DROP TABLE tags;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_reference_type.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_type_comment.result
index dc3f39d286e..dc3f39d286e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_reference_type.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_type_comment.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_type_nonexistent.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_type_nonexistent.result
new file mode 100644
index 00000000000..a66a2bd2185
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_field_type_nonexistent.result
@@ -0,0 +1,6 @@
+DROP TABLE IF EXISTS bugs;
+CREATE TABLE bugs (
+id INT UNSIGNED PRIMARY KEY,
+tag VARCHAR(64) COMMENT 'type "Nonexistent"'
+) DEFAULT CHARSET=utf8mb4;
+ERROR HY000: unknown custom Groonga type name for <tag> column: <Nonexistent>
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_comment.result
new file mode 100644
index 00000000000..828de3ebbad
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_comment.result
@@ -0,0 +1,9 @@
+SET NAMES utf8;
+CREATE TABLE memos (
+content VARCHAR(64) NOT NULL,
+FULLTEXT INDEX (content) COMMENT 'flags "WITH_POSITION|WITH_WEIGHT"'
+) DEFAULT CHARSET=utf8;
+SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
+mroonga_command("dump --dump_plugins no --dump_schema no")
+column_create memos-content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos content
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_none.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_none.result
index c9283db72bb..b5368b433e6 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_none.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_none.result
@@ -1,7 +1,7 @@
SET NAMES utf8;
CREATE TABLE memos (
content VARCHAR(64) NOT NULL,
-FULLTEXT INDEX (content) COMMENT 'index_flags "NONE"'
+FULLTEXT INDEX (content) COMMENT 'flags "NONE"'
) DEFAULT CHARSET=utf8;
SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
mroonga_command("dump --dump_plugins no --dump_schema no")
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_parameter.result
new file mode 100644
index 00000000000..7e0d29a1e1f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_parameter.result
@@ -0,0 +1,15 @@
+SET NAMES utf8;
+CREATE TABLE memos (
+content VARCHAR(64) NOT NULL,
+FULLTEXT INDEX (content) FLAGS='WITH_POSITION|WITH_WEIGHT'
+) DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE memos;
+Table Create Table
+memos CREATE TABLE `memos` (
+ `content` varchar(64) NOT NULL,
+ FULLTEXT KEY `content` (`content`) `FLAGS`='WITH_POSITION|WITH_WEIGHT'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
+mroonga_command("dump --dump_plugins no --dump_schema no")
+column_create memos-content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos content
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_none.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_none.result
new file mode 100644
index 00000000000..c9283db72bb
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_none.result
@@ -0,0 +1,9 @@
+SET NAMES utf8;
+CREATE TABLE memos (
+content VARCHAR(64) NOT NULL,
+FULLTEXT INDEX (content) COMMENT 'index_flags "NONE"'
+) DEFAULT CHARSET=utf8;
+SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
+mroonga_command("dump --dump_plugins no --dump_schema no")
+column_create memos-content index COLUMN_INDEX memos content
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_with_position_and_with_weight.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_with_position_and_with_weight.result
index 853845d5c15..853845d5c15 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_flags_with_position_and_with_weight.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_index_flags_with_position_and_with_weight.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_comment.result
index e2d405a1e35..e2d405a1e35 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_comment.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_comment.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_no_utf8_charset_with_utf8_normalizer.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_no_utf8_charset_with_utf8_normalizer.result
index 9d12e2d0e39..9d12e2d0e39 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_no_utf8_charset_with_utf8_normalizer.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_no_utf8_charset_with_utf8_normalizer.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_none.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_none.result
index 52c6f055e88..52c6f055e88 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_none.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_none.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_parameter.result
new file mode 100644
index 00000000000..d68de436c92
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_normalizer_parameter.result
@@ -0,0 +1,21 @@
+DROP TABLE IF EXISTS memos;
+SET NAMES utf8;
+CREATE TABLE memos (
+id INT NOT NULL PRIMARY KEY,
+content TEXT NOT NULL,
+FULLTEXT INDEX (content) NORMALIZER='NormalizerAuto'
+) DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE memos;
+Table Create Table
+memos CREATE TABLE `memos` (
+ `id` int(11) NOT NULL,
+ `content` text NOT NULL,
+ PRIMARY KEY (`id`),
+ FULLTEXT KEY `content` (`content`) `NORMALIZER`='NormalizerAuto'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+INSERT INTO memos VALUES (1, "1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔ãŒ");
+SELECT * FROM memos
+WHERE MATCH (content) AGAINST ("+カロリー" IN BOOLEAN MODE);
+id content
+1 1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔ãŒ
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_comment.result
new file mode 100644
index 00000000000..4088caf49d5
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_comment.result
@@ -0,0 +1,31 @@
+DROP TABLE IF EXISTS diaries;
+CREATE TABLE diaries (
+id int PRIMARY KEY AUTO_INCREMENT,
+body text,
+FULLTEXT INDEX body_index (body)
+COMMENT 'parser "TokenBigramSplitSymbolAlphaDigit"'
+) DEFAULT CHARSET utf8;
+SHOW CREATE TABLE diaries;
+Table Create Table
+diaries CREATE TABLE `diaries` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `body` text,
+ PRIMARY KEY (`id`),
+ FULLTEXT KEY `body_index` (`body`) COMMENT 'parser "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+INSERT INTO diaries (body) VALUES ("will start Groonga!");
+INSERT INTO diaries (body) VALUES ("starting Groonga...");
+INSERT INTO diaries (body) VALUES ("started Groonga.");
+SELECT * FROM diaries;
+id body
+1 will start Groonga!
+2 starting Groonga...
+3 started Groonga.
+SELECT * FROM diaries
+WHERE MATCH(body) AGAINST("+start" IN BOOLEAN MODE)
+ORDER BY id;
+id body
+1 will start Groonga!
+2 starting Groonga...
+3 started Groonga.
+DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_parser_default.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_default.result
index 6c04cae59f2..a18614d19fc 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_parser_default.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_default.result
@@ -14,20 +14,20 @@ diaries CREATE TABLE `diaries` (
PRIMARY KEY (`id`),
FULLTEXT KEY `body_index` (`body`)
) ENGINE=Mroonga DEFAULT CHARSET=utf8
-insert into diaries (body) values ("will start groonga!");
-insert into diaries (body) values ("starting groonga...");
-insert into diaries (body) values ("started groonga.");
-insert into diaries (body) values ("finished groonga.");
+insert into diaries (body) values ("will start Groonga!");
+insert into diaries (body) values ("starting Groonga...");
+insert into diaries (body) values ("started Groonga.");
+insert into diaries (body) values ("finished Groonga.");
select * from diaries;
id body
-1 will start groonga!
-2 starting groonga...
-3 started groonga.
-4 finished groonga.
-select * from diaries where match(body) against("start");
+1 will start Groonga!
+2 starting Groonga...
+3 started Groonga.
+4 finished Groonga.
+select * from diaries where match(body) against("+start" IN BOOLEAN MODE) order by id;
id body
-1 will start groonga!
-2 starting groonga...
-3 started groonga.
+1 will start Groonga!
+2 starting Groonga...
+3 started Groonga.
drop table diaries;
set global mroonga_default_parser=@mroonga_default_parser_backup;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_parser_off.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_off.result
index 77765f61dc3..77765f61dc3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_parser_off.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_parser_off.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_index_comment_multiple_token_filters.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_multiple_token_filters.result
index 785c5d785b9..c730bafc8e3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_index_comment_multiple_token_filters.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_multiple_token_filters.result
@@ -1,5 +1,5 @@
-SELECT mroonga_command("register token_filters/stop_word");
-mroonga_command("register token_filters/stop_word")
+SELECT mroonga_command("plugin_register token_filters/stop_word");
+mroonga_command("plugin_register token_filters/stop_word")
true
SET NAMES utf8;
CREATE TABLE memos (
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_index_comment_one_token_filter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_one_token_filter.result
index 9ce60054300..e0809eb0f4b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_index_comment_one_token_filter.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_one_token_filter.result
@@ -1,5 +1,5 @@
-SELECT mroonga_command("register token_filters/stop_word");
-mroonga_command("register token_filters/stop_word")
+SELECT mroonga_command("plugin_register token_filters/stop_word");
+mroonga_command("plugin_register token_filters/stop_word")
true
SET NAMES utf8;
CREATE TABLE memos (
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_parameter.result
new file mode 100644
index 00000000000..df529282a91
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_token_filters_parameter.result
@@ -0,0 +1,23 @@
+SELECT mroonga_command("plugin_register token_filters/stop_word");
+mroonga_command("plugin_register token_filters/stop_word")
+true
+SET NAMES utf8;
+CREATE TABLE memos (
+content VARCHAR(64) NOT NULL,
+FULLTEXT INDEX (content) TOKEN_FILTERS='TokenFilterStopWord,TokenFilterStopWord'
+) DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE memos;
+Table Create Table
+memos CREATE TABLE `memos` (
+ `content` varchar(64) NOT NULL,
+ FULLTEXT KEY `content` (`content`) `TOKEN_FILTERS`='TokenFilterStopWord,TokenFilterStopWord'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+SELECT mroonga_command("dump --dump_plugins no");
+mroonga_command("dump --dump_plugins no")
+table_create memos TABLE_NO_KEY
+column_create memos content COLUMN_SCALAR ShortText
+
+table_create memos-content TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord,TokenFilterStopWord
+
+column_create memos-content index COLUMN_INDEX|WITH_POSITION memos content
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_comment.result
new file mode 100644
index 00000000000..5b8d0cd780e
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_comment.result
@@ -0,0 +1,31 @@
+DROP TABLE IF EXISTS diaries;
+CREATE TABLE diaries (
+id int PRIMARY KEY AUTO_INCREMENT,
+body text,
+FULLTEXT INDEX body_index (body)
+COMMENT 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) DEFAULT CHARSET utf8;
+SHOW CREATE TABLE diaries;
+Table Create Table
+diaries CREATE TABLE `diaries` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `body` text,
+ PRIMARY KEY (`id`),
+ FULLTEXT KEY `body_index` (`body`) COMMENT 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+INSERT INTO diaries (body) VALUES ("will start Groonga!");
+INSERT INTO diaries (body) VALUES ("starting Groonga...");
+INSERT INTO diaries (body) VALUES ("started Groonga.");
+SELECT * FROM diaries;
+id body
+1 will start Groonga!
+2 starting Groonga...
+3 started Groonga.
+SELECT * FROM diaries
+WHERE MATCH(body) AGAINST("+start" IN BOOLEAN MODE)
+ORDER BY id;
+id body
+1 will start Groonga!
+2 starting Groonga...
+3 started Groonga.
+DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_default.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_default.result
new file mode 100644
index 00000000000..9efa08bab53
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_default.result
@@ -0,0 +1,33 @@
+drop table if exists diaries;
+set @mroonga_default_tokenizer_backup=@@mroonga_default_tokenizer;
+set global mroonga_default_tokenizer=TokenBigramSplitSymbolAlphaDigit;
+create table diaries (
+id int primary key auto_increment,
+body text,
+fulltext index body_index (body)
+) default charset utf8;
+show create table diaries;
+Table Create Table
+diaries CREATE TABLE `diaries` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `body` text,
+ PRIMARY KEY (`id`),
+ FULLTEXT KEY `body_index` (`body`)
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+insert into diaries (body) values ("will start Groonga!");
+insert into diaries (body) values ("starting Groonga...");
+insert into diaries (body) values ("started Groonga.");
+insert into diaries (body) values ("finished Groonga.");
+select * from diaries;
+id body
+1 will start Groonga!
+2 starting Groonga...
+3 started Groonga.
+4 finished Groonga.
+select * from diaries where match(body) against("+start" IN BOOLEAN MODE) order by id;
+id body
+1 will start Groonga!
+2 starting Groonga...
+3 started Groonga.
+drop table diaries;
+set global mroonga_default_tokenizer=@mroonga_default_tokenizer_backup;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_off.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_off.result
new file mode 100644
index 00000000000..780ac2faa3d
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_off.result
@@ -0,0 +1,42 @@
+DROP TABLE IF EXISTS variables;
+CREATE TABLE variables (
+id INT PRIMARY KEY AUTO_INCREMENT,
+name TEXT,
+FULLTEXT INDEX (name) COMMENT 'tokenizer "off"'
+) DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE variables;
+Table Create Table
+variables CREATE TABLE `variables` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `name` text,
+ PRIMARY KEY (`id`),
+ FULLTEXT KEY `name` (`name`) COMMENT 'tokenizer "off"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+INSERT INTO variables (name) VALUES ("mroonga_database_path_prefix");
+INSERT INTO variables (name) VALUES ("mroonga_default_tokenizer");
+INSERT INTO variables (name) VALUES ("mroonga_default_wrapper_engine");
+INSERT INTO variables (name) VALUES ("mroonga_dry_write");
+INSERT INTO variables (name) VALUES ("mroonga_enable_optimization");
+INSERT INTO variables (name) VALUES ("mroonga_libgroonga_version");
+INSERT INTO variables (name) VALUES ("mroonga_log_file");
+INSERT INTO variables (name) VALUES ("mroonga_log_level");
+INSERT INTO variables (name) VALUES ("mroonga_match_escalation_threshold");
+INSERT INTO variables (name) VALUES ("mroonga_version");
+SELECT * FROM variables;
+id name
+1 mroonga_database_path_prefix
+2 mroonga_default_tokenizer
+3 mroonga_default_wrapper_engine
+4 mroonga_dry_write
+5 mroonga_enable_optimization
+6 mroonga_libgroonga_version
+7 mroonga_log_file
+8 mroonga_log_level
+9 mroonga_match_escalation_threshold
+10 mroonga_version
+SELECT * FROM variables
+WHERE MATCH (name) AGAINST ("mroonga_default*" IN BOOLEAN MODE);
+id name
+3 mroonga_default_wrapper_engine
+2 mroonga_default_tokenizer
+DROP TABLE variables;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_parameter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_parameter.result
new file mode 100644
index 00000000000..67170925826
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_index_tokenizer_parameter.result
@@ -0,0 +1,30 @@
+DROP TABLE IF EXISTS diaries;
+CREATE TABLE diaries (
+id int PRIMARY KEY AUTO_INCREMENT,
+body text,
+FULLTEXT INDEX body_index (body) TOKENIZER='TokenBigramSplitSymbolAlphaDigit'
+) DEFAULT CHARSET utf8;
+SHOW CREATE TABLE diaries;
+Table Create Table
+diaries CREATE TABLE `diaries` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `body` text,
+ PRIMARY KEY (`id`),
+ FULLTEXT KEY `body_index` (`body`) `TOKENIZER`='TokenBigramSplitSymbolAlphaDigit'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8
+INSERT INTO diaries (body) VALUES ("will start Groonga!");
+INSERT INTO diaries (body) VALUES ("starting Groonga...");
+INSERT INTO diaries (body) VALUES ("started Groonga.");
+SELECT * FROM diaries;
+id body
+1 will start Groonga!
+2 starting Groonga...
+3 started Groonga.
+SELECT * FROM diaries
+WHERE MATCH(body) AGAINST("+start" IN BOOLEAN MODE)
+ORDER BY id;
+id body
+1 will start Groonga!
+2 starting Groonga...
+3 started Groonga.
+DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_primary_key_table_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_normalizer_default.result
index dbf69362ee7..dbf69362ee7 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_primary_key_table_comment.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_normalizer_default.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_primary_key_table_comment_with_using_hash.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_normalizer_hash.result
index 5e4f4afa377..5e4f4afa377 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_primary_key_table_comment_with_using_hash.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_normalizer_hash.result
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_table_comment_multiple_token_filters.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_multiple_token_filters.result
index de1946e9214..6308b33d4cf 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_table_comment_multiple_token_filters.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_multiple_token_filters.result
@@ -1,5 +1,5 @@
-SELECT mroonga_command("register token_filters/stop_word");
-mroonga_command("register token_filters/stop_word")
+SELECT mroonga_command("plugin_register token_filters/stop_word");
+mroonga_command("plugin_register token_filters/stop_word")
true
CREATE TABLE terms (
term VARCHAR(64) NOT NULL PRIMARY KEY,
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_table_comment_one_token_filter.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_one_token_filter.result
index f3349980db1..2f4a90d4086 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_token_filters_table_comment_one_token_filter.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_one_token_filter.result
@@ -1,5 +1,5 @@
-SELECT mroonga_command("register token_filters/stop_word");
-mroonga_command("register token_filters/stop_word")
+SELECT mroonga_command("plugin_register token_filters/stop_word");
+mroonga_command("plugin_register token_filters/stop_word")
true
CREATE TABLE terms (
term VARCHAR(64) NOT NULL PRIMARY KEY,
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_token_filters_skip.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_stop_word.result
index 290f96df35d..bc21ed97502 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_token_filters_skip.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_table_token_filters_stop_word.result
@@ -1,5 +1,5 @@
-SELECT mroonga_command("register token_filters/stop_word");
-mroonga_command("register token_filters/stop_word")
+SELECT mroonga_command("plugin_register token_filters/stop_word");
+mroonga_command("plugin_register token_filters/stop_word")
true
CREATE TABLE terms (
term VARCHAR(64) NOT NULL PRIMARY KEY,
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_no_operator.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_no_operator.result
index f45e8fd4fb6..0c81bf6c3ad 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_no_operator.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_no_operator.result
@@ -10,9 +10,10 @@ INSERT INTO memos VALUES ("Today is fine.");
INSERT INTO memos VALUES ("Tomorrow will be fine.");
INSERT INTO memos VALUES ("Yesterday was fine.");
SELECT * FROM memos
-WHERE MATCH (content) AGAINST ("*DOR today good" IN BOOLEAN MODE);
+WHERE MATCH (content) AGAINST ("*DOR today good" IN BOOLEAN MODE)
+ORDER BY content;
content
-Today is good day.
Today is fine.
+Today is good day.
Tomorrow will be good day.
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_with_minus.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_with_minus.result
index 103866902c2..dfeb71f0d14 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_with_minus.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_with_minus.result
@@ -10,9 +10,10 @@ INSERT INTO memos VALUES ("Today is fine.");
INSERT INTO memos VALUES ("Tomorrow will be fine.");
INSERT INTO memos VALUES ("Yesterday was fine.");
SELECT * FROM memos
-WHERE MATCH (content) AGAINST ("*DOR today -good tomorrow" IN BOOLEAN MODE);
+WHERE MATCH (content) AGAINST ("*DOR today -good tomorrow" IN BOOLEAN MODE)
+ORDER BY content;
content
-Tomorrow will be good day.
Today is fine.
Tomorrow will be fine.
+Tomorrow will be good day.
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_with_plus.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_with_plus.result
index fd52868b4bc..e72cf8d4052 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_with_plus.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_or_with_plus.result
@@ -10,9 +10,10 @@ INSERT INTO memos VALUES ("Today is fine.");
INSERT INTO memos VALUES ("Tomorrow will be fine.");
INSERT INTO memos VALUES ("Yesterday was fine.");
SELECT * FROM memos
-WHERE MATCH (content) AGAINST ("*DOR today +good tomorrow" IN BOOLEAN MODE);
+WHERE MATCH (content) AGAINST ("*DOR today +good tomorrow" IN BOOLEAN MODE)
+ORDER BY content;
content
Today is good day.
-Tomorrow will be good day.
Tomorrow will be fine.
+Tomorrow will be good day.
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.result
new file mode 100644
index 00000000000..7a30baab5a0
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.result
@@ -0,0 +1,14 @@
+DROP TABLE IF EXISTS memos;
+SET NAMES utf8;
+CREATE TABLE memos (
+content TEXT,
+FULLTEXT INDEX (content)
+) DEFAULT CHARSET=utf8;
+INSERT INTO memos VALUES ("Today is good day.");
+INSERT INTO memos VALUES ("Tomorrow will be good day.");
+INSERT INTO memos VALUES ("Today is fine.");
+SELECT * FROM memos
+WHERE MATCH (content) AGAINST ("*D+ today fi*" IN BOOLEAN MODE);
+content
+Today is fine.
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_not_match_against.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_not_match_against.result
index 2c1666369a5..b6d6febf0b3 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_not_match_against.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_not_match_against.result
@@ -18,21 +18,21 @@ c1 c2 c3
6 20 ka ki ku ke ko
7 20 aa ii uu ee oo
8 20 ka ki ku ke ko
-select * from t1 where match(c3) against("uu");
+select * from t1 where match(c3) against("+uu" in boolean mode) order by c1;
c1 c2 c3
1 10 aa ii uu ee oo
3 10 aa ii uu ee oo
5 20 aa ii uu ee oo
7 20 aa ii uu ee oo
-select * from t1 where not match(c3) against("uu");
+select * from t1 where not match(c3) against("+uu" in boolean mode) order by c1;
c1 c2 c3
2 10 ka ki ku ke ko
4 10 ka ki ku ke ko
6 20 ka ki ku ke ko
8 20 ka ki ku ke ko
-select * from t1 where match(c3) against("dummy");
+select * from t1 where match(c3) against("+dummy" in boolean mode) order by c1;
c1 c2 c3
-select * from t1 where not match(c3) against("dummy");
+select * from t1 where not match(c3) against("+dummy" in boolean mode) order by c1;
c1 c2 c3
1 10 aa ii uu ee oo
2 10 ka ki ku ke ko
@@ -42,26 +42,26 @@ c1 c2 c3
6 20 ka ki ku ke ko
7 20 aa ii uu ee oo
8 20 ka ki ku ke ko
-select * from t1 where c1 = 4 and not match(c3) against("uu");
+select * from t1 where c1 = 4 and not match(c3) against("+uu" in boolean mode) order by c1;
c1 c2 c3
4 10 ka ki ku ke ko
-select * from t1 where c1 <= 4 and not match(c3) against("uu");
+select * from t1 where c1 <= 4 and not match(c3) against("+uu" in boolean mode) order by c1;
c1 c2 c3
2 10 ka ki ku ke ko
4 10 ka ki ku ke ko
-select * from t1 where c1 > 4 and not match(c3) against("uu");
+select * from t1 where c1 > 4 and not match(c3) against("+uu" in boolean mode) order by c1;
c1 c2 c3
6 20 ka ki ku ke ko
8 20 ka ki ku ke ko
-select * from t1 where c2 = 10 and not match(c3) against("uu");
+select * from t1 where c2 = 10 and not match(c3) against("+uu" in boolean mode) order by c1;
c1 c2 c3
2 10 ka ki ku ke ko
4 10 ka ki ku ke ko
-select * from t1 where c2 >= 15 and not match(c3) against("uu");
+select * from t1 where c2 >= 15 and not match(c3) against("+uu" in boolean mode) order by c1;
c1 c2 c3
6 20 ka ki ku ke ko
8 20 ka ki ku ke ko
-select * from t1 where c2 < 15 and not match(c3) against("uu");
+select * from t1 where c2 < 15 and not match(c3) against("+uu" in boolean mode) order by c1;
c1 c2 c3
2 10 ka ki ku ke ko
4 10 ka ki ku ke ko
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_parser_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_parser_comment.result
deleted file mode 100644
index f2abfe85dd6..00000000000
--- a/storage/mroonga/mysql-test/mroonga/storage/r/fulltext_parser_comment.result
+++ /dev/null
@@ -1,29 +0,0 @@
-drop table if exists diaries;
-create table diaries (
-id int primary key auto_increment,
-body text,
-fulltext index body_index (body)
-comment 'parser "TokenBigramSplitSymbolAlphaDigit"'
-) default charset utf8;
-show create table diaries;
-Table Create Table
-diaries CREATE TABLE `diaries` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `body` text,
- PRIMARY KEY (`id`),
- FULLTEXT KEY `body_index` (`body`) COMMENT 'parser "TokenBigramSplitSymbolAlphaDigit"'
-) ENGINE=Mroonga DEFAULT CHARSET=utf8
-insert into diaries (body) values ("will start groonga!");
-insert into diaries (body) values ("starting groonga...");
-insert into diaries (body) values ("started groonga.");
-select * from diaries;
-id body
-1 will start groonga!
-2 starting groonga...
-3 started groonga.
-select * from diaries where match(body) against("start");
-id body
-1 will start groonga!
-2 starting groonga...
-3 started groonga.
-drop table diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.result
new file mode 100644
index 00000000000..155faf85510
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.result
@@ -0,0 +1,21 @@
+DROP TABLE IF EXISTS ranges;
+CREATE TABLE ranges (
+id int PRIMARY KEY,
+start datetime,
+end datetime,
+UNIQUE KEY range_key(start, end)
+);
+INSERT INTO ranges VALUES (1, "1990-00-00 00:00:00", "2012-10-05 23:59:59");
+Warnings:
+Warning 1265 Data truncated for column 'start' at row 1
+SELECT * FROM ranges;
+id start end
+1 1990-01-01 00:00:00 2012-10-05 23:59:59
+DELETE FROM ranges WHERE id = 1;
+INSERT INTO ranges VALUES (1, "1990-00-00 00:00:00", "2012-10-05 23:59:59");
+Warnings:
+Warning 1265 Data truncated for column 'start' at row 1
+SELECT * FROM ranges;
+id start end
+1 1990-01-01 00:00:00 2012-10-05 23:59:59
+DROP TABLE ranges;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/replace_select_varchar.result b/storage/mroonga/mysql-test/mroonga/storage/r/replace_select_varchar.result
index 9cbe11c5574..b9aebee3f9e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/replace_select_varchar.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/replace_select_varchar.result
@@ -31,7 +31,8 @@ SELECT v.id, v.video_id, v.description, NULL
FROM videos_master AS v
WHERE v.video_id = (video_id);
SELECT *, MATCH(description) AGAINST("my") FROM videos_groonga
-WHERE MATCH(description) AGAINST("my");
+WHERE MATCH(description) AGAINST("my")
+ORDER BY id;
id video_id description tags_unpack MATCH(description) AGAINST("my")
1 video-1 My Familly 209716
2 video-2 My Cat 209716
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/replace_without_key.result b/storage/mroonga/mysql-test/mroonga/storage/r/replace_without_key.result
index 2c6c1cbc7e8..e67f0fe4007 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/replace_without_key.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/replace_without_key.result
@@ -6,5 +6,5 @@ content text,
FULLTEXT INDEX (content)
) DEFAULT CHARSET=utf8;
REPLACE INTO diaries(content) VALUES("Hello");
-ERROR HY000: primary key is empty
+Got one of the listed errors
DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/truncate.result b/storage/mroonga/mysql-test/mroonga/storage/r/truncate.result
index 0e33976eb17..104d1d51504 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/r/truncate.result
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/truncate.result
@@ -31,15 +31,18 @@ id year month day title content
1 2011 11 9 Hello 今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚
2 2011 11 10 天気 明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦
3 2011 11 11 富士山 今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚
-SELECT * FROM diaries WHERE MATCH(content) AGAINST("今日 天気" IN BOOLEAN MODE);
+SELECT * FROM diaries
+WHERE MATCH(content) AGAINST("+今日" IN BOOLEAN MODE)
+ORDER BY id;
id year month day title content
1 2011 11 9 Hello 今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚
3 2011 11 11 富士山 今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚
-2 2011 11 10 天気 明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦
TRUNCATE TABLE diaries;
SELECT * FROM diaries;
id year month day title content
-SELECT * FROM diaries WHERE MATCH(content) AGAINST("今日 天気" IN BOOLEAN MODE);
+SELECT * FROM diaries
+WHERE MATCH(content) AGAINST("+今日" IN BOOLEAN MODE)
+ORDER BY id;
id year month day title content
INSERT INTO diaries VALUES(1, 2011, 11, 11, "帰りé“", "ã¤ã‹ã‚ŒãŸãƒ¼");
INSERT INTO diaries VALUES(2, 2011, 12, 1, "ä¹…ã—ã¶ã‚Š", "天気ãŒæ‚ªã„ã‹ã‚‰ãšã£ã¨ç•™å®ˆç•ªã€‚");
@@ -49,7 +52,9 @@ id year month day title content
1 2011 11 11 å¸°ã‚Šé“ ã¤ã‹ã‚ŒãŸãƒ¼
2 2011 12 1 ä¹…ã—ã¶ã‚Š 天気ãŒæ‚ªã„ã‹ã‚‰ãšã£ã¨ç•™å®ˆç•ªã€‚
3 2011 12 2 åˆé›ª 今年ã¯ã˜ã‚ã¦ã®é›ªï¼
-SELECT * FROM diaries WHERE MATCH(content) AGAINST("悪ã„" IN BOOLEAN MODE);
+SELECT * FROM diaries
+WHERE MATCH(content) AGAINST("+悪ã„" IN BOOLEAN MODE)
+ORDER BY id;
id year month day title content
2 2011 12 1 ä¹…ã—ã¶ã‚Š 天気ãŒæ‚ªã„ã‹ã‚‰ãšã£ã¨ç•™å®ˆç•ªã€‚
DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/suite.pm b/storage/mroonga/mysql-test/mroonga/storage/suite.pm
index 6b345c0fd6f..528ccc5d693 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/suite.pm
+++ b/storage/mroonga/mysql-test/mroonga/storage/suite.pm
@@ -5,11 +5,6 @@ package My::Suite::Mroonga;
return "No Mroonga engine" unless $ENV{HA_MROONGA_SO} or
$::mysqld_variables{'mroonga'} eq "ON";
-# RECOMPILE_FOR_EMBEDDED also means that a plugin
-# cannot be dynamically loaded into embedded
-return "Not run for embedded server" if $::opt_embedded_server and
- $ENV{HA_MROONGA_SO};
-
sub is_default { 1 }
my $groonga_normalizer_mysql_dir=$::basedir . '/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql';
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_with_flags.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_comment.test
index 96c99612190..96c99612190 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_with_flags.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_comment.test
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_parameter.test
new file mode 100644
index 00000000000..0c389ba3197
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_flags_parameter.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2014 Kenji Maruyama <mmmaru777@gmail.com>
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mariadb.inc
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+CREATE TABLE tags (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
+) DEFAULT CHARSET=utf8;
+
+ALTER TABLE tags ADD COLUMN name VARCHAR(64) FLAGS='COLUMN_VECTOR';
+SHOW CREATE TABLE tags;
+
+SELECT mroonga_command("dump --dump_plugins no");
+
+DROP TABLE tags;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_comment.test
new file mode 100644
index 00000000000..d77809c1a6c
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_comment.test
@@ -0,0 +1,44 @@
+# Copyright(C) 2014 Kenji Maruyama <mmmaru777@gmail.com>
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+CREATE TABLE tags (
+ id INT UNSIGNED PRIMARY KEY
+) DEFAULT CHARSET=utf8;
+
+CREATE TABLE bugs (
+ id INT UNSIGNED PRIMARY KEY
+) DEFAULT CHARSET=utf8;
+
+ALTER TABLE bugs ADD COLUMN name VARCHAR(64) COMMENT 'groonga_type "tags"';
+
+SELECT mroonga_command("dump --dump_plugins no");
+
+DROP TABLE bugs;
+DROP TABLE tags;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_parameter.test
new file mode 100644
index 00000000000..a65eff4529f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_groonga_type_parameter.test
@@ -0,0 +1,47 @@
+# Copyright(C) 2014 Kenji Maruyama <mmmaru777@gmail.com>
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mariadb.inc
+--source ../../include/mroonga/have_version_56_or_later.inc
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+CREATE TABLE tags (
+ id INT UNSIGNED PRIMARY KEY
+) DEFAULT CHARSET=utf8;
+
+CREATE TABLE bugs (
+ id INT UNSIGNED PRIMARY KEY
+) DEFAULT CHARSET=utf8;
+
+ALTER TABLE bugs ADD COLUMN name VARCHAR(64) GROONGA_TYPE='tags';
+SHOW CREATE TABLE bugs;
+
+SELECT mroonga_command("dump --dump_plugins no");
+
+DROP TABLE bugs;
+DROP TABLE tags;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_with_type.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_type_comment.test
index dd05765585d..dd05765585d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_with_type.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_column_type_comment.test
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_token_filters_one_token_filter.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_token_filters_one_token_filter.test
index 9c01dc27e3e..b2312997709 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_token_filters_one_token_filter.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_token_filters_one_token_filter.test
@@ -15,6 +15,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/have_groonga_plugin_register.inc
--source ../../include/mroonga/load_mroonga_functions.inc
--disable_query_log
@@ -23,7 +24,7 @@ CREATE DATABASE test;
USE test;
--enable_query_log
-SELECT mroonga_command("register token_filters/stop_word");
+SELECT mroonga_command("plugin_register token_filters/stop_word");
SET NAMES utf8;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_token_filter.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_token_filter.test
index 7ec047818e3..ada266fff0c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_token_filter.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_change_token_filter.test
@@ -15,6 +15,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/have_groonga_plugin_register.inc
--source ../../include/mroonga/load_mroonga_functions.inc
--disable_query_log
@@ -23,7 +24,7 @@ CREATE DATABASE test;
USE test;
--enable_query_log
-SELECT mroonga_command("register token_filters/stop_word");
+SELECT mroonga_command("plugin_register token_filters/stop_word");
CREATE TABLE terms (
term VARCHAR(64) NOT NULL PRIMARY KEY,
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_date_strict.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_date_strict.test
new file mode 100644
index 00000000000..7736fc45b7b
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_datetime_zero_date_strict.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS timestamps;
+--enable_warnings
+
+CREATE TABLE timestamps (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ create_dt DATETIME
+) DEFAULT CHARSET UTF8;
+SHOW CREATE TABLE timestamps;
+
+SET sql_mode='STRICT_TRANS_TABLES';
+--error ER_WARN_DATA_OUT_OF_RANGE
+INSERT INTO timestamps (create_dt) VALUES ("0000-00-00 00:00:00");
+SET sql_mode=default;
+
+SELECT * FROM timestamps;
+
+INSERT INTO timestamps (create_dt) VALUES ("2015-06-17 00:00:00");
+SELECT * FROM timestamps;
+
+DROP TABLE timestamps;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_vector.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_flags_comment.test
index 2d5498c99c8..2d5498c99c8 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_vector.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_flags_comment.test
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_flags_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_flags_parameter.test
new file mode 100644
index 00000000000..dbecd47dac6
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_flags_parameter.test
@@ -0,0 +1,39 @@
+# Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mariadb.inc
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+CREATE TABLE bugs (
+ id INT UNSIGNED PRIMARY KEY,
+ tags TEXT FLAGS='COLUMN_VECTOR'
+) DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE bugs;
+
+SELECT mroonga_command("dump --dump_plugins no");
+
+DROP TABLE bugs;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_comment.test
new file mode 100644
index 00000000000..aa4723b087c
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_comment.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+CREATE TABLE tags (
+ name VARCHAR(64) PRIMARY KEY
+) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE bugs (
+ id INT UNSIGNED PRIMARY KEY,
+ tag VARCHAR(64) COMMENT 'groonga_type "tags"'
+) DEFAULT CHARSET=utf8;
+
+SELECT mroonga_command("dump --dump_plugins no");
+
+DROP TABLE bugs;
+DROP TABLE tags;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_nonexistent.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_nonexistent.test
new file mode 100644
index 00000000000..56d81fad16c
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_nonexistent.test
@@ -0,0 +1,29 @@
+# Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS bugs;
+--enable_warnings
+
+--error ER_CANT_CREATE_TABLE
+CREATE TABLE bugs (
+ id INT UNSIGNED PRIMARY KEY,
+ tag VARCHAR(64) COMMENT 'groonga_type "Nonexistent"'
+) DEFAULT CHARSET=utf8mb4;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_parameter.test
new file mode 100644
index 00000000000..325536af3d2
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_groonga_type_parameter.test
@@ -0,0 +1,45 @@
+# Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mariadb.inc
+--source ../../include/mroonga/have_version_56_or_later.inc
+--source include/not_embedded.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+CREATE TABLE tags (
+ name VARCHAR(64) PRIMARY KEY
+) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE bugs (
+ id INT UNSIGNED PRIMARY KEY,
+ tag VARCHAR(64) GROONGA_TYPE='tags'
+) DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE bugs;
+
+SELECT mroonga_command("dump --dump_plugins no");
+
+DROP TABLE bugs;
+DROP TABLE tags;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_reference_type.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_type_comment.test
index 0a1340d24d1..0a1340d24d1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_reference_type.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_type_comment.test
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_type_nonexistent.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_type_nonexistent.test
new file mode 100644
index 00000000000..2b9a58c887c
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_field_type_nonexistent.test
@@ -0,0 +1,29 @@
+# Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS bugs;
+--enable_warnings
+
+--error ER_CANT_CREATE_TABLE
+CREATE TABLE bugs (
+ id INT UNSIGNED PRIMARY KEY,
+ tag VARCHAR(64) COMMENT 'type "Nonexistent"'
+) DEFAULT CHARSET=utf8mb4;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_comment.test
new file mode 100644
index 00000000000..668a148edf9
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_comment.test
@@ -0,0 +1,39 @@
+# Copyright(C) 2015 Naoya Murakami <naoya@createfield.com>
+# Copyright(C) 2015 Kouhei SUtou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+SET NAMES utf8;
+
+CREATE TABLE memos (
+ content VARCHAR(64) NOT NULL,
+ FULLTEXT INDEX (content) COMMENT 'flags "WITH_POSITION|WITH_WEIGHT"'
+) DEFAULT CHARSET=utf8;
+
+SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_none.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_none.test
index 039c518e673..107b045c8fc 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_none.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_none.test
@@ -1,4 +1,5 @@
# Copyright(C) 2015 Naoya Murakami <naoya@createfield.com>
+# Copyright(C) 2015 Kouhei SUtou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -27,7 +28,7 @@ SET NAMES utf8;
CREATE TABLE memos (
content VARCHAR(64) NOT NULL,
- FULLTEXT INDEX (content) COMMENT 'index_flags "NONE"'
+ FULLTEXT INDEX (content) COMMENT 'flags "NONE"'
) DEFAULT CHARSET=utf8;
SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_parameter.test
new file mode 100644
index 00000000000..14c65ad54c1
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_parameter.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2015 Naoya Murakami <naoya@createfield.com>
+# Copyright(C) 2015 Kouhei SUtou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mariadb.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+SET NAMES utf8;
+
+CREATE TABLE memos (
+ content VARCHAR(64) NOT NULL,
+ FULLTEXT INDEX (content) FLAGS='WITH_POSITION|WITH_WEIGHT'
+) DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE memos;
+
+SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_none.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_none.test
new file mode 100644
index 00000000000..039c518e673
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_none.test
@@ -0,0 +1,38 @@
+# Copyright(C) 2015 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+SET NAMES utf8;
+
+CREATE TABLE memos (
+ content VARCHAR(64) NOT NULL,
+ FULLTEXT INDEX (content) COMMENT 'index_flags "NONE"'
+) DEFAULT CHARSET=utf8;
+
+SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_with_position_and_with_weight.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_with_position_and_with_weight.test
index 9a67644d2c5..9a67644d2c5 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_flags_with_position_and_with_weight.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_index_flags_with_position_and_with_weight.test
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_comment.test
index 02e2cb9e81a..02e2cb9e81a 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_comment.test
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_no_utf8_charset_with_utf8_normalizer.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_no_utf8_charset_with_utf8_normalizer.test
index f28fb5b8695..f28fb5b8695 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_no_utf8_charset_with_utf8_normalizer.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_no_utf8_charset_with_utf8_normalizer.test
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_none.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_none.test
index ae4d4cb9f1b..ae4d4cb9f1b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_none.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_none.test
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_parameter.test
new file mode 100644
index 00000000000..a42b30b72a1
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_normalizer_parameter.test
@@ -0,0 +1,40 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mariadb.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS memos;
+--enable_warnings
+
+SET NAMES utf8;
+
+CREATE TABLE memos (
+ id INT NOT NULL PRIMARY KEY,
+ content TEXT NOT NULL,
+ FULLTEXT INDEX (content) NORMALIZER='NormalizerAuto'
+) DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE memos;
+
+INSERT INTO memos VALUES (1, "1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔ãŒ");
+
+SELECT * FROM memos
+ WHERE MATCH (content) AGAINST ("+カロリー" IN BOOLEAN MODE);
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_comment.test
new file mode 100644
index 00000000000..1b728afa1c1
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_comment.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS diaries;
+--enable_warnings
+
+CREATE TABLE diaries (
+ id int PRIMARY KEY AUTO_INCREMENT,
+ body text,
+ FULLTEXT INDEX body_index (body)
+ COMMENT 'parser "TokenBigramSplitSymbolAlphaDigit"'
+) DEFAULT CHARSET utf8;
+SHOW CREATE TABLE diaries;
+
+INSERT INTO diaries (body) VALUES ("will start Groonga!");
+INSERT INTO diaries (body) VALUES ("starting Groonga...");
+INSERT INTO diaries (body) VALUES ("started Groonga.");
+
+SELECT * FROM diaries;
+SELECT * FROM diaries
+ WHERE MATCH(body) AGAINST("+start" IN BOOLEAN MODE)
+ ORDER BY id;
+
+DROP TABLE diaries;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_parser_default.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_default.test
index 1e08cc46221..a1756ad268e 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_parser_default.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_default.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2011 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
# Copyright(C) 2014 Kentoku SHIBA
#
# This library is free software; you can redistribute it and/or
@@ -29,12 +29,12 @@ create table diaries (
fulltext index body_index (body)
) default charset utf8;
show create table diaries;
-insert into diaries (body) values ("will start groonga!");
-insert into diaries (body) values ("starting groonga...");
-insert into diaries (body) values ("started groonga.");
-insert into diaries (body) values ("finished groonga.");
+insert into diaries (body) values ("will start Groonga!");
+insert into diaries (body) values ("starting Groonga...");
+insert into diaries (body) values ("started Groonga.");
+insert into diaries (body) values ("finished Groonga.");
select * from diaries;
-select * from diaries where match(body) against("start");
+select * from diaries where match(body) against("+start" IN BOOLEAN MODE) order by id;
drop table diaries;
set global mroonga_default_parser=@mroonga_default_parser_backup;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_parser_off.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_off.test
index 0dcf494c684..0869e2334b7 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_parser_off.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_parser_off.test
@@ -14,7 +14,6 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
---source ../../include/mroonga/have_fulltext_index_comment.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_index_comment_multiple_token_filters.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_multiple_token_filters.test
index 18a2607fa0b..534ff998ff0 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_index_comment_multiple_token_filters.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_multiple_token_filters.test
@@ -15,6 +15,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/have_groonga_plugin_register.inc
--source ../../include/mroonga/load_mroonga_functions.inc
--disable_query_log
@@ -23,7 +24,7 @@ CREATE DATABASE test;
USE test;
--enable_query_log
-SELECT mroonga_command("register token_filters/stop_word");
+SELECT mroonga_command("plugin_register token_filters/stop_word");
SET NAMES utf8;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_index_comment_one_token_filter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_one_token_filter.test
index 20df762d31b..77d886579ba 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_index_comment_one_token_filter.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_one_token_filter.test
@@ -15,6 +15,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/have_groonga_plugin_register.inc
--source ../../include/mroonga/load_mroonga_functions.inc
--disable_query_log
@@ -23,7 +24,7 @@ CREATE DATABASE test;
USE test;
--enable_query_log
-SELECT mroonga_command("register token_filters/stop_word");
+SELECT mroonga_command("plugin_register token_filters/stop_word");
SET NAMES utf8;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_parameter.test
new file mode 100644
index 00000000000..d9458f4402d
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_token_filters_parameter.test
@@ -0,0 +1,44 @@
+# Copyright(C) 2014 Naoya Murakami <naoya@createfield.com>
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mariadb.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/have_groonga_plugin_register.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+SELECT mroonga_command("plugin_register token_filters/stop_word");
+
+SET NAMES utf8;
+
+CREATE TABLE memos (
+ content VARCHAR(64) NOT NULL,
+ FULLTEXT INDEX (content) TOKEN_FILTERS='TokenFilterStopWord,TokenFilterStopWord'
+) DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE memos;
+
+SELECT mroonga_command("dump --dump_plugins no");
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_comment.test
new file mode 100644
index 00000000000..4bf386a4c11
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_comment.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS diaries;
+--enable_warnings
+
+CREATE TABLE diaries (
+ id int PRIMARY KEY AUTO_INCREMENT,
+ body text,
+ FULLTEXT INDEX body_index (body)
+ COMMENT 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) DEFAULT CHARSET utf8;
+SHOW CREATE TABLE diaries;
+
+INSERT INTO diaries (body) VALUES ("will start Groonga!");
+INSERT INTO diaries (body) VALUES ("starting Groonga...");
+INSERT INTO diaries (body) VALUES ("started Groonga.");
+
+SELECT * FROM diaries;
+SELECT * FROM diaries
+ WHERE MATCH(body) AGAINST("+start" IN BOOLEAN MODE)
+ ORDER BY id;
+
+DROP TABLE diaries;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_default.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_default.test
new file mode 100644
index 00000000000..069e06b4a84
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_default.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2014 Kentoku SHIBA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+drop table if exists diaries;
+--enable_warnings
+
+set @mroonga_default_tokenizer_backup=@@mroonga_default_tokenizer;
+set global mroonga_default_tokenizer=TokenBigramSplitSymbolAlphaDigit;
+create table diaries (
+ id int primary key auto_increment,
+ body text,
+ fulltext index body_index (body)
+) default charset utf8;
+show create table diaries;
+insert into diaries (body) values ("will start Groonga!");
+insert into diaries (body) values ("starting Groonga...");
+insert into diaries (body) values ("started Groonga.");
+insert into diaries (body) values ("finished Groonga.");
+select * from diaries;
+select * from diaries where match(body) against("+start" IN BOOLEAN MODE) order by id;
+drop table diaries;
+set global mroonga_default_tokenizer=@mroonga_default_tokenizer_backup;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_off.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_off.test
new file mode 100644
index 00000000000..5aff5e3575b
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_off.test
@@ -0,0 +1,47 @@
+# Copyright(C) 2013-2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS variables;
+--enable_warnings
+
+CREATE TABLE variables (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ name TEXT,
+ FULLTEXT INDEX (name) COMMENT 'tokenizer "off"'
+) DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE variables;
+
+INSERT INTO variables (name) VALUES ("mroonga_database_path_prefix");
+INSERT INTO variables (name) VALUES ("mroonga_default_tokenizer");
+INSERT INTO variables (name) VALUES ("mroonga_default_wrapper_engine");
+INSERT INTO variables (name) VALUES ("mroonga_dry_write");
+INSERT INTO variables (name) VALUES ("mroonga_enable_optimization");
+INSERT INTO variables (name) VALUES ("mroonga_libgroonga_version");
+INSERT INTO variables (name) VALUES ("mroonga_log_file");
+INSERT INTO variables (name) VALUES ("mroonga_log_level");
+INSERT INTO variables (name) VALUES ("mroonga_match_escalation_threshold");
+INSERT INTO variables (name) VALUES ("mroonga_version");
+
+SELECT * FROM variables;
+SELECT * FROM variables
+ WHERE MATCH (name) AGAINST ("mroonga_default*" IN BOOLEAN MODE);
+
+DROP TABLE variables;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_parameter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_parameter.test
new file mode 100644
index 00000000000..d79eaefe3f6
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_index_tokenizer_parameter.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mariadb.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS diaries;
+--enable_warnings
+
+CREATE TABLE diaries (
+ id int PRIMARY KEY AUTO_INCREMENT,
+ body text,
+ FULLTEXT INDEX body_index (body) TOKENIZER='TokenBigramSplitSymbolAlphaDigit'
+) DEFAULT CHARSET utf8;
+SHOW CREATE TABLE diaries;
+
+INSERT INTO diaries (body) VALUES ("will start Groonga!");
+INSERT INTO diaries (body) VALUES ("starting Groonga...");
+INSERT INTO diaries (body) VALUES ("started Groonga.");
+
+SELECT * FROM diaries;
+SELECT * FROM diaries
+ WHERE MATCH(body) AGAINST("+start" IN BOOLEAN MODE)
+ ORDER BY id;
+
+DROP TABLE diaries;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_primary_key_table_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_default.test
index 1da8026f56d..1da8026f56d 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_primary_key_table_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_default.test
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_primary_key_table_comment_with_using_hash.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_hash.test
index 14b9ea9ab87..14b9ea9ab87 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_primary_key_table_comment_with_using_hash.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_normalizer_hash.test
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_table_comment_multiple_token_filters.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_multiple_token_filters.test
index e4d7d8618fa..944838e2fe0 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_table_comment_multiple_token_filters.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_multiple_token_filters.test
@@ -15,6 +15,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/have_groonga_plugin_register.inc
--source ../../include/mroonga/load_mroonga_functions.inc
--disable_query_log
@@ -23,7 +24,7 @@ CREATE DATABASE test;
USE test;
--enable_query_log
-SELECT mroonga_command("register token_filters/stop_word");
+SELECT mroonga_command("plugin_register token_filters/stop_word");
CREATE TABLE terms (
term VARCHAR(64) NOT NULL PRIMARY KEY,
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_table_comment_one_token_filter.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_one_token_filter.test
index 905181175d0..701a4ae425b 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_token_filters_table_comment_one_token_filter.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_one_token_filter.test
@@ -15,6 +15,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/have_groonga_plugin_register.inc
--source ../../include/mroonga/load_mroonga_functions.inc
--disable_query_log
@@ -23,7 +24,7 @@ CREATE DATABASE test;
USE test;
--enable_query_log
-SELECT mroonga_command("register token_filters/stop_word");
+SELECT mroonga_command("plugin_register token_filters/stop_word");
CREATE TABLE terms (
term VARCHAR(64) NOT NULL PRIMARY KEY,
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_token_filters_skip.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_stop_word.test
index b27fb5b70d6..b2e6be600f1 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_token_filters_skip.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_table_token_filters_stop_word.test
@@ -15,6 +15,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/have_groonga_plugin_register.inc
--source ../../include/mroonga/load_mroonga_functions.inc
--disable_query_log
@@ -23,7 +24,7 @@ CREATE DATABASE test;
USE test;
--enable_query_log
-SELECT mroonga_command("register token_filters/stop_word");
+SELECT mroonga_command("plugin_register token_filters/stop_word");
CREATE TABLE terms (
term VARCHAR(64) NOT NULL PRIMARY KEY,
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test
index 4d0f15b203a..66ff69d77e2 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
# Copyright(C) 2013 Kenji Maruyama <mmmaru777@gmail.com>
#
# This library is free software; you can redistribute it and/or
@@ -34,7 +34,8 @@ INSERT INTO memos VALUES ("Tomorrow will be fine.");
INSERT INTO memos VALUES ("Yesterday was fine.");
SELECT * FROM memos
- WHERE MATCH (content) AGAINST ("*DOR today good" IN BOOLEAN MODE);
+ WHERE MATCH (content) AGAINST ("*DOR today good" IN BOOLEAN MODE)
+ ORDER BY content;
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test
index ed93b543869..1d91bdc7a56 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
# Copyright(C) 2013 Kenji Maruyama <mmmaru777@gmail.com>
#
# This library is free software; you can redistribute it and/or
@@ -34,7 +34,8 @@ INSERT INTO memos VALUES ("Tomorrow will be fine.");
INSERT INTO memos VALUES ("Yesterday was fine.");
SELECT * FROM memos
- WHERE MATCH (content) AGAINST ("*DOR today -good tomorrow" IN BOOLEAN MODE);
+ WHERE MATCH (content) AGAINST ("*DOR today -good tomorrow" IN BOOLEAN MODE)
+ ORDER BY content;
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test
index 3a078c7eccb..63e5baeeb68 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
# Copyright(C) 2013 Kenji Maruyama <mmmaru777@gmail.com>
#
# This library is free software; you can redistribute it and/or
@@ -34,7 +34,8 @@ INSERT INTO memos VALUES ("Tomorrow will be fine.");
INSERT INTO memos VALUES ("Yesterday was fine.");
SELECT * FROM memos
- WHERE MATCH (content) AGAINST ("*DOR today +good tomorrow" IN BOOLEAN MODE);
+ WHERE MATCH (content) AGAINST ("*DOR today +good tomorrow" IN BOOLEAN MODE)
+ ORDER BY content;
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.test
new file mode 100644
index 00000000000..ded739d8e8b
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_boolean_mode_pragma_default_operator_plus_with_astarisk.test
@@ -0,0 +1,38 @@
+# Copyright(C) 2015 Naoya Murakami <naoya@createfield.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS memos;
+--enable_warnings
+
+SET NAMES utf8;
+CREATE TABLE memos (
+ content TEXT,
+ FULLTEXT INDEX (content)
+) DEFAULT CHARSET=utf8;
+
+INSERT INTO memos VALUES ("Today is good day.");
+INSERT INTO memos VALUES ("Tomorrow will be good day.");
+INSERT INTO memos VALUES ("Today is fine.");
+
+SELECT * FROM memos
+ WHERE MATCH (content) AGAINST ("*D+ today fi*" IN BOOLEAN MODE);
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_not_match_against.test b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_not_match_against.test
index 7b4e62ba0a9..ffb49f2f396 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_not_match_against.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_not_match_against.test
@@ -1,4 +1,5 @@
# Copyright(C) 2010 Tetsuro IKEDA
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -31,16 +32,16 @@ insert into t1 values(6,20,"ka ki ku ke ko");
insert into t1 values(7,20,"aa ii uu ee oo");
insert into t1 values(8,20,"ka ki ku ke ko");
select * from t1;
-select * from t1 where match(c3) against("uu");
-select * from t1 where not match(c3) against("uu");
-select * from t1 where match(c3) against("dummy");
-select * from t1 where not match(c3) against("dummy");
-select * from t1 where c1 = 4 and not match(c3) against("uu");
-select * from t1 where c1 <= 4 and not match(c3) against("uu");
-select * from t1 where c1 > 4 and not match(c3) against("uu");
-select * from t1 where c2 = 10 and not match(c3) against("uu");
-select * from t1 where c2 >= 15 and not match(c3) against("uu");
-select * from t1 where c2 < 15 and not match(c3) against("uu");
+select * from t1 where match(c3) against("+uu" in boolean mode) order by c1;
+select * from t1 where not match(c3) against("+uu" in boolean mode) order by c1;
+select * from t1 where match(c3) against("+dummy" in boolean mode) order by c1;
+select * from t1 where not match(c3) against("+dummy" in boolean mode) order by c1;
+select * from t1 where c1 = 4 and not match(c3) against("+uu" in boolean mode) order by c1;
+select * from t1 where c1 <= 4 and not match(c3) against("+uu" in boolean mode) order by c1;
+select * from t1 where c1 > 4 and not match(c3) against("+uu" in boolean mode) order by c1;
+select * from t1 where c2 = 10 and not match(c3) against("+uu" in boolean mode) order by c1;
+select * from t1 where c2 >= 15 and not match(c3) against("+uu" in boolean mode) order by c1;
+select * from t1 where c2 < 15 and not match(c3) against("+uu" in boolean mode) order by c1;
drop table t1;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.test
new file mode 100644
index 00000000000..2782fc15363
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_multiple_column_unique_datetime_insert_delete_insert_invalid_value.test
@@ -0,0 +1,39 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS ranges;
+--enable_warnings
+
+CREATE TABLE ranges (
+ id int PRIMARY KEY,
+ start datetime,
+ end datetime,
+ UNIQUE KEY range_key(start, end)
+);
+
+INSERT INTO ranges VALUES (1, "1990-00-00 00:00:00", "2012-10-05 23:59:59");
+SELECT * FROM ranges;
+
+DELETE FROM ranges WHERE id = 1;
+INSERT INTO ranges VALUES (1, "1990-00-00 00:00:00", "2012-10-05 23:59:59");
+SELECT * FROM ranges;
+
+DROP TABLE ranges;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/replace_select_varchar.test b/storage/mroonga/mysql-test/mroonga/storage/t/replace_select_varchar.test
index 192a4976cbd..d7cd89cf78c 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/replace_select_varchar.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/replace_select_varchar.test
@@ -57,7 +57,8 @@ REPLACE INTO videos_groonga
FROM videos_master AS v
WHERE v.video_id = (video_id);
SELECT *, MATCH(description) AGAINST("my") FROM videos_groonga
- WHERE MATCH(description) AGAINST("my");
+ WHERE MATCH(description) AGAINST("my")
+ ORDER BY id;
DROP TABLE videos_master, videos_groonga;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/replace_without_key.test b/storage/mroonga/mysql-test/mroonga/storage/t/replace_without_key.test
index a38c4953e67..5cbeab60fb0 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/replace_without_key.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/replace_without_key.test
@@ -27,7 +27,7 @@ CREATE TABLE diaries (
FULLTEXT INDEX (content)
) DEFAULT CHARSET=utf8;
--- error ER_ERROR_ON_WRITE
+-- error ER_ERROR_ON_WRITE, ER_NO_DEFAULT_FOR_FIELD
REPLACE INTO diaries(content) VALUES("Hello");
DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/truncate.test b/storage/mroonga/mysql-test/mroonga/storage/t/truncate.test
index 5833f77722a..dac32178011 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/truncate.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/truncate.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2011-2012 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -38,17 +38,23 @@ INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
SELECT * FROM diaries;
-SELECT * FROM diaries WHERE MATCH(content) AGAINST("今日 天気" IN BOOLEAN MODE);
+SELECT * FROM diaries
+ WHERE MATCH(content) AGAINST("+今日" IN BOOLEAN MODE)
+ ORDER BY id;
TRUNCATE TABLE diaries;
SELECT * FROM diaries;
-SELECT * FROM diaries WHERE MATCH(content) AGAINST("今日 天気" IN BOOLEAN MODE);
+SELECT * FROM diaries
+ WHERE MATCH(content) AGAINST("+今日" IN BOOLEAN MODE)
+ ORDER BY id;
INSERT INTO diaries VALUES(1, 2011, 11, 11, "帰りé“", "ã¤ã‹ã‚ŒãŸãƒ¼");
INSERT INTO diaries VALUES(2, 2011, 12, 1, "ä¹…ã—ã¶ã‚Š", "天気ãŒæ‚ªã„ã‹ã‚‰ãšã£ã¨ç•™å®ˆç•ªã€‚");
INSERT INTO diaries VALUES(3, 2011, 12, 2, "åˆé›ª", "今年ã¯ã˜ã‚ã¦ã®é›ªï¼");
SELECT * FROM diaries;
-SELECT * FROM diaries WHERE MATCH(content) AGAINST("悪ã„" IN BOOLEAN MODE);
+SELECT * FROM diaries
+ WHERE MATCH(content) AGAINST("+悪ã„" IN BOOLEAN MODE)
+ ORDER BY id;
DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_global.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_global.test
index 55a318b786a..9018bd75626 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_global.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_global.test
@@ -14,7 +14,6 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
---source ../../include/mroonga/have_fulltext_index_comment.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_session.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_session.test
index c459e50c0d7..49557069965 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_session.test
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_match_escalation_threshold_session.test
@@ -14,7 +14,6 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
---source ../../include/mroonga/have_fulltext_index_comment.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_comment.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_comment.result
new file mode 100644
index 00000000000..fb03bfe8d8d
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_comment.result
@@ -0,0 +1,9 @@
+SET NAMES utf8;
+CREATE TABLE memos (
+content VARCHAR(64) NOT NULL PRIMARY KEY,
+FULLTEXT INDEX (content) COMMENT 'flags "WITH_POSITION|WITH_WEIGHT"'
+) COMMENT='engine "InnoDB"' DEFAULT CHARSET=utf8;
+SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
+mroonga_command("dump --dump_plugins no --dump_schema no")
+column_create memos-content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_none.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_none.result
new file mode 100644
index 00000000000..4a7107146ce
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_none.result
@@ -0,0 +1,9 @@
+SET NAMES utf8;
+CREATE TABLE memos (
+content VARCHAR(64) NOT NULL PRIMARY KEY,
+FULLTEXT INDEX (content) COMMENT 'flags "NONE"'
+) COMMENT='engine "InnoDB"' DEFAULT CHARSET=utf8;
+SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
+mroonga_command("dump --dump_plugins no --dump_schema no")
+column_create memos-content index COLUMN_INDEX memos
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_parameter.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_parameter.result
new file mode 100644
index 00000000000..6e00526c736
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_flags_parameter.result
@@ -0,0 +1,16 @@
+SET NAMES utf8;
+CREATE TABLE memos (
+content VARCHAR(64) NOT NULL PRIMARY KEY,
+FULLTEXT INDEX (content) FLAGS='WITH_POSITION|WITH_WEIGHT'
+) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE memos;
+Table Create Table
+memos CREATE TABLE `memos` (
+ `content` varchar(64) NOT NULL,
+ PRIMARY KEY (`content`),
+ FULLTEXT KEY `content` (`content`) `FLAGS`='WITH_POSITION|WITH_WEIGHT'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
+SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
+mroonga_command("dump --dump_plugins no --dump_schema no")
+column_create memos-content index COLUMN_INDEX|WITH_WEIGHT|WITH_POSITION memos
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_comment.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_comment.result
new file mode 100644
index 00000000000..1c9bf50fad9
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_comment.result
@@ -0,0 +1,21 @@
+DROP TABLE IF EXISTS memos;
+SET NAMES utf8;
+CREATE TABLE memos (
+id INT NOT NULL PRIMARY KEY,
+content TEXT NOT NULL,
+FULLTEXT INDEX (content) COMMENT 'normalizer "NormalizerAuto"'
+) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE memos;
+Table Create Table
+memos CREATE TABLE `memos` (
+ `id` int(11) NOT NULL,
+ `content` text NOT NULL,
+ PRIMARY KEY (`id`),
+ FULLTEXT KEY `content` (`content`) COMMENT 'normalizer "NormalizerAuto"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
+INSERT INTO memos VALUES (1, "1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔ãŒ");
+SELECT * FROM memos
+WHERE MATCH (content) AGAINST ("+カロリー" IN BOOLEAN MODE);
+id content
+1 1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔ãŒ
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_fulltext_index.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_fulltext_index.result
deleted file mode 100644
index ea992f827ca..00000000000
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_fulltext_index.result
+++ /dev/null
@@ -1,16 +0,0 @@
-DROP TABLE IF EXISTS diaries;
-SET NAMES utf8;
-CREATE TABLE diaries (
-day DATE PRIMARY KEY,
-content VARCHAR(64) NOT NULL,
-FULLTEXT INDEX (content) COMMENT 'normalizer "NormalizerAuto"'
-) COMMENT='engine "InnoDB"' DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
-INSERT INTO diaries VALUES ("2013-04-23", "ブラックコーヒーを飲んã ã€‚");
-SELECT * FROM diaries
-WHERE MATCH (content) AGAINST ("+ãµã‚‰ã¤ã" IN BOOLEAN MODE);
-day content
-SELECT * FROM diaries
-WHERE MATCH (content) AGAINST ("+ブラック" IN BOOLEAN MODE);
-day content
-2013-04-23 ブラックコーヒーを飲んã ã€‚
-DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_parameter.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_parameter.result
new file mode 100644
index 00000000000..d3bc05a9b7d
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_normalizer_parameter.result
@@ -0,0 +1,21 @@
+DROP TABLE IF EXISTS memos;
+SET NAMES utf8;
+CREATE TABLE memos (
+id INT NOT NULL PRIMARY KEY,
+content TEXT NOT NULL,
+FULLTEXT INDEX (content) NORMALIZER='NormalizerAuto'
+) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE memos;
+Table Create Table
+memos CREATE TABLE `memos` (
+ `id` int(11) NOT NULL,
+ `content` text NOT NULL,
+ PRIMARY KEY (`id`),
+ FULLTEXT KEY `content` (`content`) `NORMALIZER`='NormalizerAuto'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
+INSERT INTO memos VALUES (1, "1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔ãŒ");
+SELECT * FROM memos
+WHERE MATCH (content) AGAINST ("+カロリー" IN BOOLEAN MODE);
+id content
+1 1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔ãŒ
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_parser_comment.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_parser_comment.result
index d7b20a3714f..7ee07329f21 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_parser_comment.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_parser_comment.result
@@ -13,17 +13,17 @@ diaries CREATE TABLE `diaries` (
PRIMARY KEY (`id`),
FULLTEXT KEY `body_index` (`body`) COMMENT 'parser "TokenBigramSplitSymbolAlphaDigit"'
) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"'
-insert into diaries (body) values ("will start groonga!");
-insert into diaries (body) values ("starting groonga...");
-insert into diaries (body) values ("started groonga.");
+insert into diaries (body) values ("will start Groonga!");
+insert into diaries (body) values ("starting Groonga...");
+insert into diaries (body) values ("started Groonga.");
select * from diaries;
id body
-1 will start groonga!
-2 starting groonga...
-3 started groonga.
-select * from diaries where match(body) against("start");
+1 will start Groonga!
+2 starting Groonga...
+3 started Groonga.
+select * from diaries where match(body) against("+start" in boolean mode) order by id;
id body
-1 will start groonga!
-2 starting groonga...
-3 started groonga.
+1 will start Groonga!
+2 starting Groonga...
+3 started Groonga.
drop table diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_comment_multiple_token_filters.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_multiple_token_filters.result
index 68319844df8..e1e32dccc37 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_comment_multiple_token_filters.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_multiple_token_filters.result
@@ -1,5 +1,5 @@
-SELECT mroonga_command("register token_filters/stop_word");
-mroonga_command("register token_filters/stop_word")
+SELECT mroonga_command("plugin_register token_filters/stop_word");
+mroonga_command("plugin_register token_filters/stop_word")
true
SET NAMES utf8;
CREATE TABLE memos (
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_comment_one_token_filter.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_one_token_filter.result
index fa3012705ad..11ee04e2998 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_comment_one_token_filter.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_one_token_filter.result
@@ -1,5 +1,5 @@
-SELECT mroonga_command("register token_filters/stop_word");
-mroonga_command("register token_filters/stop_word")
+SELECT mroonga_command("plugin_register token_filters/stop_word");
+mroonga_command("plugin_register token_filters/stop_word")
true
SET NAMES utf8;
CREATE TABLE memos (
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_parameter.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_parameter.result
new file mode 100644
index 00000000000..f6d6be1b643
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_token_filters_index_parameter.result
@@ -0,0 +1,25 @@
+SELECT mroonga_command("plugin_register token_filters/stop_word");
+mroonga_command("plugin_register token_filters/stop_word")
+true
+SET NAMES utf8;
+CREATE TABLE memos (
+id INT NOT NULL PRIMARY KEY,
+content VARCHAR(64) NOT NULL,
+FULLTEXT INDEX (content) TOKEN_FILTERS='TokenFilterStopWord,TokenFilterStopWord'
+) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE memos;
+Table Create Table
+memos CREATE TABLE `memos` (
+ `id` int(11) NOT NULL,
+ `content` varchar(64) NOT NULL,
+ PRIMARY KEY (`id`),
+ FULLTEXT KEY `content` (`content`) `TOKEN_FILTERS`='TokenFilterStopWord,TokenFilterStopWord'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
+SELECT mroonga_command("dump --dump_plugins no");
+mroonga_command("dump --dump_plugins no")
+table_create memos TABLE_HASH_KEY ShortText
+
+table_create memos-content TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerMySQLGeneralCI --token_filters TokenFilterStopWord,TokenFilterStopWord
+
+column_create memos-content index COLUMN_INDEX|WITH_POSITION memos
+DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_comment.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_comment.result
new file mode 100644
index 00000000000..f6e15804f42
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_comment.result
@@ -0,0 +1,29 @@
+drop table if exists diaries;
+create table diaries (
+id int primary key auto_increment,
+body text,
+fulltext index body_index (body)
+comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) comment = 'engine "innodb"' default charset utf8;
+show create table diaries;
+Table Create Table
+diaries CREATE TABLE `diaries` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `body` text,
+ PRIMARY KEY (`id`),
+ FULLTEXT KEY `body_index` (`body`) COMMENT 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "innodb"'
+insert into diaries (body) values ("will start Groonga!");
+insert into diaries (body) values ("starting Groonga...");
+insert into diaries (body) values ("started Groonga.");
+select * from diaries;
+id body
+1 will start Groonga!
+2 starting Groonga...
+3 started Groonga.
+select * from diaries where match(body) against("+start" in boolean mode) order by id;
+id body
+1 will start Groonga!
+2 starting Groonga...
+3 started Groonga.
+drop table diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_parameter.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_parameter.result
new file mode 100644
index 00000000000..ddec8fdadbe
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/create_table_tokenizer_parameter.result
@@ -0,0 +1,30 @@
+DROP TABLE IF EXISTS diaries;
+CREATE TABLE diaries (
+id int PRIMARY KEY AUTO_INCREMENT,
+body text,
+FULLTEXT INDEX body_index (body) TOKENIZER='TokenBigramSplitSymbolAlphaDigit'
+) COMMENT = 'ENGINE "InnoDB"' DEFAULT CHARSET utf8;
+SHOW CREATE TABLE diaries;
+Table Create Table
+diaries CREATE TABLE `diaries` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `body` text,
+ PRIMARY KEY (`id`),
+ FULLTEXT KEY `body_index` (`body`) `TOKENIZER`='TokenBigramSplitSymbolAlphaDigit'
+) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='ENGINE "InnoDB"'
+INSERT INTO diaries (body) VALUES ("will start Groonga!");
+INSERT INTO diaries (body) VALUES ("starting Groonga...");
+INSERT INTO diaries (body) VALUES ("started Groonga.");
+SELECT * FROM diaries;
+id body
+1 will start Groonga!
+2 starting Groonga...
+3 started Groonga.
+SELECT * FROM diaries
+WHERE MATCH(body) AGAINST("+start" IN BOOLEAN MODE)
+ORDER BY id;
+id body
+1 will start Groonga!
+2 starting Groonga...
+3 started Groonga.
+DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_no_operator.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_no_operator.result
index 14d30fac260..96d92e535d2 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_no_operator.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_no_operator.result
@@ -11,9 +11,10 @@ INSERT INTO memos VALUES (NULL, "Today is fine.");
INSERT INTO memos VALUES (NULL, "Tomorrow will be fine.");
INSERT INTO memos VALUES (NULL, "Yesterday was fine.");
SELECT * FROM memos
-WHERE MATCH (content) AGAINST ("*DOR today good" IN BOOLEAN MODE);
+WHERE MATCH (content) AGAINST ("*DOR today good" IN BOOLEAN MODE)
+ORDER BY id;
id content
1 Today is good day.
-3 Today is fine.
2 Tomorrow will be good day.
+3 Today is fine.
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_with_minus.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_with_minus.result
index d367ba1d21f..ee8d851011f 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_with_minus.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_with_minus.result
@@ -11,7 +11,8 @@ INSERT INTO memos VALUES (NULL, "Today is fine.");
INSERT INTO memos VALUES (NULL, "Tomorrow will be fine.");
INSERT INTO memos VALUES (NULL, "Yesterday was fine.");
SELECT * FROM memos
-WHERE MATCH (content) AGAINST ("*DOR today -good tomorrow" IN BOOLEAN MODE);
+WHERE MATCH (content) AGAINST ("*DOR today -good tomorrow" IN BOOLEAN MODE)
+ORDER BY id;
id content
2 Tomorrow will be good day.
3 Today is fine.
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_with_plus.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_with_plus.result
index 6bf48ab6556..bb94043256d 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_with_plus.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_boolean_mode_pragma_default_operator_or_with_plus.result
@@ -11,7 +11,8 @@ INSERT INTO memos VALUES (NULL, "Today is fine.");
INSERT INTO memos VALUES (NULL, "Tomorrow will be fine.");
INSERT INTO memos VALUES (NULL, "Yesterday was fine.");
SELECT * FROM memos
-WHERE MATCH (content) AGAINST ("*DOR today +good tomorrow" IN BOOLEAN MODE);
+WHERE MATCH (content) AGAINST ("*DOR today +good tomorrow" IN BOOLEAN MODE)
+ORDER BY id;
id content
1 Today is good day.
2 Tomorrow will be good day.
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_select.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_select.result
index 03300e3e9ef..7391ee4ba8d 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_select.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_insert_select.result
@@ -55,12 +55,12 @@ c1 c2 match(c2) against("ii")
3 aa ii ii ii oo 524289
select c1,c2,match(c2) against("ii") from t1 where match(c2) against("ii");
c1 c2 match(c2) against("ii")
-1 aa ii uu ee oo 174763
3 aa ii ii ii oo 524289
5 ta ti ii ii to 349526
+1 aa ii uu ee oo 174763
select c1,c2,match(c2) against("ii") from t1 where match(c2) against("ii");
c1 c2 match(c2) against("ii")
-1 aa ii uu ee oo 174763
3 aa ii ii ii oo 524289
5 ta ti ii ii to 349526
+1 aa ii uu ee oo 174763
drop table t1,t2;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_many_records.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_many_records.result
index 3809006038c..03cf96b55f8 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_many_records.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_many_records.result
@@ -4112,7 +4112,7 @@ insert into diaries values(4094, "2022-09-28");
insert into diaries values(4095, "2022-09-29");
commit;
set autocommit=1;
-select * from diaries where match(title) against("2022-09-0");
+select * from diaries where match(title) against("2022-09-0") order by id;
id title
3824 2022-01-01
3825 2022-01-02
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_matched_order.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_matched_order.result
new file mode 100644
index 00000000000..def5db40cb9
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_matched_order.result
@@ -0,0 +1,26 @@
+DROP TABLE IF EXISTS texts;
+SET NAMES UTF8;
+CREATE TABLE texts (
+id INT PRIMARY KEY,
+matched TEXT,
+not_matched TEXT,
+FULLTEXT KEY (matched),
+FULLTEXT KEY (not_matched)
+) DEFAULT CHARSET=UTF8 COMMENT='engine "InnoDB"';
+INSERT INTO texts VALUES (1, 'Hello1', 'World1');
+INSERT INTO texts VALUES (2, 'Hello2', 'World2');
+INSERT INTO texts VALUES (3, 'Hello3', 'World3');
+SELECT id,
+matched,
+not_matched,
+MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE),
+MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE)
+FROM texts
+WHERE MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE)
+ORDER BY MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE),
+id;
+id matched not_matched MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE) MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE)
+1 Hello1 World1 1 0
+2 Hello2 World2 1 0
+3 Hello3 World3 1 0
+DROP TABLE texts;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_no_order.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_no_order.result
new file mode 100644
index 00000000000..81ce556e745
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_have_where_no_order.result
@@ -0,0 +1,24 @@
+DROP TABLE IF EXISTS texts;
+SET NAMES UTF8;
+CREATE TABLE texts (
+id INT PRIMARY KEY,
+matched TEXT,
+not_matched TEXT,
+FULLTEXT KEY (matched),
+FULLTEXT KEY (not_matched)
+) DEFAULT CHARSET=UTF8 COMMENT='engine "InnoDB"';
+INSERT INTO texts VALUES (1, 'Hello1', 'World1');
+INSERT INTO texts VALUES (2, 'Hello2', 'World2');
+INSERT INTO texts VALUES (3, 'Hello3', 'World3');
+SELECT id,
+matched,
+not_matched,
+MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE),
+MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE)
+FROM texts
+WHERE MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE);
+id matched not_matched MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE) MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE)
+1 Hello1 World1 1 0
+3 Hello3 World3 1 0
+2 Hello2 World2 1 0
+DROP TABLE texts;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_no_where_both_order.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_no_where_both_order.result
new file mode 100644
index 00000000000..f619e467040
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_matched_and_not_matched_no_where_both_order.result
@@ -0,0 +1,26 @@
+DROP TABLE IF EXISTS texts;
+SET NAMES UTF8;
+CREATE TABLE texts (
+id INT PRIMARY KEY,
+matched TEXT,
+not_matched TEXT,
+FULLTEXT KEY (matched),
+FULLTEXT KEY (not_matched)
+) DEFAULT CHARSET=UTF8 COMMENT='engine "InnoDB"';
+INSERT INTO texts VALUES (1, 'Hello1', 'World1');
+INSERT INTO texts VALUES (2, 'Hello2', 'World2');
+INSERT INTO texts VALUES (3, 'Hello3', 'World3');
+SELECT id,
+matched,
+not_matched,
+MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE),
+MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE)
+FROM texts
+ORDER BY MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE),
+MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE),
+id;
+id matched not_matched MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE) MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE)
+1 Hello1 World1 1 0
+2 Hello2 World2 1 0
+3 Hello3 World3 1 0
+DROP TABLE texts;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_myisam.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_myisam.result
index de1b8d41906..860c8e548a8 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_myisam.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_myisam.result
@@ -36,17 +36,17 @@ c1 c2 c3
3 30 sa si su se so
4 40 ta ti tu te to
5 50 aa ii uu ee oo
-select * from t1 where match(c3) against("su");
+select * from t1 where match(c3) against("su") order by c1;
c1 c2 c3
3 30 sa si su se so
-select * from t1 where match(c3) against("ii");
+select * from t1 where match(c3) against("ii") order by c1;
c1 c2 c3
1 10 aa ii uu ee oo
5 50 aa ii uu ee oo
-select * from t1 where match(c3) against("+su" in boolean mode);
+select * from t1 where match(c3) against("+su" in boolean mode) order by c1;
c1 c2 c3
3 30 sa si su se so
-select * from t1 where match(c3) against("+ii" in boolean mode);
+select * from t1 where match(c3) against("+ii" in boolean mode) order by c1;
c1 c2 c3
1 10 aa ii uu ee oo
5 50 aa ii uu ee oo
@@ -61,10 +61,10 @@ c1 c2 c3
1 明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„㦠ã‚ã‚ã‚ã‚ã‚ã‚ã‚
2 ã„ã„ã„ã„ㄠ明日ã®å¯Œå£«å±±ã®å¤©æ°—ã¯åˆ†ã‹ã‚Šã¾ã›ã‚“
3 dummy dummy
-select * from t1 where match(c2) against("富士山");
+select * from t1 where match(c2) against("富士山") order by c1;
c1 c2 c3
1 明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„㦠ã‚ã‚ã‚ã‚ã‚ã‚ã‚
-select * from t1 where match(c3) against("富士山");
+select * from t1 where match(c3) against("富士山") order by c1;
c1 c2 c3
2 ã„ã„ã„ã„ㄠ明日ã®å¯Œå£«å±±ã®å¤©æ°—ã¯åˆ†ã‹ã‚Šã¾ã›ã‚“
drop table t1;
@@ -124,14 +124,14 @@ c1 c2 match(c2) against("ii")
3 aa ii ii ii oo 524289
select c1,c2,match(c2) against("ii") from t1 where match(c2) against("ii");
c1 c2 match(c2) against("ii")
-1 aa ii uu ee oo 174763
3 aa ii ii ii oo 524289
5 ta ti ii ii to 349526
+1 aa ii uu ee oo 174763
select c1,c2,match(c2) against("ii") from t1 where match(c2) against("ii");
c1 c2 match(c2) against("ii")
-1 aa ii uu ee oo 174763
3 aa ii ii ii oo 524289
5 ta ti ii ii to 349526
+1 aa ii uu ee oo 174763
drop table t1,t2;
create table t1 (c1 int primary key, c2 int, c3 text, fulltext index ft(c3)) COMMENT = 'engine "myisam"';
insert into t1 values(1,10,"aa ii uu ee oo");
@@ -152,7 +152,7 @@ c1 c2 c3
6 20 ka ki ku ke ko
7 20 aa ii uu ee oo
8 20 ka ki ku ke ko
-select *,match(c3) against("uu") from t1 where match(c3) against("uu");
+select *,match(c3) against("uu") from t1 where match(c3) against("uu") order by c1;
c1 c2 c3 match(c3) against("uu")
1 10 aa ii uu ee oo 131073
3 10 aa ii uu ee oo 131073
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_not_match_against.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_not_match_against.result
index bbe23df3e0f..4646aad6a20 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_not_match_against.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_not_match_against.result
@@ -18,21 +18,21 @@ c1 c2 c3
6 20 ka ki ku ke ko
7 20 aa ii uu ee oo
8 20 ka ki ku ke ko
-select *,match(c3) against("uu") from t1 where match(c3) against("uu");
+select *,match(c3) against("uu") from t1 where match(c3) against("uu") order by c1;
c1 c2 c3 match(c3) against("uu")
1 10 aa ii uu ee oo 131073
3 10 aa ii uu ee oo 131073
5 20 aa ii uu ee oo 131073
7 20 aa ii uu ee oo 131073
-select * from t1 where not match(c3) against("uu");
+select * from t1 where not match(c3) against("uu") order by c1;
c1 c2 c3
2 10 ka ki ku ke ko
4 10 ka ki ku ke ko
6 20 ka ki ku ke ko
8 20 ka ki ku ke ko
-select *,match(c3) against("dummy") from t1 where match(c3) against("dummy");
+select *,match(c3) against("dummy") from t1 where match(c3) against("dummy") order by c1;
c1 c2 c3 match(c3) against("dummy")
-select * from t1 where not match(c3) against("dummy");
+select * from t1 where not match(c3) against("dummy") order by c1;
c1 c2 c3
1 10 aa ii uu ee oo
2 10 ka ki ku ke ko
@@ -42,26 +42,26 @@ c1 c2 c3
6 20 ka ki ku ke ko
7 20 aa ii uu ee oo
8 20 ka ki ku ke ko
-select * from t1 where c1 = 4 and not match(c3) against("uu");
+select * from t1 where c1 = 4 and not match(c3) against("uu") order by c1;
c1 c2 c3
4 10 ka ki ku ke ko
-select * from t1 where c1 <= 4 and not match(c3) against("uu");
+select * from t1 where c1 <= 4 and not match(c3) against("uu") order by c1;
c1 c2 c3
2 10 ka ki ku ke ko
4 10 ka ki ku ke ko
-select * from t1 where c1 > 4 and not match(c3) against("uu");
+select * from t1 where c1 > 4 and not match(c3) against("uu") order by c1;
c1 c2 c3
6 20 ka ki ku ke ko
8 20 ka ki ku ke ko
-select * from t1 where c2 = 10 and not match(c3) against("uu");
+select * from t1 where c2 = 10 and not match(c3) against("uu") order by c1;
c1 c2 c3
2 10 ka ki ku ke ko
4 10 ka ki ku ke ko
-select * from t1 where c2 >= 15 and not match(c3) against("uu");
+select * from t1 where c2 >= 15 and not match(c3) against("uu") order by c1;
c1 c2 c3
6 20 ka ki ku ke ko
8 20 ka ki ku ke ko
-select * from t1 where c2 < 15 and not match(c3) against("uu");
+select * from t1 where c2 < 15 and not match(c3) against("uu") order by c1;
c1 c2 c3
2 10 ka ki ku ke ko
4 10 ka ki ku ke ko
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_TODO_SPLIT_ME.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_TODO_SPLIT_ME.result
index 279ad8bf985..18d78d88c93 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_TODO_SPLIT_ME.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/fulltext_order_TODO_SPLIT_ME.result
@@ -29,22 +29,6 @@ a b c
SELECT a, b, c FROM ft WHERE MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE) ORDER BY MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE);
a b c
2 bbbbb bcdef
-SELECT a, b, c FROM ft WHERE MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE) ORDER BY MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE);
-a b c
-2 bbbbb bcdef
SELECT a, b, c FROM ft WHERE MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE);
a b c
-SELECT a, b, c, MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE), MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE) FROM ft WHERE MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE) ORDER BY MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE);
-a b c MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE) MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE)
-2 bbbbb bcdef 1 0
-SELECT a, b, c, MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE), MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE) FROM ft WHERE MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE);
-a b c MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE) MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE)
-2 bbbbb bcdef 1 0
-SELECT a, b, c, MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE), MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE) FROM ft ORDER BY MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE), MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE), a;
-a b c MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE) MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE)
-1 aaaaa abcde 0 0
-3 ccccc cdefg 0 0
-4 ddddd defgh 0 0
-5 eeeee efghi 0 0
-2 bbbbb bcdef 1 0
DROP TABLE ft;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/r/truncate.result b/storage/mroonga/mysql-test/mroonga/wrapper/r/truncate.result
index 35b273d348f..d41231ddd33 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/r/truncate.result
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/r/truncate.result
@@ -31,15 +31,18 @@ id year month day title content
1 2011 11 9 Hello 今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚
2 2011 11 10 天気 明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦
3 2011 11 11 富士山 今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚
-SELECT * FROM diaries WHERE MATCH(content) AGAINST("今日 天気" IN BOOLEAN MODE);
+SELECT * FROM diaries
+WHERE MATCH(content) AGAINST("+今日" IN BOOLEAN MODE)
+ORDER BY id;
id year month day title content
1 2011 11 9 Hello 今日ã‹ã‚‰ã¯ã˜ã‚ã¾ã—ãŸã€‚
3 2011 11 11 富士山 今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚
-2 2011 11 10 天気 明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦
TRUNCATE TABLE diaries;
SELECT * FROM diaries;
id year month day title content
-SELECT * FROM diaries WHERE MATCH(content) AGAINST("今日 天気" IN BOOLEAN MODE);
+SELECT * FROM diaries
+WHERE MATCH(content) AGAINST("+今日" IN BOOLEAN MODE)
+ORDER BY id;
id year month day title content
INSERT INTO diaries VALUES(1, 2011, 11, 11, "帰りé“", "ã¤ã‹ã‚ŒãŸãƒ¼");
INSERT INTO diaries VALUES(2, 2011, 12, 1, "ä¹…ã—ã¶ã‚Š", "天気ãŒæ‚ªã„ã‹ã‚‰ãšã£ã¨ç•™å®ˆç•ªã€‚");
@@ -49,7 +52,9 @@ id year month day title content
1 2011 11 11 å¸°ã‚Šé“ ã¤ã‹ã‚ŒãŸãƒ¼
2 2011 12 1 ä¹…ã—ã¶ã‚Š 天気ãŒæ‚ªã„ã‹ã‚‰ãšã£ã¨ç•™å®ˆç•ªã€‚
3 2011 12 2 åˆé›ª 今年ã¯ã˜ã‚ã¦ã®é›ªï¼
-SELECT * FROM diaries WHERE MATCH(content) AGAINST("悪ã„" IN BOOLEAN MODE);
+SELECT * FROM diaries
+WHERE MATCH(content) AGAINST("+悪ã„" IN BOOLEAN MODE)
+ORDER BY id;
id year month day title content
2 2011 12 1 ä¹…ã—ã¶ã‚Š 天気ãŒæ‚ªã„ã‹ã‚‰ãšã£ã¨ç•™å®ˆç•ªã€‚
DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/suite.pm b/storage/mroonga/mysql-test/mroonga/wrapper/suite.pm
index b6e2d741674..528ccc5d693 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/suite.pm
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/suite.pm
@@ -4,11 +4,6 @@ package My::Suite::Mroonga;
return "No Mroonga engine" unless $ENV{HA_MROONGA_SO} or
$::mysqld_variables{'mroonga'} eq "ON";
-#
-# RECOMPILE_FOR_EMBEDDED also means that a plugin
-# cannot be dynamically loaded into embedded
-return "Not run for embedded server" if $::opt_embedded_server and
- $ENV{HA_MROONGA_SO};
sub is_default { 1 }
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/count_star_with_index.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/count_star_with_index.test
index 70c176b5116..899f00320c9 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/count_star_with_index.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/count_star_with_index.test
@@ -15,7 +15,6 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--source include/have_innodb.inc
---source ../../include/mroonga/have_fulltext_index_comment.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_query_log
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_comment.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_comment.test
new file mode 100644
index 00000000000..0b2565f2fb5
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_comment.test
@@ -0,0 +1,40 @@
+# Copyright(C) 2015 Naoya Murakami <naoya@createfield.com>
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+SET NAMES utf8;
+
+CREATE TABLE memos (
+ content VARCHAR(64) NOT NULL PRIMARY KEY,
+ FULLTEXT INDEX (content) COMMENT 'flags "WITH_POSITION|WITH_WEIGHT"'
+) COMMENT='engine "InnoDB"' DEFAULT CHARSET=utf8;
+
+SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_none.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_none.test
new file mode 100644
index 00000000000..656a349c1be
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_none.test
@@ -0,0 +1,40 @@
+# Copyright(C) 2015 Naoya Murakami <naoya@createfield.com>
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+SET NAMES utf8;
+
+CREATE TABLE memos (
+ content VARCHAR(64) NOT NULL PRIMARY KEY,
+ FULLTEXT INDEX (content) COMMENT 'flags "NONE"'
+) COMMENT='engine "InnoDB"' DEFAULT CHARSET=utf8;
+
+SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_parameter.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_parameter.test
new file mode 100644
index 00000000000..6b1a4c8dec2
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_flags_parameter.test
@@ -0,0 +1,42 @@
+# Copyright(C) 2015 Naoya Murakami <naoya@createfield.com>
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mariadb.inc
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+SET NAMES utf8;
+
+CREATE TABLE memos (
+ content VARCHAR(64) NOT NULL PRIMARY KEY,
+ FULLTEXT INDEX (content) FLAGS='WITH_POSITION|WITH_WEIGHT'
+) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE memos;
+
+SELECT mroonga_command("dump --dump_plugins no --dump_schema no");
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_comment.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_comment.test
new file mode 100644
index 00000000000..3b84e5d1bce
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_comment.test
@@ -0,0 +1,40 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS memos;
+--enable_warnings
+
+SET NAMES utf8;
+
+CREATE TABLE memos (
+ id INT NOT NULL PRIMARY KEY,
+ content TEXT NOT NULL,
+ FULLTEXT INDEX (content) COMMENT 'normalizer "NormalizerAuto"'
+) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE memos;
+
+INSERT INTO memos VALUES (1, "1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔ãŒ");
+
+SELECT * FROM memos
+ WHERE MATCH (content) AGAINST ("+カロリー" IN BOOLEAN MODE);
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_parameter.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_parameter.test
new file mode 100644
index 00000000000..b8fe3eb6c7d
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_parameter.test
@@ -0,0 +1,41 @@
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mariadb.inc
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS memos;
+--enable_warnings
+
+SET NAMES utf8;
+
+CREATE TABLE memos (
+ id INT NOT NULL PRIMARY KEY,
+ content TEXT NOT NULL,
+ FULLTEXT INDEX (content) NORMALIZER='NormalizerAuto'
+) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE memos;
+
+INSERT INTO memos VALUES (1, "1æ—¥ã®æ¶ˆè²»ãŒã¯ç´„2000㌔ãŒ");
+
+SELECT * FROM memos
+ WHERE MATCH (content) AGAINST ("+カロリー" IN BOOLEAN MODE);
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_parser_comment.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_parser_comment.test
index fe80aae0804..05fc2fdcb9d 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_parser_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_parser_comment.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2011 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -15,7 +15,6 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--source include/have_innodb.inc
---source ../../include/mroonga/have_fulltext_index_comment.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -29,11 +28,11 @@ create table diaries (
comment 'parser "TokenBigramSplitSymbolAlphaDigit"'
) comment = 'engine "innodb"' default charset utf8;
show create table diaries;
-insert into diaries (body) values ("will start groonga!");
-insert into diaries (body) values ("starting groonga...");
-insert into diaries (body) values ("started groonga.");
+insert into diaries (body) values ("will start Groonga!");
+insert into diaries (body) values ("starting Groonga...");
+insert into diaries (body) values ("started Groonga.");
select * from diaries;
-select * from diaries where match(body) against("start");
+select * from diaries where match(body) against("+start" in boolean mode) order by id;
drop table diaries;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_comment_multiple_token_filters.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_multiple_token_filters.test
index 9ff8e4448d9..472f26cda6e 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_comment_multiple_token_filters.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_multiple_token_filters.test
@@ -16,6 +16,7 @@
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/have_groonga_plugin_register.inc
--source ../../include/mroonga/load_mroonga_functions.inc
--disable_query_log
@@ -24,7 +25,7 @@ CREATE DATABASE test;
USE test;
--enable_query_log
-SELECT mroonga_command("register token_filters/stop_word");
+SELECT mroonga_command("plugin_register token_filters/stop_word");
SET NAMES utf8;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_comment_one_token_filter.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_one_token_filter.test
index eee08309f76..0d3c00e2c98 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_comment_one_token_filter.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_one_token_filter.test
@@ -16,6 +16,7 @@
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/have_groonga_plugin_register.inc
--source ../../include/mroonga/load_mroonga_functions.inc
--disable_query_log
@@ -24,7 +25,7 @@ CREATE DATABASE test;
USE test;
--enable_query_log
-SELECT mroonga_command("register token_filters/stop_word");
+SELECT mroonga_command("plugin_register token_filters/stop_word");
SET NAMES utf8;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_parameter.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_parameter.test
new file mode 100644
index 00000000000..9decafaf1e7
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_token_filters_index_parameter.test
@@ -0,0 +1,46 @@
+# Copyright(C) 2014 Naoya Murakami <naoya@createfield.com>
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source ../../include/mroonga/have_mariadb.inc
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+--source ../../include/mroonga/have_groonga_plugin_register.inc
+--source ../../include/mroonga/load_mroonga_functions.inc
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+SELECT mroonga_command("plugin_register token_filters/stop_word");
+
+SET NAMES utf8;
+
+CREATE TABLE memos (
+ id INT NOT NULL PRIMARY KEY,
+ content VARCHAR(64) NOT NULL,
+ FULLTEXT INDEX (content) TOKEN_FILTERS='TokenFilterStopWord,TokenFilterStopWord'
+) COMMENT='ENGINE "InnoDB"' DEFAULT CHARSET=utf8;
+SHOW CREATE TABLE memos;
+
+SELECT mroonga_command("dump --dump_plugins no");
+
+DROP TABLE memos;
+
+--source ../../include/mroonga/unload_mroonga_functions.inc
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_parser_comment.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_comment.test
index 24cc173485a..5053de07781 100644
--- a/storage/mroonga/mysql-test/mroonga/storage/t/fulltext_parser_comment.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_comment.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2011 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -14,7 +14,7 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
---source ../../include/mroonga/have_fulltext_index_comment.inc
+--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
@@ -25,14 +25,14 @@ create table diaries (
id int primary key auto_increment,
body text,
fulltext index body_index (body)
- comment 'parser "TokenBigramSplitSymbolAlphaDigit"'
-) default charset utf8;
+ comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'
+) comment = 'engine "innodb"' default charset utf8;
show create table diaries;
-insert into diaries (body) values ("will start groonga!");
-insert into diaries (body) values ("starting groonga...");
-insert into diaries (body) values ("started groonga.");
+insert into diaries (body) values ("will start Groonga!");
+insert into diaries (body) values ("starting Groonga...");
+insert into diaries (body) values ("started Groonga.");
select * from diaries;
-select * from diaries where match(body) against("start");
+select * from diaries where match(body) against("+start" in boolean mode) order by id;
drop table diaries;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_fulltext_index.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_parameter.test
index c4265ffd22e..7c688199314 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_normalizer_fulltext_index.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/create_table_tokenizer_parameter.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -14,30 +14,30 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+--source ../../include/mroonga/have_mariadb.inc
--source include/have_innodb.inc
--source ../../include/mroonga/have_mroonga.inc
---source ../../include/mroonga/load_mroonga_functions.inc
--disable_warnings
DROP TABLE IF EXISTS diaries;
--enable_warnings
-SET NAMES utf8;
-
CREATE TABLE diaries (
- day DATE PRIMARY KEY,
- content VARCHAR(64) NOT NULL,
- FULLTEXT INDEX (content) COMMENT 'normalizer "NormalizerAuto"'
-) COMMENT='engine "InnoDB"' DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+ id int PRIMARY KEY AUTO_INCREMENT,
+ body text,
+ FULLTEXT INDEX body_index (body) TOKENIZER='TokenBigramSplitSymbolAlphaDigit'
+) COMMENT = 'ENGINE "InnoDB"' DEFAULT CHARSET utf8;
+SHOW CREATE TABLE diaries;
-INSERT INTO diaries VALUES ("2013-04-23", "ブラックコーヒーを飲んã ã€‚");
+INSERT INTO diaries (body) VALUES ("will start Groonga!");
+INSERT INTO diaries (body) VALUES ("starting Groonga...");
+INSERT INTO diaries (body) VALUES ("started Groonga.");
+SELECT * FROM diaries;
SELECT * FROM diaries
- WHERE MATCH (content) AGAINST ("+ãµã‚‰ã¤ã" IN BOOLEAN MODE);
-SELECT * FROM diaries
- WHERE MATCH (content) AGAINST ("+ブラック" IN BOOLEAN MODE);
+ WHERE MATCH(body) AGAINST("+start" IN BOOLEAN MODE)
+ ORDER BY id;
DROP TABLE diaries;
---source ../../include/mroonga/unload_mroonga_functions.inc
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test
index 6a89d7556ab..c561ac84c98 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_no_operator.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -35,7 +35,8 @@ INSERT INTO memos VALUES (NULL, "Tomorrow will be fine.");
INSERT INTO memos VALUES (NULL, "Yesterday was fine.");
SELECT * FROM memos
- WHERE MATCH (content) AGAINST ("*DOR today good" IN BOOLEAN MODE);
+ WHERE MATCH (content) AGAINST ("*DOR today good" IN BOOLEAN MODE)
+ ORDER BY id;
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test
index 790d2f1c9a9..cc3c6cef5b8 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_minus.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -35,7 +35,8 @@ INSERT INTO memos VALUES (NULL, "Tomorrow will be fine.");
INSERT INTO memos VALUES (NULL, "Yesterday was fine.");
SELECT * FROM memos
- WHERE MATCH (content) AGAINST ("*DOR today -good tomorrow" IN BOOLEAN MODE);
+ WHERE MATCH (content) AGAINST ("*DOR today -good tomorrow" IN BOOLEAN MODE)
+ ORDER BY id;
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test
index a45c414580d..7002db06461 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_boolean_mode_pragma_default_operator_or_with_plus.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -35,7 +35,8 @@ INSERT INTO memos VALUES (NULL, "Tomorrow will be fine.");
INSERT INTO memos VALUES (NULL, "Yesterday was fine.");
SELECT * FROM memos
- WHERE MATCH (content) AGAINST ("*DOR today +good tomorrow" IN BOOLEAN MODE);
+ WHERE MATCH (content) AGAINST ("*DOR today +good tomorrow" IN BOOLEAN MODE)
+ ORDER BY id;
DROP TABLE memos;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_select.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_select.test
index 6037ab61da0..26c784391ab 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_select.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_insert_select.test
@@ -1,5 +1,5 @@
# Copyright(C) 2010 Tetsuro IKEDA
-# Copyright(C) 2011 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_many_records.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_many_records.test
index c12441f3c5a..442b4f248d9 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_many_records.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_many_records.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2011 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -4129,7 +4129,7 @@ insert into diaries values(4095, "2022-09-29");
commit;
set autocommit=1;
-select * from diaries where match(title) against("2022-09-0");
+select * from diaries where match(title) against("2022-09-0") order by id;
drop table diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_matched_order.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_matched_order.test
new file mode 100644
index 00000000000..2ed609d9fe2
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_matched_order.test
@@ -0,0 +1,50 @@
+# Copyright(C) 2012 Kentoku SHIBA
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS texts;
+--enable_warnings
+
+SET NAMES UTF8;
+CREATE TABLE texts (
+ id INT PRIMARY KEY,
+ matched TEXT,
+ not_matched TEXT,
+ FULLTEXT KEY (matched),
+ FULLTEXT KEY (not_matched)
+) DEFAULT CHARSET=UTF8 COMMENT='engine "InnoDB"';
+
+INSERT INTO texts VALUES (1, 'Hello1', 'World1');
+INSERT INTO texts VALUES (2, 'Hello2', 'World2');
+INSERT INTO texts VALUES (3, 'Hello3', 'World3');
+
+SELECT id,
+ matched,
+ not_matched,
+ MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE),
+ MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE)
+ FROM texts
+ WHERE MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE)
+ ORDER BY MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE),
+ id;
+
+DROP TABLE texts;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_no_order.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_no_order.test
new file mode 100644
index 00000000000..968a763917d
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_have_where_no_order.test
@@ -0,0 +1,48 @@
+# Copyright(C) 2012 Kentoku SHIBA
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS texts;
+--enable_warnings
+
+SET NAMES UTF8;
+CREATE TABLE texts (
+ id INT PRIMARY KEY,
+ matched TEXT,
+ not_matched TEXT,
+ FULLTEXT KEY (matched),
+ FULLTEXT KEY (not_matched)
+) DEFAULT CHARSET=UTF8 COMMENT='engine "InnoDB"';
+
+INSERT INTO texts VALUES (1, 'Hello1', 'World1');
+INSERT INTO texts VALUES (2, 'Hello2', 'World2');
+INSERT INTO texts VALUES (3, 'Hello3', 'World3');
+
+SELECT id,
+ matched,
+ not_matched,
+ MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE),
+ MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE)
+ FROM texts
+ WHERE MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE);
+
+DROP TABLE texts;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_no_where_both_order.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_no_where_both_order.test
new file mode 100644
index 00000000000..a0ae0ef8a2e
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_matched_and_not_matched_no_where_both_order.test
@@ -0,0 +1,50 @@
+# Copyright(C) 2012 Kentoku SHIBA
+# Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--source include/have_innodb.inc
+--source ../../include/mroonga/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS texts;
+--enable_warnings
+
+SET NAMES UTF8;
+CREATE TABLE texts (
+ id INT PRIMARY KEY,
+ matched TEXT,
+ not_matched TEXT,
+ FULLTEXT KEY (matched),
+ FULLTEXT KEY (not_matched)
+) DEFAULT CHARSET=UTF8 COMMENT='engine "InnoDB"';
+
+INSERT INTO texts VALUES (1, 'Hello1', 'World1');
+INSERT INTO texts VALUES (2, 'Hello2', 'World2');
+INSERT INTO texts VALUES (3, 'Hello3', 'World3');
+
+SELECT id,
+ matched,
+ not_matched,
+ MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE),
+ MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE)
+ FROM texts
+ ORDER BY MATCH(matched) AGAINST('+Hello' IN BOOLEAN MODE),
+ MATCH(not_matched) AGAINST('+Hello' IN BOOLEAN MODE),
+ id;
+
+DROP TABLE texts;
+
+--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_myisam.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_myisam.test
index eda8a5f15ef..4b872eb054c 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_myisam.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_myisam.test
@@ -1,5 +1,5 @@
# Copyright(C) 2010 Tetsuro IKEDA
-# Copyright(C) 2011 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -38,10 +38,10 @@ insert into t1 values(3,30,"sa si su se so");
insert into t1 values(4,40,"ta ti tu te to");
insert into t1 values(5,50,"aa ii uu ee oo");
select * from t1;
-select * from t1 where match(c3) against("su");
-select * from t1 where match(c3) against("ii");
-select * from t1 where match(c3) against("+su" in boolean mode);
-select * from t1 where match(c3) against("+ii" in boolean mode);
+select * from t1 where match(c3) against("su") order by c1;
+select * from t1 where match(c3) against("ii") order by c1;
+select * from t1 where match(c3) against("+su" in boolean mode) order by c1;
+select * from t1 where match(c3) against("+ii" in boolean mode) order by c1;
drop table t1;
set names utf8;
@@ -50,8 +50,8 @@ insert into t1 values(1, "明日ã®å¯Œå£«å±±ã®å¤©æ°—ã«ã¤ã„ã¦","ã‚ã‚ã‚ã‚
insert into t1 values(2, "ã„ã„ã„ã„ã„","明日ã®å¯Œå£«å±±ã®å¤©æ°—ã¯åˆ†ã‹ã‚Šã¾ã›ã‚“");
insert into t1 values(3, "dummy", "dummy");
select * from t1;
-select * from t1 where match(c2) against("富士山");
-select * from t1 where match(c3) against("富士山");
+select * from t1 where match(c2) against("富士山") order by c1;
+select * from t1 where match(c3) against("富士山") order by c1;
drop table t1;
create table t1 (c1 int primary key, c2 varchar(100), fulltext index(c2)) default charset utf8 COMMENT = 'engine "myisam"';
@@ -87,7 +87,7 @@ insert into t1 values(6,20,"ka ki ku ke ko");
insert into t1 values(7,20,"aa ii uu ee oo");
insert into t1 values(8,20,"ka ki ku ke ko");
select * from t1;
-select *,match(c3) against("uu") from t1 where match(c3) against("uu");
+select *,match(c3) against("uu") from t1 where match(c3) against("uu") order by c1;
select * from t1 where not match(c3) against("uu");
select *,match(c3) against("dummy") from t1 where match(c3) against("dummy");
select * from t1 where not match(c3) against("dummy");
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_not_match_against.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_not_match_against.test
index 6ce01598136..43fc4b2771a 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_not_match_against.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_not_match_against.test
@@ -1,5 +1,5 @@
# Copyright(C) 2010 Tetsuro IKEDA
-# Copyright(C) 2011 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -32,16 +32,16 @@ insert into t1 values(6,20,"ka ki ku ke ko");
insert into t1 values(7,20,"aa ii uu ee oo");
insert into t1 values(8,20,"ka ki ku ke ko");
select * from t1;
-select *,match(c3) against("uu") from t1 where match(c3) against("uu");
-select * from t1 where not match(c3) against("uu");
-select *,match(c3) against("dummy") from t1 where match(c3) against("dummy");
-select * from t1 where not match(c3) against("dummy");
-select * from t1 where c1 = 4 and not match(c3) against("uu");
-select * from t1 where c1 <= 4 and not match(c3) against("uu");
-select * from t1 where c1 > 4 and not match(c3) against("uu");
-select * from t1 where c2 = 10 and not match(c3) against("uu");
-select * from t1 where c2 >= 15 and not match(c3) against("uu");
-select * from t1 where c2 < 15 and not match(c3) against("uu");
+select *,match(c3) against("uu") from t1 where match(c3) against("uu") order by c1;
+select * from t1 where not match(c3) against("uu") order by c1;
+select *,match(c3) against("dummy") from t1 where match(c3) against("dummy") order by c1;
+select * from t1 where not match(c3) against("dummy") order by c1;
+select * from t1 where c1 = 4 and not match(c3) against("uu") order by c1;
+select * from t1 where c1 <= 4 and not match(c3) against("uu") order by c1;
+select * from t1 where c1 > 4 and not match(c3) against("uu") order by c1;
+select * from t1 where c2 = 10 and not match(c3) against("uu") order by c1;
+select * from t1 where c2 >= 15 and not match(c3) against("uu") order by c1;
+select * from t1 where c2 < 15 and not match(c3) against("uu") order by c1;
drop table t1;
--source ../../include/mroonga/have_mroonga_deinit.inc
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_TODO_SPLIT_ME.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_TODO_SPLIT_ME.test
index 5361b151661..4835f3dcd99 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_TODO_SPLIT_ME.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/fulltext_order_TODO_SPLIT_ME.test
@@ -40,11 +40,7 @@ INSERT INTO ft VALUES(5,'eeeee','efghi');
SELECT a, b, c FROM ft WHERE MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE);
SELECT a, b, c FROM ft WHERE MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE) ORDER BY MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE);
-SELECT a, b, c FROM ft WHERE MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE) ORDER BY MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE);
SELECT a, b, c FROM ft WHERE MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE);
-SELECT a, b, c, MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE), MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE) FROM ft WHERE MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE) ORDER BY MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE);
-SELECT a, b, c, MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE), MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE) FROM ft WHERE MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE);
-SELECT a, b, c, MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE), MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE) FROM ft ORDER BY MATCH(c) AGAINST('bbbbb' IN BOOLEAN MODE), MATCH(b) AGAINST('bbbbb' IN BOOLEAN MODE), a;
DROP TABLE ft;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/truncate.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/truncate.test
index 987fd284f74..8723a882ae9 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/truncate.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/truncate.test
@@ -1,4 +1,4 @@
-# Copyright(C) 2011-2012 Kouhei Sutou <kou@clear-code.com>
+# Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -39,17 +39,23 @@ INSERT INTO diaries VALUES(2, 2011, 11, 10, "天気", "明日ã®å¯Œå£«å±±ã®å¤©æ
INSERT INTO diaries VALUES(3, 2011, 11, 11, "富士山", "今日も天気ãŒã‚ˆãã¦ãã‚Œã„ã«è¦‹ãˆã‚‹ã€‚");
SELECT * FROM diaries;
-SELECT * FROM diaries WHERE MATCH(content) AGAINST("今日 天気" IN BOOLEAN MODE);
+SELECT * FROM diaries
+ WHERE MATCH(content) AGAINST("+今日" IN BOOLEAN MODE)
+ ORDER BY id;
TRUNCATE TABLE diaries;
SELECT * FROM diaries;
-SELECT * FROM diaries WHERE MATCH(content) AGAINST("今日 天気" IN BOOLEAN MODE);
+SELECT * FROM diaries
+ WHERE MATCH(content) AGAINST("+今日" IN BOOLEAN MODE)
+ ORDER BY id;
INSERT INTO diaries VALUES(1, 2011, 11, 11, "帰りé“", "ã¤ã‹ã‚ŒãŸãƒ¼");
INSERT INTO diaries VALUES(2, 2011, 12, 1, "ä¹…ã—ã¶ã‚Š", "天気ãŒæ‚ªã„ã‹ã‚‰ãšã£ã¨ç•™å®ˆç•ªã€‚");
INSERT INTO diaries VALUES(3, 2011, 12, 2, "åˆé›ª", "今年ã¯ã˜ã‚ã¦ã®é›ªï¼");
SELECT * FROM diaries;
-SELECT * FROM diaries WHERE MATCH(content) AGAINST("悪ã„" IN BOOLEAN MODE);
+SELECT * FROM diaries
+ WHERE MATCH(content) AGAINST("+悪ã„" IN BOOLEAN MODE)
+ ORDER BY id;
DROP TABLE diaries;
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_global.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_global.test
index 065b78d44a7..9704d2d3e53 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_global.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_global.test
@@ -15,7 +15,6 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--source include/have_innodb.inc
---source ../../include/mroonga/have_fulltext_index_comment.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_session.test b/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_session.test
index b47dcef3967..c6967790b01 100644
--- a/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_session.test
+++ b/storage/mroonga/mysql-test/mroonga/wrapper/t/variable_match_escalation_threshold_session.test
@@ -15,7 +15,6 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--source include/have_innodb.inc
---source ../../include/mroonga/have_fulltext_index_comment.inc
--source ../../include/mroonga/have_mroonga.inc
--disable_warnings
diff --git a/storage/mroonga/packages/apt/build-deb.sh b/storage/mroonga/packages/apt/build-deb.sh
index 7db24068a7c..510886cb24f 100755
--- a/storage/mroonga/packages/apt/build-deb.sh
+++ b/storage/mroonga/packages/apt/build-deb.sh
@@ -27,8 +27,8 @@ case "${distribution}" in
debian)
component=main
run cat <<EOF > /etc/apt/sources.list.d/groonga.list
-deb http://packages.groonga.org/debian/ wheezy main
-deb-src http://packages.groonga.org/debian/ wheezy main
+deb http://packages.groonga.org/debian/ ${code_name} main
+deb-src http://packages.groonga.org/debian/ ${code_name} main
EOF
if ! grep --quiet security /etc/apt/sources.list; then
run cat <<EOF > /etc/apt/sources.list.d/security.list
@@ -75,4 +75,4 @@ run cd -
package_initial=$(echo "${PACKAGE}" | sed -e 's/\(.\).*/\1/')
pool_dir="/vagrant/repositories/${distribution}/pool/${code_name}/${component}/${package_initial}/${PACKAGE}"
run mkdir -p "${pool_dir}/"
-run cp *.tar.gz *.diff.gz *.dsc *.deb "${pool_dir}/"
+run cp *.tar.* *.diff.gz *.dsc *.deb "${pool_dir}/"
diff --git a/storage/mroonga/packages/debian/changelog b/storage/mroonga/packages/debian/changelog
index d3025d96100..366edca7b4e 100644
--- a/storage/mroonga/packages/debian/changelog
+++ b/storage/mroonga/packages/debian/changelog
@@ -1,3 +1,15 @@
+mroonga (5.04-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Masafumi Yokoyama <myokoym@gmail.com> Mon, 29 Jun 2015 00:00:00 +0900
+
+mroonga (5.03-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- HAYASHI Kentaro <hayashi@clear-code.com> Fri, 29 May 2015 00:00:00 +0900
+
mroonga (5.02-1) unstable; urgency=low
* New upstream release.
diff --git a/storage/mroonga/packages/rpm/centos/mariadb-mroonga.spec.in b/storage/mroonga/packages/rpm/centos/mariadb-mroonga.spec.in
index ca48e59aaec..04d1c41f2cc 100644
--- a/storage/mroonga/packages/rpm/centos/mariadb-mroonga.spec.in
+++ b/storage/mroonga/packages/rpm/centos/mariadb-mroonga.spec.in
@@ -154,6 +154,12 @@ fi
%doc mysql-mroonga-doc/*
%changelog
+* Mon Jun 29 2015 Masafumi Yokoyama <myokoym@gmail.com> - 5.04-1
+- new upstream release.
+
+* Fri May 29 2015 HAYASHI Kentaro <hayashi@clear-code.com> - 5.03-1
+- new upstream release.
+
* Wed Apr 29 2015 HAYASHI Kentaro <hayashi@clear-code.com> - 5.02-1
- new upstream release.
diff --git a/storage/mroonga/packages/rpm/centos/mysql55-mroonga.spec.in b/storage/mroonga/packages/rpm/centos/mysql55-mroonga.spec.in
index 1fc641b9bca..e20e1b32162 100644
--- a/storage/mroonga/packages/rpm/centos/mysql55-mroonga.spec.in
+++ b/storage/mroonga/packages/rpm/centos/mysql55-mroonga.spec.in
@@ -163,6 +163,12 @@ fi
%doc mysql-mroonga-doc/*
%changelog
+* Mon Jun 29 2015 Masafumi Yokoyama <myokoym@gmail.com> - 5.04-1
+- new upstream release.
+
+* Fri May 29 2015 HAYASHI Kentaro <hayashi@clear-code.com> - 5.03-1
+- new upstream release.
+
* Wed Apr 29 2015 HAYASHI Kentaro <hayashi@clear-code.com> - 5.02-1
- new upstream release.
diff --git a/storage/mroonga/packages/rpm/centos/mysql56-community-mroonga.spec.in b/storage/mroonga/packages/rpm/centos/mysql56-community-mroonga.spec.in
index 53759e0c778..f3233d17afe 100644
--- a/storage/mroonga/packages/rpm/centos/mysql56-community-mroonga.spec.in
+++ b/storage/mroonga/packages/rpm/centos/mysql56-community-mroonga.spec.in
@@ -1,14 +1,14 @@
%{!?centos_ver:%define centos_ver 6}
%if %{centos_ver} == 7
-%define mysql_version_default 5.6.24
-%define mysql_release_default 3
+%define mysql_version_default 5.6.25
+%define mysql_release_default 2
%define mysql_dist_default el7
%define mysql_download_base_url_default http://repo.mysql.com/yum/mysql-5.6-community/el/7/SRPMS
%define mysql_spec_file_default mysql.spec
%else
-%define mysql_version_default 5.6.24
-%define mysql_release_default 3
+%define mysql_version_default 5.6.25
+%define mysql_release_default 2
%define mysql_dist_default el6
%define mysql_download_base_url_default http://repo.mysql.com/yum/mysql-5.6-community/el/6/SRPMS
%define mysql_spec_file_default mysql.spec
@@ -77,7 +77,10 @@ if [ ! -d ${mysql_source} ]; then
--define 'optflags -O0' \
../../SPECS/%{mysql_spec_file}
fi
-%configure --disable-static --with-mysql-source=${mysql_source} \
+%configure \
+ --disable-static \
+ --with-mysql-source=${mysql_source} \
+ --enable-fast-mutexes \
%{?mroonga_configure_options}
make %{?_smp_mflags}
@@ -91,6 +94,13 @@ mv $RPM_BUILD_ROOT%{_datadir}/doc/mroonga/ mysql-mroonga-doc/
rm -rf $RPM_BUILD_ROOT
%post
+if ! /sbin/service mysqld status > /dev/null; then
+ /sbin/service mysqld start
+ stop_after_installation=1
+else
+ stop_after_installation=0
+fi
+
mysql_command=`which mysql`
password_option=""
$mysql_command -u root -e "quit"
@@ -129,7 +139,18 @@ eval $command || \
(echo "run the following command to register Mroonga:"; \
echo " $command")
+if [ "$stop_after_installation" = "1" ]; then
+ /sbin/service mysqld stop
+fi
+
%preun
+if ! /sbin/service mysqld status > /dev/null; then
+ /sbin/service mysqld start
+ stop_after_uninstallation=1
+else
+ stop_after_uninstallation=0
+fi
+
uninstall_sql=%{_datadir}/mroonga/uninstall.sql
mysql_command=`which mysql`
if $mysql_command -u root -e "quit"; then
@@ -145,6 +166,10 @@ if [ "$1" = 0 ]; then
echo " $command")
fi
+if [ "$stop_after_uninstallation" = "1" ]; then
+ /sbin/service mysqld stop
+fi
+
%files
%defattr(-,root,root,-)
%{_libdir}/mysql/plugin/
@@ -158,6 +183,15 @@ fi
%doc mysql-mroonga-doc/*
%changelog
+* Mon Jun 29 2015 Masafumi Yokoyama <myokoym@gmail.com> - 5.04-1
+- new upstream release.
+
+* Thu Jun 02 2015 Masafumi Yokoyama <yokoyama@clear-code.com> - 5.03-2
+- build against MySQL 5.6.25.
+
+* Fri May 29 2015 HAYASHI Kentaro <hayashi@clear-code.com> - 5.03-1
+- new upstream release.
+
* Wed Apr 29 2015 HAYASHI Kentaro <hayashi@clear-code.com> - 5.02-1
- new upstream release.
diff --git a/storage/mroonga/packages/rpm/centos/percona-server-56-mroonga.spec.in b/storage/mroonga/packages/rpm/centos/percona-server-56-mroonga.spec.in
index f0306cace24..cf1947e2676 100644
--- a/storage/mroonga/packages/rpm/centos/percona-server-56-mroonga.spec.in
+++ b/storage/mroonga/packages/rpm/centos/percona-server-56-mroonga.spec.in
@@ -1,7 +1,7 @@
%{!?centos_ver:%define centos_ver 6}
-%define mysql_version_default 5.6.23
-%define mysql_release_default rel72.1
+%define mysql_version_default 5.6.24
+%define mysql_release_default rel72.2
%define mysql_dist_default %{?dist}
%define mysql_download_base_url_default http://repo.percona.com/centos/%{centos_ver}/SRPMS
%define mysql_spec_file_default percona-server.spec
@@ -85,6 +85,13 @@ mv $RPM_BUILD_ROOT%{_datadir}/doc/mroonga/ mysql-mroonga-doc/
rm -rf $RPM_BUILD_ROOT
%post
+if ! /sbin/service mysql status > /dev/null; then
+ /sbin/service mysql start
+ stop_after_installation=1
+else
+ stop_after_installation=0
+fi
+
mysql_command=`which mysql`
password_option=""
$mysql_command -u root -e "quit"
@@ -123,7 +130,18 @@ eval $command || \
(echo "run the following command to register Mroonga:"; \
echo " $command")
+if [ "$stop_after_installation" = "1" ]; then
+ /sbin/service mysql stop
+fi
+
%preun
+if ! /sbin/service mysql status > /dev/null; then
+ /sbin/service mysql start
+ stop_after_uninstallation=1
+else
+ stop_after_uninstallation=0
+fi
+
uninstall_sql=%{_datadir}/mroonga/uninstall.sql
mysql_command=`which mysql`
if $mysql_command -u root -e "quit"; then
@@ -139,6 +157,10 @@ if [ "$1" = 0 ]; then
echo " $command")
fi
+if [ "$stop_after_uninstallation" = "1" ]; then
+ /sbin/service mysql stop
+fi
+
%files
%defattr(-,root,root,-)
%{_libdir}/mysql/plugin/
diff --git a/storage/mroonga/packages/source/Makefile.am b/storage/mroonga/packages/source/Makefile.am
index 0f242c4e038..143f5d0387e 100644
--- a/storage/mroonga/packages/source/Makefile.am
+++ b/storage/mroonga/packages/source/Makefile.am
@@ -1,17 +1,17 @@
MROONGA_BASE = $(PACKAGE)-$(VERSION)
MROONGA_TAR_GZ = $(MROONGA_BASE).tar.gz
-GROONGA_VERSION = 5.0.3
+GROONGA_VERSION = 5.0.5
GROONGA_BASE = groonga-$(GROONGA_VERSION)
GROONGA_TAR_GZ = $(GROONGA_BASE).tar.gz
-GROONGA_NORMALIZER_MYSQL_VERSION = 1.0.9
+GROONGA_NORMALIZER_MYSQL_VERSION = 1.1.0
GROONGA_NORMALIZER_MYSQL_BASE = \
groonga-normalizer-mysql-$(GROONGA_NORMALIZER_MYSQL_VERSION)
GROONGA_NORMALIZER_MYSQL_TAR_GZ = \
$(GROONGA_NORMALIZER_MYSQL_BASE).tar.gz
-MARIADB_VERSION = 10.0.17
+MARIADB_VERSION = 10.0.20
MARIADB_BASE = mariadb-$(MARIADB_VERSION)
MARIADB_TAR_GZ = $(MARIADB_BASE).tar.gz
diff --git a/storage/mroonga/packages/ubuntu/upload.rb b/storage/mroonga/packages/ubuntu/upload.rb
index 79331a06c8d..8743520b5ac 100755
--- a/storage/mroonga/packages/ubuntu/upload.rb
+++ b/storage/mroonga/packages/ubuntu/upload.rb
@@ -127,8 +127,8 @@ allow_unsigned_uploads = 0
case code_name
when "vivid"
run_command("sed",
- "-i", "-e", "s,5\.5,5\.6,g",
- "debian/rules")
+ "-i", "-e", "s,5\\.5,5.6,g",
+ "debian/rules")
end
run_command("sed",
"-i", "-e", "s,MYSQL_VERSION,#{@mysql_version[code_name]},",
diff --git a/storage/mroonga/packages/yum/sign-rpm.sh b/storage/mroonga/packages/yum/sign-rpm.sh
index b3a45afe7f5..27ec5711010 100755
--- a/storage/mroonga/packages/yum/sign-rpm.sh
+++ b/storage/mroonga/packages/yum/sign-rpm.sh
@@ -24,7 +24,7 @@ run()
unsigned_rpms()
{
while read rpm; do
- rpm --checksig "$rpm" | grep -v 'gpg OK' | cut -d":" -f1
+ rpm --checksig "$rpm" | grep -v 'gpg OK' | grep -v 'MISSING KEYS' | cut -d":" -f1
done
}
diff --git a/storage/mroonga/plugin_version b/storage/mroonga/plugin_version
index 341d0b550fd..48c32b26a12 100644
--- a/storage/mroonga/plugin_version
+++ b/storage/mroonga/plugin_version
@@ -1 +1 @@
-5.2 \ No newline at end of file
+5.4 \ No newline at end of file
diff --git a/storage/mroonga/tools/travis/before_script.sh b/storage/mroonga/tools/travis/before_script.sh
index 7d4d7dcec5f..1b3ba158675 100755
--- a/storage/mroonga/tools/travis/before_script.sh
+++ b/storage/mroonga/tools/travis/before_script.sh
@@ -20,9 +20,26 @@
set -e
if [ "${MROONGA_BUNDLED}" = "yes" ]; then
- cmake_args=(-DCMAKE_BUILD_TYPE=Debug)
+ cmake_args=(-DCMAKE_BUILD_TYPE=Debug -DWITH_UNIT_TESTS=FALSE)
+ cmake_args=("${cmake_args[@]}" -DWITH_EMBEDDED_SERVER=TRUE)
+ cmake_args=("${cmake_args[@]}" -DWITHOUT_ARCHIVE=TRUE)
+ cmake_args=("${cmake_args[@]}" -DWITHOUT_BLACKHOLE=TRUE)
+ cmake_args=("${cmake_args[@]}" -DWITHOUT_CASSANDRA=TRUE)
+ cmake_args=("${cmake_args[@]}" -DWITHOUT_CONNECT=TRUE)
+ cmake_args=("${cmake_args[@]}" -DWITHOUT_CSV=TRUE)
+ cmake_args=("${cmake_args[@]}" -DWITHOUT_EXAMPLE=TRUE)
+ cmake_args=("${cmake_args[@]}" -DWITHOUT_FEDERATED=TRUE)
+ cmake_args=("${cmake_args[@]}" -DWITHOUT_FEDERATEDX=TRUE)
+ cmake_args=("${cmake_args[@]}" -DWITHOUT_HEAP=TRUE)
+ cmake_args=("${cmake_args[@]}" -DWITHOUT_MYISAMMRG=TRUE)
+ cmake_args=("${cmake_args[@]}" -DWITHOUT_OQGRAPH=TRUE)
+ cmake_args=("${cmake_args[@]}" -DWITHOUT_SEQUENCE=TRUE)
+ cmake_args=("${cmake_args[@]}" -DWITHOUT_SPHINX=TRUE)
+ cmake_args=("${cmake_args[@]}" -DWITHOUT_SPIDER=TRUE)
+ cmake_args=("${cmake_args[@]}" -DWITHOUT_TEST_SQL_DISCOVERY=TRUE)
+ cmake_args=("${cmake_args[@]}" -DWITHOUT_TOKUDB=TRUE)
if [ "${MROONGA_TEST_EMBEDDED}" = "yes" ]; then
- cmake_args=("${cmake_args[@]}" "-DWITH_EMBEDDED_SERVER=TRUE")
+ cmake_args=("${cmake_args[@]}" -DWITH_EMBEDDED_SERVER=TRUE)
fi
cmake . "${cmake_args[@]}"
else
@@ -31,6 +48,10 @@ else
if [ -d /opt/mysql/ ]; then
PATH=$(echo /opt/mysql/server-*/bin/):$PATH
fi
- ./configure \
- --with-mysql-source=$PWD/vendor/mysql
+ configure_args=("--with-mysql-source=$PWD/vendor/mysql")
+ if [ "${MYSQL_VERSION}" = "mysql-5.6.25" ]; then
+ configure_args=("${configure_args[@]}" --enable-fast-mutexes)
+ fi
+ ./configure "${configure_args[@]}"
+ cat "$(mysql_config --include | sed -e 's/-I//g')/my_config.h"
fi
diff --git a/storage/mroonga/tools/travis/script.sh b/storage/mroonga/tools/travis/script.sh
index 6ea5c86068b..d8dd188f1f2 100755
--- a/storage/mroonga/tools/travis/script.sh
+++ b/storage/mroonga/tools/travis/script.sh
@@ -32,7 +32,11 @@ else
fi
n_processors="$(grep '^processor' /proc/cpuinfo | wc -l)"
-max_n_processors=8
+if [ "${MROONGA_BUNDLED}" = "yes" ]; then
+ max_n_processors=2
+else
+ max_n_processors=4
+fi
if (( $n_processors > $max_n_processors )); then
n_processors=$max_n_processors
fi
@@ -98,6 +102,14 @@ run_sql_test()
fi
if [ "${MROONGA_BUNDLED}" = "yes" ]; then
+ # Plugins aren't supported.
+ cd ${mroonga_dir}/mysql-test/mroonga/storage
+ rm -rf alter_table/add_index/token_filters/
+ rm -rf alter_table/t/change_token_filter.test
+ rm -rf create/table/token_filters/
+ rm -rf fulltext/token_filters/
+ cd -
+
${mroonga_dir}/test/run-sql-test.sh \
"${test_args[@]}" \
--parallel="${n_processors}"
diff --git a/storage/mroonga/vendor/groonga/CMakeLists.txt b/storage/mroonga/vendor/groonga/CMakeLists.txt
index f1ca174ed50..ebe7f6b7fe5 100644
--- a/storage/mroonga/vendor/groonga/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/CMakeLists.txt
@@ -168,7 +168,7 @@ macro(check_build_flag flag)
check_cxxflag(${flag})
endmacro()
-if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGCXX)
+if(CMAKE_COMPILER_IS_GNUCXX)
check_build_flag("-Wall")
check_build_flag("-Wextra")
check_build_flag("-Wno-unused-but-set-variable")
@@ -185,7 +185,7 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGCXX)
check_cflag("-Wdeclaration-after-statement")
check_cflag("-Wbad-function-cast")
check_build_flag("-Wcast-align")
- check_build_flag("-Wredundant-decls")
+ # check_build_flag("-Wredundant-decls")
check_build_flag("-Wwrite-strings")
check_cxxflag("-fexceptions")
check_cxxflag("-fimplicit-templates")
@@ -201,7 +201,7 @@ endif()
option(GRN_WITH_DEBUG "enable debug build." OFF)
if(GRN_WITH_DEBUG)
- if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGCXX)
+ if(CMAKE_COMPILER_IS_GNUCXX)
set(GRN_C_COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS} -g3 -O0")
set(GRN_CXX_COMPILE_FLAGS "${GRN_CXX_COMPILE_FLAGS} -g3 -O0")
endif()
@@ -210,6 +210,9 @@ endif()
add_definitions(
-DHAVE_CONFIG_H
)
+if(GRN_EMBED)
+ add_definitions(-DGRN_EMBEDDED)
+endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGCXX)
set(_GNU_SOURCE TRUE)
@@ -556,6 +559,9 @@ endif()
add_definitions(-DONIG_EXTERN=extern)
add_subdirectory(vendor)
+if(GRN_EMBED)
+ add_subdirectory(plugins)
+endif()
add_subdirectory(lib)
if(NOT GRN_EMBED)
add_subdirectory(src)
diff --git a/storage/mroonga/vendor/groonga/base_version b/storage/mroonga/vendor/groonga/base_version
index 26611488b0a..25b08bbc78f 100644
--- a/storage/mroonga/vendor/groonga/base_version
+++ b/storage/mroonga/vendor/groonga/base_version
@@ -1 +1 @@
-5.0.3 \ No newline at end of file
+5.0.5 \ No newline at end of file
diff --git a/storage/mroonga/vendor/groonga/bindings/php/groonga.c b/storage/mroonga/vendor/groonga/bindings/php/groonga.c
index b92cc1a2385..a04bb9cd42f 100644
--- a/storage/mroonga/vendor/groonga/bindings/php/groonga.c
+++ b/storage/mroonga/vendor/groonga/bindings/php/groonga.c
@@ -101,6 +101,9 @@ PHP_FUNCTION(grn_ctx_init)
long flags = 0;
grn_rc rc;
+ if (ctx == NULL) {
+ RETURN_FALSE; // unable to allocate memory for ctx
+ }
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags) == FAILURE) {
return;
diff --git a/storage/mroonga/vendor/groonga/build/ac_macros/check_headers.m4 b/storage/mroonga/vendor/groonga/build/ac_macros/check_headers.m4
index 2a7e0f03acc..9a30ca8fc9c 100644
--- a/storage/mroonga/vendor/groonga/build/ac_macros/check_headers.m4
+++ b/storage/mroonga/vendor/groonga/build/ac_macros/check_headers.m4
@@ -5,14 +5,10 @@ AC_CHECK_HEADERS(dlfcn.h)
AC_CHECK_HEADERS(errno.h)
AC_CHECK_HEADERS(execinfo.h)
AC_CHECK_HEADERS(inttypes.h)
-AC_CHECK_HEADERS(io.h)
AC_CHECK_HEADERS(netdb.h)
-AC_CHECK_HEADERS(netinet/in.h)
-AC_CHECK_HEADERS(netinet/tcp.h)
AC_CHECK_HEADERS(signal.h)
AC_CHECK_HEADERS(stdarg.h)
AC_CHECK_HEADERS(stdint.h)
-AC_CHECK_HEADERS(stdlib.h)
AC_CHECK_HEADERS(string.h)
AC_CHECK_HEADERS(strings.h)
AC_CHECK_HEADERS(sys/mman.h)
@@ -21,7 +17,6 @@ AC_CHECK_HEADERS(sys/resource.h)
AC_CHECK_HEADERS(sys/socket.h)
AC_CHECK_HEADERS(sys/sysctl.h)
AC_CHECK_HEADERS(sys/time.h)
-AC_CHECK_HEADERS(sys/types.h)
AC_CHECK_HEADERS(sys/wait.h)
AC_CHECK_HEADERS(time.h)
AC_CHECK_HEADERS(ucontext.h)
diff --git a/storage/mroonga/vendor/groonga/config.h.cmake b/storage/mroonga/vendor/groonga/config.h.cmake
index cd8e4f6cc2d..8e3bdaf216b 100644
--- a/storage/mroonga/vendor/groonga/config.h.cmake
+++ b/storage/mroonga/vendor/groonga/config.h.cmake
@@ -14,7 +14,7 @@
#define PACKAGE_URL "${PACKAGE_URL}"
#define PACKAGE_VERSION "${VERSION}"
-/* groonga related constants */
+/* Groonga related constants */
#define GRN_CONFIG_PATH "${GRN_CONFIG_PATH}"
#define GRN_LOG_PATH "${GRN_LOG_PATH}"
#define GRN_VERSION "${GRN_VERSION}"
@@ -98,17 +98,13 @@
#cmakedefine HAVE_ERRNO_H
#cmakedefine HAVE_EXECINFO_H
#cmakedefine HAVE_INTTYPES_H
-#cmakedefine HAVE_IO_H
#cmakedefine HAVE_LINUX_FUTEX_H
#cmakedefine HAVE_MEMORY_H
#cmakedefine HAVE_NETDB_H
-#cmakedefine HAVE_NETINET_IN_H
-#cmakedefine HAVE_NETINET_TCP_H
#cmakedefine HAVE_PTHREAD_H
#cmakedefine HAVE_SIGNAL_H
#cmakedefine HAVE_STDARG_H
#cmakedefine HAVE_STDINT_H
-#cmakedefine HAVE_STDLIB_H
#cmakedefine HAVE_STRINGS_H
#cmakedefine HAVE_STRING_H
#cmakedefine HAVE_SYS_MMAN_H
@@ -120,7 +116,6 @@
#cmakedefine HAVE_SYS_SYSCALL_H
#cmakedefine HAVE_SYS_SYSCTL_H
#cmakedefine HAVE_SYS_TIME_H
-#cmakedefine HAVE_SYS_TYPES_H
#cmakedefine HAVE_SYS_WAIT_H
#cmakedefine HAVE_TIME_H
#cmakedefine HAVE_UCONTEXT_H
diff --git a/storage/mroonga/vendor/groonga/configure.ac b/storage/mroonga/vendor/groonga/configure.ac
index 17f3abcc2ed..dad29c78f4c 100644
--- a/storage/mroonga/vendor/groonga/configure.ac
+++ b/storage/mroonga/vendor/groonga/configure.ac
@@ -169,7 +169,7 @@ if test "$GCC" = "yes"; then
if test "$CLANG" = "no"; then
CHECK_BUILD_FLAG([-Wcast-align])
fi
- CHECK_BUILD_FLAG([-Wredundant-decls])
+# CHECK_BUILD_FLAG([-Wredundant-decls])
# CHECK_BUILD_FLAG([-Wunsafe-loop-optimizations])
# CHECK_BUILD_FLAG([-Wunreachable-code])
# CHECK_BUILD_FLAG([-Wswitch-enum])
@@ -1508,6 +1508,8 @@ AM_CONDITIONAL(WITH_SHARED_ONIGMO, test "$enable_shared_onigmo" = "yes")
# TODO: Support using system Onigmo instead of bundled Onigmo.
AC_DEFINE(GRN_WITH_ONIGMO, [1], [Use Onigmo.])
+GRN_WITH_ONIGMO="yes"
+AC_SUBST(GRN_WITH_ONIGMO)
AC_CONFIG_SUBDIRS([vendor/onigmo])
ONIGMO_CFLAGS="-I\$(top_srcdir)/vendor/onigmo-source"
diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/edict/edict2grn.rb b/storage/mroonga/vendor/groonga/examples/dictionary/edict/edict2grn.rb
index 664b12c2148..b795e25a50b 100755
--- a/storage/mroonga/vendor/groonga/examples/dictionary/edict/edict2grn.rb
+++ b/storage/mroonga/vendor/groonga/examples/dictionary/edict/edict2grn.rb
@@ -1,47 +1,23 @@
#!/usr/bin/env ruby
-# -*- coding: utf-8 -*-
-$KCODE = 'u'
+require "English"
+require "nkf"
+require "json"
-require 'English'
-require 'kconv'
-
-class String
- def to_json
- a = split(//).map {|char|
- case char
- when '"' then '\\"'
- when '\\' then '\\\\'
- when "\b" then '\b'
- when "\f" then '\f'
- when "\n" then '\n'
- when "\r" then ''
- when "\t" then '\t'
- else char
- end
- }
- "\"#{a.join('')}\""
- end
-end
-
-class Array
- def to_json
- '[' + map {|element|
- element.to_json
- }.join(',') + ']'
- end
-end
-
-puts <<END
+print(<<HEADER.chomp)
column_create item_dictionary edict_desc COLUMN_SCALAR ShortText
column_create bigram item_dictionary_edict_desc COLUMN_INDEX|WITH_POSITION item_dictionary edict_desc
load --table item_dictionary
-[["_key","edict_desc","kana"],
-END
+[
+["_key","edict_desc","kana"]
+HEADER
+
+loop do
+ raw_line = gets
+ break if raw_line.nil?
-while !STDIN.eof?
- line = Kconv.toutf8(gets)
- key, body = line.strip.split('/', 2)
+ line = raw_line.encode("UTF-8", "EUC-JP")
+ key, body = line.strip.split("/", 2)
key = key.strip
if /\s*\[(.+)\]\z/ =~ key
key = $PREMATCH
@@ -51,6 +27,8 @@ while !STDIN.eof?
else
kana = NKF.nkf("-Ww --katakana", key)
end
- puts [key, body, kana].to_json
+ puts(",")
+ puts([key, body, kana].to_json)
end
-puts ']'
+puts
+puts("]")
diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/gene95/gene2grn.rb b/storage/mroonga/vendor/groonga/examples/dictionary/gene95/gene2grn.rb
index 0d10cfd1085..c9d9a593b11 100755
--- a/storage/mroonga/vendor/groonga/examples/dictionary/gene95/gene2grn.rb
+++ b/storage/mroonga/vendor/groonga/examples/dictionary/gene95/gene2grn.rb
@@ -1,46 +1,33 @@
#!/usr/bin/env ruby
-# -*- coding: utf-8 -*-
-$KCODE = 'u'
+require "json"
-require 'kconv'
-
-class String
- def to_json
- a = split(//).map {|char|
- case char
- when '"' then '\\"'
- when '\\' then '\\\\'
- when "\b" then '\b'
- when "\f" then '\f'
- when "\n" then '\n'
- when "\r" then ''
- when "\t" then '\t'
- else char
- end
- }
- "\"#{a.join('')}\""
- end
-end
-
-class Array
- def to_json
- '[' + map {|element|
- element.to_json
- }.join(',') + ']'
- end
-end
-
-puts <<END
+print(<<HEADER.chomp)
column_create item_dictionary gene95_desc COLUMN_SCALAR ShortText
column_create bigram item_dictionary_gene95_desc COLUMN_INDEX|WITH_POSITION item_dictionary gene95_desc
load --table item_dictionary
-[["_key","gene95_desc"],
-END
+[
+["_key","gene95_desc"]
+HEADER
-while !STDIN.eof?
- key = Kconv.toutf8(gets.strip)
- body = Kconv.toutf8(gets.strip)
- puts [key, body].to_json
+loop do
+ raw_key = gets
+ break if raw_key.nil?
+ raw_body = gets
+
+ key = nil
+ body = nil
+ begin
+ key = raw_key.encode("UTF-8", "Windows-31J").strip
+ body = raw_body.encode("UTF-8", "Windows-31J").strip
+ rescue EncodingError
+ $stderr.puts("Ignore:")
+ $stderr.puts(" key: <#{raw_key}>")
+ $stderr.puts(" body: <#{raw_body}>")
+ next
+ end
+ puts(",")
+ print([key, body].to_json)
end
-puts ']'
+puts
+puts("]")
diff --git a/storage/mroonga/vendor/groonga/groonga-httpd-conf.sh.in b/storage/mroonga/vendor/groonga/groonga-httpd-conf.sh.in
index 380495bb391..73b8867eafa 100644
--- a/storage/mroonga/vendor/groonga/groonga-httpd-conf.sh.in
+++ b/storage/mroonga/vendor/groonga/groonga-httpd-conf.sh.in
@@ -25,4 +25,6 @@ export GROONGA_HTTPD_DEBUG="@grn_debug@"
export GROONGA_HTTPD_WITH_PCRE="@GRN_WITH_PCRE@"
export GROONGA_HTTPD_PCRE_CFLAGS="@PCRE_CFLAGS@"
export GROONGA_HTTPD_PCRE_LIBS_ONLY_L="@PCRE_LIBS_ONLY_L@"
+export GROONGA_HTTPD_WITH_ONIGMO="@GRN_WITH_ONIGMO@"
+export GROONGA_HTTPD_ONIGMO_IN_TREE_LINK_PATH="@abs_top_builddir@/vendor/onigmo-source/.libs"
export GROONGA_HTTPD_WITH_ZLIB="@GRN_WITH_ZLIB@"
diff --git a/storage/mroonga/vendor/groonga/include/groonga/command.h b/storage/mroonga/vendor/groonga/include/groonga/command.h
index 101956a04f9..ac5270e9798 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/command.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/command.h
@@ -43,6 +43,8 @@ GRN_PLUGIN_EXPORT grn_obj *grn_command_input_get(grn_ctx *ctx,
GRN_PLUGIN_EXPORT grn_obj *grn_command_input_at(grn_ctx *ctx,
grn_command_input *input,
unsigned int offset);
+GRN_PLUGIN_EXPORT grn_obj *grn_command_input_get_arguments(grn_ctx *ctx,
+ grn_command_input *input);
typedef void grn_command_run_func(grn_ctx *ctx,
grn_obj *command,
diff --git a/storage/mroonga/vendor/groonga/include/groonga/groonga.h b/storage/mroonga/vendor/groonga/include/groonga/groonga.h
index 6f2aae79c01..14b21bda05c 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/groonga.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/groonga.h
@@ -907,6 +907,8 @@ GRN_API grn_rc grn_obj_lock(grn_ctx *ctx, grn_obj *obj, grn_id id, int timeout);
GRN_API grn_rc grn_obj_unlock(grn_ctx *ctx, grn_obj *obj, grn_id id);
GRN_API grn_rc grn_obj_clear_lock(grn_ctx *ctx, grn_obj *obj);
GRN_API unsigned int grn_obj_is_locked(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_rc grn_obj_flush(grn_ctx *ctx, grn_obj *obj);
+GRN_API grn_rc grn_obj_flush_recursive(grn_ctx *ctx, grn_obj *obj);
GRN_API int grn_obj_defrag(grn_ctx *ctx, grn_obj *obj, int threshold);
GRN_API grn_obj *grn_obj_db(grn_ctx *ctx, grn_obj *obj);
diff --git a/storage/mroonga/vendor/groonga/include/groonga/plugin.h b/storage/mroonga/vendor/groonga/include/groonga/plugin.h
index bbd8923e5d6..98ca6961407 100644
--- a/storage/mroonga/vendor/groonga/include/groonga/plugin.h
+++ b/storage/mroonga/vendor/groonga/include/groonga/plugin.h
@@ -55,6 +55,11 @@ GRN_PLUGIN_EXPORT grn_rc GRN_PLUGIN_INIT(grn_ctx *ctx);
GRN_PLUGIN_EXPORT grn_rc GRN_PLUGIN_REGISTER(grn_ctx *ctx);
GRN_PLUGIN_EXPORT grn_rc GRN_PLUGIN_FIN(grn_ctx *ctx);
+#define GRN_PLUGIN_DECLARE_FUNCTIONS(tag) \
+ extern grn_rc GRN_PLUGIN_IMPL_NAME_TAGGED(init, tag)(grn_ctx *ctx); \
+ extern grn_rc GRN_PLUGIN_IMPL_NAME_TAGGED(register, tag)(grn_ctx *ctx); \
+ extern grn_rc GRN_PLUGIN_IMPL_NAME_TAGGED(fin, tag)(grn_ctx *ctx)
+
/*
Don't call these functions directly. Use GRN_PLUGIN_MALLOC(),
GRN_PLUGIN_REALLOC() and GRN_PLUGIN_FREE() instead.
diff --git a/storage/mroonga/vendor/groonga/lib/CMakeLists.txt b/storage/mroonga/vendor/groonga/lib/CMakeLists.txt
index 8959f883ca3..45b2c923635 100644
--- a/storage/mroonga/vendor/groonga/lib/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/lib/CMakeLists.txt
@@ -36,7 +36,7 @@ string(REGEX REPLACE "([^;]+)" "mrb/\\1"
set_source_files_properties(${LIBGROONGA_SOURCES} ${LIBGRNMRB_SOURCES}
PROPERTIES
COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
-set_source_files_properties(dat.cpp ${LIBGRNDAT_SOURCES}
+set_source_files_properties(dat.cpp egn.cpp ${LIBGRNDAT_SOURCES}
PROPERTIES
COMPILE_FLAGS "${GRN_CXX_COMPILE_FLAGS}")
@@ -67,9 +67,14 @@ set(GRN_ALL_LIBRARIES
${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})
+ ${STDCPP_LIBS}
+ ${GRN_EMBEDDED_PLUGIN_LIBRARIES})
else()
target_link_libraries(libgroonga
${GRN_ALL_LIBRARIES})
diff --git a/storage/mroonga/vendor/groonga/lib/com.c b/storage/mroonga/vendor/groonga/lib/com.c
index eb1cacfd4c1..a7450ec31f0 100644
--- a/storage/mroonga/vendor/groonga/lib/com.c
+++ b/storage/mroonga/vendor/groonga/lib/com.c
@@ -22,20 +22,17 @@
#include "grn_ctx_impl.h"
#ifdef WIN32
-# include <ws2tcpip.h>
+# include <ws2tcpip.h>
#else
-# ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-# endif /* HAVE_SYS_SOCKET_H */
-# ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-# endif /* HAVE_NETINET_IN_H */
-# ifdef HAVE_NETINET_TCP_H
-# include <netinet/tcp.h>
-# endif /* HAVE_NETINET_TCP_H */
-# ifdef HAVE_SIGNAL_H
-# include <signal.h>
-# endif /* HAVE_SIGNAL_H */
+# 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"
@@ -736,13 +733,11 @@ grn_com_send(grn_ctx *ctx, grn_com *cs,
#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.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_flags = 0;
msg_iov[0].iov_base = header;
msg_iov[0].iov_len = sizeof(grn_com_header);
msg_iov[1].iov_base = (char *)body;
diff --git a/storage/mroonga/vendor/groonga/lib/command.c b/storage/mroonga/vendor/groonga/lib/command.c
index e4be0d1ff92..282d15b6a0e 100644
--- a/storage/mroonga/vendor/groonga/lib/command.c
+++ b/storage/mroonga/vendor/groonga/lib/command.c
@@ -129,6 +129,14 @@ grn_command_input_at(grn_ctx *ctx,
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,
diff --git a/storage/mroonga/vendor/groonga/lib/ctx.c b/storage/mroonga/vendor/groonga/lib/ctx.c
index 85878036dc2..92caba561eb 100644
--- a/storage/mroonga/vendor/groonga/lib/ctx.c
+++ b/storage/mroonga/vendor/groonga/lib/ctx.c
@@ -21,22 +21,24 @@
#include "grn_request_canceler.h"
#include "grn_tokenizers.h"
#include "grn_ctx_impl.h"
+#include "grn_ii.h"
#include "grn_pat.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 <stdio.h>
#include <stdarg.h>
#include <time.h>
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif /* HAVE_NETINET_IN_H */
#ifdef WIN32
# include <share.h>
+#else /* WIN32 */
+# include <netinet/in.h>
#endif /* WIN32 */
#if defined(HAVE__LOCALTIME64_S) && defined(__GNUC__)
@@ -74,6 +76,30 @@ int grn_lock_timeout = GRN_LOCK_TIMEOUT;
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_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_proc_init_from_env();
+ grn_plugin_init_from_env();
+}
+
void
grn_sleep(uint32_t seconds)
{
@@ -621,14 +647,8 @@ grn_ctx_init_internal(grn_ctx *ctx, int flags)
// if (ctx->stat != GRN_CTX_FIN) { return GRN_INVALID_ARGUMENT; }
ERRCLR(ctx);
ctx->flags = flags;
- {
- 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) {
- ctx->flags |= GRN_CTX_PER_DB;
- }
+ if (grn_ctx_per_db) {
+ ctx->flags |= GRN_CTX_PER_DB;
}
if (ERRP(ctx, GRN_ERROR)) { return ctx->rc; }
ctx->stat = GRN_CTX_INITED;
@@ -821,6 +841,7 @@ grn_init(void)
{
grn_rc rc;
grn_ctx *ctx = &grn_gctx;
+ grn_init_from_env();
grn_logger_init();
grn_query_logger_init();
CRITICAL_SECTION_INIT(grn_glock);
@@ -898,12 +919,8 @@ grn_init(void)
return rc;
}
grn_ctx_impl_init(ctx);
- if ((rc = grn_io_init())) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "io initialize failed (%d)", rc);
- return rc;
- }
if ((rc = grn_plugins_init())) {
- GRN_LOG(ctx, GRN_LOG_ALERT, "plugins initialize failed (%d)", rc);
+ GRN_LOG(ctx, GRN_LOG_ALERT, "grn_plugins_init failed (%d)", rc);
return rc;
}
if ((rc = grn_normalizer_init())) {
@@ -1018,7 +1035,6 @@ grn_fin(void)
grn_tokenizers_fin();
grn_normalizer_fin();
grn_plugins_fin();
- grn_io_fin();
grn_ctx_fin(ctx);
grn_com_fin();
GRN_LOG(ctx, GRN_LOG_NOTICE, "grn_fin (%d)", alloc_count);
@@ -1535,7 +1551,6 @@ grn_ctx_send(grn_ctx *ctx, const char *str, unsigned int str_len, int flags)
goto exit;
} else {
grn_obj *expr = NULL;
- if (comment_command_p(str, str_len)) { goto output; };
if (ctx->impl->qe_next) {
grn_obj *val;
expr = ctx->impl->qe_next;
@@ -1546,6 +1561,7 @@ grn_ctx_send(grn_ctx *ctx, const char *str, unsigned int str_len, int flags)
}
grn_expr_exec(ctx, expr, 0);
} else {
+ if (comment_command_p(str, str_len)) { goto output; };
ctx->impl->mime_type = "application/json";
ctx->impl->output_type = GRN_CONTENT_JSON;
grn_timeval_now(ctx, &ctx->impl->tv);
@@ -2382,9 +2398,8 @@ grn_calloc_default(grn_ctx *ctx, size_t size, const char* file, int line, const
grn_alloc_info_add(res, file, line, func);
} else {
if (!(res = calloc(size, 1))) {
- MERR("calloc fail (%" GRN_FMT_LLU ")=%p (%s:%d) <%" GRN_FMT_LLU ">",
- (unsigned long long int)size, res, file, line,
- (unsigned long long int)alloc_count);
+ MERR("calloc fail (%" GRN_FMT_SIZE ")=%p (%s:%d) <%d>",
+ size, res, file, line, alloc_count);
} else {
GRN_ADD_ALLOC_COUNT(1);
grn_alloc_info_add(res, file, line, func);
diff --git a/storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c b/storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c
index 4c1a2a3b4f9..39a1aa17b86 100644
--- a/storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c
+++ b/storage/mroonga/vendor/groonga/lib/ctx_impl_mrb.c
@@ -18,9 +18,9 @@
#include "grn_ctx_impl.h"
-#ifdef GRN_WITH_MRUBY
-# include <string.h>
+#include <string.h>
+#ifdef GRN_WITH_MRUBY
# include "grn_ctx_impl_mrb.h"
# include "grn_mrb.h"
@@ -40,6 +40,10 @@
# 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_column.h"
# include "mrb/mrb_fixed_size_column.h"
# include "mrb/mrb_variable_size_column.h"
@@ -60,6 +64,23 @@
# 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)
@@ -125,6 +146,10 @@ grn_ctx_impl_mrb_init_bindings(grn_ctx *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_column_init(ctx);
grn_mrb_fixed_size_column_init(ctx);
grn_mrb_variable_size_column_init(ctx);
@@ -147,11 +172,7 @@ grn_ctx_impl_mrb_init_bindings(grn_ctx *ctx)
void
grn_ctx_impl_mrb_init(grn_ctx *ctx)
{
- char grn_mruby_enabled[GRN_ENV_BUFFER_SIZE];
- grn_getenv("GRN_MRUBY_ENABLED",
- grn_mruby_enabled,
- GRN_ENV_BUFFER_SIZE);
- if (grn_mruby_enabled[0] && strcmp(grn_mruby_enabled, "no") == 0) {
+ if (!grn_ctx_impl_mrb_mruby_enabled) {
ctx->impl->mrb.state = NULL;
ctx->impl->mrb.base_directory[0] = '\0';
ctx->impl->mrb.module = NULL;
@@ -162,7 +183,6 @@ grn_ctx_impl_mrb_init(grn_ctx *ctx)
ctx->impl->mrb.groonga.operator_class = NULL;
} else {
mrb_state *mrb;
-
mrb = mrb_open();
ctx->impl->mrb.state = mrb;
ctx->impl->mrb.base_directory[0] = '\0';
diff --git a/storage/mroonga/vendor/groonga/lib/dat.cpp b/storage/mroonga/vendor/groonga/lib/dat.cpp
index 60588d55710..51a84da2af9 100644
--- a/storage/mroonga/vendor/groonga/lib/dat.cpp
+++ b/storage/mroonga/vendor/groonga/lib/dat.cpp
@@ -1,5 +1,5 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011-2014 Brazil
+/* 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
@@ -1112,4 +1112,34 @@ grn_dat_repair(grn_ctx *ctx, grn_dat *dat)
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");
+ } else {
+ ERR(error_code, "grn::dat::Trie::flush failed");
+ }
+ return error_code;
+ }
+ }
+
+ return GRN_SUCCESS;
+}
+
} // extern "C"
diff --git a/storage/mroonga/vendor/groonga/lib/dat/file-impl.cpp b/storage/mroonga/vendor/groonga/lib/dat/file-impl.cpp
index 3643a806292..7a9879aa369 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/file-impl.cpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/file-impl.cpp
@@ -1,5 +1,5 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/* 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
@@ -123,6 +123,15 @@ void FileImpl::swap(FileImpl *rhs) {
std::swap(addr_, rhs->addr_);
}
+void FileImpl::flush() {
+ if (!addr_) {
+ return;
+ }
+
+ BOOL succeeded = ::FlushViewOfFile(addr_, size_);
+ 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,
@@ -193,6 +202,15 @@ void FileImpl::swap(FileImpl *rhs) {
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()));
diff --git a/storage/mroonga/vendor/groonga/lib/dat/file-impl.hpp b/storage/mroonga/vendor/groonga/lib/dat/file-impl.hpp
index f4e0543635a..245dbfc2ae7 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/file-impl.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/file-impl.hpp
@@ -1,5 +1,5 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011-2012 Brazil
+/* 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
@@ -45,6 +45,8 @@ class FileImpl {
void swap(FileImpl *rhs);
+ void flush();
+
private:
void *ptr_;
UInt64 size_;
diff --git a/storage/mroonga/vendor/groonga/lib/dat/file.cpp b/storage/mroonga/vendor/groonga/lib/dat/file.cpp
index 57bfcb9ece6..82d6159ed09 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/file.cpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/file.cpp
@@ -1,5 +1,5 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/* 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
@@ -63,5 +63,11 @@ void File::swap(File *rhs) {
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
index c2be8d86da3..e7dda0e025e 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/file.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/file.hpp
@@ -1,5 +1,5 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/* 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
@@ -46,6 +46,8 @@ class GRN_DAT_API File {
void swap(File *rhs);
+ void flush();
+
private:
FileImpl *impl_;
diff --git a/storage/mroonga/vendor/groonga/lib/dat/trie.cpp b/storage/mroonga/vendor/groonga/lib/dat/trie.cpp
index 82c8c273286..2f9e79bac56 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/trie.cpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/trie.cpp
@@ -1,5 +1,5 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/* 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
@@ -168,6 +168,10 @@ void Trie::swap(Trie *trie) {
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,
diff --git a/storage/mroonga/vendor/groonga/lib/dat/trie.hpp b/storage/mroonga/vendor/groonga/lib/dat/trie.hpp
index 6bd307bb70e..8a272bb7940 100644
--- a/storage/mroonga/vendor/groonga/lib/dat/trie.hpp
+++ b/storage/mroonga/vendor/groonga/lib/dat/trie.hpp
@@ -1,5 +1,5 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011 Brazil
+/* 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
@@ -189,6 +189,8 @@ class GRN_DAT_API Trie {
header_->set_status_flags(status_flags() & ~CHANGING_MASK);
}
+ void flush();
+
private:
File file_;
Header *header_;
diff --git a/storage/mroonga/vendor/groonga/lib/db.c b/storage/mroonga/vendor/groonga/lib/db.c
index 357df82e314..e213812d926 100644
--- a/storage/mroonga/vendor/groonga/lib/db.c
+++ b/storage/mroonga/vendor/groonga/lib/db.c
@@ -85,6 +85,33 @@ inline static void
grn_obj_get_range_info(grn_ctx *ctx, grn_obj *obj,
grn_id *range_id, grn_obj_flags *range_flags);
+
+static char grn_db_key[GRN_ENV_BUFFER_SIZE];
+static uint64_t grn_index_sparsity = 10;
+
+void
+grn_db_init_from_env(void)
+{
+ grn_getenv("GRN_DB_KEY",
+ grn_db_key,
+ GRN_ENV_BUFFER_SIZE);
+
+ {
+ char grn_index_sparsity_env[GRN_ENV_BUFFER_SIZE];
+ grn_getenv("GRN_INDEX_SPARSITY",
+ grn_index_sparsity_env,
+ GRN_ENV_BUFFER_SIZE);
+ if (grn_index_sparsity_env[0]) {
+ uint64_t sparsity;
+ errno = 0;
+ sparsity = strtoull(grn_index_sparsity_env, NULL, 0);
+ if (errno == 0) {
+ grn_index_sparsity = sparsity;
+ }
+ }
+ }
+}
+
inline static void
gen_pathname(const char *path, char *buffer, int fno)
{
@@ -155,15 +182,11 @@ grn_db_create(grn_ctx *ctx, const char *path, grn_db_create_optarg *optarg)
if ((s = GRN_MALLOC(sizeof(grn_db)))) {
grn_bool use_default_db_key = GRN_TRUE;
grn_bool use_pat_as_db_keys = GRN_FALSE;
- char grn_db_key_env[GRN_ENV_BUFFER_SIZE];
- grn_getenv("GRN_DB_KEY",
- grn_db_key_env,
- GRN_ENV_BUFFER_SIZE);
- if (grn_db_key_env[0]) {
- if (!strcmp(grn_db_key_env, "pat")) {
+ 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_env, "dat")) {
+ } else if (!strcmp(grn_db_key, "dat")) {
use_default_db_key = GRN_FALSE;
}
}
@@ -245,6 +268,10 @@ grn_db_open(grn_ctx *ctx, const char *path)
break;
default :
s->keys = NULL;
+ if (ctx->rc == GRN_SUCCESS) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[db][open] invalid keys table's type: %#x", type);
+ }
break;
}
if (s->keys) {
@@ -870,6 +897,7 @@ grn_table_create_with_max_n_subrecs(grn_ctx *ctx, const char *name,
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 {
@@ -878,10 +906,12 @@ grn_table_create_with_max_n_subrecs(grn_ctx *ctx, const char *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;
}
}
@@ -2758,6 +2788,181 @@ grn_table_next(grn_ctx *ctx, grn_obj *table, grn_id id)
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_search_optarg *optarg)
+{
+ 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_ii_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_data_column(grn_ctx *ctx, grn_accessor *accessor,
+ grn_obj *current_res, grn_obj **next_res,
+ grn_search_optarg *optarg)
+{
+ grn_rc rc = GRN_SUCCESS;
+ grn_obj *index = NULL;
+ grn_operator index_op = GRN_OP_MATCH;
+ grn_id next_res_domain_id = GRN_ID_NIL;
+
+ if (grn_column_index(ctx, accessor->obj, index_op, &index, 1, NULL) == 0) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ next_res_domain_id = DB_OBJ(index)->range;
+
+ {
+ 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;
+ grn_ii_cursor *ii_cursor;
+ grn_ii_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_ii_posting 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,
@@ -2780,69 +2985,28 @@ grn_accessor_resolve(grn_ctx *ctx, grn_obj *accessor, int deep,
}
for (i = n_accessors; i > 0; i--) {
- grn_obj *index;
- grn_operator index_op = GRN_OP_MATCH;
+ grn_obj *next_res = NULL;
a = (grn_accessor *)GRN_PTR_VALUE_AT(&accessor_stack, i - 1);
- if (grn_column_index(ctx, a->obj, index_op, &index, 1, NULL) == 0) {
- rc = GRN_INVALID_ARGUMENT;
- break;
+ if (a->obj->header.type == GRN_COLUMN_INDEX) {
+ rc = grn_accessor_resolve_one_index_column(ctx, a,
+ current_res, &next_res,
+ optarg);
+ } else {
+ rc = grn_accessor_resolve_one_data_column(ctx, a,
+ current_res, &next_res,
+ optarg);
}
- {
- grn_id *tid;
- grn_obj *next_res;
- grn_rset_recinfo *recinfo;
- {
- grn_obj *range = grn_ctx_at(ctx, DB_OBJ(index)->range);
- next_res = grn_table_create(ctx, NULL, 0, NULL,
- GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
- range, NULL);
- rc = ctx->rc;
- grn_obj_unlink(ctx, range);
- if (!next_res) {
- if (current_res != base_res) {
- grn_obj_unlink(ctx, current_res);
- }
- break;
- }
- }
- GRN_HASH_EACH(ctx, (grn_hash *)current_res, id, &tid, NULL, &recinfo, {
- grn_ii *ii = (grn_ii *)index;
- grn_ii_cursor *ii_cursor;
- grn_ii_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_ii_posting add_posting = *posting;
- add_posting.weight += recinfo->score - 1;
- grn_ii_posting_add(ctx,
- &add_posting,
- (grn_hash *)next_res,
- GRN_OP_OR);
- }
- grn_ii_cursor_close(ctx, ii_cursor);
+ if (current_res != base_res) {
+ grn_obj_unlink(ctx, current_res);
+ }
- if (rc != GRN_SUCCESS) {
- break;
- }
- });
- if (current_res != base_res) {
- grn_obj_unlink(ctx, current_res);
- }
- if (rc != GRN_SUCCESS) {
- grn_obj_unlink(ctx, next_res);
- break;
- }
- current_res = next_res;
+ if (rc != GRN_SUCCESS) {
+ break;
}
+
+ current_res = next_res;
}
if (rc == GRN_SUCCESS && current_res != base_res) {
@@ -6846,7 +7010,7 @@ grn_obj_get_value(grn_ctx *ctx, grn_obj *obj, grn_id id, grn_obj *value)
}
switch (value->header.type) {
case GRN_VOID :
- GRN_TEXT_INIT(value, 0);
+ grn_obj_reinit(ctx, value, GRN_DB_TEXT, 0);
break;
case GRN_BULK :
case GRN_VECTOR :
@@ -7225,18 +7389,7 @@ build_index(grn_ctx *ctx, grn_obj *obj)
}
}
if (use_grn_ii_build) {
- uint64_t sparsity = 10;
- 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 v;
- errno = 0;
- v = strtoull(grn_index_sparsity_env, NULL, 0);
- if (!errno) { sparsity = v; }
- }
- grn_ii_build(ctx, ii, sparsity);
+ 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,
@@ -9528,6 +9681,7 @@ grn_obj_clear_lock(grn_ctx *ctx, grn_obj *obj)
case GRN_TABLE_DAT_KEY:
case GRN_TABLE_NO_KEY:
grn_obj_clear_lock(ctx, tbl);
+ break;
}
} else {
if (ctx->rc != GRN_SUCCESS) {
@@ -9580,6 +9734,132 @@ grn_obj_is_locked(grn_ctx *ctx, grn_obj *obj)
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) {
+ rc = grn_obj_flush(ctx, (grn_obj *)(db->specs));
+ }
+ }
+ 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 :
+ rc = grn_io_flush(ctx, grn_obj_io(obj));
+ break;
+ }
+ 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)
{
@@ -11181,6 +11461,11 @@ grn_table_sort_key_from_str(grn_ctx *ctx, const char *str, unsigned int str_size
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;
}
diff --git a/storage/mroonga/vendor/groonga/lib/egn.cpp b/storage/mroonga/vendor/groonga/lib/egn.cpp
new file mode 100644
index 00000000000..c7e7357fffb
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/egn.cpp
@@ -0,0 +1,3245 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifdef GRN_WITH_EGN
+
+#include "grn_egn.hpp"
+
+#include <cctype>
+#include <cstdio>
+#include <limits>
+#include <memory>
+#include <string>
+
+#include <iostream> // for debug!
+
+#include "grn_ctx_impl.h"
+#include "grn_db.h"
+#include "grn_output.h"
+#include "grn_str.h"
+
+// TODO: Error handling.
+
+namespace {
+
+enum { GRN_EGN_MAX_BATCH_SIZE = 1024 };
+
+bool grn_egn_is_table_cursor(grn_obj *obj) {
+ if (!obj) {
+ return false;
+ }
+ switch (obj->header.type) {
+ case GRN_CURSOR_TABLE_PAT_KEY:
+ case GRN_CURSOR_TABLE_DAT_KEY:
+ case GRN_CURSOR_TABLE_HASH_KEY:
+ case GRN_CURSOR_TABLE_NO_KEY: {
+ return true;
+ }
+ default: {
+ return false;
+ }
+ }
+}
+
+bool grn_egn_is_table(grn_obj *obj) {
+ if (!obj) {
+ return false;
+ }
+ switch (obj->header.type) {
+ case GRN_TABLE_HASH_KEY:
+ case GRN_TABLE_PAT_KEY:
+ case GRN_TABLE_DAT_KEY:
+ case GRN_TABLE_NO_KEY: {
+ return true;
+ }
+ default: {
+ return false;
+ }
+ }
+}
+
+} // namespace
+
+namespace grn {
+namespace egn {
+
+// -- TableCursor --
+
+// TableCursor is a wrapper for grn_table_cursor:
+// - GRN_CURSOR_PAT_KEY
+// - GRN_CURSOR_DAT_KEY
+// - GRN_CURSOR_HASH_KEY
+// - GRN_CURSOR_NO_KEY
+class TableCursor : public Cursor {
+ public:
+ ~TableCursor() {
+ grn_table_cursor_close(ctx_, cursor_);
+ }
+
+ static grn_rc open(grn_ctx *ctx, grn_obj *cursor, Score default_score,
+ Cursor **wrapper) {
+ if (!ctx || !grn_egn_is_table_cursor(cursor) || !wrapper) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ TableCursor *new_wrapper =
+ new (std::nothrow) TableCursor(ctx, cursor, default_score);
+ if (!new_wrapper) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *wrapper = new_wrapper;
+ return GRN_SUCCESS;
+ }
+
+ grn_rc read(Record *records, size_t size, size_t *count);
+
+ private:
+ grn_ctx *ctx_;
+ grn_obj *cursor_;
+ Score default_score_;
+
+ TableCursor(grn_ctx *ctx, grn_obj *cursor, Score default_score)
+ : Cursor(), ctx_(ctx), cursor_(cursor), default_score_(default_score) {}
+};
+
+grn_rc TableCursor::read(Record *records, size_t size, size_t *count) {
+ if ((!records && (size != 0)) || !count) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ switch (cursor_->header.type) {
+ case GRN_CURSOR_TABLE_PAT_KEY: {
+ for (size_t i = 0; i < size; ++i) {
+ grn_id id = grn_pat_cursor_next(
+ ctx_, reinterpret_cast<grn_pat_cursor *>(cursor_));
+ if (id == GRN_ID_NIL) {
+ *count = i;
+ return GRN_SUCCESS;
+ }
+ records[i].id = id;
+ records[i].score = default_score_;
+ }
+ break;
+ }
+ case GRN_CURSOR_TABLE_DAT_KEY: {
+ for (size_t i = 0; i < size; ++i) {
+ grn_id id = grn_dat_cursor_next(
+ ctx_, reinterpret_cast<grn_dat_cursor *>(cursor_));
+ if (id == GRN_ID_NIL) {
+ *count = i;
+ return GRN_SUCCESS;
+ }
+ records[i].id = id;
+ records[i].score = default_score_;
+ }
+ break;
+ }
+ case GRN_CURSOR_TABLE_HASH_KEY: {
+ for (size_t i = 0; i < size; ++i) {
+ grn_id id = grn_hash_cursor_next(
+ ctx_, reinterpret_cast<grn_hash_cursor *>(cursor_));
+ if (id == GRN_ID_NIL) {
+ *count = i;
+ return GRN_SUCCESS;
+ }
+ records[i].id = id;
+ records[i].score = default_score_;
+ }
+ break;
+ }
+ case GRN_CURSOR_TABLE_NO_KEY: {
+ for (size_t i = 0; i < size; ++i) {
+ grn_id id = grn_array_cursor_next(
+ ctx_, reinterpret_cast<grn_array_cursor *>(cursor_));
+ if (id == GRN_ID_NIL) {
+ *count = i;
+ return GRN_SUCCESS;
+ }
+ records[i].id = id;
+ records[i].score = default_score_;
+ }
+ break;
+ }
+ default: {
+ return GRN_UNKNOWN_ERROR;
+ }
+ }
+ *count = size;
+ return GRN_SUCCESS;
+}
+
+// -- Cursor --
+
+grn_rc Cursor::open_table_cursor(
+ grn_ctx *ctx, grn_obj *table, Cursor **cursor) {
+ if (!ctx || !grn_egn_is_table(table) || !cursor) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ grn_table_cursor *table_cursor = grn_table_cursor_open(
+ ctx, table, NULL, 0, NULL, 0, 0, -1,
+ GRN_CURSOR_ASCENDING | GRN_CURSOR_BY_ID);
+ if (!table_cursor) {
+ return ctx->rc;
+ }
+ grn_rc rc = TableCursor::open(ctx, table_cursor, 0.0, cursor);
+ if (rc != GRN_SUCCESS) {
+ grn_table_cursor_close(ctx, table_cursor);
+ }
+ return rc;
+}
+
+grn_rc Cursor::read(Record *records, size_t size, size_t *count) {
+ if ((!records && (size != 0)) || !count) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ *count = 0;
+ return GRN_SUCCESS;
+}
+
+// -- ExpressionNode --
+
+class ExpressionNode {
+ public:
+ ExpressionNode() {}
+ virtual ~ExpressionNode() {}
+
+ virtual ExpressionNodeType type() const = 0;
+ virtual DataType data_type() const = 0;
+
+ virtual grn_rc filter(Record *input, size_t input_size,
+ Record *output, size_t *output_size) {
+ return GRN_OPERATION_NOT_SUPPORTED;
+ }
+ virtual grn_rc adjust(Record *records, size_t num_records) {
+ return GRN_OPERATION_NOT_SUPPORTED;
+ }
+};
+
+// -- TypedNode<T> --
+
+template <typename T>
+class TypedNode : public ExpressionNode {
+ public:
+ TypedNode() : ExpressionNode() {}
+ virtual ~TypedNode() {}
+
+ DataType data_type() const {
+ return T::data_type();
+ }
+
+ virtual grn_rc evaluate(
+ const Record *records, size_t num_records, T *results) = 0;
+};
+
+// -- TypedNode<Bool> --
+
+template <>
+class TypedNode<Bool> : public ExpressionNode {
+ public:
+ TypedNode() : ExpressionNode(), values_for_filter_() {}
+ virtual ~TypedNode() {}
+
+ DataType data_type() const {
+ return Bool::data_type();
+ }
+
+ virtual grn_rc filter(Record *input, size_t input_size,
+ Record *output, size_t *output_size);
+
+ virtual grn_rc evaluate(
+ const Record *records, size_t num_records, Bool *results) = 0;
+
+ private:
+ std::vector<Bool> values_for_filter_;
+};
+
+grn_rc TypedNode<Bool>::filter(Record *input, size_t input_size,
+ Record *output, size_t *output_size) {
+ if (values_for_filter_.size() < input_size) {
+ values_for_filter_.resize(input_size);
+ }
+ grn_rc rc = evaluate(input, input_size, &*values_for_filter_.begin());
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ size_t count = 0;
+ for (size_t i = 0; i < input_size; ++i) {
+ if (values_for_filter_[i].raw) {
+ output[count] = input[i];
+ ++count;
+ }
+ }
+ *output_size = count;
+ return GRN_SUCCESS;
+}
+
+// -- TypedNode<Float> --
+
+template <>
+class TypedNode<Float> : public ExpressionNode {
+ public:
+ TypedNode() : ExpressionNode(), values_for_adjust_() {}
+ virtual ~TypedNode() {}
+
+ DataType data_type() const {
+ return Float::data_type();
+ }
+
+ virtual grn_rc adjust(Record *records, size_t num_records);
+
+ virtual grn_rc evaluate(
+ const Record *records, size_t num_records, Float *results) = 0;
+
+ private:
+ std::vector<Float> values_for_adjust_;
+};
+
+grn_rc TypedNode<Float>::adjust(Record *records, size_t num_records) {
+ if (values_for_adjust_.size() < num_records) {
+ values_for_adjust_.resize(num_records);
+ }
+ grn_rc rc = evaluate(records, num_records, &*values_for_adjust_.begin());
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ for (size_t i = 0; i < num_records; ++i) {
+ records[i].score = values_for_adjust_[i].raw;
+ }
+ return GRN_SUCCESS;
+}
+
+// -- IDNode --
+
+class IDNode : public TypedNode<Int> {
+ public:
+ ~IDNode() {}
+
+ static grn_rc open(ExpressionNode **node) {
+ ExpressionNode *new_node = new (std::nothrow) IDNode();
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+ }
+
+ ExpressionNodeType type() const {
+ return GRN_EGN_ID_NODE;
+ }
+
+ grn_rc evaluate(
+ const Record *records, size_t num_records, Int *results) {
+ for (size_t i = 0; i < num_records; ++i) {
+ results[i] = Int(records[i].id);
+ }
+ return GRN_SUCCESS;
+ }
+
+ private:
+ IDNode() : TypedNode<Int>() {}
+};
+
+// -- ScoreNode --
+
+class ScoreNode : public TypedNode<Float> {
+ public:
+ ~ScoreNode() {}
+
+ static grn_rc open(ExpressionNode **node) {
+ ExpressionNode *new_node = new (std::nothrow) ScoreNode();
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+ }
+
+ ExpressionNodeType type() const {
+ return GRN_EGN_SCORE_NODE;
+ }
+
+ grn_rc evaluate(
+ const Record *records, size_t num_records, Float *results) {
+ for (size_t i = 0; i < num_records; ++i) {
+ results[i] = Float(records[i].score);
+ }
+ return GRN_SUCCESS;
+ }
+
+ private:
+ ScoreNode() : TypedNode<Float>() {}
+};
+
+// -- ConstantNode<T> --
+
+template <typename T>
+class ConstantNode : public TypedNode<T> {
+ public:
+ ~ConstantNode() {}
+
+ static grn_rc open(const T &value, ExpressionNode **node) {
+ ConstantNode *new_node = new (std::nothrow) ConstantNode(value);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+ }
+
+ ExpressionNodeType type() const {
+ return GRN_EGN_CONSTANT_NODE;
+ }
+
+ grn_rc evaluate(
+ const Record *records, size_t num_records, T *results) {
+ for (size_t i = 0; i < num_records; ++i) {
+ results[i] = value_;
+ }
+ return GRN_SUCCESS;
+ }
+
+ private:
+ T value_;
+
+ explicit ConstantNode(const T &value) : TypedNode<T>(), value_(value) {}
+};
+
+// -- ConstantNode<Bool> --
+
+template <>
+class ConstantNode<Bool> : public TypedNode<Bool> {
+ public:
+ ~ConstantNode() {}
+
+ static grn_rc open(Bool value, ExpressionNode **node) {
+ ConstantNode *new_node = new (std::nothrow) ConstantNode(value);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+ }
+
+ ExpressionNodeType type() const {
+ return GRN_EGN_CONSTANT_NODE;
+ }
+
+ grn_rc filter(Record *input, size_t input_size,
+ Record *output, size_t *output_size);
+
+ grn_rc evaluate(
+ const Record *records, size_t num_records, Bool *results) {
+ for (size_t i = 0; i < num_records; ++i) {
+ results[i] = value_;
+ }
+ return GRN_SUCCESS;
+ }
+
+ private:
+ Bool value_;
+
+ explicit ConstantNode(Bool value) : TypedNode<Bool>(), value_(value) {}
+};
+
+grn_rc ConstantNode<Bool>::filter(
+ Record *input, size_t input_size,
+ Record *output, size_t *output_size) {
+ if (value_.raw == GRN_TRUE) {
+ // The I/O areas are the same and there is no need to copy records.
+ if (input != output) {
+ for (size_t i = 0; i < input_size; ++i) {
+ output[i] = input[i];
+ }
+ }
+ *output_size = input_size;
+ } else {
+ *output_size = 0;
+ }
+ return GRN_SUCCESS;
+}
+
+// -- ConstantNode<Float> --
+
+template <>
+class ConstantNode<Float> : public TypedNode<Float> {
+ public:
+ ~ConstantNode() {}
+
+ static grn_rc open(Float value, ExpressionNode **node) {
+ ConstantNode *new_node = new (std::nothrow) ConstantNode(value);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+ }
+
+ ExpressionNodeType type() const {
+ return GRN_EGN_CONSTANT_NODE;
+ }
+
+ grn_rc adjust(Record *records, size_t num_records) {
+ for (size_t i = 0; i < num_records; ++i) {
+ records[i].score = value_.raw;
+ }
+ return GRN_SUCCESS;
+ }
+
+ grn_rc evaluate(
+ const Record *records, size_t num_records, Float *results) {
+ for (size_t i = 0; i < num_records; ++i) {
+ results[i] = value_;
+ }
+ return GRN_SUCCESS;
+ }
+
+ private:
+ Float value_;
+
+ explicit ConstantNode(Float value) : TypedNode<Float>(), value_(value) {}
+};
+
+// -- ConstantNode<Text> --
+
+template <>
+class ConstantNode<Text> : public TypedNode<Text> {
+ public:
+ ~ConstantNode() {}
+
+ static grn_rc open(const Text &value, ExpressionNode **node) {
+ ConstantNode *new_node = new (std::nothrow) ConstantNode(value);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ try {
+ new_node->value_buf_.resize(value.raw.size);
+ } catch (const std::bad_alloc &) {
+ delete new_node;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ std::memcpy(&*new_node->value_buf_.begin(), value.raw.ptr, value.raw.size);
+ new_node->value_.raw.ptr = &*new_node->value_buf_.begin();
+ *node = new_node;
+ return GRN_SUCCESS;
+ }
+
+ ExpressionNodeType type() const {
+ return GRN_EGN_CONSTANT_NODE;
+ }
+
+ grn_rc evaluate(
+ const Record *records, size_t num_records, Text *results) {
+ for (size_t i = 0; i < num_records; ++i) {
+ results[i] = value_;
+ }
+ return GRN_SUCCESS;
+ }
+
+ private:
+ Text value_;
+ std::vector<char> value_buf_;
+
+ explicit ConstantNode(const Text &value)
+ : TypedNode<Text>(), value_(value), value_buf_() {}
+};
+
+// -- ColumnNode --
+
+template <typename T>
+class ColumnNode : public TypedNode<T> {
+ public:
+ ~ColumnNode() {}
+
+ static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) {
+ ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+ }
+
+ ExpressionNodeType type() const {
+ return GRN_EGN_COLUMN_NODE;
+ }
+
+ grn_rc evaluate(
+ const Record *records, size_t num_records, T *results) {
+ // TODO
+ return GRN_OPERATION_NOT_SUPPORTED;
+ }
+
+ private:
+ grn_ctx *ctx_;
+ grn_obj *column_;
+
+ ColumnNode(grn_ctx *ctx, grn_obj *column)
+ : TypedNode<T>(), ctx_(ctx), column_(column) {}
+};
+
+// -- ColumnNode<Bool> --
+
+template <>
+class ColumnNode<Bool> : public TypedNode<Bool> {
+ public:
+ ~ColumnNode() {}
+
+ static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) {
+ ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+ }
+
+ ExpressionNodeType type() const {
+ return GRN_EGN_COLUMN_NODE;
+ }
+
+ grn_rc filter(
+ Record *input, size_t input_size,
+ Record *output, size_t *output_size);
+
+ grn_rc evaluate(
+ const Record *records, size_t num_records, Bool *results);
+
+ private:
+ grn_ctx *ctx_;
+ grn_obj *column_;
+
+ ColumnNode(grn_ctx *ctx, grn_obj *column)
+ : TypedNode<Bool>(), ctx_(ctx), column_(column) {}
+};
+
+grn_rc ColumnNode<Bool>::filter(
+ Record *input, size_t input_size,
+ Record *output, size_t *output_size) {
+ grn_obj value;
+ GRN_BOOL_INIT(&value, 0);
+ size_t count = 0;
+ for (size_t i = 0; i < input_size; ++i) {
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx_, column_, input[i].id, &value);
+ if (ctx_->rc != GRN_SUCCESS) {
+ return ctx_->rc;
+ }
+ if (GRN_BOOL_VALUE(&value) == GRN_TRUE) {
+ output[count] = input[i];
+ ++count;
+ }
+ }
+ GRN_OBJ_FIN(ctx_, &value);
+ *output_size = count;
+ return GRN_SUCCESS;
+}
+
+grn_rc ColumnNode<Bool>::evaluate(
+ const Record *records, size_t num_records, Bool *results) {
+ grn_obj value;
+ GRN_BOOL_INIT(&value, 0);
+ for (size_t i = 0; i < num_records; i++) {
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx_, column_, records[i].id, &value);
+ if (ctx_->rc != GRN_SUCCESS) {
+ return ctx_->rc;
+ }
+ results[i] = Bool(GRN_BOOL_VALUE(&value) == GRN_TRUE);
+ }
+ GRN_OBJ_FIN(ctx_, &value);
+ return GRN_SUCCESS;
+}
+
+// -- ColumnNode<Int> --
+
+template <>
+class ColumnNode<Int> : public TypedNode<Int> {
+ public:
+ ~ColumnNode() {}
+
+ static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) {
+ ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+ }
+
+ ExpressionNodeType type() const {
+ return GRN_EGN_COLUMN_NODE;
+ }
+
+ grn_rc evaluate(
+ const Record *records, size_t num_records, Int *results);
+
+ private:
+ grn_ctx *ctx_;
+ grn_obj *column_;
+
+ ColumnNode(grn_ctx *ctx, grn_obj *column)
+ : TypedNode<Int>(), ctx_(ctx), column_(column) {}
+};
+
+grn_rc ColumnNode<Int>::evaluate(
+ const Record *records, size_t num_records, Int *results) {
+ grn_id range = grn_obj_get_range(ctx_, column_);
+ grn_obj value;
+ switch (range) {
+ case GRN_DB_INT8: {
+ GRN_INT8_INIT(&value, 0);
+ for (size_t i = 0; i < num_records; i++) {
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx_, column_, records[i].id, &value);
+ results[i] = Int(GRN_INT8_VALUE(&value));
+ }
+ break;
+ }
+ case GRN_DB_INT16: {
+ GRN_INT16_INIT(&value, 0);
+ for (size_t i = 0; i < num_records; i++) {
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx_, column_, records[i].id, &value);
+ results[i] = Int(GRN_INT16_VALUE(&value));
+ }
+ break;
+ }
+ case GRN_DB_INT32: {
+ GRN_INT32_INIT(&value, 0);
+ for (size_t i = 0; i < num_records; i++) {
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx_, column_, records[i].id, &value);
+ results[i] = Int(GRN_INT32_VALUE(&value));
+ }
+ break;
+ }
+ case GRN_DB_INT64: {
+ GRN_INT64_INIT(&value, 0);
+ for (size_t i = 0; i < num_records; i++) {
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx_, column_, records[i].id, &value);
+ results[i] = Int(GRN_INT64_VALUE(&value));
+ }
+ break;
+ }
+ case GRN_DB_UINT8: {
+ GRN_UINT8_INIT(&value, 0);
+ for (size_t i = 0; i < num_records; i++) {
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx_, column_, records[i].id, &value);
+ results[i] = Int(GRN_UINT8_VALUE(&value));
+ }
+ break;
+ }
+ case GRN_DB_UINT16: {
+ GRN_UINT16_INIT(&value, 0);
+ for (size_t i = 0; i < num_records; i++) {
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx_, column_, records[i].id, &value);
+ results[i] = Int(GRN_UINT16_VALUE(&value));
+ }
+ break;
+ }
+ case GRN_DB_UINT32: {
+ GRN_UINT32_INIT(&value, 0);
+ for (size_t i = 0; i < num_records; i++) {
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx_, column_, records[i].id, &value);
+ results[i] = Int(GRN_UINT32_VALUE(&value));
+ }
+ break;
+ }
+ case GRN_DB_UINT64: {
+ GRN_UINT64_INIT(&value, 0);
+ for (size_t i = 0; i < num_records; i++) {
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx_, column_, records[i].id, &value);
+ // FIXME: Type conversion from UInt64 to Int may lose the content.
+ results[i] = Int(GRN_UINT64_VALUE(&value));
+ }
+ break;
+ }
+ }
+ GRN_OBJ_FIN(ctx_, &value);
+ return GRN_SUCCESS;
+}
+
+// -- ColumnNode<Float> --
+
+template <>
+class ColumnNode<Float> : public TypedNode<Float> {
+ public:
+ ~ColumnNode() {}
+
+ static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) {
+ ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+ }
+
+ ExpressionNodeType type() const {
+ return GRN_EGN_COLUMN_NODE;
+ }
+
+ grn_rc adjust(Record *records, size_t num_records);
+
+ grn_rc evaluate(
+ const Record *records, size_t num_records, Float *results);
+
+ private:
+ grn_ctx *ctx_;
+ grn_obj *column_;
+
+ ColumnNode(grn_ctx *ctx, grn_obj *column)
+ : TypedNode<Float>(), ctx_(ctx), column_(column) {}
+};
+
+grn_rc ColumnNode<Float>::adjust(Record *records, size_t num_records) {
+ grn_obj value;
+ GRN_FLOAT_INIT(&value, 0);
+ for (size_t i = 0; i < num_records; ++i) {
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx_, column_, records[i].id, &value);
+ records[i].score = GRN_FLOAT_VALUE(&value);
+ }
+ GRN_OBJ_FIN(ctx_, &value);
+ return GRN_SUCCESS;
+}
+
+grn_rc ColumnNode<Float>::evaluate(
+ const Record *records, size_t num_records, Float *results) {
+ grn_obj value;
+ GRN_FLOAT_INIT(&value, 0);
+ for (size_t i = 0; i < num_records; i++) {
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx_, column_, records[i].id, &value);
+ results[i] = Float(GRN_FLOAT_VALUE(&value));
+ }
+ GRN_OBJ_FIN(ctx_, &value);
+ return GRN_SUCCESS;
+}
+
+// -- ColumnNode<Time> --
+
+template <>
+class ColumnNode<Time> : public TypedNode<Time> {
+ public:
+ ~ColumnNode() {}
+
+ static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) {
+ ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+ }
+
+ ExpressionNodeType type() const {
+ return GRN_EGN_COLUMN_NODE;
+ }
+
+ grn_rc evaluate(
+ const Record *records, size_t num_records, Time *results);
+
+ private:
+ grn_ctx *ctx_;
+ grn_obj *column_;
+
+ ColumnNode(grn_ctx *ctx, grn_obj *column)
+ : TypedNode<Time>(), ctx_(ctx), column_(column) {}
+};
+
+grn_rc ColumnNode<Time>::evaluate(
+ const Record *records, size_t num_records, Time *results) {
+ grn_obj value;
+ GRN_TIME_INIT(&value, 0);
+ for (size_t i = 0; i < num_records; i++) {
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx_, column_, records[i].id, &value);
+ results[i] = Time(GRN_TIME_VALUE(&value));
+ }
+ GRN_OBJ_FIN(ctx_, &value);
+ return GRN_SUCCESS;
+}
+
+// -- ColumnNode<Text> --
+
+template <>
+class ColumnNode<Text> : public TypedNode<Text> {
+ public:
+ ~ColumnNode() {
+ GRN_OBJ_FIN(ctx_, &buf_);
+ }
+
+ static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) {
+ ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+ }
+
+ ExpressionNodeType type() const {
+ return GRN_EGN_COLUMN_NODE;
+ }
+
+ grn_rc evaluate(
+ const Record *records, size_t num_records, Text *results);
+
+ private:
+ grn_ctx *ctx_;
+ grn_obj *column_;
+ grn_obj buf_;
+
+ ColumnNode(grn_ctx *ctx, grn_obj *column)
+ : TypedNode<Text>(), ctx_(ctx), column_(column), buf_() {
+ GRN_TEXT_INIT(&buf_, 0);
+ }
+};
+
+grn_rc ColumnNode<Text>::evaluate(
+ const Record *records, size_t num_records, Text *results) {
+ GRN_BULK_REWIND(&buf_);
+ size_t offset = 0;
+ for (size_t i = 0; i < num_records; i++) {
+ grn_obj_get_value(ctx_, column_, records[i].id, &buf_);
+ if (ctx_->rc != GRN_SUCCESS) {
+ return ctx_->rc;
+ }
+ size_t next_offset = GRN_TEXT_LEN(&buf_);
+ results[i].raw.size = next_offset - offset;
+ offset = next_offset;
+ }
+ char *ptr = GRN_TEXT_VALUE(&buf_);
+ for (size_t i = 0; i < num_records; i++) {
+ results[i].raw.ptr = ptr;
+ ptr += results[i].raw.size;
+ }
+ return GRN_SUCCESS;
+}
+
+// -- ColumnNode<GeoPoint> --
+
+template <>
+class ColumnNode<GeoPoint> : public TypedNode<GeoPoint> {
+ public:
+ ~ColumnNode() {}
+
+ static grn_rc open(grn_ctx *ctx, grn_obj *column, ExpressionNode **node) {
+ ColumnNode *new_node = new (std::nothrow) ColumnNode(ctx, column);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+ }
+
+ ExpressionNodeType type() const {
+ return GRN_EGN_COLUMN_NODE;
+ }
+
+ grn_rc evaluate(
+ const Record *records, size_t num_records, GeoPoint *results);
+
+ private:
+ grn_ctx *ctx_;
+ grn_obj *column_;
+
+ ColumnNode(grn_ctx *ctx, grn_obj *column)
+ : TypedNode<GeoPoint>(), ctx_(ctx), column_(column) {}
+};
+
+grn_rc ColumnNode<GeoPoint>::evaluate(
+ const Record *records, size_t num_records, GeoPoint *results) {
+ grn_obj value;
+ GRN_WGS84_GEO_POINT_INIT(&value, 0);
+ for (size_t i = 0; i < num_records; i++) {
+ GRN_BULK_REWIND(&value);
+ grn_obj_get_value(ctx_, column_, records[i].id, &value);
+ GRN_GEO_POINT_VALUE(
+ &value, results[i].raw.latitude, results[i].raw.longitude);
+ }
+ GRN_OBJ_FIN(ctx_, &value);
+ return GRN_SUCCESS;
+}
+
+// -- OperatorNode --
+
+template <typename T>
+class OperatorNode : public TypedNode<T> {
+ public:
+ OperatorNode() : TypedNode<T>() {}
+ virtual ~OperatorNode() {}
+
+ ExpressionNodeType type() const {
+ return GRN_EGN_OPERATOR_NODE;
+ }
+};
+
+template <typename T>
+grn_rc operator_node_fill_arg_values(
+ const Record *records, size_t num_records,
+ TypedNode<T> *arg, std::vector<T> *arg_values) {
+ size_t old_size = arg_values->size();
+ if (old_size < num_records) try {
+ arg_values->resize(num_records);
+ } catch (const std::bad_alloc &) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ switch (arg->type()) {
+ case GRN_EGN_CONSTANT_NODE: {
+ if (old_size < num_records) {
+ return arg->evaluate(records + old_size, num_records - old_size,
+ &*arg_values->begin() + old_size);
+ }
+ return GRN_SUCCESS;
+ }
+ default: {
+ return arg->evaluate(records, num_records, &*arg_values->begin());
+ }
+ }
+}
+
+// --- UnaryNode ---
+
+template <typename T, typename U>
+class UnaryNode : public OperatorNode<T> {
+ public:
+ explicit UnaryNode(ExpressionNode *arg)
+ : OperatorNode<T>(), arg_(static_cast<TypedNode<U> *>(arg)),
+ arg_values_() {}
+ virtual ~UnaryNode() {
+ delete arg_;
+ }
+
+ protected:
+ TypedNode<U> *arg_;
+ std::vector<U> arg_values_;
+
+ grn_rc fill_arg_values(const Record *records, size_t num_records) {
+ return operator_node_fill_arg_values(
+ records, num_records, arg_, &arg_values_);
+ }
+};
+
+// ---- LogicalNotNode ----
+
+class LogicalNotNode : public UnaryNode<Bool, Bool> {
+ public:
+ ~LogicalNotNode() {}
+
+ static grn_rc open(ExpressionNode *arg, ExpressionNode **node) {
+ LogicalNotNode *new_node = new (std::nothrow) LogicalNotNode(arg);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+ }
+
+ grn_rc filter(
+ Record *input, size_t input_size,
+ Record *output, size_t *output_size);
+
+ grn_rc evaluate(
+ const Record *records, size_t num_records, Bool *results);
+
+ private:
+ std::vector<Record> temp_records_;
+
+ explicit LogicalNotNode(ExpressionNode *arg)
+ : UnaryNode<Bool, Bool>(arg), temp_records_() {}
+};
+
+grn_rc LogicalNotNode::filter(
+ Record *input, size_t input_size,
+ Record *output, size_t *output_size) {
+ if (temp_records_.size() <= input_size) {
+ try {
+ temp_records_.resize(input_size + 1);
+ temp_records_[input_size].id = GRN_ID_NIL;
+ } catch (const std::bad_alloc &) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ }
+ size_t temp_size;
+ grn_rc rc =
+ arg_->filter(input, input_size, &*temp_records_.begin(), &temp_size);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ if (temp_size == 0) {
+ *output_size = 0;
+ return GRN_SUCCESS;
+ }
+
+ size_t count = 0;
+ for (size_t i = 0; i < input_size; ++i) {
+ if (input[i].id != temp_records_[i - count].id) {
+ output[count] = input[i];
+ ++count;
+ }
+ }
+ *output_size = count;
+ return GRN_SUCCESS;
+}
+
+grn_rc LogicalNotNode::evaluate(
+ const Record *records, size_t num_records, Bool *results) {
+ grn_rc rc = arg_->evaluate(records, num_records, results);
+ if (rc == GRN_SUCCESS) {
+ for (size_t i = 0; i < num_records; ++i) {
+ results[i] = Bool(results[i].raw != GRN_TRUE);
+ }
+ }
+ return rc;
+}
+
+// --- BinaryNode ---
+
+template <typename T, typename U, typename V>
+class BinaryNode : public OperatorNode<T> {
+ public:
+ BinaryNode(ExpressionNode *arg1, ExpressionNode *arg2)
+ : OperatorNode<T>(),
+ arg1_(static_cast<TypedNode<U> *>(arg1)),
+ arg2_(static_cast<TypedNode<V> *>(arg2)),
+ arg1_values_(), arg2_values_() {}
+ virtual ~BinaryNode() {
+ delete arg1_;
+ delete arg2_;
+ }
+
+ protected:
+ TypedNode<U> *arg1_;
+ TypedNode<V> *arg2_;
+ std::vector<U> arg1_values_;
+ std::vector<V> arg2_values_;
+
+ grn_rc fill_arg1_values(const Record *records, size_t num_records) {
+ return operator_node_fill_arg_values(
+ records, num_records, arg1_, &arg1_values_);
+ }
+ grn_rc fill_arg2_values(const Record *records, size_t num_records) {
+ return operator_node_fill_arg_values(
+ records, num_records, arg2_, &arg2_values_);
+ }
+};
+
+// ---- LogicalAndNode ----
+
+class LogicalAndNode : public BinaryNode<Bool, Bool, Bool> {
+ public:
+ ~LogicalAndNode() {}
+
+ static grn_rc open(
+ ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) {
+ LogicalAndNode *new_node = new (std::nothrow) LogicalAndNode(arg1, arg2);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+ }
+
+ grn_rc filter(
+ Record *input, size_t input_size,
+ Record *output, size_t *output_size) {
+ grn_rc rc = arg1_->filter(input, input_size, output, output_size);
+ if (rc == GRN_SUCCESS) {
+ rc = arg2_->filter(output, *output_size, output, output_size);
+ }
+ return rc;
+ }
+
+ grn_rc evaluate(
+ const Record *records, size_t num_records, Bool *results);
+
+ private:
+ std::vector<Record> temp_records_;
+
+ LogicalAndNode(ExpressionNode *arg1, ExpressionNode *arg2)
+ : BinaryNode<Bool, Bool, Bool>(arg1, arg2), temp_records_() {}
+};
+
+grn_rc LogicalAndNode::evaluate(
+ const Record *records, size_t num_records, Bool *results) {
+ // Evaluate "arg1" for all the records.
+ // Then, evaluate "arg2" for non-false records.
+ grn_rc rc = arg1_->evaluate(records, num_records, results);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ if (temp_records_.size() < num_records) try {
+ temp_records_.resize(num_records);
+ } catch (const std::bad_alloc &) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ size_t count = 0;
+ for (size_t i = 0; i < num_records; ++i) {
+ if (results[i].raw == GRN_TRUE) {
+ temp_records_[count] = records[i];
+ ++count;
+ }
+ }
+ if (count == 0) {
+ // Nothing to do.
+ return GRN_SUCCESS;
+ }
+ rc = fill_arg2_values(&*temp_records_.begin(), count);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+
+ // Merge the evaluation results.
+ count = 0;
+ for (size_t i = 0; i < num_records; ++i) {
+ if (results[i].raw == GRN_TRUE) {
+ results[i] = arg2_values_[count];
+ ++count;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+// ---- LogicalOrNode ----
+
+class LogicalOrNode : public BinaryNode<Bool, Bool, Bool> {
+ public:
+ ~LogicalOrNode() {}
+
+ static grn_rc open(
+ ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) {
+ LogicalOrNode *new_node = new (std::nothrow) LogicalOrNode(arg1, arg2);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+ }
+
+ grn_rc filter(
+ Record *input, size_t input_size,
+ Record *output, size_t *output_size);
+
+ grn_rc evaluate(
+ const Record *records, size_t num_records, Bool *results);
+
+ private:
+ std::vector<Record> temp_records_;
+
+ LogicalOrNode(ExpressionNode *arg1, ExpressionNode *arg2)
+ : BinaryNode<Bool, Bool, Bool>(arg1, arg2), temp_records_() {}
+};
+
+grn_rc LogicalOrNode::filter(
+ Record *input, size_t input_size,
+ Record *output, size_t *output_size) {
+ // Evaluate "arg1" for all the records.
+ // Then, evaluate "arg2" for non-true records.
+ grn_rc rc = fill_arg1_values(input, input_size);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ if (temp_records_.size() < input_size) try {
+ temp_records_.resize(input_size);
+ } catch (const std::bad_alloc &) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ size_t count = 0;
+ for (size_t i = 0; i < input_size; ++i) {
+ if (arg1_values_[i].raw == GRN_FALSE) {
+ temp_records_[count] = input[i];
+ ++count;
+ }
+ }
+ if (count == 0) {
+ if (input != output) {
+ for (size_t i = 0; i < input_size; ++i) {
+ output[i] = input[i];
+ }
+ }
+ *output_size = input_size;
+ return GRN_SUCCESS;
+ }
+ rc = fill_arg2_values(&*temp_records_.begin(), count);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+
+ // Merge the evaluation results.
+ count = 0;
+ size_t output_count = 0;
+ for (size_t i = 0; i < input_size; ++i) {
+ if (arg1_values_[i].raw == GRN_TRUE) {
+ output[output_count] = input[i];
+ ++output_count;
+ } else {
+ if (arg2_values_[count].raw == GRN_TRUE) {
+ output[output_count] = input[i];
+ ++output_count;
+ }
+ ++count;
+ }
+ }
+ *output_size = output_count;
+ return GRN_SUCCESS;
+}
+
+grn_rc LogicalOrNode::evaluate(
+ const Record *records, size_t num_records, Bool *results) {
+ // Evaluate "arg1" for all the records.
+ // Then, evaluate "arg2" for non-true records.
+ grn_rc rc = arg1_->evaluate(records, num_records, results);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ if (temp_records_.size() < num_records) try {
+ temp_records_.resize(num_records);
+ } catch (const std::bad_alloc &) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ size_t count = 0;
+ for (size_t i = 0; i < num_records; ++i) {
+ if (results[i].raw == GRN_FALSE) {
+ temp_records_[count] = records[i];
+ ++count;
+ }
+ }
+ if (count == 0) {
+ // Nothing to do.
+ return GRN_SUCCESS;
+ }
+ rc = fill_arg2_values(&*temp_records_.begin(), count);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+
+ // Merge the evaluation results.
+ count = 0;
+ for (size_t i = 0; i < num_records; ++i) {
+ if (results[i].raw == GRN_FALSE) {
+ results[i] = arg2_values_[count];
+ ++count;
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+// -- GenericBinaryNode --
+
+template <typename T,
+ typename U = typename T::Value,
+ typename V = typename T::Arg1,
+ typename W = typename T::Arg2>
+class GenericBinaryNode : public BinaryNode<U, V, W> {
+ public:
+ GenericBinaryNode(ExpressionNode *arg1, ExpressionNode *arg2)
+ : BinaryNode<U, V, W>(arg1, arg2), operator_() {}
+ ~GenericBinaryNode() {}
+
+ grn_rc evaluate(
+ const Record *records, size_t num_records, Bool *results);
+
+ private:
+ T operator_;
+};
+
+template <typename T, typename U, typename V, typename W>
+grn_rc GenericBinaryNode<T, U, V, W>::evaluate(
+ const Record *records, size_t num_records, Bool *results) {
+ grn_rc rc = this->fill_arg1_values(records, num_records);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = this->fill_arg2_values(records, num_records);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ for (size_t i = 0; i < num_records; ++i) {
+ results[i] = operator_(this->arg1_values_[i], this->arg2_values_[i]);
+ }
+ return GRN_SUCCESS;
+}
+
+template <typename T, typename V, typename W>
+class GenericBinaryNode<T, Bool, V, W> : public BinaryNode<Bool, V, W> {
+ public:
+ GenericBinaryNode(ExpressionNode *arg1, ExpressionNode *arg2)
+ : BinaryNode<Bool, V, W>(arg1, arg2), operator_() {}
+ ~GenericBinaryNode() {}
+
+ grn_rc filter(
+ Record *input, size_t input_size,
+ Record *output, size_t *output_size);
+
+ grn_rc evaluate(
+ const Record *records, size_t num_records, Bool *results);
+
+ private:
+ T operator_;
+};
+
+template <typename T, typename V, typename W>
+grn_rc GenericBinaryNode<T, Bool, V, W>::filter(
+ Record *input, size_t input_size,
+ Record *output, size_t *output_size) {
+ grn_rc rc = this->fill_arg1_values(input, input_size);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = this->fill_arg2_values(input, input_size);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ size_t count = 0;
+ for (size_t i = 0; i < input_size; ++i) {
+ if (operator_(this->arg1_values_[i], this->arg2_values_[i]).raw ==
+ GRN_TRUE) {
+ output[count] = input[i];
+ ++count;
+ }
+ }
+ *output_size = count;
+ return GRN_SUCCESS;
+}
+
+template <typename T, typename V, typename W>
+grn_rc GenericBinaryNode<T, Bool, V, W>::evaluate(
+ const Record *records, size_t num_records, Bool *results) {
+ grn_rc rc = this->fill_arg1_values(records, num_records);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ rc = this->fill_arg2_values(records, num_records);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ for (size_t i = 0; i < num_records; ++i) {
+ results[i] = operator_(this->arg1_values_[i], this->arg2_values_[i]);
+ }
+ return GRN_SUCCESS;
+}
+
+// ----- EqualNode -----
+
+template <typename T>
+struct EqualOperator {
+ typedef Bool Value;
+ typedef T Arg1;
+ typedef T Arg2;
+ Value operator()(const Arg1 &arg1, const Arg2 &arg2) const {
+ return Bool(arg1 == arg2);
+ }
+};
+
+template <typename T>
+grn_rc equal_node_open(EqualOperator<T> op,
+ ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) {
+ GenericBinaryNode<EqualOperator<T> > *new_node =
+ new (std::nothrow) GenericBinaryNode<EqualOperator<T> >(arg1, arg2);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+}
+
+// ----- NotEqualNode -----
+
+template <typename T>
+struct NotEqualOperator {
+ typedef Bool Value;
+ typedef T Arg1;
+ typedef T Arg2;
+ Value operator()(const Arg1 &arg1, const Arg2 &arg2) const {
+ return Bool(arg1 != arg2);
+ }
+};
+
+template <typename T>
+grn_rc not_equal_node_open(NotEqualOperator<T> op,
+ ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) {
+ GenericBinaryNode<NotEqualOperator<T> > *new_node =
+ new (std::nothrow) GenericBinaryNode<NotEqualOperator<T> >(arg1, arg2);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+}
+
+// ----- LessNode -----
+
+template <typename T>
+struct LessOperator {
+ typedef Bool Value;
+ typedef T Arg1;
+ typedef T Arg2;
+ Value operator()(const Arg1 &arg1, const Arg2 &arg2) const {
+ return Bool(arg1 < arg2);
+ }
+};
+
+template <typename T>
+grn_rc less_node_open(LessOperator<T> op,
+ ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) {
+ GenericBinaryNode<LessOperator<T> > *new_node =
+ new (std::nothrow) GenericBinaryNode<LessOperator<T> >(arg1, arg2);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+}
+
+// ----- LessEqualNode -----
+
+template <typename T>
+struct LessEqualOperator {
+ typedef Bool Value;
+ typedef T Arg1;
+ typedef T Arg2;
+ Value operator()(const Arg1 &arg1, const Arg2 &arg2) const {
+ return Bool(arg1 < arg2);
+ }
+};
+
+template <typename T>
+grn_rc less_equal_node_open(LessEqualOperator<T> op,
+ ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) {
+ GenericBinaryNode<LessEqualOperator<T> > *new_node =
+ new (std::nothrow) GenericBinaryNode<LessEqualOperator<T> >(arg1, arg2);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+}
+
+// ----- GreaterNode -----
+
+template <typename T>
+struct GreaterOperator {
+ typedef Bool Value;
+ typedef T Arg1;
+ typedef T Arg2;
+ Value operator()(const Arg1 &arg1, const Arg2 &arg2) const {
+ return Bool(arg1 < arg2);
+ }
+};
+
+template <typename T>
+grn_rc greater_node_open(GreaterOperator<T> op,
+ ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) {
+ GenericBinaryNode<GreaterOperator<T> > *new_node =
+ new (std::nothrow) GenericBinaryNode<GreaterOperator<T> >(arg1, arg2);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+}
+
+// ----- GreaterEqualNode -----
+
+template <typename T>
+struct GreaterEqualOperator {
+ typedef Bool Value;
+ typedef T Arg1;
+ typedef T Arg2;
+ Value operator()(const Arg1 &arg1, const Arg2 &arg2) const {
+ return Bool(arg1 < arg2);
+ }
+};
+
+template <typename T>
+grn_rc greater_equal_node_open(GreaterEqualOperator<T> op,
+ ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) {
+ GenericBinaryNode<GreaterEqualOperator<T> > *new_node =
+ new (std::nothrow) GenericBinaryNode<GreaterEqualOperator<T> >(arg1, arg2);
+ if (!new_node) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *node = new_node;
+ return GRN_SUCCESS;
+}
+
+// -- ExpressionToken --
+
+enum ExpressionTokenType {
+ DUMMY_TOKEN,
+ CONSTANT_TOKEN,
+ NAME_TOKEN,
+ UNARY_OPERATOR_TOKEN,
+ BINARY_OPERATOR_TOKEN,
+ DEREFERENCE_TOKEN,
+ BRACKET_TOKEN
+};
+
+enum ExpressionBracketType {
+ LEFT_ROUND_BRACKET,
+ RIGHT_ROUND_BRACKET,
+ LEFT_SQUARE_BRACKET,
+ RIGHT_SQUARE_BRACKET
+};
+
+// TODO: std::string should not be used.
+class ExpressionToken {
+ public:
+ ExpressionToken() : string_(), type_(DUMMY_TOKEN), dummy_(0), priority_(0) {}
+ ExpressionToken(const std::string &string, ExpressionTokenType token_type)
+ : string_(string), type_(token_type), dummy_(0), priority_(0) {}
+ ExpressionToken(const std::string &string,
+ ExpressionBracketType bracket_type)
+ : string_(string), type_(BRACKET_TOKEN), bracket_type_(bracket_type),
+ priority_(0) {}
+ ExpressionToken(const std::string &string, OperatorType operator_type)
+ : string_(string), type_(get_operator_token_type(operator_type)),
+ operator_type_(operator_type),
+ priority_(get_operator_priority(operator_type)) {}
+
+ const std::string &string() const {
+ return string_;
+ }
+ ExpressionTokenType type() const {
+ return type_;
+ }
+ ExpressionBracketType bracket_type() const {
+ return bracket_type_;
+ }
+ OperatorType operator_type() const {
+ return operator_type_;
+ }
+ int priority() const {
+ return priority_;
+ }
+
+ private:
+ std::string string_;
+ ExpressionTokenType type_;
+ union {
+ int dummy_;
+ ExpressionBracketType bracket_type_;
+ OperatorType operator_type_;
+ };
+ int priority_;
+
+ static ExpressionTokenType get_operator_token_type(
+ OperatorType operator_type);
+ static int get_operator_priority(OperatorType operator_type);
+};
+
+ExpressionTokenType ExpressionToken::get_operator_token_type(
+ OperatorType operator_type) {
+ switch (operator_type) {
+ case GRN_OP_NOT: {
+ return UNARY_OPERATOR_TOKEN;
+ }
+ case GRN_OP_AND:
+ case GRN_OP_OR:
+ case GRN_OP_EQUAL:
+ case GRN_OP_NOT_EQUAL:
+ case GRN_OP_LESS:
+ case GRN_OP_LESS_EQUAL:
+ case GRN_OP_GREATER:
+ case GRN_OP_GREATER_EQUAL: {
+ return BINARY_OPERATOR_TOKEN;
+ }
+ default: {
+ // TODO: ERROR_TOKEN or something should be used...?
+ // Or, default should be removed?
+ return DUMMY_TOKEN;
+ }
+ }
+}
+
+int ExpressionToken::get_operator_priority(
+ OperatorType operator_type) {
+ switch (operator_type) {
+ case GRN_OP_NOT: {
+// case GRN_OP_BITWISE_NOT:
+// case GRN_OP_POSITIVE:
+// case GRN_OP_NEGATIVE:
+// case GRN_OP_TO_INT:
+// case GRN_OP_TO_FLOAT: {
+ return 3;
+ }
+ case GRN_OP_AND: {
+ return 13;
+ }
+ case GRN_OP_OR: {
+ return 14;
+ }
+ case GRN_OP_EQUAL:
+ case GRN_OP_NOT_EQUAL: {
+ return 9;
+ }
+ case GRN_OP_LESS:
+ case GRN_OP_LESS_EQUAL:
+ case GRN_OP_GREATER:
+ case GRN_OP_GREATER_EQUAL: {
+ return 8;
+ }
+// case GRN_OP_BITWISE_AND: {
+// return 10;
+// }
+// case GRN_OP_BITWISE_OR: {
+// return 12;
+// }
+// case GRN_OP_BITWISE_XOR: {
+// return 11;
+// }
+// case GRN_OP_PLUS:
+// case GRN_OP_MINUS: {
+// return 6;
+// }
+// case GRN_OP_MULTIPLICATION:
+// case GRN_OP_DIVISION:
+// case GRN_OP_MODULUS: {
+// return 5;
+// }
+// case GRN_OP_STARTS_WITH:
+// case GRN_OP_ENDS_WITH:
+// case GRN_OP_CONTAINS: {
+// return 7;
+// }
+// case GRN_OP_SUBSCRIPT: {
+// return 2;
+// }
+ default: {
+ return 100;
+ }
+ }
+}
+
+// -- ExpressionParser --
+
+class ExpressionParser {
+ public:
+ static grn_rc parse(grn_ctx *ctx, grn_obj *table,
+ const char *query, size_t query_size, Expression **expression);
+
+ private:
+ grn_ctx *ctx_;
+ grn_obj *table_;
+ std::vector<ExpressionToken> tokens_;
+ std::vector<ExpressionToken> stack_;
+ Expression *expression_;
+
+ ExpressionParser(grn_ctx *ctx, grn_obj *table)
+ : ctx_(ctx), table_(table), tokens_(), stack_(), expression_(NULL) {}
+ ~ExpressionParser() {
+ delete expression_;
+ }
+
+ grn_rc tokenize(const char *query, size_t query_size);
+ grn_rc compose();
+ grn_rc push_token(const ExpressionToken &token);
+};
+
+grn_rc ExpressionParser::parse(grn_ctx *ctx, grn_obj *table,
+ const char *query, size_t query_size, Expression **expression) {
+ ExpressionParser *parser = new (std::nothrow) ExpressionParser(ctx, table);
+ if (!parser) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ grn_rc rc = parser->tokenize(query, query_size);
+ if (rc == GRN_SUCCESS) {
+ rc = parser->compose();
+ if (rc == GRN_SUCCESS) {
+ *expression = parser->expression_;
+ parser->expression_ = NULL;
+ }
+ }
+ delete parser;
+ return rc;
+}
+
+grn_rc ExpressionParser::tokenize(const char *query, size_t query_size) {
+ const char *rest = query;
+ size_t rest_size = query_size;
+ while (rest_size != 0) {
+ // Ignore white-space characters.
+ size_t pos;
+ for (pos = 0; pos < rest_size; ++pos) {
+ if (!std::isspace(static_cast<uint8_t>(rest[pos]))) {
+ break;
+ }
+ }
+ rest += pos;
+ rest_size -= pos;
+ switch (rest[0]) {
+ case '!': {
+ if ((rest_size >= 2) && (rest[1] == '=')) {
+ tokens_.push_back(ExpressionToken("!=", GRN_OP_NOT_EQUAL));
+ rest += 2;
+ rest_size -= 2;
+ } else {
+ tokens_.push_back(ExpressionToken("!", GRN_OP_NOT));
+ ++rest;
+ --rest_size;
+ }
+ break;
+ }
+// case '~': {
+// tokens_.push_back(ExpressionToken("~", GRN_OP_BITWISE_NOT));
+// rest = rest.substring(1);
+// break;
+// }
+ case '=': {
+ if ((rest_size >= 2) && (rest[1] == '=')) {
+ tokens_.push_back(ExpressionToken("==", GRN_OP_EQUAL));
+ rest += 2;
+ rest_size -= 2;
+ } else {
+ return GRN_INVALID_ARGUMENT;
+ }
+ break;
+ }
+ case '<': {
+ if ((rest_size >= 2) && (rest[1] == '=')) {
+ tokens_.push_back(ExpressionToken("<=", GRN_OP_LESS_EQUAL));
+ rest += 2;
+ rest_size -= 2;
+ } else {
+ tokens_.push_back(ExpressionToken("<", GRN_OP_LESS));
+ ++rest;
+ --rest_size;
+ }
+ break;
+ }
+ case '>': {
+ if ((rest_size >= 2) && (rest[1] == '=')) {
+ tokens_.push_back(ExpressionToken(">=", GRN_OP_GREATER_EQUAL));
+ rest += 2;
+ rest_size -= 2;
+ } else {
+ tokens_.push_back(ExpressionToken(">", GRN_OP_GREATER));
+ ++rest;
+ --rest_size;
+ }
+ break;
+ }
+ case '&': {
+ if ((rest_size >= 2) && (rest[1] == '&')) {
+ tokens_.push_back(ExpressionToken("&&", GRN_OP_AND));
+ rest += 2;
+ rest_size -= 2;
+ } else {
+// tokens_.push_back(ExpressionToken("&", GRN_OP_BITWISE_AND));
+// ++rest;
+// --rest_size;
+ return GRN_INVALID_ARGUMENT;
+ }
+ break;
+ }
+ case '|': {
+ if ((rest_size >= 2) && (rest[1] == '|')) {
+ tokens_.push_back(ExpressionToken("||", GRN_OP_OR));
+ rest += 2;
+ rest_size -= 2;
+ } else {
+// tokens_.push_back(ExpressionToken("|", GRN_OP_BITWISE_OR));
+// ++rest;
+// --rest_size;
+ return GRN_INVALID_ARGUMENT;
+ }
+ break;
+ }
+// case '^': {
+// tokens_.push_back(ExpressionToken("^", GRN_OP_BITWISE_XOR));
+// rest = rest.substring(1);
+// break;
+// }
+// case '+': {
+// tokens_.push_back(ExpressionToken("+", GRN_OP_PLUS));
+// rest = rest.substring(1);
+// break;
+// }
+// case '-': {
+// tokens_.push_back(ExpressionToken("-", GRN_OP_MINUS));
+// rest = rest.substring(1);
+// break;
+// }
+// case '*': {
+// tokens_.push_back(ExpressionToken("*", GRN_OP_MULTIPLICATION));
+// rest = rest.substring(1);
+// break;
+// }
+// case '/': {
+// tokens_.push_back(ExpressionToken("/", GRN_OP_DIVISION));
+// rest = rest.substring(1);
+// break;
+// }
+// case '%': {
+// tokens_.push_back(ExpressionToken("%", GRN_OP_MODULUS));
+// rest = rest.substring(1);
+// break;
+// }
+// case '@': {
+// if ((rest_size >= 2) && (rest[1] == '^')) {
+// tokens_.push_back(ExpressionToken("@^", GRN_OP_STARTS_WITH));
+// rest = rest.substring(2);
+// } else if ((rest_size >= 2) && (rest[1] == '$')) {
+// tokens_.push_back(ExpressionToken("@$", GRN_OP_ENDS_WITH));
+// rest = rest.substring(2);
+// } else {
+// tokens_.push_back(ExpressionToken("@", GRN_OP_CONTAINS));
+// rest = rest.substring(1);
+// }
+// break;
+// }
+// case '.': {
+// tokens_.push_back(ExpressionToken(".", DEREFERENCE_TOKEN));
+// rest = rest.substring(1);
+// break;
+// }
+ case '(': {
+ tokens_.push_back(ExpressionToken("(", LEFT_ROUND_BRACKET));
+ ++rest;
+ --rest_size;
+ break;
+ }
+ case ')': {
+ tokens_.push_back(ExpressionToken(")", RIGHT_ROUND_BRACKET));
+ ++rest;
+ --rest_size;
+ break;
+ }
+// case '[': {
+// tokens_.push_back(ExpressionToken("[", LEFT_SQUARE_BRACKET));
+// rest = rest.substring(1);
+// break;
+// }
+// case ']': {
+// tokens_.push_back(ExpressionToken("]", RIGHT_SQUARE_BRACKET));
+// rest = rest.substring(1);
+// break;
+// }
+ case '"': {
+ for (pos = 1; pos < rest_size; ++pos) {
+ if (rest[pos] == '\\') {
+ if (pos == rest_size) {
+ break;
+ }
+ ++pos;
+ } else if (rest[pos] == '"') {
+ break;
+ }
+ }
+ if (pos == rest_size) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ tokens_.push_back(
+ ExpressionToken(std::string(rest + 1, pos - 1), CONSTANT_TOKEN));
+ rest += pos + 1;
+ rest_size -= pos + 1;
+ break;
+ }
+ case '0' ... '9': {
+ // TODO: Improve this.
+ for (pos = 1; pos < rest_size; ++pos) {
+ if (!std::isdigit(static_cast<uint8_t>(rest[pos]))) {
+ break;
+ }
+ }
+ tokens_.push_back(
+ ExpressionToken(std::string(rest, pos), CONSTANT_TOKEN));
+ rest += pos;
+ rest_size -= pos;
+ break;
+ }
+ case '_':
+ case 'A' ... 'Z':
+ case 'a' ... 'z': {
+ // TODO: Improve this.
+ for (pos = 1; pos < rest_size; ++pos) {
+ if ((rest[pos] != '_') && (!std::isalnum(rest[pos]))) {
+ break;
+ }
+ }
+ std::string token(rest, pos);
+ if ((token == "true") || (token == "false")) {
+ tokens_.push_back(ExpressionToken(token, CONSTANT_TOKEN));
+ } else {
+ tokens_.push_back(ExpressionToken(token, NAME_TOKEN));
+ }
+ rest += pos;
+ rest_size -= pos;
+ break;
+ }
+ default: {
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+ }
+ return GRN_SUCCESS;
+}
+
+grn_rc ExpressionParser::compose() {
+ if (tokens_.size() == 0) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ expression_ = new (std::nothrow) Expression(ctx_, table_);
+ grn_rc rc = push_token(ExpressionToken("(", LEFT_ROUND_BRACKET));
+ if (rc == GRN_SUCCESS) {
+ for (size_t i = 0; i < tokens_.size(); ++i) {
+ rc = push_token(tokens_[i]);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ }
+ if (rc == GRN_SUCCESS) {
+ rc = push_token(ExpressionToken(")", RIGHT_ROUND_BRACKET));
+ }
+ }
+ return rc;
+}
+
+grn_rc ExpressionParser::push_token(const ExpressionToken &token) {
+ grn_rc rc = GRN_SUCCESS;
+ switch (token.type()) {
+ case DUMMY_TOKEN: {
+ if ((stack_.size() != 0) && (stack_.back().type() == DUMMY_TOKEN)) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ stack_.push_back(token);
+ break;
+ }
+ case CONSTANT_TOKEN: {
+ grn_obj obj;
+ const std::string string = token.string();
+ if (std::isdigit(static_cast<uint8_t>(string[0]))) {
+ if (string.find_first_of('.') == string.npos) {
+ GRN_INT64_INIT(&obj, 0);
+ GRN_INT64_SET(ctx_, &obj, strtoll(string.c_str(), NULL, 10));
+ } else {
+ GRN_FLOAT_INIT(&obj, 0);
+ GRN_FLOAT_SET(ctx_, &obj, strtod(string.c_str(), NULL));
+ }
+ } else if (string == "true") {
+ GRN_BOOL_INIT(&obj, 0);
+ GRN_BOOL_SET(ctx_, &obj, GRN_TRUE);
+ } else if (string == "false") {
+ GRN_BOOL_INIT(&obj, 0);
+ GRN_BOOL_SET(ctx_, &obj, GRN_FALSE);
+ } else {
+ GRN_TEXT_INIT(&obj, 0);
+ GRN_TEXT_SET(ctx_, &obj, string.data(), string.size());
+ }
+ rc = push_token(ExpressionToken(string, DUMMY_TOKEN));
+ if (rc == GRN_SUCCESS) {
+ rc = expression_->push_object(&obj);
+ }
+ GRN_OBJ_FIN(ctx_, &obj);
+ break;
+ }
+ case NAME_TOKEN: {
+ rc = push_token(ExpressionToken(token.string(), DUMMY_TOKEN));
+ if (rc == GRN_SUCCESS) {
+ grn_obj *column = grn_obj_column(
+ ctx_, table_, token.string().data(), token.string().size());
+ rc = expression_->push_object(column);
+ }
+ break;
+ }
+ case UNARY_OPERATOR_TOKEN: {
+ if ((stack_.size() != 0) && (stack_.back().type() == DUMMY_TOKEN)) {
+ // A unary operator must not follow an operand.
+ return GRN_INVALID_ARGUMENT;
+ }
+ stack_.push_back(token);
+ break;
+ }
+ case BINARY_OPERATOR_TOKEN: {
+ if ((stack_.size() == 0) || (stack_.back().type() != DUMMY_TOKEN)) {
+ // A binary operator must follow an operand.
+ return GRN_INVALID_ARGUMENT;
+ }
+ // Apply previous operators if those are prior to the new operator.
+ while (stack_.size() >= 2) {
+ ExpressionToken operator_token = stack_[stack_.size() - 2];
+// if (operator_token.type() == DEREFERENCE_TOKEN) {
+// expression_->end_subexpression();
+// stack_.pop_back();
+// stack_.pop_back();
+// push_token(ExpressionToken("", DUMMY_TOKEN));
+// } else if (operator_token.type() == UNARY_OPERATOR_TOKEN) {
+ if (operator_token.type() == UNARY_OPERATOR_TOKEN) {
+ rc = expression_->push_operator(operator_token.operator_type());
+ if (rc == GRN_SUCCESS) {
+ stack_.pop_back();
+ stack_.pop_back();
+ rc = push_token(ExpressionToken("", DUMMY_TOKEN));
+ }
+ } else if ((operator_token.type() == BINARY_OPERATOR_TOKEN) &&
+ (operator_token.priority() <= token.priority())) {
+ rc = expression_->push_operator(operator_token.operator_type());
+ if (rc == GRN_SUCCESS) {
+ stack_.pop_back();
+ stack_.pop_back();
+ stack_.pop_back();
+ rc = push_token(ExpressionToken("", DUMMY_TOKEN));
+ }
+ } else {
+ break;
+ }
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ stack_.push_back(token);
+ break;
+ }
+// case DEREFERENCE_TOKEN: {
+// builder_->begin_subexpression();
+// stack_.pop_back();
+// stack_.push_back(token);
+// break;
+// }
+ case BRACKET_TOKEN: {
+ if (token.bracket_type() == LEFT_ROUND_BRACKET) {
+ // A left round bracket must not follow a dummy.
+ if ((stack_.size() != 0) && (stack_.back().type() == DUMMY_TOKEN)) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ stack_.push_back(token);
+ } else if (token.bracket_type() == RIGHT_ROUND_BRACKET) {
+ // A right round bracket must follow a dummy.
+ // A left round bracket must exist before a right round bracket.
+ if ((stack_.size() < 2) || (stack_.back().type() != DUMMY_TOKEN)) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ // Apply operators in brackets.
+ while (stack_.size() >= 2) {
+ ExpressionToken operator_token = stack_[stack_.size() - 2];
+// if (operator_token.type() == DEREFERENCE_TOKEN) {
+// rc = expression_->end_subexpression();
+// if (rc == GRN_SUCCESS) {
+// stack_.pop_back();
+// stack_.pop_back();
+// rc = push_token(ExpressionToken("", DUMMY_TOKEN));
+// }
+// } else if (operator_token.type() == UNARY_OPERATOR_TOKEN) {
+ if (operator_token.type() == UNARY_OPERATOR_TOKEN) {
+ rc = expression_->push_operator(operator_token.operator_type());
+ if (rc == GRN_SUCCESS) {
+ stack_.pop_back();
+ stack_.pop_back();
+ rc = push_token(ExpressionToken("", DUMMY_TOKEN));
+ }
+ } else if (operator_token.type() == BINARY_OPERATOR_TOKEN) {
+ rc = expression_->push_operator(operator_token.operator_type());
+ if (rc == GRN_SUCCESS) {
+ stack_.pop_back();
+ stack_.pop_back();
+ stack_.pop_back();
+ rc = push_token(ExpressionToken("", DUMMY_TOKEN));
+ }
+ } else {
+ break;
+ }
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ }
+ if ((stack_.size() < 2) ||
+ (stack_[stack_.size() - 2].type() != BRACKET_TOKEN) ||
+ (stack_[stack_.size() - 2].bracket_type() != LEFT_ROUND_BRACKET)) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ stack_[stack_.size() - 2] = stack_.back();
+ stack_.pop_back();
+// } else if (token.bracket_type() == LEFT_SQUARE_BRACKET) {
+// // A left square bracket must follow a dummy.
+// if ((stack_.size() == 0) || (stack_.back().type() != DUMMY_TOKEN)) {
+// return GRN_INVALID_ARGUMENT;
+// }
+// stack_.push_back(token);
+// } else if (token.bracket_type() == RIGHT_SQUARE_BRACKET) {
+// // A right round bracket must follow a dummy.
+// // A left round bracket must exist before a right round bracket.
+// if ((stack_.size() < 2) || (stack_.back().type() != DUMMY_TOKEN)) {
+// return GRN_INVALID_ARGUMENT;
+// }
+// // Apply operators in bracket.
+// while (stack_.size() >= 2) {
+// ExpressionToken operator_token = stack_[stack_.size() - 2];
+// if (operator_token.type() == DEREFERENCE_TOKEN) {
+// builder_->end_subexpression();
+// stack_.pop_back();
+// stack_.pop_back();
+// push_token(ExpressionToken("", DUMMY_TOKEN));
+// } else if (operator_token.type() == UNARY_OPERATOR_TOKEN) {
+// builder_->push_operator(operator_token.operator_type());
+// stack_.pop_back();
+// stack_.pop_back();
+// push_token(ExpressionToken("", DUMMY_TOKEN));
+// } else if (operator_token.type() == BINARY_OPERATOR_TOKEN) {
+// builder_->push_operator(operator_token.operator_type());
+// stack_.pop_back();
+// stack_.pop_back();
+// stack_.pop_back();
+// push_token(ExpressionToken("", DUMMY_TOKEN));
+// } else {
+// break;
+// }
+// }
+// if ((stack_.size() < 2) ||
+// (stack_[stack_.size() - 2].type() != BRACKET_TOKEN) ||
+// (stack_[stack_.size() - 2].bracket_type() != LEFT_SQUARE_BRACKET)) {
+// return GRN_INVALID_ARGUMENT;
+// }
+// stack_.pop_back();
+// stack_.pop_back();
+// builder_->push_operator(GRNXX_SUBSCRIPT);
+ } else {
+ return GRN_INVALID_ARGUMENT;
+ }
+ break;
+ }
+ default: {
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+ return rc;
+}
+
+// -- Expression --
+
+Expression::Expression(grn_ctx *ctx, grn_obj *table)
+ : ctx_(ctx), table_(table), type_(GRN_EGN_INCOMPLETE),
+ data_type_(GRN_DB_VOID), stack_() {}
+
+Expression::~Expression() {
+ for (size_t i = 0; i < stack_.size(); ++i) {
+ delete stack_[i];
+ }
+}
+
+grn_rc Expression::open(
+ grn_ctx *ctx, grn_obj *table, Expression **expression) {
+ if (!ctx || !grn_egn_is_table(table) || !expression) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ Expression *new_expression = new (std::nothrow) Expression(ctx, table);
+ if (!new_expression) {
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ *expression = new_expression;
+ return GRN_SUCCESS;
+}
+
+grn_rc Expression::parse(grn_ctx *ctx, grn_obj *table,
+ const char *query, size_t query_size, Expression **expression) {
+ if (!ctx || !grn_egn_is_table(table) ||
+ !query || (query_size == 0) || !expression) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ return ExpressionParser::parse(ctx, table, query, query_size, expression);
+}
+
+grn_rc Expression::push_object(grn_obj *obj) {
+ if (!obj) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ grn_rc rc = GRN_UNKNOWN_ERROR;
+ switch (obj->header.type) {
+ case GRN_BULK: {
+ rc = push_bulk_object(obj);
+ break;
+ }
+ case GRN_UVECTOR: {
+ // FIXME: To be supported.
+ return GRN_INVALID_ARGUMENT;
+ }
+ case GRN_VECTOR: {
+ // FIXME: To be supported.
+ return GRN_INVALID_ARGUMENT;
+ }
+ case GRN_ACCESSOR: {
+ grn_accessor *accessor = (grn_accessor *)obj;
+ switch (accessor->action) {
+ case GRN_ACCESSOR_GET_ID: {
+ ExpressionNode *node;
+ rc = IDNode::open(&node);
+ if (rc == GRN_SUCCESS) try {
+ stack_.push_back(node);
+ } catch (const std::bad_alloc &) {
+ delete node;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ break;
+ }
+ case GRN_ACCESSOR_GET_KEY: {
+ // TODO: KeyNode should be provided for performance.
+ ExpressionNode *node;
+ grn_id range = grn_obj_get_range(ctx_, obj);
+ switch (range) {
+ case GRN_DB_BOOL: {
+ rc = ColumnNode<Bool>::open(ctx_, obj, &node);
+ break;
+ }
+ case GRN_DB_INT8:
+ case GRN_DB_INT16:
+ case GRN_DB_INT32:
+ case GRN_DB_INT64:
+ case GRN_DB_UINT8:
+ case GRN_DB_UINT16:
+ case GRN_DB_UINT32:
+ case GRN_DB_UINT64: {
+ rc = ColumnNode<Int>::open(ctx_, obj, &node);
+ break;
+ }
+ case GRN_DB_FLOAT: {
+ rc = ColumnNode<Float>::open(ctx_, obj, &node);
+ break;
+ }
+ case GRN_DB_TIME: {
+ rc = ColumnNode<Time>::open(ctx_, obj, &node);
+ break;
+ }
+ case GRN_DB_TOKYO_GEO_POINT:
+ case GRN_DB_WGS84_GEO_POINT: {
+ rc = ColumnNode<GeoPoint>::open(ctx_, obj, &node);
+ break;
+ }
+ default: {
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+ if (rc == GRN_SUCCESS) try {
+ stack_.push_back(node);
+ } catch (const std::bad_alloc &) {
+ delete node;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ break;
+ }
+ case GRN_ACCESSOR_GET_VALUE: {
+ // TODO
+ return GRN_INVALID_ARGUMENT;
+ }
+ case GRN_ACCESSOR_GET_SCORE: {
+ ExpressionNode *node;
+ rc = ScoreNode::open(&node);
+ if (rc == GRN_SUCCESS) try {
+ stack_.push_back(node);
+ } catch (const std::bad_alloc &) {
+ delete node;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ break;
+ }
+ default: {
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+ break;
+ }
+ case GRN_COLUMN_FIX_SIZE:
+ case GRN_COLUMN_VAR_SIZE: {
+ rc = push_column_object(obj);
+ break;
+ }
+ default: {
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+ if (rc == GRN_SUCCESS) {
+ update_types();
+ }
+ return rc;
+}
+
+grn_rc Expression::push_operator(OperatorType operator_type) {
+ grn_rc rc = GRN_UNKNOWN_ERROR;
+ ExpressionNode *node;
+ switch (operator_type) {
+ case GRN_OP_NOT: {
+ if (stack_.size() < 1) {
+ return GRN_INVALID_FORMAT;
+ }
+ ExpressionNode *arg = stack_[stack_.size() - 1];
+ rc = create_unary_node(operator_type, arg, &node);
+ if (rc == GRN_SUCCESS) {
+ stack_.resize(stack_.size() - 1);
+ }
+ break;
+ }
+ case GRN_OP_AND:
+ case GRN_OP_OR:
+ case GRN_OP_EQUAL:
+ case GRN_OP_NOT_EQUAL:
+ case GRN_OP_LESS:
+ case GRN_OP_LESS_EQUAL:
+ case GRN_OP_GREATER:
+ case GRN_OP_GREATER_EQUAL: {
+ if (stack_.size() < 2) {
+ return GRN_INVALID_FORMAT;
+ }
+ ExpressionNode *arg1 = stack_[stack_.size() - 2];
+ ExpressionNode *arg2 = stack_[stack_.size() - 1];
+ rc = create_binary_node(operator_type, arg1, arg2, &node);
+ if (rc == GRN_SUCCESS) {
+ stack_.resize(stack_.size() - 2);
+ }
+ break;
+ }
+ default: {
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+ if (rc == GRN_SUCCESS) {
+ stack_.push_back(node);
+ update_types();
+ }
+ return rc;
+}
+
+grn_rc Expression::filter(
+ Record *input, size_t input_size,
+ Record *output, size_t *output_size) {
+ if ((!input && (input_size != 0)) ||
+ ((output > input) && (output < (input + input_size))) || !output_size) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ ExpressionNode *root = this->root();
+ if (!root) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ if (!output) {
+ output = input;
+ }
+ size_t total_output_size = 0;
+ while (input_size > 0) {
+ size_t batch_input_size = GRN_EGN_MAX_BATCH_SIZE;
+ if (input_size < batch_input_size) {
+ batch_input_size = input_size;
+ }
+ size_t batch_output_size;
+ grn_rc rc = root->filter(
+ input, batch_input_size, output, &batch_output_size);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ input += batch_input_size;
+ input_size -= batch_input_size;
+ output += batch_output_size;
+ total_output_size += batch_output_size;
+ }
+ *output_size = total_output_size;
+ return GRN_SUCCESS;
+}
+
+grn_rc Expression::adjust(Record *records, size_t num_records) {
+ if (!records && (num_records != 0)) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ ExpressionNode *root = this->root();
+ if (!root) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ while (num_records > 0) {
+ size_t batch_size = GRN_EGN_MAX_BATCH_SIZE;
+ if (num_records < batch_size) {
+ batch_size = num_records;
+ }
+ grn_rc rc = root->adjust(records, batch_size);
+ if (rc != GRN_SUCCESS) {
+ return rc;
+ }
+ records += batch_size;
+ num_records -= batch_size;
+ }
+ return GRN_SUCCESS;
+}
+
+template <typename T>
+grn_rc Expression::evaluate(
+ const Record *records, size_t num_records, T *results) {
+ if (((!records || !results) && (num_records != 0)) ||
+ (T::data_type() != data_type())) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ ExpressionNode *root = this->root();
+ if (!root) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ // FIXME: Records should be processed per block.
+ // However, the contents of old blocks will be lost.
+ return static_cast<TypedNode<T> *>(root)->evaluate(
+ records, num_records, results);
+}
+
+template grn_rc Expression::evaluate(
+ const Record *records, size_t num_records, Bool *results);
+template grn_rc Expression::evaluate(
+ const Record *records, size_t num_records, Int *results);
+template grn_rc Expression::evaluate(
+ const Record *records, size_t num_records, Float *results);
+template grn_rc Expression::evaluate(
+ const Record *records, size_t num_records, Time *results);
+template grn_rc Expression::evaluate(
+ const Record *records, size_t num_records, Text *results);
+template grn_rc Expression::evaluate(
+ const Record *records, size_t num_records, GeoPoint *results);
+
+ExpressionNode *Expression::root() const {
+ if (stack_.size() != 1) {
+ return NULL;
+ }
+ return stack_.front();
+}
+
+void Expression::update_types() {
+ ExpressionNode *root = this->root();
+ if (!root) {
+ type_ = GRN_EGN_INCOMPLETE;
+ data_type_ = GRN_DB_VOID;
+ } else {
+ switch (root->type()) {
+ case GRN_EGN_ID_NODE: {
+ type_ = GRN_EGN_ID;
+ break;
+ }
+ case GRN_EGN_SCORE_NODE: {
+ type_ = GRN_EGN_SCORE;
+ break;
+ }
+ case GRN_EGN_CONSTANT_NODE: {
+ type_ = GRN_EGN_CONSTANT;
+ break;
+ }
+ case GRN_EGN_COLUMN_NODE:
+ case GRN_EGN_OPERATOR_NODE: {
+ type_ = GRN_EGN_VARIABLE;
+ break;
+ }
+ default: {
+ type_ = GRN_EGN_INCOMPLETE;
+ break;
+ }
+ }
+ data_type_ = root->data_type();
+ }
+}
+
+grn_rc Expression::push_bulk_object(grn_obj *obj) {
+ grn_rc rc;
+ ExpressionNode *node;
+ switch (obj->header.domain) {
+ case GRN_DB_BOOL: {
+ rc = ConstantNode<Bool>::open(Bool(GRN_BOOL_VALUE(obj)), &node);
+ break;
+ }
+ case GRN_DB_INT8: {
+ rc = ConstantNode<Int>::open(Int(GRN_INT8_VALUE(obj)), &node);
+ break;
+ }
+ case GRN_DB_INT16: {
+ rc = ConstantNode<Int>::open(Int(GRN_INT16_VALUE(obj)), &node);
+ break;
+ }
+ case GRN_DB_INT32: {
+ rc = ConstantNode<Int>::open(Int(GRN_INT32_VALUE(obj)), &node);
+ break;
+ }
+ case GRN_DB_INT64: {
+ rc = ConstantNode<Int>::open(Int(GRN_INT64_VALUE(obj)), &node);
+ break;
+ }
+ case GRN_DB_UINT8: {
+ rc = ConstantNode<Int>::open(Int(GRN_UINT8_VALUE(obj)), &node);
+ break;
+ }
+ case GRN_DB_UINT16: {
+ rc = ConstantNode<Int>::open(Int(GRN_UINT16_VALUE(obj)), &node);
+ break;
+ }
+ case GRN_DB_UINT32: {
+ rc = ConstantNode<Int>::open(Int(GRN_UINT32_VALUE(obj)), &node);
+ break;
+ }
+ case GRN_DB_UINT64: {
+ // FIXME: Type conversion from UInt64 to Int may lose the content.
+ rc = ConstantNode<Int>::open(Int(GRN_UINT64_VALUE(obj)), &node);
+ break;
+ }
+ case GRN_DB_FLOAT: {
+ rc = ConstantNode<Float>::open(Float(GRN_FLOAT_VALUE(obj)), &node);
+ break;
+ }
+ case GRN_DB_TIME: {
+ rc = ConstantNode<Time>::open(Time(GRN_TIME_VALUE(obj)), &node);
+ break;
+ }
+ case GRN_DB_SHORT_TEXT:
+ case GRN_DB_TEXT:
+ case GRN_DB_LONG_TEXT: {
+ Text value(GRN_TEXT_VALUE(obj), GRN_TEXT_LEN(obj));
+ rc = ConstantNode<Text>::open(value, &node);
+ break;
+ }
+ // TODO: TokyoGeoPoint and Wgs84GeoPoint should be provided?
+ case GRN_DB_TOKYO_GEO_POINT:
+ case GRN_DB_WGS84_GEO_POINT: {
+ GeoPoint value;
+ GRN_GEO_POINT_VALUE(obj, value.raw.latitude, value.raw.longitude);
+ rc = ConstantNode<GeoPoint>::open(value, &node);
+ break;
+ }
+ default: {
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+ if (rc == GRN_SUCCESS) try {
+ stack_.push_back(node);
+ } catch (const std::bad_alloc &) {
+ delete node;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ return rc;
+}
+
+grn_rc Expression::push_column_object(grn_obj *obj) {
+ grn_obj *owner_table = grn_column_table(ctx_, obj);
+ if (owner_table != table_) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ grn_id range = grn_obj_get_range(ctx_, obj);
+ grn_rc rc;
+ ExpressionNode *node;
+ switch (obj->header.type) {
+ case GRN_COLUMN_FIX_SIZE: {
+ switch (range) {
+ case GRN_DB_BOOL: {
+ rc = ColumnNode<Bool>::open(ctx_, obj, &node);
+ break;
+ }
+ case GRN_DB_INT8:
+ case GRN_DB_INT16:
+ case GRN_DB_INT32:
+ case GRN_DB_INT64:
+ case GRN_DB_UINT8:
+ case GRN_DB_UINT16:
+ case GRN_DB_UINT32:
+ case GRN_DB_UINT64: {
+ rc = ColumnNode<Int>::open(ctx_, obj, &node);
+ break;
+ }
+ case GRN_DB_FLOAT: {
+ rc = ColumnNode<Float>::open(ctx_, obj, &node);
+ break;
+ }
+ case GRN_DB_TIME: {
+ rc = ColumnNode<Time>::open(ctx_, obj, &node);
+ break;
+ }
+ case GRN_DB_TOKYO_GEO_POINT:
+ case GRN_DB_WGS84_GEO_POINT: {
+ rc = ColumnNode<GeoPoint>::open(ctx_, obj, &node);
+ break;
+ }
+ default: {
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+ break;
+ }
+ case GRN_COLUMN_VAR_SIZE: {
+ grn_obj_flags column_type = obj->header.flags & GRN_OBJ_COLUMN_TYPE_MASK;
+ switch (column_type) {
+ case GRN_OBJ_COLUMN_SCALAR: {
+ switch (range) {
+ case GRN_DB_SHORT_TEXT:
+ case GRN_DB_TEXT:
+ case GRN_DB_LONG_TEXT: {
+ rc = ColumnNode<Text>::open(ctx_, obj, &node);
+ break;
+ }
+ default: {
+ return GRN_INVALID_ARGUMENT;
+ }
+ break;
+ }
+ break;
+ }
+ case GRN_OBJ_COLUMN_VECTOR: {
+ return GRN_OPERATION_NOT_SUPPORTED;
+ }
+ default: {
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+ break;
+ }
+ default: {
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+ if (rc == GRN_SUCCESS) try {
+ stack_.push_back(node);
+ } catch (const std::bad_alloc &) {
+ delete node;
+ return GRN_NO_MEMORY_AVAILABLE;
+ }
+ return rc;
+}
+
+grn_rc Expression::create_unary_node(OperatorType operator_type,
+ ExpressionNode *arg, ExpressionNode **node) {
+ grn_rc rc = GRN_SUCCESS;
+ switch (operator_type) {
+ case GRN_OP_NOT: {
+ if (arg->data_type() != GRN_DB_BOOL) {
+ return GRN_UNKNOWN_ERROR;
+ }
+ rc = LogicalNotNode::open(arg, node);
+ break;
+ }
+ default: {
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+ return rc;
+}
+
+grn_rc Expression::create_binary_node(OperatorType operator_type,
+ ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node) {
+ switch (operator_type) {
+ case GRN_OP_AND: {
+ if ((arg1->data_type() != GRN_DB_BOOL) ||
+ (arg1->data_type() != GRN_DB_BOOL)) {
+ return GRN_INVALID_FORMAT;
+ }
+ return LogicalAndNode::open(arg1, arg2, node);
+ }
+ case GRN_OP_OR: {
+ if ((arg1->data_type() != GRN_DB_BOOL) ||
+ (arg1->data_type() != GRN_DB_BOOL)) {
+ return GRN_INVALID_FORMAT;
+ }
+ return LogicalOrNode::open(arg1, arg2, node);
+ }
+ case GRN_OP_EQUAL: {
+ if (arg1->data_type() != arg2->data_type()) {
+ return GRN_INVALID_FORMAT;
+ }
+ switch (arg1->data_type()) {
+ case GRN_DB_BOOL: {
+ return equal_node_open(EqualOperator<Bool>(), arg1, arg2, node);
+ }
+ case GRN_DB_INT64: {
+ return equal_node_open(EqualOperator<Int>(), arg1, arg2, node);
+ }
+ case GRN_DB_FLOAT: {
+ return equal_node_open(EqualOperator<Float>(), arg1, arg2, node);
+ }
+ case GRN_DB_TIME: {
+ return equal_node_open(EqualOperator<Time>(), arg1, arg2, node);
+ }
+ case GRN_DB_TEXT: {
+ return equal_node_open(EqualOperator<Text>(), arg1, arg2, node);
+ }
+ case GRN_DB_WGS84_GEO_POINT: {
+ return equal_node_open(EqualOperator<GeoPoint>(), arg1, arg2, node);
+ }
+ default: {
+ return GRN_UNKNOWN_ERROR;
+ }
+ }
+ }
+ case GRN_OP_NOT_EQUAL: {
+ if (arg1->data_type() != arg2->data_type()) {
+ return GRN_INVALID_FORMAT;
+ }
+ switch (arg1->data_type()) {
+ case GRN_DB_BOOL: {
+ return not_equal_node_open(
+ NotEqualOperator<Bool>(), arg1, arg2, node);
+ }
+ case GRN_DB_INT64: {
+ return not_equal_node_open(
+ NotEqualOperator<Int>(), arg1, arg2, node);
+ }
+ case GRN_DB_FLOAT: {
+ return not_equal_node_open(
+ NotEqualOperator<Float>(), arg1, arg2, node);
+ }
+ case GRN_DB_TIME: {
+ return not_equal_node_open(
+ NotEqualOperator<Time>(), arg1, arg2, node);
+ }
+ case GRN_DB_TEXT: {
+ return not_equal_node_open(
+ NotEqualOperator<Text>(), arg1, arg2, node);
+ }
+ case GRN_DB_WGS84_GEO_POINT: {
+ return not_equal_node_open(
+ NotEqualOperator<GeoPoint>(), arg1, arg2, node);
+ }
+ default: {
+ return GRN_UNKNOWN_ERROR;
+ }
+ }
+ }
+ case GRN_OP_LESS: {
+ if (arg1->data_type() != arg2->data_type()) {
+ return GRN_INVALID_FORMAT;
+ }
+ switch (arg1->data_type()) {
+ case GRN_DB_INT64: {
+ return less_node_open(LessOperator<Int>(), arg1, arg2, node);
+ }
+ case GRN_DB_FLOAT: {
+ return less_node_open(LessOperator<Float>(), arg1, arg2, node);
+ }
+ case GRN_DB_TIME: {
+ return less_node_open(LessOperator<Time>(), arg1, arg2, node);
+ }
+ case GRN_DB_TEXT: {
+ return less_node_open(LessOperator<Text>(), arg1, arg2, node);
+ }
+ default: {
+ return GRN_UNKNOWN_ERROR;
+ }
+ }
+ }
+ case GRN_OP_LESS_EQUAL: {
+ if (arg1->data_type() != arg2->data_type()) {
+ return GRN_INVALID_FORMAT;
+ }
+ switch (arg1->data_type()) {
+ case GRN_DB_INT64: {
+ return less_equal_node_open(
+ LessEqualOperator<Int>(), arg1, arg2, node);
+ }
+ case GRN_DB_FLOAT: {
+ return less_equal_node_open(
+ LessEqualOperator<Float>(), arg1, arg2, node);
+ }
+ case GRN_DB_TIME: {
+ return less_equal_node_open(
+ LessEqualOperator<Time>(), arg1, arg2, node);
+ }
+ case GRN_DB_TEXT: {
+ return less_equal_node_open(
+ LessEqualOperator<Text>(), arg1, arg2, node);
+ }
+ default: {
+ return GRN_UNKNOWN_ERROR;
+ }
+ }
+ }
+ case GRN_OP_GREATER: {
+ if (arg1->data_type() != arg2->data_type()) {
+ return GRN_INVALID_FORMAT;
+ }
+ switch (arg1->data_type()) {
+ case GRN_DB_INT64: {
+ return greater_node_open(GreaterOperator<Int>(), arg1, arg2, node);
+ }
+ case GRN_DB_FLOAT: {
+ return greater_node_open(GreaterOperator<Float>(), arg1, arg2, node);
+ }
+ case GRN_DB_TIME: {
+ return greater_node_open(GreaterOperator<Time>(), arg1, arg2, node);
+ }
+ case GRN_DB_TEXT: {
+ return greater_node_open(GreaterOperator<Text>(), arg1, arg2, node);
+ }
+ default: {
+ return GRN_UNKNOWN_ERROR;
+ }
+ }
+ }
+ case GRN_OP_GREATER_EQUAL: {
+ if (arg1->data_type() != arg2->data_type()) {
+ return GRN_INVALID_FORMAT;
+ }
+ switch (arg1->data_type()) {
+ case GRN_DB_INT64: {
+ return greater_equal_node_open(
+ GreaterEqualOperator<Int>(), arg1, arg2, node);
+ }
+ case GRN_DB_FLOAT: {
+ return greater_equal_node_open(
+ GreaterEqualOperator<Float>(), arg1, arg2, node);
+ }
+ case GRN_DB_TIME: {
+ return greater_equal_node_open(
+ GreaterEqualOperator<Time>(), arg1, arg2, node);
+ }
+ case GRN_DB_TEXT: {
+ return greater_equal_node_open(
+ GreaterEqualOperator<Text>(), arg1, arg2, node);
+ }
+ default: {
+ return GRN_UNKNOWN_ERROR;
+ }
+ }
+ }
+ default: {
+ return GRN_INVALID_ARGUMENT;
+ }
+ }
+}
+
+} // namespace egn
+} // namespace grn
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static grn_rc
+grn_egn_select_filter(grn_ctx *ctx, grn_obj *table,
+ const char *filter, size_t filter_size,
+ int offset, int limit,
+ std::vector<grn_egn_record> *records,
+ size_t *num_hits) {
+ if (offset < 0) {
+ offset = 0;
+ }
+ if (limit < 0) {
+ limit = std::numeric_limits<int>::max();
+ }
+ grn::egn::Cursor *cursor;
+ grn_rc rc = grn::egn::Cursor::open_table_cursor(ctx, table, &cursor);
+ if (rc == GRN_SUCCESS) {
+ grn::egn::Expression *expression;
+ rc = grn::egn::Expression::parse(
+ ctx, table, filter, filter_size, &expression);
+ if (rc == GRN_SUCCESS) {
+ size_t count = 0;
+ for ( ; ; ) {
+ size_t records_offset = records->size();
+ try {
+ records->resize(records->size() + GRN_EGN_MAX_BATCH_SIZE);
+ } catch (const std::bad_alloc &) {
+ rc = GRN_NO_MEMORY_AVAILABLE;
+ break;
+ }
+ size_t batch_size;
+ rc = cursor->read(&(*records)[records_offset],
+ GRN_EGN_MAX_BATCH_SIZE, &batch_size);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ if (batch_size == 0) {
+ records->resize(records_offset);
+ break;
+ }
+ rc = expression->filter(&(*records)[records_offset], batch_size,
+ NULL, &batch_size);
+ if (rc != GRN_SUCCESS) {
+ break;
+ }
+ count += batch_size;
+ if (offset > 0) {
+ if (offset >= batch_size) {
+ offset -= batch_size;
+ batch_size = 0;
+ } else {
+ std::memcpy(&(*records)[0], &(*records)[offset],
+ sizeof(grn_egn_record) * (batch_size - offset));
+ batch_size -= offset;
+ offset = 0;
+ }
+ }
+ if (limit >= batch_size) {
+ limit -= batch_size;
+ } else {
+ batch_size = limit;
+ limit = 0;
+ }
+ records->resize(records_offset + batch_size);
+ }
+ delete expression;
+ *num_hits = count;
+ }
+ delete cursor;
+ }
+ return rc;
+}
+
+static grn_rc
+grn_egn_select_output(grn_ctx *ctx, grn_obj *table,
+ const char *output_columns, size_t output_columns_size,
+ const grn_egn_record *records, size_t num_records,
+ size_t num_hits) {
+ grn_rc rc = GRN_SUCCESS;
+ std::vector<std::string> names;
+ std::vector<grn::egn::Expression *> expressions;
+
+ const char *rest = output_columns;
+ size_t rest_size = output_columns_size;
+ while (rest_size != 0) {
+ size_t pos;
+ for (pos = 0; pos < rest_size; ++pos) {
+ if ((rest[pos] != ',') &&
+ !std::isspace(static_cast<unsigned char>(rest[pos]))) {
+ break;
+ }
+ }
+ if (pos >= rest_size) {
+ break;
+ }
+ rest += pos;
+ rest_size -= pos;
+ for (pos = 0; pos < rest_size; ++pos) {
+ if ((rest[pos] == ',') ||
+ std::isspace(static_cast<unsigned char>(rest[pos]))) {
+ break;
+ }
+ }
+ // TODO: Error handling.
+ std::string name(rest, pos);
+ if (name == "*") {
+ grn_hash *columns;
+ if ((columns = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY))) {
+ if (grn_table_columns(ctx, table, "", 0, (grn_obj *)columns)) {
+ grn_id *key;
+ GRN_HASH_EACH(ctx, columns, id, &key, NULL, NULL, {
+ grn_obj *column = grn_ctx_at(ctx, *key);
+ if (column) {
+ char name_buf[1024];
+ int name_size = grn_column_name(
+ ctx, column, name_buf, sizeof(name_buf));
+ grn::egn::Expression *expression;
+ grn_rc r = grn::egn::Expression::open(ctx, table, &expression);
+ if (r == GRN_SUCCESS) {
+ r = expression->push_object(column);
+ if (r == GRN_SUCCESS) {
+ names.push_back(std::string(name_buf, name_size));
+ expressions.push_back(expression);
+ }
+ }
+ }
+ });
+ }
+ grn_hash_close(ctx, columns);
+ }
+ } else {
+ grn::egn::Expression *expression;
+ grn_rc r = grn::egn::Expression::parse(
+ ctx, table, rest, pos, &expression);
+ if (r == GRN_SUCCESS) {
+ names.push_back(name);
+ expressions.push_back(expression);
+ }
+ }
+ if (pos >= rest_size) {
+ break;
+ }
+ rest += pos + 1;
+ rest_size -= pos + 1;
+ }
+
+ GRN_OUTPUT_ARRAY_OPEN("RESULT", 1);
+ GRN_OUTPUT_ARRAY_OPEN("RESULTSET", 2 + num_records);
+ GRN_OUTPUT_ARRAY_OPEN("NHITS", 1);
+ grn_text_ulltoa(ctx, ctx->impl->outbuf, num_hits);
+ GRN_OUTPUT_ARRAY_CLOSE(); // NHITS.
+ GRN_OUTPUT_ARRAY_OPEN("COLUMNS", expressions.size());
+ for (size_t i = 0; i < expressions.size(); ++i) {
+ GRN_OUTPUT_ARRAY_OPEN("COLUMN", 2);
+ GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, '"');
+ GRN_TEXT_PUT(ctx, ctx->impl->outbuf, names[i].data(), names[i].size());
+ GRN_TEXT_PUT(ctx, ctx->impl->outbuf, "\",\"", 3);
+ switch (expressions[i]->data_type()) {
+ case GRN_DB_BOOL: {
+ GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "Bool");
+ break;
+ }
+ case GRN_DB_INT64: {
+ GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "Int64");
+ break;
+ }
+ case GRN_DB_FLOAT: {
+ GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "Float");
+ break;
+ }
+ case GRN_DB_TIME: {
+ GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "Time");
+ break;
+ }
+ case GRN_DB_SHORT_TEXT:
+ case GRN_DB_TEXT:
+ case GRN_DB_LONG_TEXT: {
+ GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "Text");
+ break;
+ }
+ case GRN_DB_WGS84_GEO_POINT: {
+ GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "GeoPoint");
+ break;
+ }
+ default: {
+ GRN_TEXT_PUTS(ctx, ctx->impl->outbuf, "N/A");
+ break;
+ }
+ }
+ GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, '"');
+ GRN_OUTPUT_ARRAY_CLOSE();
+ }
+ GRN_OUTPUT_ARRAY_CLOSE(); // COLUMNS.
+ if (num_records != 0) {
+ size_t count = 0;
+ std::vector<std::vector<char> > bufs(expressions.size());
+ while (count < num_records) {
+ size_t batch_size = GRN_EGN_MAX_BATCH_SIZE;
+ if (batch_size > (num_records - count)) {
+ batch_size = num_records - count;
+ }
+ for (size_t i = 0; i < expressions.size(); ++i) {
+ switch (expressions[i]->data_type()) {
+ case GRN_DB_BOOL: {
+ bufs[i].resize(sizeof(grn_egn_bool) * batch_size);
+ expressions[i]->evaluate(records + count, batch_size,
+ (grn::egn::Bool *)&bufs[i][0]);
+ break;
+ }
+ case GRN_DB_INT64: {
+ bufs[i].resize(sizeof(grn_egn_int) * batch_size);
+ expressions[i]->evaluate(records + count, batch_size,
+ (grn::egn::Int *)&bufs[i][0]);
+ break;
+ }
+ case GRN_DB_FLOAT: {
+ bufs[i].resize(sizeof(grn_egn_float) * batch_size);
+ expressions[i]->evaluate(records + count, batch_size,
+ (grn::egn::Float *)&bufs[i][0]);
+ break;
+ }
+ case GRN_DB_TIME: {
+ bufs[i].resize(sizeof(grn_egn_time) * batch_size);
+ expressions[i]->evaluate(records + count, batch_size,
+ (grn::egn::Time *)&bufs[i][0]);
+ break;
+ }
+ case GRN_DB_TEXT: {
+ bufs[i].resize(sizeof(grn_egn_text) * batch_size);
+ expressions[i]->evaluate(records + count, batch_size,
+ (grn::egn::Text *)&bufs[i][0]);
+ break;
+ }
+ case GRN_DB_WGS84_GEO_POINT: {
+ bufs[i].resize(sizeof(grn_egn_geo_point) * batch_size);
+ expressions[i]->evaluate(records + count, batch_size,
+ (grn::egn::GeoPoint *)&bufs[i][0]);
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ for (size_t i = 0; i < batch_size; ++i) {
+ GRN_OUTPUT_ARRAY_OPEN("HIT", expressions.size());
+ for (size_t j = 0; j < expressions.size(); ++j) {
+ if (j != 0) {
+ GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, ',');
+ }
+ switch (expressions[j]->data_type()) {
+ case GRN_DB_BOOL: {
+ if (((grn_egn_bool *)&bufs[j][0])[i]) {
+ GRN_TEXT_PUT(ctx, ctx->impl->outbuf, "true", 4);
+ } else {
+ GRN_TEXT_PUT(ctx, ctx->impl->outbuf, "false", 5);
+ }
+ break;
+ }
+ case GRN_DB_INT64: {
+ grn_text_lltoa(ctx, ctx->impl->outbuf,
+ ((grn_egn_int *)&bufs[j][0])[i]);
+ break;
+ }
+ case GRN_DB_FLOAT: {
+ grn_text_ftoa(ctx, ctx->impl->outbuf,
+ ((grn_egn_float *)&bufs[j][0])[i]);
+ break;
+ }
+ case GRN_DB_TIME: {
+ grn_text_ftoa(ctx, ctx->impl->outbuf,
+ ((grn_egn_time *)&bufs[j][0])[i] * 0.000001);
+ break;
+ }
+ case GRN_DB_TEXT: {
+ grn_egn_text text = ((grn_egn_text *)&bufs[j][0])[i];
+ grn_text_esc(ctx, ctx->impl->outbuf, text.ptr, text.size);
+ break;
+ }
+ case GRN_DB_WGS84_GEO_POINT: {
+ grn_egn_geo_point geo_point =
+ ((grn_egn_geo_point *)&bufs[j][0])[i];
+ GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, '"');
+ grn_text_itoa(ctx, ctx->impl->outbuf, geo_point.latitude);
+ GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, 'x');
+ grn_text_itoa(ctx, ctx->impl->outbuf, geo_point.longitude);
+ GRN_TEXT_PUTC(ctx, ctx->impl->outbuf, '"');
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ GRN_OUTPUT_ARRAY_CLOSE(); // HITS.
+ }
+ count += batch_size;
+ }
+ }
+ GRN_OUTPUT_ARRAY_CLOSE(); // RESULTSET.
+ GRN_OUTPUT_ARRAY_CLOSE(); // RESET.
+ for (size_t i = 0; i < expressions.size(); ++i) {
+ delete expressions[i];
+ }
+ return rc;
+}
+
+grn_rc
+grn_egn_select(grn_ctx *ctx, grn_obj *table,
+ const char *filter, size_t filter_size,
+ const char *output_columns, size_t output_columns_size,
+ int offset, int limit) {
+ if (!ctx || !grn_egn_is_table(table) || (!filter && (filter_size != 0)) ||
+ (!output_columns && (output_columns_size != 0))) {
+ return GRN_INVALID_ARGUMENT;
+ }
+ std::vector<grn_egn_record> records;
+ size_t num_hits;
+ grn_rc rc = grn_egn_select_filter(ctx, table, filter, filter_size,
+ offset, limit, &records, &num_hits);
+ if (rc == GRN_SUCCESS) {
+ rc = grn_egn_select_output(ctx, table, output_columns, output_columns_size,
+ &*records.begin(), records.size(), num_hits);
+ }
+ return rc;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GRN_WITH_EGN
diff --git a/storage/mroonga/vendor/groonga/lib/error.c b/storage/mroonga/vendor/groonga/lib/error.c
index e14ef3754fd..561394231ea 100644
--- a/storage/mroonga/vendor/groonga/lib/error.c
+++ b/storage/mroonga/vendor/groonga/lib/error.c
@@ -62,3 +62,17 @@ 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 */
+}
diff --git a/storage/mroonga/vendor/groonga/lib/expr.c b/storage/mroonga/vendor/groonga/lib/expr.c
index f13502a0f14..9ce1fa0adfc 100644
--- a/storage/mroonga/vendor/groonga/lib/expr.c
+++ b/storage/mroonga/vendor/groonga/lib/expr.c
@@ -22,6 +22,7 @@
#include "grn_ii.h"
#include "grn_geo.h"
#include "grn_expr.h"
+#include "grn_expr_code.h"
#include "grn_util.h"
#include "grn_mrb.h"
#include "mrb/mrb_expr.h"
@@ -782,8 +783,9 @@ grn_expr_append_obj(grn_ctx *ctx, grn_obj *expr, grn_obj *obj, grn_operator op,
for (i = 0; i < nargs; i++) {
int rest_n_codes = 1;
while (rest_n_codes > 0) {
- if (!code->value) {
- rest_n_codes += code->nargs;
+ rest_n_codes += code->nargs;
+ if (code->value) {
+ rest_n_codes--;
}
rest_n_codes--;
code--;
@@ -1274,7 +1276,10 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller)
}
#define PUSH1(v) do {\
- if (EXPRVP(v)) { vp++; }\
+ if (EXPRVP(v)) {\
+ vp++;\
+ if (vp - e->values > e->values_tail) { e->values_tail = vp - e->values; }\
+ }\
s1 = s0;\
*sp++ = s0 = v;\
} while (0)
@@ -1301,6 +1306,7 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller)
} 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)
@@ -1314,6 +1320,7 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller)
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)
@@ -2226,11 +2233,11 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller)
} while (0)
inline static void
-grn_expr_exec_get_member(grn_ctx *ctx,
- grn_obj *expr,
- grn_obj *column_and_record_id,
- grn_obj *index,
- grn_obj *result)
+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;
@@ -2268,6 +2275,34 @@ grn_expr_exec_get_member(grn_ctx *ctx,
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)
{
@@ -3045,16 +3080,16 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
break;
case GRN_OP_GEO_DISTANCE1 :
{
- grn_obj *e;
+ grn_obj *value;
double lng1, lat1, lng2, lat2, x, y, d;
- POP1(e);
- lng1 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1(e);
- lat1 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1(e);
- lng2 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1ALLOC1(e, res);
- lat2 = GEO_INT2RAD(GRN_INT32_VALUE(e));
+ 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;
@@ -3066,16 +3101,16 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
break;
case GRN_OP_GEO_DISTANCE2 :
{
- grn_obj *e;
+ grn_obj *value;
double lng1, lat1, lng2, lat2, x, y, d;
- POP1(e);
- lng1 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1(e);
- lat1 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1(e);
- lng2 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1ALLOC1(e, res);
- lat2 = GEO_INT2RAD(GRN_INT32_VALUE(e));
+ 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;
@@ -3087,16 +3122,16 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
break;
case GRN_OP_GEO_DISTANCE3 :
{
- grn_obj *e;
+ grn_obj *value;
double lng1, lat1, lng2, lat2, p, q, m, n, x, y, d;
- POP1(e);
- lng1 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1(e);
- lat1 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1(e);
- lng2 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1ALLOC1(e, res);
- lat2 = GEO_INT2RAD(GRN_INT32_VALUE(e));
+ 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);
@@ -3112,16 +3147,16 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
break;
case GRN_OP_GEO_DISTANCE4 :
{
- grn_obj *e;
+ grn_obj *value;
double lng1, lat1, lng2, lat2, p, q, m, n, x, y, d;
- POP1(e);
- lng1 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1(e);
- lat1 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1(e);
- lng2 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1ALLOC1(e, res);
- lat2 = GEO_INT2RAD(GRN_INT32_VALUE(e));
+ 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);
@@ -3138,26 +3173,26 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
case GRN_OP_GEO_WITHINP5 :
{
int r;
- grn_obj *e;
+ grn_obj *value;
double lng0, lat0, lng1, lat1, x, y, d;
- POP1(e);
- lng0 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1(e);
- lat0 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1(e);
- lng1 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1(e);
- lat1 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1ALLOC1(e, res);
+ 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 (e->header.domain) {
+ switch (value->header.domain) {
case GRN_DB_INT32 :
- r = d <= GRN_INT32_VALUE(e);
+ r = d <= GRN_INT32_VALUE(value);
break;
case GRN_DB_FLOAT :
- r = d <= GRN_FLOAT_VALUE(e);
+ r = d <= GRN_FLOAT_VALUE(value);
break;
default :
r = 0;
@@ -3172,20 +3207,20 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
case GRN_OP_GEO_WITHINP6 :
{
int r;
- grn_obj *e;
+ grn_obj *value;
double lng0, lat0, lng1, lat1, lng2, lat2, x, y, d;
- POP1(e);
- lng0 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1(e);
- lat0 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1(e);
- lng1 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1(e);
- lat1 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1(e);
- lng2 = GEO_INT2RAD(GRN_INT32_VALUE(e));
- POP1ALLOC1(e, res);
- lat2 = GEO_INT2RAD(GRN_INT32_VALUE(e));
+ 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);
@@ -3201,24 +3236,24 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
case GRN_OP_GEO_WITHINP8 :
{
int r;
- grn_obj *e;
+ grn_obj *value;
int64_t ln0, la0, ln1, la1, ln2, la2, ln3, la3;
- POP1(e);
- ln0 = GRN_INT32_VALUE(e);
- POP1(e);
- la0 = GRN_INT32_VALUE(e);
- POP1(e);
- ln1 = GRN_INT32_VALUE(e);
- POP1(e);
- la1 = GRN_INT32_VALUE(e);
- POP1(e);
- ln2 = GRN_INT32_VALUE(e);
- POP1(e);
- la2 = GRN_INT32_VALUE(e);
- POP1(e);
- ln3 = GRN_INT32_VALUE(e);
- POP1ALLOC1(e, res);
- la3 = GRN_INT32_VALUE(e);
+ 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;
@@ -3458,9 +3493,15 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs)
break;
case GRN_OP_GET_MEMBER :
{
- grn_obj *column_and_record_id, *index;
- POP2ALLOC1(column_and_record_id, index, res);
- grn_expr_exec_get_member(ctx, expr, column_and_record_id, index, res);
+ 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;
@@ -5996,7 +6037,7 @@ resolve_top_level_name(grn_ctx *ctx, const char *name, unsigned int name_size)
}
static grn_rc
-get_identifier(grn_ctx *ctx, efs_info *q)
+get_identifier(grn_ctx *ctx, efs_info *q, grn_obj *name_resolve_context)
{
const char *s;
unsigned int len;
@@ -6072,6 +6113,14 @@ done :
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))) {
+ 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);
@@ -6108,11 +6157,59 @@ set_tos_minor_to_curr(grn_ctx *ctx, efs_info *q)
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) {
@@ -6150,6 +6247,7 @@ parse_script(grn_ctx *ctx, efs_info *q)
break;
case '.' :
PARSE(GRN_EXPR_TOKEN_DOT);
+ name_resolve_context = parse_script_extract_name_resolve_context(ctx, q);
q->cur++;
break;
case ':' :
@@ -6538,7 +6636,9 @@ parse_script(grn_ctx *ctx, efs_info *q)
}
break;
default :
- if ((rc = get_identifier(ctx, q))) { goto exit; }
+ if ((rc = get_identifier(ctx, q, current_name_resolve_context))) {
+ goto exit;
+ }
break;
}
if (ctx->rc) { rc = ctx->rc; break; }
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 00000000000..4f03867402a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/expr_code.c
@@ -0,0 +1,71 @@
+/* -*- 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-1301 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_bool have_proc_push_code = GRN_FALSE;
+ grn_expr_code *sub_code;
+
+ if (start == target) {
+ return 0;
+ }
+
+ n_args = target->nargs;
+ if (target->op == GRN_OP_CALL) {
+ if (!target->value) {
+ have_proc_push_code = GRN_TRUE;
+ }
+ } else {
+ if (target->value) {
+ n_args--;
+ if (n_args == 0) {
+ return 1;
+ }
+ }
+ }
+
+ 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;
+ }
+ }
+
+ if (have_proc_push_code) {
+ n_codes++;
+ sub_code--;
+ if (sub_code < start) {
+ /* TODO: report error */
+ return 0;
+ }
+ }
+
+ return n_codes;
+}
diff --git a/storage/mroonga/vendor/groonga/lib/grn.h b/storage/mroonga/vendor/groonga/lib/grn.h
index f4ee6e962a9..80622a8421b 100644
--- a/storage/mroonga/vendor/groonga/lib/grn.h
+++ b/storage/mroonga/vendor/groonga/lib/grn.h
@@ -31,17 +31,13 @@
# define __STDC_LIMIT_MACROS
#endif
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif /* HAVE_STDLIB_H */
+#include <stdlib.h>
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif /* HAVE_STDINT_H */
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif /* HAVE_SYS_TYPES_H */
+#include <sys/types.h>
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
diff --git a/storage/mroonga/vendor/groonga/lib/grn_ctx.h b/storage/mroonga/vendor/groonga/lib/grn_ctx.h
index 2f052f5f1c5..4ba5f3c9bc6 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_ctx.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_ctx.h
@@ -153,7 +153,6 @@ GRN_API void grn_ctx_impl_set_current_error_message(grn_ctx *ctx);
#ifdef WIN32
-#define SYSTEM_ERROR_MESSAGE_BUFFER_SIZE 1024
#define SERR(str) do {\
grn_rc rc;\
const char *system_message;\
@@ -333,8 +332,8 @@ GRN_API void grn_ctx_impl_set_current_error_message(grn_ctx *ctx);
grn_rc rc;\
int errno_keep = errno;\
grn_bool show_errno = GRN_FALSE;\
- char system_message[SYSTEM_ERROR_MESSAGE_BUFFER_SIZE];\
- strerror_s(system_message, SYSTEM_ERROR_MESSAGE_BUFFER_SIZE, errno);\
+ const char *system_message;\
+ 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;\
diff --git a/storage/mroonga/vendor/groonga/lib/grn_ctx_impl_mrb.h b/storage/mroonga/vendor/groonga/lib/grn_ctx_impl_mrb.h
index 61cf088b2ae..3e46d2e417f 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_ctx_impl_mrb.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_ctx_impl_mrb.h
@@ -1,6 +1,6 @@
/* -*- c-basic-offset: 2 -*- */
/*
- Copyright(C) 2013 Brazil
+ 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
@@ -26,6 +26,7 @@
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);
diff --git a/storage/mroonga/vendor/groonga/lib/grn_dat.h b/storage/mroonga/vendor/groonga/lib/grn_dat.h
index aefd044d0b7..d3c768fa65c 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_dat.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_dat.h
@@ -1,5 +1,5 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2011-2014 Brazil
+/* 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
@@ -79,6 +79,8 @@ GRN_API grn_rc grn_dat_clear_status_flags(grn_ctx *ctx, grn_dat *dat);
*/
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);
+
#ifdef __cplusplus
}
#endif
diff --git a/storage/mroonga/vendor/groonga/lib/grn_db.h b/storage/mroonga/vendor/groonga/lib/grn_db.h
index cbc2cccaf4e..6c84ad921f4 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_db.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_db.h
@@ -56,6 +56,8 @@ typedef struct {
grn_id range;
} grn_obj_spec;
+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);
diff --git a/storage/mroonga/vendor/groonga/lib/grn_egn.h b/storage/mroonga/vendor/groonga/lib/grn_egn.h
new file mode 100644
index 00000000000..3d1d54ca9aa
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_egn.h
@@ -0,0 +1,90 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef GRN_EGN_H
+#define GRN_EGN_H
+
+#include "grn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Constant values.
+
+typedef grn_operator grn_egn_operator_type;
+typedef grn_builtin_type grn_egn_data_type;
+
+typedef enum {
+ GRN_EGN_ID_NODE,
+ GRN_EGN_SCORE_NODE,
+ GRN_EGN_CONSTANT_NODE,
+ GRN_EGN_COLUMN_NODE,
+ GRN_EGN_OPERATOR_NODE
+} grn_egn_expression_node_type;
+
+typedef enum {
+ GRN_EGN_INCOMPLETE,
+ GRN_EGN_ID,
+ GRN_EGN_SCORE,
+ GRN_EGN_CONSTANT,
+ GRN_EGN_VARIABLE
+} grn_egn_expression_type;
+
+// Built-in data types.
+
+typedef grn_id grn_egn_id;
+typedef float grn_egn_score;
+typedef struct {
+ grn_egn_id id;
+ grn_egn_score score;
+} grn_egn_record;
+
+typedef grn_bool grn_egn_bool;
+typedef int64_t grn_egn_int;
+typedef double grn_egn_float;
+typedef int64_t grn_egn_time;
+typedef struct {
+ const char *ptr;
+ size_t size;
+} grn_egn_text;
+typedef grn_geo_point grn_egn_geo_point;
+
+/*
+ * grn_egn_select() finds records passing through a filter (specified by
+ * `filter' and `filter_size') and writes the associated values (specified by
+ * `output_columns' and `output_columns_size') into the output buffer of `ctx'
+ * (`ctx->impl->outbuf').
+ *
+ * Note that the first `offset` records will be discarded and at most `limit`
+ * records will be output.
+ *
+ * On success, grn_egn_select() returns GRN_SUCCESS.
+ * On failure, grn_egn_select() returns an error code and set the details into
+ * `ctx`.
+ */
+grn_rc grn_egn_select(grn_ctx *ctx, grn_obj *table,
+ const char *filter, size_t filter_size,
+ const char *output_columns, size_t output_columns_size,
+ int offset, int limit);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRN_EGN_H */
diff --git a/storage/mroonga/vendor/groonga/lib/grn_egn.hpp b/storage/mroonga/vendor/groonga/lib/grn_egn.hpp
new file mode 100644
index 00000000000..46511afd6ca
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_egn.hpp
@@ -0,0 +1,318 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef GRN_EGN_HPP
+#define GRN_EGN_HPP
+
+#include <cstring>
+#include <vector>
+
+#include "grn_egn.h"
+
+namespace grn {
+namespace egn {
+
+// Constant values.
+
+typedef grn_egn_operator_type OperatorType;
+typedef grn_egn_data_type DataType;
+
+typedef grn_egn_expression_node_type ExpressionNodeType;
+typedef grn_egn_expression_type ExpressionType;
+
+// Built-in data types.
+
+typedef grn_egn_id ID;
+typedef grn_egn_score Score;
+typedef grn_egn_record Record;
+
+//typedef grn_egn_bool Bool;
+//typedef grn_egn_int Int;
+//typedef grn_egn_float Float;
+//typedef grn_egn_time Time;
+//typedef grn_egn_text Text;
+//typedef grn_egn_geo_point GeoPoint;
+
+//inline bool operator==(const Text &lhs, const Text &rhs) {
+// if (lhs.size != rhs.size) {
+// return false;
+// }
+// return std::memcmp(lhs.ptr, rhs.ptr, lhs.size) == 0;
+//}
+//inline bool operator!=(const Text &lhs, const Text &rhs) {
+// if (lhs.size != rhs.size) {
+// return true;
+// }
+// return std::memcmp(lhs.ptr, rhs.ptr, lhs.size) != 0;
+//}
+//inline bool operator<(const Text &lhs, const Text &rhs) {
+// size_t min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;
+// int result = std::memcmp(lhs.ptr, rhs.ptr, min_size);
+// if (result == 0) {
+// return lhs.size < rhs.size;
+// }
+// return result < 0;
+//}
+//inline bool operator<=(const Text &lhs, const Text &rhs) {
+// size_t min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;
+// int result = std::memcmp(lhs.ptr, rhs.ptr, min_size);
+// if (result == 0) {
+// return lhs.size <= rhs.size;
+// }
+// return result <= 0;
+//}
+//inline bool operator>(const Text &lhs, const Text &rhs) {
+// return rhs < lhs;
+//}
+//inline bool operator>=(const Text &lhs, const Text &rhs) {
+// return rhs <= lhs;
+//}
+
+//inline bool operator==(const GeoPoint &lhs, const GeoPoint &rhs) {
+// return (lhs.latitude == rhs.latitude) && (lhs.longitude == rhs.longitude);
+//}
+//inline bool operator!=(const GeoPoint &lhs, const GeoPoint &rhs) {
+// return (lhs.latitude != rhs.latitude) || (lhs.longitude != rhs.longitude);
+//}
+
+struct Bool {
+ typedef grn_egn_bool Raw;
+ Raw raw;
+
+ static DataType data_type() {
+ return GRN_DB_BOOL;
+ }
+
+ Bool() : raw() {}
+ Bool(const Bool &value) : raw(value.raw) {}
+ explicit Bool(Raw value) : raw(value) {}
+ ~Bool() {}
+};
+
+inline bool operator!(Bool value) { return !value.raw; }
+inline bool operator==(Bool lhs, Bool rhs) { return lhs.raw == rhs.raw; }
+inline bool operator!=(Bool lhs, Bool rhs) { return lhs.raw != rhs.raw; }
+
+struct Int {
+ typedef grn_egn_int Raw;
+ Raw raw;
+
+ static DataType data_type() {
+ return GRN_DB_INT64;
+ }
+
+ Int() : raw() {}
+ Int(const Int &value) : raw(value.raw) {}
+ explicit Int(Raw value) : raw(value) {}
+ ~Int() {}
+};
+
+inline bool operator==(Int lhs, Int rhs) { return lhs.raw == rhs.raw; }
+inline bool operator!=(Int lhs, Int rhs) { return lhs.raw != rhs.raw; }
+inline bool operator<(Int lhs, Int rhs) { return lhs.raw < rhs.raw; }
+inline bool operator<=(Int lhs, Int rhs) { return lhs.raw <= rhs.raw; }
+inline bool operator>(Int lhs, Int rhs) { return lhs.raw > rhs.raw; }
+inline bool operator>=(Int lhs, Int rhs) { return lhs.raw >= rhs.raw; }
+
+struct Float {
+ typedef grn_egn_float Raw;
+ Raw raw;
+
+ static DataType data_type() {
+ return GRN_DB_FLOAT;
+ }
+
+ Float() : raw() {}
+ Float(const Float &value) : raw(value.raw) {}
+ explicit Float(Raw value) : raw(value) {}
+ ~Float() {}
+};
+
+inline bool operator==(Float lhs, Float rhs) { return lhs.raw == rhs.raw; }
+inline bool operator!=(Float lhs, Float rhs) { return lhs.raw != rhs.raw; }
+inline bool operator<(Float lhs, Float rhs) { return lhs.raw < rhs.raw; }
+inline bool operator<=(Float lhs, Float rhs) { return lhs.raw <= rhs.raw; }
+inline bool operator>(Float lhs, Float rhs) { return lhs.raw > rhs.raw; }
+inline bool operator>=(Float lhs, Float rhs) { return lhs.raw >= rhs.raw; }
+
+struct Time {
+ typedef grn_egn_time Raw;
+ Raw raw;
+
+ static DataType data_type() {
+ return GRN_DB_TIME;
+ }
+
+ Time() : raw() {}
+ Time(const Time &value) : raw(value.raw) {}
+ explicit Time(Raw value) : raw(value) {}
+ ~Time() {}
+};
+
+inline bool operator==(Time lhs, Time rhs) { return lhs.raw == rhs.raw; }
+inline bool operator!=(Time lhs, Time rhs) { return lhs.raw != rhs.raw; }
+inline bool operator<(Time lhs, Time rhs) { return lhs.raw < rhs.raw; }
+inline bool operator<=(Time lhs, Time rhs) { return lhs.raw <= rhs.raw; }
+inline bool operator>(Time lhs, Time rhs) { return lhs.raw > rhs.raw; }
+inline bool operator>=(Time lhs, Time rhs) { return lhs.raw >= rhs.raw; }
+
+struct Text {
+ typedef grn_egn_text Raw;
+ Raw raw;
+
+ static DataType data_type() {
+ return GRN_DB_TEXT;
+ }
+
+ Text() : raw() {}
+ Text(const Text &value) : raw(value.raw) {}
+ explicit Text(const Raw &value) : raw(value) {}
+ Text(const char *ptr, size_t size) : raw((Raw){ptr, size}) {}
+ ~Text() {}
+};
+
+inline bool operator==(const Text &lhs, const Text &rhs) {
+ if (lhs.raw.size != rhs.raw.size) {
+ return false;
+ }
+ return std::memcmp(lhs.raw.ptr, rhs.raw.ptr, lhs.raw.size) == 0;
+}
+inline bool operator!=(const Text &lhs, const Text &rhs) {
+ if (lhs.raw.size != rhs.raw.size) {
+ return true;
+ }
+ return std::memcmp(lhs.raw.ptr, rhs.raw.ptr, lhs.raw.size) != 0;
+}
+inline bool operator<(const Text &lhs, const Text &rhs) {
+ size_t min_size = (lhs.raw.size < rhs.raw.size) ?
+ lhs.raw.size : rhs.raw.size;
+ int result = std::memcmp(lhs.raw.ptr, rhs.raw.ptr, min_size);
+ if (result == 0) {
+ return lhs.raw.size < rhs.raw.size;
+ }
+ return result < 0;
+}
+inline bool operator<=(const Text &lhs, const Text &rhs) {
+ size_t min_size = (lhs.raw.size < rhs.raw.size) ?
+ lhs.raw.size : rhs.raw.size;
+ int result = std::memcmp(lhs.raw.ptr, rhs.raw.ptr, min_size);
+ if (result == 0) {
+ return lhs.raw.size <= rhs.raw.size;
+ }
+ return result <= 0;
+}
+inline bool operator>(const Text &lhs, const Text &rhs) { return rhs < lhs; }
+inline bool operator>=(const Text &lhs, const Text &rhs) { return rhs <= lhs; }
+
+struct GeoPoint {
+ typedef grn_egn_geo_point Raw;
+ Raw raw;
+
+ static DataType data_type() {
+ return GRN_DB_WGS84_GEO_POINT;
+ }
+
+ GeoPoint() : raw() {}
+ GeoPoint(const GeoPoint &value) : raw(value.raw) {}
+ explicit GeoPoint(Raw value) : raw(value) {}
+ GeoPoint(int latitude, int longitude) : raw((Raw){ latitude, longitude }) {}
+ ~GeoPoint() {}
+};
+
+inline bool operator==(GeoPoint lhs, GeoPoint rhs) {
+ return (lhs.raw.latitude == rhs.raw.latitude) &&
+ (lhs.raw.longitude == rhs.raw.longitude);
+}
+inline bool operator!=(GeoPoint lhs, GeoPoint rhs) {
+ return (lhs.raw.latitude != rhs.raw.latitude) ||
+ (lhs.raw.longitude != rhs.raw.longitude);
+}
+
+// Cursor is a base class which provides an interface for sequential access to
+// records.
+class Cursor {
+ public:
+ Cursor() {}
+ virtual ~Cursor() {}
+
+ // FIXME: Give me options.
+ static grn_rc open_table_cursor(grn_ctx *ctx, grn_obj *table,
+ Cursor **cursor);
+
+ virtual grn_rc read(Record *records, size_t size, size_t *count);
+};
+
+// ExpressionNode is an element of Expression.
+class ExpressionNode;
+
+// Expression is a class which represents an expression.
+class Expression {
+ public:
+ Expression(grn_ctx *ctx, grn_obj *table);
+ ~Expression();
+
+ static grn_rc open(grn_ctx *ctx, grn_obj *table, Expression **expression);
+ static grn_rc parse(grn_ctx *ctx, grn_obj *table,
+ const char *query, size_t query_size,
+ Expression **expression);
+
+ ExpressionType type() const {
+ return type_;
+ }
+ DataType data_type() const {
+ return data_type_;
+ }
+
+ grn_rc push_object(grn_obj *obj);
+ grn_rc push_operator(grn_operator operator_type);
+
+ grn_rc filter(Record *input, size_t input_size,
+ Record *output, size_t *output_size);
+ grn_rc adjust(Record *records, size_t num_records);
+
+ template <typename T>
+ grn_rc evaluate(const Record *records, size_t num_records, T *results);
+
+ private:
+ grn_ctx *ctx_;
+ grn_obj *table_;
+ ExpressionType type_;
+ DataType data_type_;
+ std::vector<ExpressionNode *> stack_;
+
+ // Disable copy and assignment.
+ Expression(const Expression &);
+ Expression &operator=(const Expression &);
+
+ ExpressionNode *root() const;
+
+ void update_types();
+
+ grn_rc push_bulk_object(grn_obj *obj);
+ grn_rc push_column_object(grn_obj *obj);
+
+ grn_rc create_unary_node(OperatorType operator_type,
+ ExpressionNode *arg, ExpressionNode **node);
+ grn_rc create_binary_node(OperatorType operator_type,
+ ExpressionNode *arg1, ExpressionNode *arg2, ExpressionNode **node);
+};
+
+} // namespace egn
+} // namespace grn
+
+#endif // GRN_EGN_HPP
diff --git a/storage/mroonga/vendor/groonga/lib/grn_error.h b/storage/mroonga/vendor/groonga/lib/grn_error.h
index 2581f934135..a0b18ca7183 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_error.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_error.h
@@ -27,6 +27,7 @@ extern "C" {
#endif
GRN_API const char *grn_current_error_message(void);
+GRN_API const char *grn_strerror(int error_code);
#ifdef __cplusplus
}
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 00000000000..a0fd680e7d4
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/grn_expr_code.h
@@ -0,0 +1,37 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef GRN_EXPR_CODE_H
+#define GRN_EXPR_CODE_H
+
+#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
+
+#endif /* GRN_EXPR_CODE_H */
+
diff --git a/storage/mroonga/vendor/groonga/lib/grn_ii.h b/storage/mroonga/vendor/groonga/lib/grn_ii.h
index fe9b1ec26a4..1ac9528e4cd 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_ii.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_ii.h
@@ -1,5 +1,5 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2012 Brazil
+/* 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
@@ -87,6 +87,8 @@ struct _grn_ii_updspec {
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);
@@ -103,6 +105,7 @@ grn_rc grn_ii_updspec_add(grn_ctx *ctx, grn_ii_updspec *u, int pos, int32_t weig
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);
typedef struct {
grn_id rid;
diff --git a/storage/mroonga/vendor/groonga/lib/grn_io.h b/storage/mroonga/vendor/groonga/lib/grn_io.h
index 14f5e496f8b..6de63bd172a 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_io.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_io.h
@@ -350,12 +350,13 @@ 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);
-grn_rc grn_io_init(void);
-grn_rc grn_io_fin(void);
+void grn_io_init_from_env(void);
uint32_t grn_io_expire(grn_ctx *ctx, grn_io *io, int count_thresh, uint32_t limit);
uint32_t grn_expire(grn_ctx *ctx, int count_thresh, uint32_t limit);
+grn_rc grn_io_flush(grn_ctx *ctx, grn_io *io);
+
/* encode/decode */
#define GRN_B_ENC(v,p) do {\
diff --git a/storage/mroonga/vendor/groonga/lib/grn_mrb.h b/storage/mroonga/vendor/groonga/lib/grn_mrb.h
index 7fae820d342..3726cdcba29 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_mrb.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_mrb.h
@@ -30,6 +30,8 @@
extern "C" {
#endif
+void grn_mrb_init_from_env(void);
+
#ifdef GRN_WITH_MRUBY
GRN_API mrb_value grn_mrb_eval(grn_ctx *ctx, const char *script, int script_length);
GRN_API mrb_value grn_mrb_load(grn_ctx *ctx, const char *path);
diff --git a/storage/mroonga/vendor/groonga/lib/grn_plugin.h b/storage/mroonga/vendor/groonga/lib/grn_plugin.h
index 75b29f56cc9..22749c634aa 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_plugin.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_plugin.h
@@ -46,6 +46,7 @@ struct _grn_plugin {
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);
diff --git a/storage/mroonga/vendor/groonga/lib/grn_proc.h b/storage/mroonga/vendor/groonga/lib/grn_proc.h
index fb01698ea69..b75d11079a2 100644
--- a/storage/mroonga/vendor/groonga/lib/grn_proc.h
+++ b/storage/mroonga/vendor/groonga/lib/grn_proc.h
@@ -1,5 +1,5 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009 Brazil
+/* 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
@@ -23,6 +23,8 @@
extern "C" {
#endif
+void grn_proc_init_from_env(void);
+
GRN_VAR const char *grn_document_root;
void grn_db_init_builtin_query(grn_ctx *ctx);
diff --git a/storage/mroonga/vendor/groonga/lib/ii.c b/storage/mroonga/vendor/groonga/lib/ii.c
index 2d32df2fd4d..388e0566756 100644
--- a/storage/mroonga/vendor/groonga/lib/ii.c
+++ b/storage/mroonga/vendor/groonga/lib/ii.c
@@ -74,6 +74,36 @@
# define S_IWUSR 0200
#endif /* S_IWUSR */
+static grn_bool grn_ii_cursor_set_min_enable = GRN_FALSE;
+static double grn_ii_select_too_many_index_match_ratio = -1;
+
+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 (grn_ii_cursor_set_min_enable_env[0]) {
+ grn_ii_cursor_set_min_enable = GRN_TRUE;
+ } else {
+ grn_ii_cursor_set_min_enable = GRN_FALSE;
+ }
+ }
+
+ {
+ 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);
+ }
+ }
+}
+
/* segment */
inline static uint32_t
@@ -3492,6 +3522,7 @@ _grn_ii_create(grn_ctx *ctx, grn_ii *ii, const char *path, grn_obj *lexicon, uin
}
if (!chunk) {
grn_io_close(ctx, seg);
+ grn_io_remove(ctx, path);
return NULL;
}
header = grn_io_header(seg);
@@ -3688,6 +3719,19 @@ grn_ii_expire(grn_ctx *ctx, grn_ii *ii)
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;
+}
+
#define BIT11_01(x) ((x >> 1) & 0x7ff)
#define BIT31_12(x) (x >> 12)
@@ -4023,6 +4067,7 @@ grn_ii_cursor_open(grn_ctx *ctx, grn_ii *ii, grn_id tid,
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));
@@ -4112,16 +4157,11 @@ exit :
static inline void
grn_ii_cursor_set_min(grn_ctx *ctx, grn_ii_cursor *c, grn_id min)
{
- char grn_ii_cursor_set_min_enable_env[GRN_ENV_BUFFER_SIZE];
-
if (c->min >= min) {
return;
}
- grn_getenv("GRN_II_CURSOR_SET_MIN_ENABLE",
- grn_ii_cursor_set_min_enable_env,
- GRN_ENV_BUFFER_SIZE);
- if (grn_ii_cursor_set_min_enable_env[0]) {
+ if (grn_ii_cursor_set_min_enable) {
c->min = min;
if (c->buf && c->pc.rid < c->min && c->curr_chunk < c->nchunks) {
uint32_t i, skip_chunk = 0;
@@ -6019,6 +6059,77 @@ grn_ii_term_extract(grn_ctx *ctx, grn_ii *ii, const char *string,
return rc;
}
+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_string;
+ grn_bool escaping = GRN_FALSE;
+ int nth_char = 0;
+ const char *current = string;
+ const char *string_end = string + string_len;
+
+ GRN_TEXT_INIT(&parsed_string, 0);
+ while (current < string_end) {
+ const char *target;
+ int char_len;
+
+ char_len = grn_charlen(ctx, current, string_end);
+ if (char_len == 0) {
+ ERR(GRN_INVALID_ARGUMENT,
+ "[ii][select][regexp] invalid encoding character: <%.*s|%#x|>",
+ (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 && *target == '\\') {
+ escaping = GRN_TRUE;
+ continue;
+ }
+ }
+
+ GRN_TEXT_PUT(ctx, &parsed_string, target, char_len);
+ nth_char++;
+ }
+
+ if (optarg) {
+ optarg->mode = GRN_OP_MATCH;
+ }
+
+ rc = grn_ii_select(ctx, ii,
+ GRN_TEXT_VALUE(&parsed_string),
+ GRN_TEXT_LEN(&parsed_string),
+ s, op, optarg);
+
+ return rc;
+}
+
#ifdef GRN_II_SELECT_ENABLE_SEQUENTIAL_SEARCH
static grn_bool
grn_ii_select_sequential_search_should_use(grn_ctx *ctx,
@@ -6156,16 +6267,6 @@ grn_ii_select_sequential_search(grn_ctx *ctx,
grn_bool processed = GRN_TRUE;
{
- /* Disabled by default. */
- double too_many_index_match_ratio = -1;
- char too_many_index_match_ratio_env[GRN_ENV_BUFFER_SIZE];
- grn_getenv("GRN_II_SELECT_TOO_MANY_INDEX_MATCH_RATIO",
- too_many_index_match_ratio_env,
- GRN_ENV_BUFFER_SIZE);
- if (too_many_index_match_ratio_env[0]) {
- too_many_index_match_ratio = atof(too_many_index_match_ratio_env);
- }
-
if (!grn_ii_select_sequential_search_should_use(ctx,
ii,
raw_query,
@@ -6176,7 +6277,7 @@ grn_ii_select_sequential_search(grn_ctx *ctx,
optarg,
token_infos,
n_token_infos,
- too_many_index_match_ratio)) {
+ grn_ii_select_too_many_index_match_ratio)) {
return GRN_FALSE;
}
}
@@ -6259,6 +6360,9 @@ grn_ii_select(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_
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);
@@ -7907,6 +8011,20 @@ grn_ii_buffer_parse(grn_ctx *ctx, grn_ii_buffer *ii_buffer,
grn_ii_buffer_tokenize(ctx, ii_buffer, rid, sid, 0,
GRN_TEXT_VALUE(&rv), GRN_TEXT_LEN(&rv));
break;
+ case GRN_UVECTOR :
+ {
+ unsigned int i, size;
+ unsigned int element_size;
+
+ size = grn_uvector_size(ctx, &rv);
+ element_size = grn_uvector_element_size(ctx, &rv);
+ for (i = 0; i < size; i++) {
+ grn_ii_buffer_tokenize(ctx, ii_buffer, rid, sid, 0,
+ GRN_BULK_HEAD(&rv) + (element_size * i),
+ element_size);
+ }
+ }
+ break;
case GRN_VECTOR :
if (rv.u.v.body) {
int i;
diff --git a/storage/mroonga/vendor/groonga/lib/io.c b/storage/mroonga/vendor/groonga/lib/io.c
index a78c7f242c9..3cee03f5123 100644
--- a/storage/mroonga/vendor/groonga/lib/io.c
+++ b/storage/mroonga/vendor/groonga/lib/io.c
@@ -30,10 +30,12 @@
#include "grn_ctx_impl.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
@@ -99,8 +101,8 @@ inline static int grn_msync(grn_ctx *ctx, void *start, size_t length);
inline static grn_rc grn_pread(grn_ctx *ctx, fileinfo *fi, void *buf, size_t count, off_t offset);
inline static grn_rc grn_pwrite(grn_ctx *ctx, fileinfo *fi, void *buf, size_t count, off_t offset);
-grn_rc
-grn_io_init(void)
+void
+grn_io_init_from_env(void)
{
char version_env[GRN_ENV_BUFFER_SIZE];
@@ -110,14 +112,6 @@ grn_io_init(void)
if (version_env[0]) {
grn_io_version_default = atoi(version_env);
}
-
- return GRN_SUCCESS;
-}
-
-grn_rc
-grn_io_fin(void)
-{
- return GRN_SUCCESS;
}
static inline uint32_t
@@ -320,7 +314,12 @@ grn_io_create(grn_ctx *ctx, const char *path, uint32_t header_size, uint32_t seg
GRN_MUNMAP(&grn_gctx, NULL, &fis->fmo, fis, header, b);
}
grn_fileinfo_close(ctx, fis);
- grn_unlink(path);
+ if (grn_unlink(path) == -1) {
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "failed to grn_unlink() path on grn_io_create() error: "
+ "<%s>: <%s>",
+ path, grn_strerror(errno));
+ }
}
GRN_GFREE(fis);
}
@@ -479,13 +478,19 @@ grn_io_detect_type(grn_ctx *ctx, const char *path)
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, 16)) {
+ if (!memcmp(h.idstr, GRN_IO_IDSTR, GRN_IO_IDSTR_LEN)) {
res = h.type;
} else {
- ERR(GRN_INCOMPATIBLE_FILE_FORMAT, "incompatible file format");
+ 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(path);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "failed to read enough data for detecting type: <%s>",
+ path);
}
} else {
ERR(GRN_INVALID_FORMAT, "grn_io_detect_type failed");
@@ -493,6 +498,9 @@ grn_io_detect_type(grn_ctx *ctx, const char *path)
grn_close(fd);
} else {
ERRNO_ERR(path);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "failed to open path for detecting type: <%s>",
+ path);
}
return res;
}
@@ -513,17 +521,23 @@ grn_io_open(grn_ctx *ctx, const char *path, grn_io_mode mode)
grn_open(fd, path, O_RDWR | GRN_OPEN_FLAG_BINARY);
if (fd == -1) {
ERRNO_ERR(path);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "failed to open path: <%s>",
+ path);
return NULL;
}
if (fstat(fd, &s) != -1 && s.st_size >= sizeof(struct _grn_io_header)) {
if (grn_read(fd, &h, sizeof(struct _grn_io_header)) == sizeof(struct _grn_io_header)) {
- if (!memcmp(h.idstr, GRN_IO_IDSTR, 16)) {
+ if (!memcmp(h.idstr, GRN_IO_IDSTR, GRN_IO_IDSTR_LEN)) {
header_size = h.header_size;
segment_size = h.segment_size;
max_segment = h.max_segment;
flags = h.flags;
} else {
- ERR(GRN_INCOMPATIBLE_FILE_FORMAT, "incompatible file format");
+ ERR(GRN_INCOMPATIBLE_FILE_FORMAT,
+ "failed to open: format ID is different: <%s>: <%.*s>",
+ path,
+ (int)GRN_IO_IDSTR_LEN, GRN_IO_IDSTR);
}
}
}
@@ -705,6 +719,9 @@ grn_io_size(grn_ctx *ctx, grn_io *io, uint64_t *size)
gen_pathname(io->path, buffer, fno);
if (stat(buffer, &s)) {
SERR(buffer);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "failed to stat path to compute size: <%s>",
+ buffer);
} else {
tsize += s.st_size;
}
@@ -722,6 +739,9 @@ grn_io_remove(grn_ctx *ctx, const char *path)
return ctx->rc;
} else if (grn_unlink(path)) {
ERRNO_ERR(path);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "failed to remove path: <%s>",
+ path);
return ctx->rc;
} else {
int fno;
@@ -731,6 +751,9 @@ grn_io_remove(grn_ctx *ctx, const char *path)
if (!stat(buffer, &s)) {
if (grn_unlink(buffer)) {
ERRNO_ERR(buffer);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "failed to remove path: <%s>",
+ buffer);
}
} else {
break;
@@ -749,6 +772,9 @@ grn_io_rename(grn_ctx *ctx, const char *old_name, const char *new_name)
return ctx->rc;
} else if (rename(old_name, new_name)) {
SERR(old_name);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "failed to rename path: <%s> -> <%s>",
+ old_name, new_name);
return ctx->rc;
} else {
int fno;
@@ -758,9 +784,17 @@ grn_io_rename(grn_ctx *ctx, const char *old_name, const char *new_name)
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(old_buffer); }
+ if (rename(old_buffer, new_buffer)) {
+ SERR(old_buffer);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "failed to rename path: <%s> -> <%s>",
+ old_buffer, new_buffer);
+ }
} else {
SERR("stat");
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "failed to stat path to rename: <%s>",
+ old_buffer);
return ctx->rc;
}
}
@@ -1057,34 +1091,30 @@ grn_io_win_unmap(grn_io_win *iw)
}\
} while (0)
-#define SEG_MAP(io,segno,info) do {\
- 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];\
- gen_pathname(io->path, path, fno);\
- if (!grn_fileinfo_open(ctx, fi, path, O_RDWR|O_CREAT)) { \
- DO_MAP(io, &info->fmo, fi, pos, segment_size, segno, info->map);\
- }\
- } else {\
- DO_MAP(io, &info->fmo, fi, pos, segment_size, segno, info->map);\
- }\
- }\
-} while (0)
-
void
grn_io_seg_map_(grn_ctx *ctx, grn_io *io, uint32_t segno, grn_io_mapinfo *info)
{
- SEG_MAP(io, segno, 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];
+ gen_pathname(io->path, path, fno);
+ if (!grn_fileinfo_open(ctx, fi, path, O_RDWR|O_CREAT)) {
+ DO_MAP(io, &info->fmo, fi, pos, segment_size, segno, info->map);
+ }
+ } else {
+ DO_MAP(io, &info->fmo, fi, pos, segment_size, segno, info->map);
+ }
+ }
}
grn_rc
@@ -1311,6 +1341,49 @@ 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) {
+ return GRN_SUCCESS;
+ }
+
+ header = io->header;
+ aligned_header_size = grn_io_compute_base(header->header_size);
+
+ if (grn_msync(ctx, header, aligned_header_size) != 0) {
+ 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]);
+ if (!info) {
+ continue;
+ }
+ if (!info->map) {
+ continue;
+ }
+ if (grn_msync(ctx, info->map, segment_size) != 0) {
+ rc = ctx->rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
/** mmap abstraction **/
static size_t mmap_size = 0;
@@ -1341,7 +1414,15 @@ grn_mmap_v1(grn_ctx *ctx, HANDLE *fmo, fileinfo *fi, off_t offset, size_t length
/* CRITICAL_SECTION_ENTER(fi->cs); */
/* try to create fmo */
*fmo = CreateFileMapping(fi->fh, NULL, PAGE_READWRITE, 0, offset + length, NULL);
- if (!*fmo) { return NULL; }
+ if (!*fmo) {
+ SERR("CreateFileMapping");
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "CreateFileMapping(%lu + %" GRN_FMT_SIZE ") failed "
+ "<%" GRN_FMT_SIZE ">",
+ (DWORD)offset, length,
+ mmap_size);
+ return NULL;
+ }
res = MapViewOfFile(*fmo, FILE_MAP_WRITE, 0, (DWORD)offset, (SIZE_T)length);
if (!res) {
SERR("MapViewOfFile");
@@ -1486,16 +1567,22 @@ 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, NULL,
dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, 0);
if (fi->fh == INVALID_HANDLE_VALUE) {
SERR("CreateFile");
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "CreateFile(<%s>, <%s>) failed",
+ path, flags_description);
goto exit;
}
goto exit;
@@ -1508,6 +1595,9 @@ grn_fileinfo_open_common(grn_ctx *ctx, fileinfo *fi, const char *path, int flags
TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (fi->fh == INVALID_HANDLE_VALUE) {
SERR("CreateFile");
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "CreateFile(<%s>, <O_RDWR|O_TRUNC>) failed",
+ path);
goto exit;
}
goto exit;
@@ -1518,6 +1608,9 @@ grn_fileinfo_open_common(grn_ctx *ctx, fileinfo *fi, const char *path, int flags
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (fi->fh == INVALID_HANDLE_VALUE) {
SERR("CreateFile");
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "CreateFile(<%s>, <O_RDWR>) failed",
+ path);
goto exit;
}
@@ -1636,8 +1729,18 @@ grn_fileinfo_opened(fileinfo *fi)
inline static int
grn_msync(grn_ctx *ctx, void *start, size_t length)
{
- /* return value may be wrong... */
- return FlushViewOfFile(start, length);
+ BOOL succeeded;
+
+ succeeded = FlushViewOfFile(start, length);
+ if (succeeded) {
+ return 0;
+ } else {
+ SERR("FlushViewOfFile");
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "FlushViewOfFile(<%p>, <%" GRN_FMT_SIZE ">) failed",
+ start, length);
+ return -1;
+ }
}
inline static grn_rc
@@ -1693,10 +1796,16 @@ grn_fileinfo_open(grn_ctx *ctx, fileinfo *fi, const char *path, int flags)
grn_open(fi->fd, path, flags);
if (fi->fd == -1) {
ERRNO_ERR(path);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "failed to open file info path: <%s>",
+ path);
return ctx->rc;
}
if (fstat(fi->fd, &st) == -1) {
ERRNO_ERR(path);
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "failed to stat file info path: <%s>",
+ path);
return ctx->rc;
}
fi->dev = st.st_dev;
diff --git a/storage/mroonga/vendor/groonga/lib/logger.c b/storage/mroonga/vendor/groonga/lib/logger.c
index fc9fe71767e..5a85de3d43e 100644
--- a/storage/mroonga/vendor/groonga/lib/logger.c
+++ b/storage/mroonga/vendor/groonga/lib/logger.c
@@ -314,9 +314,6 @@ grn_logger_put(grn_ctx *ctx, grn_log_level level,
void
grn_logger_init(void)
{
- if (!default_logger_path) {
- default_logger_path = grn_strdup_raw(GRN_LOG_PATH);
- }
grn_memcpy(&current_logger, &default_logger, sizeof(grn_logger));
CRITICAL_SECTION_INIT(default_logger_lock);
}
@@ -572,6 +569,7 @@ 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);
}
diff --git a/storage/mroonga/vendor/groonga/lib/mrb.c b/storage/mroonga/vendor/groonga/lib/mrb.c
index 60d2172d520..d406c2d356a 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb.c
@@ -20,6 +20,8 @@
#include "grn_ctx_impl.h"
#include "grn_util.h"
+#include <string.h>
+
#ifdef GRN_WITH_MRUBY
# include <mruby/proc.h>
# include <mruby/compile.h>
@@ -35,6 +37,16 @@
#define BUFFER_SIZE 2048
#define E_LOAD_ERROR (mrb_class_get(mrb, "LoadError"))
+static char grn_mrb_ruby_scripts_dir[GRN_ENV_BUFFER_SIZE];
+
+void
+grn_mrb_init_from_env(void)
+{
+ grn_getenv("GRN_RUBY_SCRIPTS_DIR",
+ grn_mrb_ruby_scripts_dir,
+ GRN_ENV_BUFFER_SIZE);
+}
+
#ifdef GRN_WITH_MRUBY
# ifdef WIN32
static char *win32_ruby_scripts_dir = NULL;
@@ -68,13 +80,8 @@ grn_mrb_get_default_system_ruby_scripts_dir(void)
const char *
grn_mrb_get_system_ruby_scripts_dir(grn_ctx *ctx)
{
- static char ruby_scripts_dir[GRN_ENV_BUFFER_SIZE];
-
- grn_getenv("GRN_RUBY_SCRIPTS_DIR",
- ruby_scripts_dir,
- GRN_ENV_BUFFER_SIZE);
- if (ruby_scripts_dir[0]) {
- return ruby_scripts_dir;
+ if (grn_mrb_ruby_scripts_dir[0]) {
+ return grn_mrb_ruby_scripts_dir;
} else {
return grn_mrb_get_default_system_ruby_scripts_dir();
}
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c
index f19bcfa9563..f90a7c6a639 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c
@@ -23,6 +23,7 @@
#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 = {
@@ -31,6 +32,33 @@ static struct mrb_data_type mrb_grn_array_type = {
};
static mrb_value
+mrb_grn_array_singleton_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;
@@ -54,6 +82,10 @@ grn_mrb_array_init(grn_ctx *ctx)
klass = mrb_define_class_under(mrb, module, "Array", table_class);
MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+ mrb_define_singleton_method(mrb, (struct RObject *)klass, "create",
+ mrb_grn_array_singleton_create,
+ MRB_ARGS_REQ(2));
+
mrb_define_method(mrb, klass, "initialize",
mrb_grn_array_initialize, MRB_ARGS_REQ(1));
}
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c
index eb57a016148..84cfb8dc204 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_bulk.c
@@ -28,6 +28,7 @@
#include "../grn_db.h"
#include "mrb_bulk.h"
+#include "mrb_object.h"
static struct mrb_data_type mrb_grn_bulk_type = {
"Groonga::Bulk",
@@ -136,27 +137,47 @@ grn_mrb_value_from_bulk(mrb_state *mrb, grn_obj *bulk)
break;
default :
{
-#define MESSAGE_SIZE 4096
- char message[MESSAGE_SIZE];
grn_obj *domain;
- char domain_name[GRN_TABLE_MAX_KEY_SIZE];
- int domain_name_size;
+ grn_bool is_record = GRN_FALSE;
domain = grn_ctx_at(ctx, bulk->header.domain);
if (domain) {
- domain_name_size = grn_obj_name(ctx, domain,
- domain_name, GRN_TABLE_MAX_KEY_SIZE);
+ 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 {
- grn_strcpy(domain_name, GRN_TABLE_MAX_KEY_SIZE, "unknown");
- domain_name_size = strlen(domain_name);
+#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);
}
- 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;
@@ -234,5 +255,7 @@ grn_mrb_bulk_init(grn_ctx *ctx)
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_column.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_column.c
index 1d3bbb69422..68aadce6658 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_column.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_column.c
@@ -25,9 +25,25 @@
#include "mrb_ctx.h"
#include "mrb_column.h"
+#include "mrb_bulk.h"
#include "mrb_converter.h"
static mrb_value
+mrb_grn_column_array_reference(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *column;
+ grn_id record_id;
+ 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_locked(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
@@ -65,6 +81,9 @@ grn_mrb_column_init(grn_ctx *ctx)
klass = mrb_define_class_under(mrb, module, "Column", object_class);
MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+ mrb_define_method(mrb, klass, "[]",
+ mrb_grn_column_array_reference, MRB_ARGS_REQ(1));
+
mrb_define_method(mrb, klass, "locked?",
mrb_grn_column_is_locked, MRB_ARGS_NONE());
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.c
index f39202398d1..07c0a74dd31 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.c
@@ -27,6 +27,7 @@
#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 = {
@@ -102,6 +103,19 @@ mrb_grn_command_input_array_reference(mrb_state *mrb, mrb_value self)
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)
{
@@ -118,5 +132,8 @@ grn_mrb_command_input_init(grn_ctx *ctx)
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_converter.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c
index e4c3aceb435..387d921b6d0 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_converter.c
@@ -130,7 +130,7 @@ grn_mrb_value_to_raw_data(mrb_state *mrb,
"%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_value_);
+ mrb_funcall(mrb, mrb_value_, "inspect", 0));
}
*raw_value = GRN_BULK_HEAD(&(buffer->to));
*raw_value_size = GRN_BULK_VSIZE(&(buffer->to));
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c
index eb85ff955fa..2af198c2fdb 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_index_column.c
@@ -24,6 +24,7 @@
#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"
@@ -77,14 +78,22 @@ 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;
- char *query;
- mrb_int query_len;
+ 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, "s|H", &query, &query_len, &mrb_options);
+ 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;
@@ -99,7 +108,11 @@ mrb_grn_index_column_estimate_size_for_query(mrb_state *mrb, mrb_value self)
}
size = grn_ii_estimate_size_for_query(ctx, (grn_ii *)index_column,
- query, query_len, &optarg);
+ query, query_size, &optarg);
+ grn_mrb_value_to_raw_data_buffer_fin(mrb, &buffer);
+
+ grn_mrb_ctx_check(mrb);
+
return mrb_fixnum_value(size);
}
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c
index 8efaa41e50d..77eb4ef3025 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.c
@@ -26,12 +26,13 @@
#include <mruby/data.h>
#include "../grn_mrb.h"
+#include "mrb_ctx.h"
#include "mrb_object.h"
#include "mrb_operator.h"
#include "mrb_converter.h"
-static mrb_value
-object_inspect(mrb_state *mrb, mrb_value self)
+mrb_value
+grn_mrb_object_inspect(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
grn_obj *object;
@@ -170,6 +171,21 @@ object_close(mrb_state *mrb, mrb_value self)
}
static mrb_value
+object_remove(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *object;
+
+ object = DATA_PTR(self);
+ grn_obj_remove(ctx, object);
+ grn_mrb_ctx_check(mrb);
+
+ DATA_PTR(self) = NULL;
+
+ return mrb_nil_value();
+}
+
+static mrb_value
object_get_domain_id(mrb_state *mrb, mrb_value self)
{
grn_obj *object;
@@ -237,7 +253,7 @@ grn_mrb_object_init(grn_ctx *ctx)
data->object_class = klass;
mrb_define_method(mrb, klass, "inspect",
- object_inspect, MRB_ARGS_NONE());
+ 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());
@@ -247,6 +263,7 @@ grn_mrb_object_init(grn_ctx *ctx)
object_grn_inspect, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "==", object_equal, MRB_ARGS_REQ(1));
mrb_define_method(mrb, klass, "close", object_close, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "remove", object_remove, MRB_ARGS_NONE());
mrb_define_method(mrb, klass, "domain_id", object_get_domain_id,
MRB_ARGS_NONE());
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.h b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.h
index 97a586c0f11..82468bd0156 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.h
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_object.h
@@ -27,6 +27,8 @@ extern "C" {
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_table.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c
index 651a77e4549..2b9e00d8f04 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c
@@ -66,6 +66,25 @@ mrb_grn_table_array_reference(mrb_state *mrb, mrb_value self)
}
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_is_locked(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
@@ -138,22 +157,21 @@ mrb_grn_table_select(mrb_state *mrb, mrb_value self)
return grn_mrb_value_from_grn_obj(mrb, result);
}
-/* TODO: Fix memory leak on error */
static mrb_value
-mrb_grn_table_sort(mrb_state *mrb, mrb_value self)
+mrb_grn_table_sort_raw(mrb_state *mrb, mrb_value self)
{
grn_ctx *ctx = (grn_ctx *)mrb->ud;
grn_obj *table;
- grn_obj *result = NULL;
+ mrb_value mrb_keys;
grn_table_sort_key *keys;
int i, n_keys;
- int offset = 0;
- int limit = -1;
- mrb_value mrb_keys;
- mrb_value mrb_options = mrb_nil_value();
+ mrb_int offset;
+ mrb_int limit;
+ mrb_value mrb_result;
+ grn_obj *result;
table = DATA_PTR(self);
- mrb_get_args(mrb, "o|H", &mrb_keys, &mrb_options);
+ 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");
@@ -161,69 +179,118 @@ mrb_grn_table_sort(mrb_state *mrb, mrb_value self)
n_keys = RARRAY_LEN(mrb_keys);
keys = GRN_MALLOCN(grn_table_sort_key, n_keys);
for (i = 0; i < n_keys; i++) {
- mrb_value mrb_sort_options;
- mrb_value mrb_sort_key;
- mrb_value mrb_sort_order;
-
- mrb_sort_options = RARRAY_PTR(mrb_keys)[i];
- mrb_sort_key = grn_mrb_options_get_lit(mrb, mrb_sort_options, "key");
- switch (mrb_type(mrb_sort_key)) {
- case MRB_TT_STRING :
- keys[i].key = grn_obj_column(ctx, table,
- RSTRING_PTR(mrb_sort_key),
- RSTRING_LEN(mrb_sort_key));
- break;
- case MRB_TT_SYMBOL :
- {
- const char *name;
- mrb_int name_length;
- name = mrb_sym2name_len(mrb, mrb_symbol(mrb_sort_key), &name_length);
- keys[i].key = grn_obj_column(ctx, table, name, name_length);
- }
- break;
- default :
- /* TODO: free */
- mrb_raisef(mrb, E_ARGUMENT_ERROR,
- "sort key must be string or symbol: %S",
- mrb_sort_key);
- break;
- }
-
- keys[i].flags = 0;
- mrb_sort_order = grn_mrb_options_get_lit(mrb, mrb_sort_options, "order");
- if (mrb_nil_p(mrb_sort_order) ||
- (mrb_symbol(mrb_sort_order) == mrb_intern_lit(mrb, "ascending"))) {
- keys[i].flags |= GRN_TABLE_SORT_ASC;
- } else {
- keys[i].flags |= GRN_TABLE_SORT_DESC;
- }
+ 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);
- if (!mrb_nil_p(mrb_options)) {
- mrb_value mrb_offset;
- mrb_value mrb_limit;
+ return mrb_result;
+}
- mrb_offset = grn_mrb_options_get_lit(mrb, mrb_options, "offset");
- if (!mrb_nil_p(mrb_offset)) {
- offset = mrb_fixnum(mrb_offset);
- }
+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;
- mrb_limit = grn_mrb_options_get_lit(mrb, mrb_options, "limit");
- if (!mrb_nil_p(mrb_limit)) {
- limit = mrb_fixnum(mrb_limit);
- }
- }
+ table = DATA_PTR(self);
+ mrb_get_args(mrb, "oo", &mrb_keys, &mrb_result);
- result = grn_table_create(ctx, NULL, 0, NULL, GRN_TABLE_NO_KEY,
- NULL, table);
- grn_table_sort(ctx, table, offset, limit, result, keys, n_keys);
+ 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_obj_unlink(ctx, keys[i].key);
+ 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 grn_mrb_value_from_grn_obj(mrb, result);
+ 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();
}
void
@@ -241,6 +308,9 @@ grn_mrb_table_init(grn_ctx *ctx)
mrb_define_method(mrb, klass, "[]",
mrb_grn_table_array_reference, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "find_column",
+ mrb_grn_table_find_column, MRB_ARGS_REQ(1));
+
mrb_define_method(mrb, klass, "locked?",
mrb_grn_table_is_locked, MRB_ARGS_NONE());
@@ -251,7 +321,13 @@ grn_mrb_table_init(grn_ctx *ctx)
mrb_define_method(mrb, klass, "select",
mrb_grn_table_select, MRB_ARGS_ARG(1, 1));
- mrb_define_method(mrb, klass, "sort",
- mrb_grn_table_sort, 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));
+
}
#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 00000000000..9419f1b7939
--- /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-1301 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 00000000000..fda2a9be82f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_flags.h
@@ -0,0 +1,34 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef GRN_MRB_TABLE_GROUP_FLAGS_H
+#define GRN_MRB_TABLE_GROUP_FLAGS_H
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_table_group_flags_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRN_MRB_TABLE_GROUP_FLAGS_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.c
new file mode 100644
index 00000000000..970ebd06220
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.c
@@ -0,0 +1,250 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+#include <mruby/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_subrecs(mrb_state *mrb, mrb_value self)
+{
+ grn_table_group_result *result;
+ mrb_int max_n_subrecs;
+
+ result = DATA_PTR(self);
+ mrb_get_args(mrb, "i", &max_n_subrecs);
+
+ result->max_n_subrecs = max_n_subrecs;
+
+ 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);
+
+ 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_subrecs=",
+ mrb_grn_table_group_result_set_max_n_subrecs,
+ 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 00000000000..cc3c70ff3bb
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_group_result.h
@@ -0,0 +1,34 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef GRN_MRB_TABLE_GROUP_RESULT_H
+#define GRN_MRB_TABLE_GROUP_RESULT_H
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_table_group_result_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRN_MRB_TABLE_GROUP_RESULT_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.c
new file mode 100644
index 00000000000..0c402591042
--- /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-1301 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 00000000000..0b5c40b9993
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_flags.h
@@ -0,0 +1,34 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef GRN_MRB_TABLE_SORT_FLAGS_H
+#define GRN_MRB_TABLE_SORT_FLAGS_H
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_table_sort_flags_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRN_MRB_TABLE_SORT_FLAGS_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.c
new file mode 100644
index 00000000000..3313cceebb6
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.c
@@ -0,0 +1,157 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+#include <mruby/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) {
+ 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 00000000000..1d56bcd6313
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_table_sort_key.h
@@ -0,0 +1,34 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2015 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef GRN_MRB_TABLE_SORT_KEY_H
+#define GRN_MRB_TABLE_SORT_KEY_H
+
+#include "../grn_ctx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grn_mrb_table_sort_key_init(grn_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRN_MRB_TABLE_SORT_KEY_H */
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb
index 73b44cae3dd..28b80fc3de3 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/expression_size_estimator.rb
@@ -99,7 +99,12 @@ module Groonga
def estimate_equal(data, index_column)
lexicon = index_column.lexicon
- term_id = lexicon[data.query]
+ query = data.query
+ if query.domain == lexicon.id
+ term_id = query.value
+ else
+ term_id = lexicon[query]
+ end
return 0 if term_id.nil?
index_column.estimate_size(:term_id => term_id)
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb
index ea26a031e0a..ccd44758d07 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb
@@ -6,6 +6,7 @@ require "writer"
require "object"
require "database"
+require "table"
require "index_column"
require "command"
require "table_cursor"
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am
index 5ddcba18d4c..6fda01812b9 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/sources.am
@@ -19,5 +19,6 @@ RUBY_SCRIPT_FILES = \
scan_info_builder.rb \
scan_info_data.rb \
scan_info_search_index.rb \
+ table.rb \
table_cursor.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 00000000000..5a1b640c25f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/scripts/table.rb
@@ -0,0 +1,90 @@
+module Groonga
+ class Table
+ 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
+
+ private
+ 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
+
+ sort_key.key = find_column(key_name)
+ 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/sources.am b/storage/mroonga/vendor/groonga/lib/mrb/sources.am
index 5cda570bc37..b27e3654af8 100644
--- a/storage/mroonga/vendor/groonga/lib/mrb/sources.am
+++ b/storage/mroonga/vendor/groonga/lib/mrb/sources.am
@@ -55,6 +55,14 @@ libgrnmrb_la_SOURCES = \
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_type.c \
mrb_type.h \
mrb_variable_size_column.c \
diff --git a/storage/mroonga/vendor/groonga/lib/operator.c b/storage/mroonga/vendor/groonga/lib/operator.c
index 14a870cd885..e57408e0081 100644
--- a/storage/mroonga/vendor/groonga/lib/operator.c
+++ b/storage/mroonga/vendor/groonga/lib/operator.c
@@ -612,6 +612,60 @@ grn_operator_exec_greater_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y)
}
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;
+}
+
+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)
@@ -905,7 +959,17 @@ grn_operator_exec_match(grn_ctx *ctx, grn_obj *target, grn_obj *sub_text)
{
grn_bool matched;
GRN_API_ENTER;
- matched = exec_text_operator_bulk_bulk(ctx, GRN_OP_MATCH, target, sub_text);
+ 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);
}
diff --git a/storage/mroonga/vendor/groonga/lib/output.c b/storage/mroonga/vendor/groonga/lib/output.c
index 0036e9a8619..f78ef75a560 100644
--- a/storage/mroonga/vendor/groonga/lib/output.c
+++ b/storage/mroonga/vendor/groonga/lib/output.c
@@ -1,5 +1,5 @@
/* -*- c-basic-offset: 2 -*- */
-/* Copyright(C) 2009-2014 Brazil
+/* 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
@@ -20,6 +20,7 @@
#include <string.h>
#include "grn_str.h"
#include "grn_db.h"
+#include "grn_expr_code.h"
#include "grn_util.h"
#include "grn_output.h"
@@ -1134,57 +1135,6 @@ count_n_elements_in_expression(grn_ctx *ctx, grn_obj *expression)
return n_elements;
}
-static inline int
-count_used_n_codes(grn_ctx *ctx, grn_expr_code *start, grn_expr_code *target)
-{
- int n_codes;
- int i, n_args;
- grn_bool have_proc_push_code = GRN_FALSE;
- grn_expr_code *sub_code;
-
- if (start == target) {
- return 0;
- }
-
- n_args = target->nargs;
- if (target->op == GRN_OP_CALL) {
- if (!target->value) {
- have_proc_push_code = GRN_TRUE;
- }
- } else {
- if (target->value) {
- n_args--;
- if (n_args == 0) {
- return 1;
- }
- }
- }
-
- n_codes = 1;
- sub_code = target - 1;
- for (i = 0; i < n_args; i++) {
- int sub_n_codes;
- sub_n_codes = count_used_n_codes(ctx, start, sub_code);
- n_codes += sub_n_codes;
- sub_code -= sub_n_codes;
- if (sub_code < start) {
- /* TODO: report error */
- return 0;
- }
- }
-
- if (have_proc_push_code) {
- n_codes++;
- sub_code--;
- if (sub_code < start) {
- /* TODO: report error */
- return 0;
- }
- }
-
- return n_codes;
-}
-
static grn_bool
is_score_accessor(grn_ctx *ctx, grn_obj *obj)
{
@@ -1305,10 +1255,10 @@ grn_output_table_columns_by_expression(grn_ctx *ctx, grn_obj *outbuf,
have_comma = GRN_TRUE;
if (is_first_comma) {
- int n_used_codes;
+ unsigned int n_used_codes;
int code_end_offset;
- n_used_codes = count_used_n_codes(ctx, expr->codes, code - 1);
+ 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,
@@ -1417,13 +1367,13 @@ grn_output_table_records_by_expression(grn_ctx *ctx, grn_obj *outbuf,
have_comma = GRN_TRUE;
if (is_first_comma) {
int second_code_offset;
- int second_code_n_used_code;
+ unsigned int second_code_n_used_codes;
second_code_offset = code - expr->codes - 1;
- second_code_n_used_code =
- count_used_n_codes(ctx,
- expr->codes,
- expr->codes + second_code_offset);
- expr->codes_curr = second_code_offset - second_code_n_used_code + 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);
code_start_offset = expr->codes_curr;
diff --git a/storage/mroonga/vendor/groonga/lib/plugin.c b/storage/mroonga/vendor/groonga/lib/plugin.c
index 48ccded0b92..7db19c1a5a5 100644
--- a/storage/mroonga/vendor/groonga/lib/plugin.c
+++ b/storage/mroonga/vendor/groonga/lib/plugin.c
@@ -66,6 +66,16 @@ static grn_critical_section grn_plugins_lock;
#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)
{
@@ -513,13 +523,8 @@ grn_plugin_get_default_system_plugins_dir(void)
const char *
grn_plugin_get_system_plugins_dir(void)
{
- static char plugins_dir[GRN_ENV_BUFFER_SIZE];
-
- grn_getenv("GRN_PLUGINS_DIR",
- plugins_dir,
- GRN_ENV_BUFFER_SIZE);
- if (plugins_dir[0]) {
- return plugins_dir;
+ if (grn_plugins_dir[0]) {
+ return grn_plugins_dir;
} else {
return grn_plugin_get_default_system_plugins_dir();
}
diff --git a/storage/mroonga/vendor/groonga/lib/proc.c b/storage/mroonga/vendor/groonga/lib/proc.c
index fc6aa690e74..86b0fd58c02 100644
--- a/storage/mroonga/vendor/groonga/lib/proc.c
+++ b/storage/mroonga/vendor/groonga/lib/proc.c
@@ -26,12 +26,17 @@
#include "grn_token_cursor.h"
#include "grn_expr.h"
+#ifdef GRN_WITH_EGN
+# include "grn_egn.h"
+#endif /* GRN_WITH_EGN */
+
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#ifdef WIN32
+# include <io.h>
# include <share.h>
#endif /* WIN32 */
@@ -57,6 +62,36 @@ const char *grn_document_root = NULL;
#define GRN_SELECT_INTERNAL_VAR_CONDITION "$condition"
#define GRN_SELECT_INTERNAL_VAR_MATCH_COLUMNS "$match_columns"
+
+static double grn_between_too_many_index_match_ratio = 0.01;
+static double grn_in_values_too_many_index_match_ratio = 0.01;
+
+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)
@@ -871,6 +906,19 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len,
long long int threshold, original_threshold = 0;
grn_cache *cache_obj = grn_cache_current_get(ctx);
+ {
+ const char *query_end = query + query_len;
+ int space_len;
+ while (query < query_end) {
+ space_len = grn_isspace(query, ctx->encoding);
+ if (space_len == 0) {
+ break;
+ }
+ query += space_len;
+ query_len -= space_len;
+ }
+ }
+
cache_key_size = table_len + 1 + match_columns_len + 1 + query_len + 1 +
filter_len + 1 + scorer_len + 1 + sortby_len + 1 + output_columns_len + 1 +
match_escalation_threshold_len + 1 +
@@ -963,6 +1011,19 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len,
}
if ((table_ = grn_ctx_get(ctx, table, table_len))) {
// match_columns_ = grn_obj_column(ctx, table_, match_columns, match_columns_len);
+#ifdef GRN_WITH_EGN
+ if (filter_len && (filter[0] == '?') &&
+ (ctx->impl->output_type == GRN_CONTENT_JSON)) {
+ ctx->rc = grn_egn_select(ctx, table_, filter + 1, filter_len - 1,
+ output_columns, output_columns_len,
+ offset, limit);
+ if (!ctx->rc && cacheable && cache_key_size <= GRN_CACHE_MAX_KEY_SIZE &&
+ (!cache || cache_len != 2 || cache[0] != 'n' || cache[1] != 'o')) {
+ grn_cache_update(ctx, cache_obj, cache_key, cache_key_size, outbuf);
+ }
+ goto exit;
+ }
+#endif /* GRN_WITH_EGN */
if (query_len || filter_len) {
grn_obj *v;
GRN_EXPR_CREATE_FOR_QUERY(ctx, table_, cond, v);
@@ -973,6 +1034,9 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len,
grn_expr_parse(ctx, match_columns_, match_columns, match_columns_len,
NULL, GRN_OP_MATCH, GRN_OP_AND,
GRN_EXPR_SYNTAX_SCRIPT);
+ if (ctx->rc) {
+ goto exit;
+ }
} else {
/* todo */
}
@@ -980,16 +1044,16 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len,
if (query_len) {
grn_expr_flags flags;
grn_obj query_expander_buf;
- GRN_TEXT_INIT(&query_expander_buf, 0);
flags = GRN_EXPR_SYNTAX_QUERY;
if (query_flags_len) {
flags |= grn_parse_query_flags(ctx, query_flags, query_flags_len);
- } else {
- flags |= GRN_EXPR_ALLOW_PRAGMA|GRN_EXPR_ALLOW_COLUMN;
if (ctx->rc) {
goto exit;
}
+ } else {
+ flags |= GRN_EXPR_ALLOW_PRAGMA|GRN_EXPR_ALLOW_COLUMN;
}
+ GRN_TEXT_INIT(&query_expander_buf, 0);
if (query_expander_len) {
if (expand_query(ctx, query, query_len, flags,
query_expander, query_expander_len,
@@ -3953,6 +4017,7 @@ parse_tokenize_flags(grn_ctx *ctx, grn_obj *flag_names)
typedef struct {
grn_id id;
int32_t position;
+ grn_bool force_prefix;
} tokenize_token;
static void
@@ -3969,7 +4034,7 @@ output_tokens(grn_ctx *ctx, grn_obj *tokens, grn_obj *lexicon)
token = ((tokenize_token *)(GRN_BULK_HEAD(tokens))) + i;
- GRN_OUTPUT_MAP_OPEN("TOKEN", 2);
+ GRN_OUTPUT_MAP_OPEN("TOKEN", 3);
GRN_OUTPUT_CSTR("value");
value_size = grn_table_get_key(ctx, lexicon, token->id,
@@ -3979,6 +4044,9 @@ output_tokens(grn_ctx *ctx, grn_obj *tokens, grn_obj *lexicon)
GRN_OUTPUT_CSTR("position");
GRN_OUTPUT_INT32(token->position);
+ GRN_OUTPUT_CSTR("force_prefix");
+ GRN_OUTPUT_BOOL(token->force_prefix);
+
GRN_OUTPUT_MAP_CLOSE();
}
GRN_OUTPUT_ARRAY_CLOSE();
@@ -4088,6 +4156,7 @@ tokenize(grn_ctx *ctx, grn_obj *lexicon, grn_obj *string, grn_tokenize_mode mode
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);
}
@@ -5134,11 +5203,12 @@ run_sub_filter(grn_ctx *ctx, grn_obj *table,
case GRN_ACCESSOR :
case GRN_COLUMN_FIX_SIZE :
case GRN_COLUMN_VAR_SIZE :
+ case GRN_COLUMN_INDEX :
break;
default :
- /* TODO: put inspected the 1nd argument to message */
+ /* TODO: put inspected the 1st argument to message */
ERR(GRN_INVALID_ARGUMENT,
- "sub_filter(): the 1nd argument must be column or accessor");
+ "sub_filter(): the 1st argument must be column or accessor");
rc = ctx->rc;
goto exit;
break;
@@ -5712,21 +5782,9 @@ selector_between_sequential_search(grn_ctx *ctx,
between_data *data,
grn_obj *res, grn_operator op)
{
- double too_many_index_match_ratio = 0.01;
-
- {
- char too_many_index_match_ratio_env[GRN_ENV_BUFFER_SIZE];
- grn_getenv("GRN_BETWEEN_TOO_MANY_INDEX_MATCH_RATIO",
- too_many_index_match_ratio_env,
- GRN_ENV_BUFFER_SIZE);
- if (too_many_index_match_ratio_env[0]) {
- too_many_index_match_ratio = atof(too_many_index_match_ratio_env);
- }
- }
-
if (!selector_between_sequential_search_should_use(
ctx, table, index, index_table, data, res, op,
- too_many_index_match_ratio)) {
+ grn_between_too_many_index_match_ratio)) {
return GRN_FALSE;
}
@@ -6210,19 +6268,8 @@ selector_in_values_sequential_search(grn_ctx *ctx,
{
grn_obj *source;
int n_existing_records;
- double too_many_index_match_ratio = 0.01;
- {
- char too_many_index_match_ratio_env[GRN_ENV_BUFFER_SIZE];
- grn_getenv("GRN_IN_VALUES_TOO_MANY_INDEX_MATCH_RATIO",
- too_many_index_match_ratio_env,
- GRN_ENV_BUFFER_SIZE);
- if (too_many_index_match_ratio_env[0]) {
- too_many_index_match_ratio = atof(too_many_index_match_ratio_env);
- }
- }
-
- if (too_many_index_match_ratio < 0.0) {
+ if (grn_in_values_too_many_index_match_ratio < 0.0) {
return GRN_FALSE;
}
@@ -6288,9 +6335,11 @@ selector_in_values_sequential_search(grn_ctx *ctx,
/*
* Same as:
- * ((n_existing_record / n_indexed_records) > too_many_index_match_ratio)
+ * ((n_existing_record / n_indexed_records) >
+ * grn_in_values_too_many_index_match_ratio)
*/
- if (n_existing_records > (n_indexed_records * 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;
@@ -6709,6 +6758,47 @@ proc_plugin_unregister(grn_ctx *ctx, int nargs, grn_obj **args,
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 *target;
+ grn_bool is_recursive;
+
+ target_name = VAR(0);
+ recursive = VAR(1);
+
+ 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 = bool_option_value(recursive, GRN_TRUE);
+ {
+ grn_rc rc;
+ 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;
+}
+
#define DEF_VAR(v,name_str) do {\
(v).name = (name_str);\
(v).name_size = GRN_STRLEN(name_str);\
@@ -6987,4 +7077,8 @@ grn_db_init_builtin_query(grn_ctx *ctx)
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_COMMAND("io_flush", proc_io_flush, 2, vars);
}
diff --git a/storage/mroonga/vendor/groonga/lib/sources.am b/storage/mroonga/vendor/groonga/lib/sources.am
index 459b73792ab..ab1ad3e81b5 100644
--- a/storage/mroonga/vendor/groonga/lib/sources.am
+++ b/storage/mroonga/vendor/groonga/lib/sources.am
@@ -11,10 +11,15 @@ libgroonga_la_SOURCES = \
grn_dat.h \
db.c \
grn_db.h \
+ egn.cpp \
+ grn_egn.h \
+ grn_egn.hpp \
error.c \
grn_error.h \
expr.c \
grn_expr.h \
+ expr_code.c \
+ grn_expr_code.h \
geo.c \
grn_geo.h \
grn.h \
diff --git a/storage/mroonga/vendor/groonga/lib/store.c b/storage/mroonga/vendor/groonga/lib/store.c
index 027f86baac8..d43ebb466e3 100644
--- a/storage/mroonga/vendor/groonga/lib/store.c
+++ b/storage/mroonga/vendor/groonga/lib/store.c
@@ -23,7 +23,8 @@
/* rectangular arrays */
-#define GRN_RA_SEGMENT_SIZE (1 << 22)
+#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)
@@ -46,7 +47,7 @@ _grn_ra_create(grn_ctx *ctx, grn_ra *ra, const char *path, unsigned int element_
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 = 22; (1 << w_elm) > n_elm; w_elm--);
+ 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;
@@ -89,7 +90,7 @@ grn_ra_open(grn_ctx *ctx, const char *path)
return NULL;
}
n_elm = GRN_RA_SEGMENT_SIZE / header->element_size;
- for (w_elm = 22; (1 << w_elm) > n_elm; w_elm--);
+ 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;
diff --git a/storage/mroonga/vendor/groonga/lib/token_cursor.c b/storage/mroonga/vendor/groonga/lib/token_cursor.c
index d98d1d46342..ac1c936110b 100644
--- a/storage/mroonga/vendor/groonga/lib/token_cursor.c
+++ b/storage/mroonga/vendor/groonga/lib/token_cursor.c
@@ -245,7 +245,7 @@ grn_token_cursor_next(grn_ctx *ctx, grn_token_cursor *token_cursor)
continue;
}
} else {
- if (status & GRN_TOKEN_LAST) {
+ if (status & GRN_TOKEN_REACH_END) {
token_cursor->force_prefix = GRN_TRUE;
}
}
diff --git a/storage/mroonga/vendor/groonga/lib/tokenizers.c b/storage/mroonga/vendor/groonga/lib/tokenizers.c
index 8ed0b8c37fa..28fd13c33c4 100644
--- a/storage/mroonga/vendor/groonga/lib/tokenizers.c
+++ b/storage/mroonga/vendor/groonga/lib/tokenizers.c
@@ -473,23 +473,23 @@ typedef struct {
grn_tokenizer_token token;
grn_tokenizer_query *query;
struct {
- grn_bool have_begin;
- grn_bool have_end;
int32_t n_skip_tokens;
} get;
grn_bool is_begin;
grn_bool is_end;
- grn_bool is_first_token;
+ 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 = 0;
+ unsigned int normalize_flags = GRN_STRING_WITH_TYPES;
grn_tokenizer_query *query;
const char *normalized;
unsigned int normalized_length_in_bytes;
@@ -512,13 +512,11 @@ regexp_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
grn_tokenizer_token_init(ctx, &(tokenizer->token));
tokenizer->query = query;
- tokenizer->get.have_begin = GRN_FALSE;
- tokenizer->get.have_end = GRN_FALSE;
tokenizer->get.n_skip_tokens = 0;
tokenizer->is_begin = GRN_TRUE;
tokenizer->is_end = GRN_FALSE;
- tokenizer->is_first_token = GRN_TRUE;
+ tokenizer->is_start_token = GRN_TRUE;
tokenizer->is_overlapping = GRN_FALSE;
grn_string_get_normalized(ctx, tokenizer->query->normalized_query,
@@ -526,39 +524,9 @@ regexp_init(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
NULL);
tokenizer->next = normalized;
tokenizer->end = tokenizer->next + normalized_length_in_bytes;
-
- if (tokenizer->query->tokenize_mode == GRN_TOKEN_GET) {
- unsigned int query_length = tokenizer->query->length;
- if (query_length >= 2) {
- const char *query_string = tokenizer->query->ptr;
- grn_encoding encoding = tokenizer->query->encoding;
- if (query_string[0] == '\\' && query_string[1] == 'A') {
- tokenizer->get.have_begin = GRN_TRUE;
- /* TODO: It assumes that both "\\" and "A" are normalized to 1
- characters. Normalizer may omit character or expand to
- multiple characters. */
- tokenizer->next += grn_charlen_(ctx, tokenizer->next, tokenizer->end,
- encoding);
- tokenizer->next += grn_charlen_(ctx, tokenizer->next, tokenizer->end,
- encoding);
- }
- if (query_string[query_length - 2] == '\\' &&
- query_string[query_length - 1] == 'z') {
- tokenizer->get.have_end = GRN_TRUE;
- /* TODO: It assumes that both "\\" and "z" are normalized to 1
- byte characters. Normalizer may omit character or expand to
- multiple characters. */
- tokenizer->end -= grn_charlen_(ctx,
- tokenizer->end - 1,
- tokenizer->end,
- encoding);
- tokenizer->end -= grn_charlen_(ctx,
- tokenizer->end - 1,
- tokenizer->end,
- encoding);
- }
- }
- }
+ tokenizer->nth_char = 0;
+ tokenizer->char_types =
+ grn_string_get_types(ctx, tokenizer->query->normalized_query);
GRN_TEXT_INIT(&(tokenizer->buffer), 0);
@@ -576,23 +544,32 @@ regexp_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
grn_obj *buffer = &(tokenizer->buffer);
const char *current = tokenizer->next;
const char *end = tokenizer->end;
+ const const uint_least8_t *char_types = tokenizer->char_types;
grn_tokenize_mode mode = tokenizer->query->tokenize_mode;
- grn_bool escaping = GRN_FALSE;
+ 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 (mode == GRN_TOKEN_GET) {
- if (tokenizer->get.have_begin) {
+ 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);
- tokenizer->get.have_begin = GRN_FALSE;
return NULL;
}
- if (tokenizer->is_end && tokenizer->get.have_end) {
+ if (tokenizer->is_end) {
status |= GRN_TOKEN_LAST | GRN_TOKEN_REACH_END;
grn_tokenizer_token_push(ctx,
&(tokenizer->token),
@@ -601,18 +578,45 @@ regexp_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
status);
return NULL;
}
- } else {
- if (tokenizer->is_begin) {
+ 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) {
+ 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);
- tokenizer->is_begin = GRN_FALSE;
return NULL;
}
- if (tokenizer->is_end) {
+ 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),
@@ -623,28 +627,21 @@ regexp_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
}
}
- 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;
- }
-
while (GRN_TRUE) {
- if (!escaping && mode == GRN_TOKEN_GET &&
- char_len == 1 && current[0] == '\\') {
- current += char_len;
- escaping = GRN_TRUE;
- } else {
- n_characters++;
- GRN_TEXT_PUT(ctx, buffer, current, char_len);
- current += char_len;
- escaping = GRN_FALSE;
- if (n_characters == 1) {
- tokenizer->next = current;
- }
- if (n_characters == ngram_unit) {
- break;
+ 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;
}
}
@@ -653,6 +650,21 @@ regexp_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
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) {
@@ -664,27 +676,21 @@ regexp_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
tokenizer->is_overlapping = (n_characters > 1);
if (mode == GRN_TOKEN_GET) {
- if ((end - tokenizer->next) < ngram_unit) {
- if (tokenizer->get.have_end) {
- if (tokenizer->next == end) {
- tokenizer->is_end = GRN_TRUE;
- }
- if (status & GRN_TOKEN_UNMATURED) {
- if (tokenizer->is_first_token) {
- status |= GRN_TOKEN_FORCE_PREFIX;
- } else {
- status |= GRN_TOKEN_SKIP;
- }
- }
- } else {
- tokenizer->is_end = GRN_TRUE;
- status |= GRN_TOKEN_LAST | GRN_TOKEN_REACH_END;
- if (status & GRN_TOKEN_UNMATURED) {
- status |= GRN_TOKEN_FORCE_PREFIX;
- }
+ 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 (tokenizer->get.n_skip_tokens > 0) {
+ 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 {
@@ -695,6 +701,9 @@ regexp_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
if (tokenizer->next == end) {
tokenizer->is_end = GRN_TRUE;
}
+ if (break_by_blank) {
+ tokenizer->is_start_token = GRN_TRUE;
+ }
}
grn_tokenizer_token_push(ctx,
@@ -702,7 +711,6 @@ regexp_next(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
GRN_TEXT_VALUE(buffer),
GRN_TEXT_LEN(buffer),
status);
- tokenizer->is_first_token = GRN_FALSE;
return NULL;
}
@@ -751,6 +759,20 @@ grn_db_init_mecab_tokenizer(grn_ctx *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;
@@ -762,6 +784,7 @@ grn_db_init_mecab_tokenizer(grn_ctx *ctx)
return GRN_NO_SUCH_FILE_OR_DIRECTORY;
}
}
+#endif /* defined(GRN_EMBEDDED) && defined(GRN_WITH_MECAB) */
break;
default :
return GRN_OPERATION_NOT_SUPPORTED;
diff --git a/storage/mroonga/vendor/groonga/plugins/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/CMakeLists.txt
index 37f6127b0d2..6d6a8df5d5e 100644
--- a/storage/mroonga/vendor/groonga/plugins/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/plugins/CMakeLists.txt
@@ -22,8 +22,10 @@ add_subdirectory(token_filters)
add_subdirectory(sharding)
add_subdirectory(functions)
-if(GRN_WITH_MRUBY)
- read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/ruby_scripts.am RUBY_SCRIPTS)
- install(FILES ${RUBY_SCRIPTS}
- DESTINATION "${GRN_RELATIVE_PLUGINS_DIR}")
+if(NOT GRN_EMBED)
+ if(GRN_WITH_MRUBY)
+ read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/ruby_scripts.am RUBY_SCRIPTS)
+ install(FILES ${RUBY_SCRIPTS}
+ DESTINATION "${GRN_RELATIVE_PLUGINS_DIR}")
+ endif()
endif()
diff --git a/storage/mroonga/vendor/groonga/plugins/functions/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/functions/CMakeLists.txt
index 28db8b42ef3..d831589b28b 100644
--- a/storage/mroonga/vendor/groonga/plugins/functions/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/plugins/functions/CMakeLists.txt
@@ -21,12 +21,20 @@ set(GRN_FUNCTIONS_PLUGIN_DIR "${GRN_RELATIVE_PLUGINS_DIR}/functions")
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/vector_sources.am
VECTOR_SOURCES)
-add_library(vector_functions MODULE ${VECTOR_SOURCES})
set_source_files_properties(${VECTOR_SOURCES}
PROPERTIES
COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
-set_target_properties(vector_functions PROPERTIES
- PREFIX ""
- OUTPUT_NAME "vector")
+if(GRN_EMBED)
+ add_library(vector_functions STATIC ${VECTOR_SOURCES})
+ set_target_properties(
+ vector_functions
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+else()
+ add_library(vector_functions MODULE ${VECTOR_SOURCES})
+ set_target_properties(vector_functions PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "vector")
+ install(TARGETS vector_functions DESTINATION "${GRN_FUNCTIONS_PLUGIN_DIR}")
+endif()
target_link_libraries(vector_functions libgroonga)
-install(TARGETS vector_functions DESTINATION "${GRN_FUNCTIONS_PLUGIN_DIR}")
diff --git a/storage/mroonga/vendor/groonga/plugins/functions/vector.c b/storage/mroonga/vendor/groonga/plugins/functions/vector.c
index 34f7a98fd27..a92fee9dbec 100644
--- a/storage/mroonga/vendor/groonga/plugins/functions/vector.c
+++ b/storage/mroonga/vendor/groonga/plugins/functions/vector.c
@@ -16,6 +16,10 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef GRN_EMBEDDED
+# define GRN_PLUGIN_FUNCTION_TAG functions_vector
+#endif
+
#include <groonga/plugin.h>
static grn_obj *
diff --git a/storage/mroonga/vendor/groonga/plugins/query_expanders/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/query_expanders/CMakeLists.txt
index 57d11abfbcb..7f622608e4b 100644
--- a/storage/mroonga/vendor/groonga/plugins/query_expanders/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/plugins/query_expanders/CMakeLists.txt
@@ -22,9 +22,17 @@ read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/tsv_sources.am TSV_SOURCES)
set_source_files_properties(${TSV_SOURCES}
PROPERTIES
COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
-add_library(tsv_query_expander MODULE ${TSV_SOURCES})
-set_target_properties(tsv_query_expander PROPERTIES
- PREFIX ""
- OUTPUT_NAME "tsv")
+if(GRN_EMBED)
+ add_library(tsv_query_expander STATIC ${TSV_SOURCES})
+ set_target_properties(
+ tsv_query_expander
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+else()
+ add_library(tsv_query_expander MODULE ${TSV_SOURCES})
+ set_target_properties(tsv_query_expander PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "tsv")
+ install(TARGETS tsv_query_expander DESTINATION "${QUERY_EXPANDERS_DIR}")
+endif()
target_link_libraries(tsv_query_expander libgroonga)
-install(TARGETS tsv_query_expander DESTINATION "${QUERY_EXPANDERS_DIR}")
diff --git a/storage/mroonga/vendor/groonga/plugins/query_expanders/tsv.c b/storage/mroonga/vendor/groonga/plugins/query_expanders/tsv.c
index 06bb322acb2..00550f6822b 100644
--- a/storage/mroonga/vendor/groonga/plugins/query_expanders/tsv.c
+++ b/storage/mroonga/vendor/groonga/plugins/query_expanders/tsv.c
@@ -15,6 +15,10 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef GRN_EMBEDDED
+# define GRN_PLUGIN_FUNCTION_TAG query_expanders_tsv
+#endif
+
/* groonga's internal headers */
/* for grn_text_fgets(): We don't want to require stdio.h for groonga.h.
What should we do? Should we split header file such as groonga/stdio.h? */
diff --git a/storage/mroonga/vendor/groonga/plugins/ruby/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/ruby/CMakeLists.txt
index ba7deafe0d3..63a79938552 100644
--- a/storage/mroonga/vendor/groonga/plugins/ruby/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/plugins/ruby/CMakeLists.txt
@@ -21,20 +21,40 @@ if(GRN_WITH_MRUBY)
set(GRN_RELATIVE_RUBY_PLUGINS_DIR "${GRN_RELATIVE_PLUGINS_DIR}/ruby")
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/eval_sources.am RUBY_EVAL_SOURCES)
- add_library(eval MODULE ${RUBY_EVAL_SOURCES})
set_source_files_properties(${RUBY_EVAL_SOURCES}
PROPERTIES
COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
- set_target_properties(eval PROPERTIES PREFIX "")
- target_link_libraries(eval libgroonga)
- install(TARGETS eval DESTINATION "${GRN_RELATIVE_RUBY_PLUGINS_DIR}")
+ if(GRN_EMBED)
+ add_library(ruby_eval STATIC ${RUBY_EVAL_SOURCES})
+ set_target_properties(
+ ruby_eval
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+ else()
+ add_library(ruby_eval MODULE ${RUBY_EVAL_SOURCES})
+ set_target_properties(ruby_eval PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "eval")
+ install(TARGETS ruby_eval DESTINATION "${GRN_RELATIVE_RUBY_PLUGINS_DIR}")
+ endif()
+ target_link_libraries(ruby_eval libgroonga)
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/load_sources.am RUBY_LOAD_SOURCES)
- add_library(load MODULE ${RUBY_LOAD_SOURCES})
set_source_files_properties(${RUBY_LOAD_SOURCES}
PROPERTIES
COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
- set_target_properties(load PROPERTIES PREFIX "")
- target_link_libraries(load libgroonga)
- install(TARGETS load DESTINATION "${GRN_RELATIVE_RUBY_PLUGINS_DIR}")
+ if(GRN_EMBED)
+ add_library(ruby_load STATIC ${RUBY_LOAD_SOURCES})
+ set_target_properties(
+ ruby_load
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+ else()
+ add_library(ruby_load MODULE ${RUBY_LOAD_SOURCES})
+ set_target_properties(ruby_load PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "load")
+ install(TARGETS ruby_load DESTINATION "${GRN_RELATIVE_RUBY_PLUGINS_DIR}")
+ endif()
+ target_link_libraries(ruby_load libgroonga)
endif()
diff --git a/storage/mroonga/vendor/groonga/plugins/ruby/eval.c b/storage/mroonga/vendor/groonga/plugins/ruby/eval.c
index ad1e7948249..bacd9011c12 100644
--- a/storage/mroonga/vendor/groonga/plugins/ruby/eval.c
+++ b/storage/mroonga/vendor/groonga/plugins/ruby/eval.c
@@ -16,6 +16,10 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef GRN_EMBEDDED
+# define GRN_PLUGIN_FUNCTION_TAG ruby_eval
+#endif
+
#include "ruby_plugin.h"
static grn_obj *
diff --git a/storage/mroonga/vendor/groonga/plugins/ruby/load.c b/storage/mroonga/vendor/groonga/plugins/ruby/load.c
index a4e60acc357..447882319a5 100644
--- a/storage/mroonga/vendor/groonga/plugins/ruby/load.c
+++ b/storage/mroonga/vendor/groonga/plugins/ruby/load.c
@@ -16,6 +16,10 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef GRN_EMBEDDED
+# define GRN_PLUGIN_FUNCTION_TAG ruby_load
+#endif
+
#include "ruby_plugin.h"
static grn_obj *
diff --git a/storage/mroonga/vendor/groonga/plugins/sharding.rb b/storage/mroonga/vendor/groonga/plugins/sharding.rb
index e369c3798da..4ebc9baf438 100644
--- a/storage/mroonga/vendor/groonga/plugins/sharding.rb
+++ b/storage/mroonga/vendor/groonga/plugins/sharding.rb
@@ -2,3 +2,5 @@ require "sharding/range_expression_builder"
require "sharding/logical_enumerator"
require "sharding/logical_count"
require "sharding/logical_range_filter"
+require "sharding/logical_select"
+require "sharding/logical_table_remove"
diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/sharding/CMakeLists.txt
index 8d0cdd976dc..588a434e0e0 100644
--- a/storage/mroonga/vendor/groonga/plugins/sharding/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/plugins/sharding/CMakeLists.txt
@@ -13,10 +13,12 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-if(GRN_WITH_MRUBY)
- set(GRN_RELATIVE_SHARDING_PLUGINS_DIR "${GRN_RELATIVE_PLUGINS_DIR}/sharding")
+if(NOT GRN_EMBED)
+ if(GRN_WITH_MRUBY)
+ set(GRN_RELATIVE_SHARDING_PLUGINS_DIR "${GRN_RELATIVE_PLUGINS_DIR}/sharding")
- read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/sources.am SHARDING_SCRIPTS)
- install(FILES ${SHARDING_SCRIPTS}
- DESTINATION "${GRN_RELATIVE_SHARDING_PLUGINS_DIR}")
+ read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/sources.am SHARDING_SCRIPTS)
+ install(FILES ${SHARDING_SCRIPTS}
+ DESTINATION "${GRN_RELATIVE_SHARDING_PLUGINS_DIR}")
+ endif()
endif()
diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/logical_enumerator.rb b/storage/mroonga/vendor/groonga/plugins/sharding/logical_enumerator.rb
index 1aeafef5438..35934182591 100644
--- a/storage/mroonga/vendor/groonga/plugins/sharding/logical_enumerator.rb
+++ b/storage/mroonga/vendor/groonga/plugins/sharding/logical_enumerator.rb
@@ -20,15 +20,37 @@ module Groonga
private
def each_internal(order)
- prefix = "#{@logical_table}_"
context = Context.instance
- context.database.each_table(:prefix => prefix,
- :order_by => :key,
- :order => order) do |table|
- shard_range_raw = table.name[prefix.size..-1]
+ each_shard_with_around(order) do |prev_shard, current_shard, next_shard|
+ table = current_shard.table
+ shard_range_data = current_shard.range_data
+ shard_range = nil
- next unless /\A(\d{4})(\d{2})(\d{2})\z/ =~ shard_range_raw
- shard_range = ShardRange.new($1.to_i, $2.to_i, $3.to_i)
+ if shard_range_data.day.nil?
+ if order == :ascending
+ if next_shard
+ next_shard_range_data = next_shard.range_data
+ else
+ next_shard_range_data = nil
+ end
+ else
+ if prev_shard
+ next_shard_range_data = prev_shard.range_data
+ else
+ next_shard_range_data = nil
+ end
+ end
+ max_day = compute_month_shard_max_day(shard_range_data.year,
+ shard_range_data.month,
+ next_shard_range_data)
+ shard_range = MonthShardRange.new(shard_range_data.year,
+ shard_range_data.month,
+ max_day)
+ else
+ shard_range = DayShardRange.new(shard_range_data.year,
+ shard_range_data.month,
+ shard_range_data.day)
+ end
physical_shard_key_name = "#{table.name}.#{@shard_key_name}"
shard_key = context[physical_shard_key_name]
@@ -43,6 +65,36 @@ module Groonga
end
end
+ def each_shard_with_around(order)
+ context = Context.instance
+ prefix = "#{@logical_table}_"
+
+ shards = [nil]
+ context.database.each_table(:prefix => prefix,
+ :order_by => :key,
+ :order => order) do |table|
+ shard_range_raw = table.name[prefix.size..-1]
+
+ case shard_range_raw
+ when /\A(\d{4})(\d{2})\z/
+ shard_range_data = ShardRangeData.new($1.to_i, $2.to_i, nil)
+ when /\A(\d{4})(\d{2})(\d{2})\z/
+ shard_range_data = ShardRangeData.new($1.to_i, $2.to_i, $3.to_i)
+ else
+ next
+ end
+
+ shards << Shard.new(table, shard_range_data)
+ next if shards.size < 3
+ yield(*shards)
+ shards.shift
+ end
+
+ if shards.size == 2
+ yield(shards[0], shards[1], nil)
+ end
+ end
+
private
def initialize_parameters
@logical_table = @input[:logical_table]
@@ -58,13 +110,84 @@ module Groonga
@target_range = TargetRange.new(@command_name, @input)
end
- class ShardRange
+ def compute_month_shard_max_day(year, month, next_shard_range)
+ return nil if next_shard_range.nil?
+
+ return nil if month != next_shard_range.month
+
+ next_shard_range.day
+ end
+
+ class Shard
+ attr_reader :table, :range_data
+ def initialize(table, range_data)
+ @table = table
+ @range_data = range_data
+ end
+ end
+
+ class ShardRangeData
+ attr_reader :year, :month, :day
+ def initialize(year, month, day)
+ @year = year
+ @month = month
+ @day = day
+ end
+ end
+
+ class DayShardRange
attr_reader :year, :month, :day
def initialize(year, month, day)
@year = year
@month = month
@day = day
end
+
+ def least_over_time
+ Time.local(@year, @month, @day + 1)
+ end
+
+ def min_time
+ Time.local(@year, @month, @day)
+ end
+
+ def include?(time)
+ @year == time.year and
+ @month == time.month and
+ @day == time.day
+ end
+ end
+
+ class MonthShardRange
+ attr_reader :year, :month, :max_day
+ def initialize(year, month, max_day)
+ @year = year
+ @month = month
+ @max_day = max_day
+ end
+
+ def least_over_time
+ if @max_day.nil?
+ Time.local(@year, @month + 1, 1)
+ else
+ Time.local(@year, @month, @max_day + 1)
+ end
+ end
+
+ def min_time
+ Time.local(@year, @month, 1)
+ end
+
+ def include?(time)
+ return false unless @year == time.year
+ return false unless @month == time.month
+
+ if @max_day.nil?
+ true
+ else
+ time.day <= @max_day
+ end
+ end
end
class TargetRange
@@ -139,16 +262,11 @@ module Groonga
end
def in_min?(shard_range)
- base_time = Time.local(shard_range.year,
- shard_range.month,
- shard_range.day + 1)
- @min < base_time
+ @min < shard_range.least_over_time
end
def in_min_partial?(shard_range)
- return false unless @min.year == shard_range.year
- return false unless @min.month == shard_range.month
- return false unless @min.day == shard_range.day
+ return false unless shard_range.include?(@min)
return true if @min_border == :exclude
@@ -159,9 +277,7 @@ module Groonga
end
def in_max?(shard_range)
- max_base_time = Time.local(shard_range.year,
- shard_range.month,
- shard_range.day)
+ max_base_time = shard_range.min_time
if @max_border == :include
@max >= max_base_time
else
@@ -170,9 +286,7 @@ module Groonga
end
def in_max_partial?(shard_range)
- @max.year == shard_range.year and
- @max.month == shard_range.month and
- @max.day == shard_range.day
+ shard_range.include?(@max)
end
end
end
diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/logical_select.rb b/storage/mroonga/vendor/groonga/plugins/sharding/logical_select.rb
new file mode 100644
index 00000000000..da6dbe5ae91
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/sharding/logical_select.rb
@@ -0,0 +1,332 @@
+module Groonga
+ module Sharding
+ class LogicalSelectCommand < Command
+ register("logical_select",
+ [
+ "logical_table",
+ "shard_key",
+ "min",
+ "min_border",
+ "max",
+ "max_border",
+ "filter",
+ "sortby",
+ "output_columns",
+ "offset",
+ "limit",
+ "drilldown",
+ "drilldown_sortby",
+ "drilldown_output_columns",
+ "drilldown_offset",
+ "drilldown_limit",
+ ])
+
+ def run_body(input)
+ enumerator = LogicalEnumerator.new("logical_select", input)
+
+ context = ExecuteContext.new(input)
+ begin
+ executor = Executor.new(context)
+ executor.execute
+
+ n_results = 1
+ drilldowns = context.drilldown.result_sets
+ n_results += drilldowns.size
+
+ writer.array("RESULT", n_results) do
+ write_records(writer, context)
+ write_drilldowns(writer, context, drilldowns)
+ end
+ ensure
+ context.close
+ end
+ end
+
+ private
+ def write_records(writer, context)
+ result_sets = context.result_sets
+
+ n_hits = 0
+ n_elements = 2 # for N hits and columns
+ result_sets.each do |result_set|
+ n_hits += result_set.size
+ n_elements += result_set.size
+ end
+
+ output_columns = context.output_columns
+
+ writer.array("RESULTSET", n_elements) do
+ writer.array("NHITS", 1) do
+ writer.write(n_hits)
+ end
+ first_result_set = result_sets.first
+ if first_result_set
+ writer.write_table_columns(first_result_set, output_columns)
+ end
+
+ current_offset = context.offset
+ current_offset += n_hits if current_offset < 0
+ current_limit = context.limit
+ current_limit += n_hits + 1 if current_limit < 0
+ options = {
+ :offset => current_offset,
+ :limit => current_limit,
+ }
+ result_sets.each do |result_set|
+ if result_set.size > current_offset
+ writer.write_table_records(result_set, output_columns, options)
+ end
+ if current_offset > 0
+ current_offset = [current_offset - result_set.size, 0].max
+ end
+ current_limit -= result_set.size
+ break if current_limit <= 0
+ options[:offset] = current_offset
+ options[:limit] = current_limit
+ end
+ end
+ end
+
+ def write_drilldowns(writer, context, drilldowns)
+ output_columns = context.drilldown.output_columns
+
+ options = {
+ :offset => context.drilldown.output_offset,
+ :limit => context.drilldown.limit,
+ }
+
+ drilldowns.each do |drilldown|
+ n_elements = 2 # for N hits and columns
+ n_elements += drilldown.size
+ writer.array("RESULTSET", n_elements) do
+ writer.array("NHITS", 1) do
+ writer.write(drilldown.size)
+ end
+ writer.write_table_columns(drilldown, output_columns)
+ writer.write_table_records(drilldown, output_columns,
+ options)
+ end
+ end
+ end
+
+ module KeysParsable
+ private
+ def parse_keys(raw_keys)
+ return [] if raw_keys.nil?
+
+ raw_keys.strip.split(/ *, */)
+ end
+ end
+
+ class ExecuteContext
+ include KeysParsable
+
+ attr_reader :enumerator
+ attr_reader :filter
+ attr_reader :offset
+ attr_reader :limit
+ attr_reader :sort_keys
+ attr_reader :output_columns
+ attr_reader :result_sets
+ attr_reader :drilldown
+ def initialize(input)
+ @input = input
+ @enumerator = LogicalEnumerator.new("logical_select", @input)
+ @filter = @input[:filter]
+ @offset = (@input[:offset] || 0).to_i
+ @limit = (@input[:limit] || 10).to_i
+ @sort_keys = parse_keys(@input[:sortby])
+ @output_columns = @input[:output_columns] || "_key, *"
+
+ @result_sets = []
+
+ @drilldown = DrilldownExecuteContext.new(@input)
+ end
+
+ def close
+ @result_sets.each do |result_set|
+ result_set.close if result_set.temporary?
+ end
+
+ @drilldown.close
+ end
+ end
+
+ class DrilldownExecuteContext
+ include KeysParsable
+
+ attr_reader :keys
+ attr_reader :offset
+ attr_reader :limit
+ attr_reader :sort_keys
+ attr_reader :output_columns
+ attr_reader :output_offset
+ attr_reader :result_sets
+ attr_reader :unsorted_result_sets
+ def initialize(input)
+ @input = input
+ @keys = parse_keys(@input[:drilldown])
+ @offset = (@input[:drilldown_offset] || 0).to_i
+ @limit = (@input[:drilldown_limit] || 10).to_i
+ @sort_keys = parse_keys(@input[:drilldown_sortby])
+ @output_columns = @input[:drilldown_output_columns]
+ @output_columns ||= "_key, _nsubrecs"
+
+ if @sort_keys.empty?
+ @output_offset = @offset
+ else
+ @output_offset = 0
+ end
+
+ @result_sets = []
+ @unsorted_result_sets = []
+ end
+
+ def close
+ @result_sets.each do |result_set|
+ result_set.close
+ end
+ @unsorted_result_sets.each do |result_set|
+ result_set.close
+ end
+ end
+ end
+
+ class Executor
+ def initialize(context)
+ @context = context
+ end
+
+ def execute
+ execute_search
+ execute_drilldown
+ end
+
+ private
+ def execute_search
+ first_table = nil
+ enumerator = @context.enumerator
+ enumerator.each do |table, shard_key, shard_range|
+ first_table ||= table
+ next if table.empty?
+
+ shard_executor = ShardExecutor.new(@context,
+ table, shard_key, shard_range)
+ shard_executor.execute
+ end
+ if first_table.nil?
+ message =
+ "[logical_select] no shard exists: " +
+ "logical_table: <#{enumerator.logical_table}>: " +
+ "shard_key: <#{enumerator.shard_key_name}>"
+ raise InvalidArgument, message
+ end
+ if @context.result_sets.empty?
+ result_set = HashTable.create(:flags => ObjectFlags::WITH_SUBREC,
+ :key_type => first_table)
+ @context.result_sets << result_set
+ end
+ end
+
+ def execute_drilldown
+ drilldown = @context.drilldown
+ group_result = TableGroupResult.new
+ sort_options = {
+ :offset => drilldown.offset,
+ :limit => drilldown.limit,
+ }
+ begin
+ group_result.key_begin = 0
+ group_result.key_end = 0
+ group_result.limit = 1
+ group_result.flags = TableGroupFlags::CALC_COUNT
+ drilldown.keys.each do |key|
+ @context.result_sets.each do |result_set|
+ result_set.group([key], group_result)
+ end
+ result_set = group_result.table
+ if drilldown.sort_keys.empty?
+ drilldown.result_sets << result_set
+ else
+ drilldown.result_sets << result_set.sort(drilldown.sort_keys,
+ sort_options)
+ drilldown.unsorted_result_sets << result_set
+ end
+ group_result.table = nil
+ end
+ ensure
+ group_result.close
+ end
+ end
+ end
+
+ class ShardExecutor
+ def initialize(context, table, shard_key, shard_range)
+ @context = context
+ @table = table
+ @shard_key = shard_key
+ @shard_range = shard_range
+
+ @filter = @context.filter
+ @result_sets = @context.result_sets
+
+ @target_range = @context.enumerator.target_range
+
+ @cover_type = @target_range.cover_type(@shard_range)
+
+ @expression_builder = RangeExpressionBuilder.new(@shard_key,
+ @target_range,
+ @filter)
+ end
+
+ def execute
+ return if @cover_type == :none
+
+ case @cover_type
+ when :all
+ filter_shard_all
+ when :partial_min
+ filter_table do |expression|
+ @expression_builder.build_partial_min(expression)
+ end
+ when :partial_max
+ filter_table do |expression|
+ @expression_builder.build_partial_max(expression)
+ end
+ when :partial_min_and_max
+ filter_table do |expression|
+ @expression_builder.build_partial_min_and_max(expression)
+ end
+ end
+ end
+
+ private
+ def filter_shard_all
+ if @filter.nil?
+ @result_sets << @table
+ else
+ filter_table do |expression|
+ @expression_builder.build_all(expression)
+ end
+ end
+ end
+
+ def create_expression(table)
+ expression = Expression.create(table)
+ begin
+ yield(expression)
+ ensure
+ expression.close
+ end
+ end
+
+ def filter_table
+ create_expression(@table) do |expression|
+ yield(expression)
+ @result_sets << @table.select(expression)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/logical_table_remove.rb b/storage/mroonga/vendor/groonga/plugins/sharding/logical_table_remove.rb
new file mode 100644
index 00000000000..f5c31c72bb1
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/plugins/sharding/logical_table_remove.rb
@@ -0,0 +1,70 @@
+module Groonga
+ module Sharding
+ class LogicalTableRemoveCommand < Command
+ register("logical_table_remove",
+ [
+ "logical_table",
+ "shard_key",
+ "min",
+ "min_border",
+ "max",
+ "max_border",
+ ])
+
+ def run_body(input)
+ enumerator = LogicalEnumerator.new("logical_table_remove", input)
+
+ succeess = true
+ enumerator.each do |table, shard_key, shard_range|
+ remove_table(table,
+ shard_key,
+ shard_range,
+ enumerator.target_range)
+ end
+ writer.write(succeess)
+ end
+
+ private
+ def remove_table(table, shard_key, shard_range, target_range)
+ cover_type = target_range.cover_type(shard_range)
+ return if cover_type == :none
+
+ expression_builder = RangeExpressionBuilder.new(shard_key,
+ target_range,
+ nil)
+
+ case cover_type
+ when :all
+ table.remove
+ when :partial_min
+ remove_records(table) do |expression|
+ expression_builder.build_partial_min(expression)
+ end
+ table.remove if table.empty?
+ when :partial_max
+ remove_records(table) do |expression|
+ expression_builder.build_partial_max(expression)
+ end
+ table.remove if table.empty?
+ when :partial_min_and_max
+ remove_records(table) do |expression|
+ expression_builder.build_partial_min_and_max(expression)
+ end
+ table.remove if table.empty?
+ end
+ end
+
+ def remove_records(table)
+ expression = nil
+
+ begin
+ expression = Expression.create(table)
+ yield(expression)
+ table.delete(:expression => expression)
+ ensure
+ expression.close if expression
+ end
+ end
+ end
+ end
+end
diff --git a/storage/mroonga/vendor/groonga/plugins/sharding/sources.am b/storage/mroonga/vendor/groonga/plugins/sharding/sources.am
index 5defd4880f1..14e56609cae 100644
--- a/storage/mroonga/vendor/groonga/plugins/sharding/sources.am
+++ b/storage/mroonga/vendor/groonga/plugins/sharding/sources.am
@@ -2,4 +2,6 @@ sharding_scripts = \
logical_count.rb \
logical_enumerator.rb \
logical_range_filter.rb \
+ logical_select.rb \
+ logical_table_remove.rb \
range_expression_builder.rb
diff --git a/storage/mroonga/vendor/groonga/plugins/suggest/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/suggest/CMakeLists.txt
index 519193918b4..03375f97adb 100644
--- a/storage/mroonga/vendor/groonga/plugins/suggest/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/plugins/suggest/CMakeLists.txt
@@ -18,10 +18,18 @@ include_directories(
${MRUBY_INCLUDE_DIRS})
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/sources.am SUGGEST_SOURCES)
-add_library(suggest MODULE ${SUGGEST_SOURCES})
set_source_files_properties(${SUGGEST_SOURCES}
PROPERTIES
COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
-set_target_properties(suggest PROPERTIES PREFIX "")
+if(GRN_EMBED)
+ add_library(suggest STATIC ${SUGGEST_SOURCES})
+ set_target_properties(
+ suggest
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+else()
+ add_library(suggest MODULE ${SUGGEST_SOURCES})
+ set_target_properties(suggest PROPERTIES PREFIX "")
+ install(TARGETS suggest DESTINATION "${GRN_RELATIVE_PLUGINS_DIR}/suggest")
+endif()
target_link_libraries(suggest libgroonga)
-install(TARGETS suggest DESTINATION "${GRN_RELATIVE_PLUGINS_DIR}/suggest")
diff --git a/storage/mroonga/vendor/groonga/plugins/suggest/suggest.c b/storage/mroonga/vendor/groonga/plugins/suggest/suggest.c
index 863ffcf13e3..073f5e00103 100644
--- a/storage/mroonga/vendor/groonga/plugins/suggest/suggest.c
+++ b/storage/mroonga/vendor/groonga/plugins/suggest/suggest.c
@@ -15,6 +15,10 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef GRN_EMBEDDED
+# define GRN_PLUGIN_FUNCTION_TAG suggest_suggest
+#endif
+
#include <string.h>
#include "grn_ctx.h"
diff --git a/storage/mroonga/vendor/groonga/plugins/table/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/table/CMakeLists.txt
index eada0395080..bd423a830b3 100644
--- a/storage/mroonga/vendor/groonga/plugins/table/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/plugins/table/CMakeLists.txt
@@ -18,10 +18,12 @@ include_directories(
${MRUBY_INCLUDE_DIRS})
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/sources.am TABLE_SOURCES)
-add_library(table MODULE ${TABLE_SOURCES})
-set_source_files_properties(${TABLE_SOURCES}
- PROPERTIES
- COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
-set_target_properties(table PROPERTIES PREFIX "")
-target_link_libraries(table libgroonga)
-install(TARGETS table DESTINATION "${GRN_RELATIVE_PLUGINS_DIR}/table")
+if(NOT GRN_EMBED)
+ add_library(table MODULE ${TABLE_SOURCES})
+ set_source_files_properties(${TABLE_SOURCES}
+ PROPERTIES
+ COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
+ set_target_properties(table PROPERTIES PREFIX "")
+ target_link_libraries(table libgroonga)
+ install(TARGETS table DESTINATION "${GRN_RELATIVE_PLUGINS_DIR}/table")
+endif()
diff --git a/storage/mroonga/vendor/groonga/plugins/token_filters/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/token_filters/CMakeLists.txt
index a0b964fb659..55491b20bd7 100644
--- a/storage/mroonga/vendor/groonga/plugins/token_filters/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/plugins/token_filters/CMakeLists.txt
@@ -21,27 +21,43 @@ set(TOKEN_FILTERS_DIR "${GRN_RELATIVE_PLUGINS_DIR}/token_filters")
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/stop_word_sources.am
STOP_WORD_SOURCES)
-add_library(stop_word_token_filter MODULE ${STOP_WORD_SOURCES})
set_source_files_properties(${STOP_WORD_SOURCES}
PROPERTIES
COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
-set_target_properties(stop_word_token_filter PROPERTIES
- PREFIX ""
- OUTPUT_NAME "stop_word")
+if(GRN_EMBED)
+ add_library(stop_word_token_filter STATIC ${STOP_WORD_SOURCES})
+ set_target_properties(
+ stop_word_token_filter
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+else()
+ add_library(stop_word_token_filter MODULE ${STOP_WORD_SOURCES})
+ set_target_properties(stop_word_token_filter PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "stop_word")
+ install(TARGETS stop_word_token_filter DESTINATION "${TOKEN_FILTERS_DIR}")
+endif()
target_link_libraries(stop_word_token_filter libgroonga)
-install(TARGETS stop_word_token_filter DESTINATION "${TOKEN_FILTERS_DIR}")
if(GRN_WITH_LIBSTEMMER)
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/stem_sources.am STEM_SOURCES)
include_directories(${LIBSTEMMER_INCLUDE_DIRS})
link_directories(${LIBSTEMMER_LIBRARY_DIRS})
- add_library(stem_token_filter MODULE ${STEM_SOURCES})
set_source_files_properties(${STEM_SOURCES}
PROPERTIES
COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
- set_target_properties(stem_token_filter PROPERTIES
- PREFIX ""
- OUTPUT_NAME "stem")
+ if(GRN_EMBED)
+ add_library(stem_token_filter STATIC ${STEM_SOURCES})
+ set_target_properties(
+ stem_token_filter
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+ else()
+ add_library(stem_token_filter MODULE ${STEM_SOURCES})
+ set_target_properties(stem_token_filter PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "stem")
+ install(TARGETS stem_token_filter DESTINATION "${TOKEN_FILTERS_DIR}")
+ endif()
target_link_libraries(stem_token_filter libgroonga ${LIBSTEMMER_LIBRARIES})
- install(TARGETS stem_token_filter DESTINATION "${TOKEN_FILTERS_DIR}")
endif()
diff --git a/storage/mroonga/vendor/groonga/plugins/token_filters/stem.c b/storage/mroonga/vendor/groonga/plugins/token_filters/stem.c
index 010b8c91867..63e640d5ea2 100644
--- a/storage/mroonga/vendor/groonga/plugins/token_filters/stem.c
+++ b/storage/mroonga/vendor/groonga/plugins/token_filters/stem.c
@@ -16,6 +16,10 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef GRN_EMBEDDED
+# define GRN_PLUGIN_FUNCTION_TAG token_filters_stem
+#endif
+
#include <grn_str.h>
#include <groonga.h>
diff --git a/storage/mroonga/vendor/groonga/plugins/token_filters/stop_word.c b/storage/mroonga/vendor/groonga/plugins/token_filters/stop_word.c
index 054cd65aa37..e5a9a77de2e 100644
--- a/storage/mroonga/vendor/groonga/plugins/token_filters/stop_word.c
+++ b/storage/mroonga/vendor/groonga/plugins/token_filters/stop_word.c
@@ -16,6 +16,10 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef GRN_EMBEDDED
+# define GRN_PLUGIN_FUNCTION_TAG token_filters_stop_word
+#endif
+
#include <grn_str.h>
#include <groonga.h>
diff --git a/storage/mroonga/vendor/groonga/plugins/tokenizers/CMakeLists.txt b/storage/mroonga/vendor/groonga/plugins/tokenizers/CMakeLists.txt
index 5871e982211..9209b44d36f 100644
--- a/storage/mroonga/vendor/groonga/plugins/tokenizers/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/plugins/tokenizers/CMakeLists.txt
@@ -22,28 +22,44 @@ if(GRN_WITH_MECAB)
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/mecab_sources.am MECAB_SOURCES)
include_directories(${MECAB_INCLUDE_DIRS})
link_directories(${MECAB_LIBRARY_DIRS})
- add_library(mecab_tokenizer MODULE ${MECAB_SOURCES})
set_source_files_properties(${MECAB_SOURCES}
PROPERTIES
COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
- set_target_properties(mecab_tokenizer PROPERTIES
- PREFIX ""
- OUTPUT_NAME "mecab")
+ if(GRN_EMBED)
+ add_library(mecab_tokenizer STATIC ${MECAB_SOURCES})
+ set_target_properties(
+ mecab_tokenizer
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+ else()
+ add_library(mecab_tokenizer MODULE ${MECAB_SOURCES})
+ set_target_properties(mecab_tokenizer PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "mecab")
+ install(TARGETS mecab_tokenizer DESTINATION "${TOKENIZERS_DIR}")
+ endif()
target_link_libraries(mecab_tokenizer libgroonga ${MECAB_LIBRARIES})
- install(TARGETS mecab_tokenizer DESTINATION "${TOKENIZERS_DIR}")
endif()
if(GRN_WITH_KYTEA)
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/kytea_sources.am KYTEA_SOURCES)
include_directories(${KYTEA_INCLUDE_DIRS})
link_directories(${KYTEA_LIBRARY_DIRS})
- add_library(kytea_tokenizer MODULE ${KYTEA_SOURCES})
set_source_files_properties(${KYTEA_SOURCES}
PROPERTIES
COMPILE_FLAGS "${GRN_CXX_COMPILE_FLAGS}")
- set_target_properties(kytea_tokenizer PROPERTIES
- PREFIX ""
- OUTPUT_NAME "kytea")
+ if(GRN_EMBED)
+ add_library(kytea_tokenizer STATIC ${KYTEA_SOURCES})
+ set_target_properties(
+ kytea_tokenizer
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+ else()
+ add_library(kytea_tokenizer MODULE ${KYTEA_SOURCES})
+ set_target_properties(kytea_tokenizer PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "kytea")
+ install(TARGETS kytea_tokenizer DESTINATION "${TOKENIZERS_DIR}")
+ endif()
target_link_libraries(kytea_tokenizer libgroonga ${KYTEA_LIBRARIES})
- install(TARGETS kytea_tokenizer DESTINATION "${TOKENIZERS_DIR}")
endif()
diff --git a/storage/mroonga/vendor/groonga/plugins/tokenizers/kytea.cpp b/storage/mroonga/vendor/groonga/plugins/tokenizers/kytea.cpp
index a7ee4104592..62ef0bb5845 100644
--- a/storage/mroonga/vendor/groonga/plugins/tokenizers/kytea.cpp
+++ b/storage/mroonga/vendor/groonga/plugins/tokenizers/kytea.cpp
@@ -15,6 +15,10 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef GRN_EMBEDDED
+# define GRN_PLUGIN_FUNCTION_TAG tokenizers_kytea
+#endif
+
#include <groonga/tokenizer.h>
#include <kytea/kytea.h>
diff --git a/storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c b/storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c
index 9207f94229e..bade2f9d3de 100644
--- a/storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c
+++ b/storage/mroonga/vendor/groonga/plugins/tokenizers/mecab.c
@@ -15,6 +15,10 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef GRN_EMBEDDED
+# define GRN_PLUGIN_FUNCTION_TAG tokenizers_mecab
+#endif
+
#include <grn_str.h>
#include <groonga.h>
@@ -509,17 +513,21 @@ grn_rc
GRN_PLUGIN_INIT(grn_ctx *ctx)
{
{
- const char *env;
+ char env[GRN_ENV_BUFFER_SIZE];
- env = getenv("GRN_MECAB_CHUNKED_TOKENIZE_ENABLED");
- grn_mecab_chunked_tokenize_enabled = (env && strcmp(env, "yes") == 0);
+ grn_getenv("GRN_MECAB_CHUNKED_TOKENIZE_ENABLED",
+ env,
+ GRN_ENV_BUFFER_SIZE);
+ grn_mecab_chunked_tokenize_enabled = (env[0] && strcmp(env, "yes") == 0);
}
{
- const char *env;
+ char env[GRN_ENV_BUFFER_SIZE];
- env = getenv("GRN_MECAB_CHUNK_SIZE_THRESHOLD");
- if (env) {
+ grn_getenv("GRN_MECAB_CHUNK_SIZE_THRESHOLD",
+ env,
+ GRN_ENV_BUFFER_SIZE);
+ if (env[0]) {
int threshold = -1;
const char *end;
const char *rest;
diff --git a/storage/mroonga/vendor/groonga/ra.rb b/storage/mroonga/vendor/groonga/ra.rb
new file mode 100755
index 00000000000..dbe493d7454
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/ra.rb
@@ -0,0 +1,12 @@
+#!/usr/bin/env ruby
+
+puts "table_create X TABLE_NO_KEY"
+puts "column_create X a COLUMN_SCALAR Int64"
+puts "load --table X"
+puts "["
+n_records = 2 ** 28
+(n_records - 1).times do |i|
+ puts "{\"a\": #{i}},"
+end
+puts "{\"a\": #{n_records - 1}}"
+puts "]"
diff --git a/storage/mroonga/vendor/groonga/src/grndb.c b/storage/mroonga/vendor/groonga/src/grndb.c
index d493338f57e..d5a353e229a 100644
--- a/storage/mroonga/vendor/groonga/src/grndb.c
+++ b/storage/mroonga/vendor/groonga/src/grndb.c
@@ -120,6 +120,8 @@ main(int argc, char **argv)
{
int exit_code = EXIT_SUCCESS;
+ grn_default_logger_set_path(GRN_LOG_PATH);
+
if (grn_init() != GRN_SUCCESS) {
return EXIT_FAILURE;
}
diff --git a/storage/mroonga/vendor/groonga/src/grnslap.c b/storage/mroonga/vendor/groonga/src/grnslap.c
index 2f5562fe6a9..f9eee1081fd 100644
--- a/storage/mroonga/vendor/groonga/src/grnslap.c
+++ b/storage/mroonga/vendor/groonga/src/grnslap.c
@@ -21,11 +21,11 @@
#include <string.h>
#include <stdio.h>
#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
+# include <sys/wait.h>
#endif /* HAVE_SYS_WAIT_H */
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif /* HAVE_NETINET_IN_H */
+#ifndef WIN32
+# include <netinet/in.h>
+#endif /* WIN32 */
#define DEFAULT_PORT 10041
#define DEFAULT_HOST "localhost"
@@ -362,6 +362,8 @@ main(int argc, char **argv)
flags |= flag_usage;
}
+ grn_default_logger_set_path(GRN_LOG_PATH);
+
if (grn_init()) { return -1; }
if (flags & flag_usage) {
usage(); r = -1;
diff --git a/storage/mroonga/vendor/groonga/src/groonga.c b/storage/mroonga/vendor/groonga/src/groonga.c
index 262c4de2e86..28c318664e0 100644
--- a/storage/mroonga/vendor/groonga/src/groonga.c
+++ b/storage/mroonga/vendor/groonga/src/groonga.c
@@ -39,9 +39,9 @@
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif /* HAVE_SYS_SOCKET_H */
-#ifdef HAVE_NETINET_IN_H
+#ifndef WIN32
# include <netinet/in.h>
-#endif /* HAVE_NETINET_IN_H */
+#endif /* WIN32 */
#ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h>
@@ -51,9 +51,12 @@
# include <sys/sysctl.h>
#endif /* HAVE_SYS_SYSCTL_H */
-#ifdef HAVE_IO_H
+#ifdef WIN32
# include <io.h>
-#endif /* HAVE_IO_H */
+# include <direct.h>
+#else /* WIN32 */
+# include <sys/uio.h>
+#endif /* WIN32 */
#ifdef HAVE__STRNICMP
# ifdef strncasecmp
@@ -2656,7 +2659,7 @@ main(int argc, char **argv)
const char *bind_address_arg = NULL;
const char *hostname_arg = NULL;
const char *protocol_arg = NULL;
- const char *log_path_arg = NULL;
+ const char *log_path_arg = GRN_LOG_PATH;
const char *log_rotate_threshold_size_arg = NULL;
const char *query_log_path_arg = NULL;
const char *query_log_rotate_threshold_size_arg = NULL;
diff --git a/storage/mroonga/vendor/groonga/src/groonga_benchmark.c b/storage/mroonga/vendor/groonga/src/groonga_benchmark.c
index 656984a7695..2ebca387232 100644
--- a/storage/mroonga/vendor/groonga/src/groonga_benchmark.c
+++ b/storage/mroonga/vendor/groonga/src/groonga_benchmark.c
@@ -28,14 +28,14 @@
#include <sys/stat.h>
#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
+# include <sys/wait.h>
#endif /* HAVE_SYS_WAIT_H */
#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
+# include <sys/socket.h>
#endif /* HAVE_SYS_SOCKET_H */
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif /* HAVE_NETINET_IN_H */
+#ifndef WIN32
+# include <netinet/in.h>
+#endif /* WIN32 */
#include <grn_str.h>
#include <grn_com.h>
@@ -3062,6 +3062,8 @@ main(int argc, char **argv)
grntest_outtype = OUT_TSV;
}
+ grn_default_logger_set_path(GRN_LOG_PATH);
+
grn_init();
CRITICAL_SECTION_INIT(grntest_cs);
diff --git a/storage/mroonga/vendor/groonga/src/groonga_mruby.c b/storage/mroonga/vendor/groonga/src/groonga_mruby.c
index 9978a002f18..2f442fbd126 100644
--- a/storage/mroonga/vendor/groonga/src/groonga_mruby.c
+++ b/storage/mroonga/vendor/groonga/src/groonga_mruby.c
@@ -67,6 +67,8 @@ main(int argc, char **argv)
return EXIT_FAILURE;
}
+ grn_default_logger_set_path(GRN_LOG_PATH);
+
if (grn_init() != GRN_SUCCESS) {
return EXIT_FAILURE;
}
diff --git a/storage/mroonga/vendor/groonga/src/httpd/nginx-module/config b/storage/mroonga/vendor/groonga/src/httpd/nginx-module/config
index fc1fe16fad7..b79eef6ba17 100644
--- a/storage/mroonga/vendor/groonga/src/httpd/nginx-module/config
+++ b/storage/mroonga/vendor/groonga/src/httpd/nginx-module/config
@@ -10,7 +10,11 @@ if [ "$GROONGA_HTTPD_IN_TREE" = yes ]; then
groonga_cflags="-I${GROONGA_HTTPD_IN_TREE_INCLUDE_PATH}"
groonga_cflags="${groonga_cflags} -DNGX_HTTP_GROONGA_LOG_PATH=\\\"\"${GROONGA_HTTPD_GROONGA_LOG_PATH}\"\\\""
groonga_cflags="${groonga_cflags} -DNGX_HTTP_GROONGA_QUERY_LOG_PATH=\\\"\"${GROONGA_HTTPD_GROONGA_QUERY_LOG_PATH}\"\\\""
- groonga_libs="-L${GROONGA_HTTPD_IN_TREE_LINK_PATH} -lgroonga"
+ groonga_libs="-L${GROONGA_HTTPD_IN_TREE_LINK_PATH}"
+ if [ "${GROONGA_HTTPD_WITH_ONIGMO}" = "yes" ]; then
+ groonga_libs="$groonga_libs -L${GROONGA_HTTPD_ONIGMO_IN_TREE_LINK_PATH}"
+ fi
+ groonga_libs="$groonga_libs -lgroonga"
if [ -n "${GROONGA_HTTPD_RPATH}" ]; then
groonga_libs="$groonga_libs -Wl,-rpath -Wl,${GROONGA_HTTPD_RPATH}"
fi
@@ -46,7 +50,7 @@ if [ $ngx_found = yes ]; then
CORE_LIBS="$CORE_LIBS $groonga_libs"
else
cat << END
-$0: error: the groonga module requires the groonga library.
+$0: error: the groonga module requires the Groonga library.
END
exit 1
fi
diff --git a/storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c b/storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c
index 6ba1df4a9e8..727e65fa468 100644
--- a/storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c
+++ b/storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c
@@ -134,6 +134,30 @@ ngx_str_is_custom_path(ngx_str_t *string)
}
static void
+ngx_http_groonga_write_fd(ngx_fd_t fd,
+ u_char *buffer, size_t buffer_size,
+ const char *message, size_t message_size)
+{
+ size_t rest_message_size = message_size;
+ const char *current_message = message;
+
+ while (rest_message_size > 0) {
+ size_t current_message_size;
+
+ if (rest_message_size > NGX_MAX_ERROR_STR) {
+ current_message_size = NGX_MAX_ERROR_STR;
+ } else {
+ current_message_size = rest_message_size;
+ }
+
+ grn_memcpy(buffer, current_message, current_message_size);
+ ngx_write_fd(fd, buffer, current_message_size);
+ rest_message_size -= current_message_size;
+ current_message += current_message_size;
+ }
+}
+
+static void
ngx_http_groonga_logger_log(grn_ctx *ctx, grn_log_level level,
const char *timestamp, const char *title,
const char *message, const char *location,
@@ -171,10 +195,14 @@ ngx_http_groonga_logger_log(grn_ctx *ctx, grn_log_level level,
LOG_PREFIX_FORMAT,
timestamp, *(level_marks + level), title);
ngx_write_fd(logger_data->file->fd, buffer, last - buffer);
- ngx_write_fd(logger_data->file->fd, (void *)message, message_size);
+ ngx_http_groonga_write_fd(logger_data->file->fd,
+ buffer, NGX_MAX_ERROR_STR,
+ message, message_size);
if (location_size > 0) {
ngx_write_fd(logger_data->file->fd, " ", 1);
- ngx_write_fd(logger_data->file->fd, (void *)location, location_size);
+ ngx_http_groonga_write_fd(logger_data->file->fd,
+ buffer, NGX_MAX_ERROR_STR,
+ location, location_size);
}
ngx_write_fd(logger_data->file->fd, "\n", 1);
} else {
diff --git a/storage/mroonga/vendor/groonga/tools/install/install-for-debian-jessie.sh b/storage/mroonga/vendor/groonga/tools/install/install-for-debian-jessie.sh
new file mode 100755
index 00000000000..d053d2d9caf
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/tools/install/install-for-debian-jessie.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+set -e
+
+sources_list_path=/etc/apt/sources.list.d/groonga.list
+
+if [ ! -f $sources_list_path ]; then
+ sudo cat <<SOURCES_LIST | sudo tee $sources_list_path
+deb http://packages.groonga.org/debian/ jessie main
+deb-src http://packages.groonga.org/debian/ jessie main
+SOURCES_LIST
+fi
+
+sudo apt-get update
+sudo apt-get install -y --allow-unauthenticated groonga-keyring
+sudo apt-get update
+sudo apt-get install -y -V groonga
diff --git a/storage/mroonga/vendor/groonga/vendor/mruby/CMakeLists.txt b/storage/mroonga/vendor/groonga/vendor/mruby/CMakeLists.txt
index c78fde5d258..f2b27aff7e8 100644
--- a/storage/mroonga/vendor/groonga/vendor/mruby/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/vendor/mruby/CMakeLists.txt
@@ -17,6 +17,7 @@ if(GRN_WITH_MRUBY)
include_directories(
"${CMAKE_CURRENT_SOURCE_DIR}/../mruby-source/include"
"${CMAKE_CURRENT_SOURCE_DIR}/../mruby-source/src"
+ "${CMAKE_CURRENT_SOURCE_DIR}/../mruby-source/mrbgems/mruby-compiler/core"
"${CMAKE_CURRENT_SOURCE_DIR}/../onigmo-source"
)
diff --git a/storage/mroonga/vendor/groonga/vendor/mruby/Makefile.am b/storage/mroonga/vendor/groonga/vendor/mruby/Makefile.am
index d995ccfcce1..c4285c1c85c 100644
--- a/storage/mroonga/vendor/groonga/vendor/mruby/Makefile.am
+++ b/storage/mroonga/vendor/groonga/vendor/mruby/Makefile.am
@@ -3,10 +3,11 @@ EXTRA_DIST = \
mruby_build.rb \
mruby_build.timestamp
-DEFAULT_INCLUDES = \
- -I$(srcdir)/../mruby-source/include \
- -I$(srcdir)/../mruby-source/src \
- -Imruby-io/include \
+DEFAULT_INCLUDES = \
+ -I$(srcdir)/../mruby-source/include \
+ -I$(srcdir)/../mruby-source/src \
+ -I$(srcdir)/../mruby-source/mrbgems/mruby-compiler/core \
+ -Imruby-io/include \
-I$(srcdir)/mruby-io/include
CFLAGS += $(NO_FLOAT_EQUAL_CFLAGS)
@@ -27,9 +28,9 @@ include sources.am
include built_sources.am
libmruby_la_SOURCES += $(BUILT_SOURCES)
-parse.c: mruby_build.timestamp
mrblib.c: mruby_build.timestamp
mrbgems_init.c: mruby_build.timestamp
+mruby-compiler/core/parse.c: mruby_build.timestamp
mruby-onig-regexp/src/mruby_onig_regexp.c: mruby_build.timestamp
mruby-env/src/env.c: mruby_build.timestamp
mruby-io/include/mruby/ext/io.h: mruby_build.timestamp
diff --git a/storage/mroonga/vendor/groonga/vendor/mruby/build_config.rb b/storage/mroonga/vendor/groonga/vendor/mruby/build_config.rb
index 5a963f9c7e7..f487e08b808 100644
--- a/storage/mroonga/vendor/groonga/vendor/mruby/build_config.rb
+++ b/storage/mroonga/vendor/groonga/vendor/mruby/build_config.rb
@@ -12,6 +12,7 @@ MRuby::Build.new do |conf|
enable_debug
+ conf.gem :core => "mruby-compiler"
conf.gem :core => "mruby-sprintf"
conf.gem :core => "mruby-print"
conf.gem :core => "mruby-math"
diff --git a/storage/mroonga/vendor/groonga/vendor/mruby/built_sources.am b/storage/mroonga/vendor/groonga/vendor/mruby/built_sources.am
index 08c5e3a9453..73726cda58b 100644
--- a/storage/mroonga/vendor/groonga/vendor/mruby/built_sources.am
+++ b/storage/mroonga/vendor/groonga/vendor/mruby/built_sources.am
@@ -1,7 +1,7 @@
BUILT_SOURCES = \
- parse.c \
mrblib.c \
mrbgems_init.c \
+ mruby-compiler/core/parse.c \
mruby-onig-regexp/src/mruby_onig_regexp.c \
mruby-env/src/env.c \
mruby-io/include/mruby/ext/io.h \
diff --git a/storage/mroonga/vendor/groonga/vendor/mruby/mruby_build.rb b/storage/mroonga/vendor/groonga/vendor/mruby/mruby_build.rb
index f0db931ed38..e2e8d68e7cf 100755
--- a/storage/mroonga/vendor/groonga/vendor/mruby/mruby_build.rb
+++ b/storage/mroonga/vendor/groonga/vendor/mruby/mruby_build.rb
@@ -28,7 +28,6 @@ end
FileUtils.touch(timestamp_file)
-FileUtils.cp("#{mruby_build_dir}/host/src/y.tab.c", "parse.c")
FileUtils.cp("#{mruby_build_dir}/host/mrblib/mrblib.c", "./")
File.open("mrbgems_init.c", "w") do |mrbgems_init|
@@ -37,6 +36,11 @@ File.open("mrbgems_init.c", "w") do |mrbgems_init|
end
end
+mruby_compiler_dir = "#{mruby_build_dir}/host/mrbgems/mruby-compiler"
+FileUtils.mkdir_p("mruby-compiler/core/")
+FileUtils.cp("#{mruby_compiler_dir}/core/y.tab.c",
+ "mruby-compiler/core/parse.c")
+
mruby_onig_regexp_dir = "#{mruby_build_dir}/mrbgems/mruby-onig-regexp"
FileUtils.mkdir_p("mruby-onig-regexp/")
FileUtils.cp_r("#{mruby_onig_regexp_dir}/src/", "mruby-onig-regexp/")
diff --git a/storage/mroonga/vendor/groonga/vendor/mruby/sources.am b/storage/mroonga/vendor/groonga/vendor/mruby/sources.am
index 68f15c64571..78ecc9b85df 100644
--- a/storage/mroonga/vendor/groonga/vendor/mruby/sources.am
+++ b/storage/mroonga/vendor/groonga/vendor/mruby/sources.am
@@ -2,7 +2,7 @@ libmruby_la_SOURCES = \
../mruby-source/src/array.c \
../mruby-source/src/backtrace.c \
../mruby-source/src/class.c \
- ../mruby-source/src/codegen.c \
+ ../mruby-source/src/codedump.c \
../mruby-source/src/compar.c \
../mruby-source/src/crc.c \
../mruby-source/src/debug.c \
@@ -17,8 +17,6 @@ libmruby_la_SOURCES = \
../mruby-source/src/init.c \
../mruby-source/src/kernel.c \
../mruby-source/src/load.c \
- ../mruby-source/src/mrb_throw.h \
- ../mruby-source/src/node.h \
../mruby-source/src/numeric.c \
../mruby-source/src/object.c \
../mruby-source/src/opcode.h \
@@ -33,6 +31,8 @@ libmruby_la_SOURCES = \
../mruby-source/src/variable.c \
../mruby-source/src/version.c \
../mruby-source/src/vm.c \
+ ../mruby-source/mrbgems/mruby-compiler/core/codegen.c \
+ ../mruby-source/mrbgems/mruby-compiler/core/node.h \
../mruby-source/mrbgems/mruby-sprintf/src/kernel.c \
../mruby-source/mrbgems/mruby-sprintf/src/sprintf.c \
../mruby-source/mrbgems/mruby-print/src/print.c \
diff --git a/storage/mroonga/vendor/groonga/vendor/onigmo/CMakeLists.txt b/storage/mroonga/vendor/groonga/vendor/onigmo/CMakeLists.txt
index 0f79347aa73..e52bb1d195c 100644
--- a/storage/mroonga/vendor/groonga/vendor/onigmo/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/vendor/onigmo/CMakeLists.txt
@@ -34,12 +34,23 @@ if(GRN_WITH_ONIGMO)
ac_check_sizeof(int)
ac_check_sizeof(long)
+ add_definitions(-DHAVE_STDARG_H)
+ add_definitions(-DHAVE_STDINT_H)
+ add_definitions(-DHAVE_STDLIB_H)
+ add_definitions(-DHAVE_STRING_H)
+ add_definitions(-DHAVE_SYS_TYPES_H)
+
+ add_definitions(-DSTDC_HEADERS)
+
if(MSVC)
add_definitions(-Dinline=__inline)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
+ else()
+ add_definitions(-DHAVE_INTTYPES_H)
endif()
include_directories(
+ BEFORE
${ONIGMO_BINARY_DIR}
${ONIGMO_SOURCE_DIR}
)
@@ -107,4 +118,6 @@ if(GRN_WITH_ONIGMO)
onigmo
PROPERTIES
POSITION_INDEPENDENT_CODE ON)
+
+ configure_file(config.h.cmake "${ONIGMO_BINARY_DIR}/config.h")
endif()
diff --git a/storage/mroonga/vendor/groonga/vendor/onigmo/Makefile.am b/storage/mroonga/vendor/groonga/vendor/onigmo/Makefile.am
index 73632ebd3bd..cbd419d6736 100644
--- a/storage/mroonga/vendor/groonga/vendor/onigmo/Makefile.am
+++ b/storage/mroonga/vendor/groonga/vendor/onigmo/Makefile.am
@@ -1,5 +1,6 @@
EXTRA_DIST = \
configure \
+ config.h.cmake \
CMakeLists.txt
CONFIGURE_DEPENDENCIES = \
diff --git a/storage/mroonga/vendor/groonga/vendor/onigmo/config.h.cmake b/storage/mroonga/vendor/groonga/vendor/onigmo/config.h.cmake
new file mode 100644
index 00000000000..2997587d820
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/vendor/onigmo/config.h.cmake
@@ -0,0 +1 @@
+/* dummy */
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/doc/text/news.md b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/doc/text/news.md
index 22a7fdb17cf..f66e285bc7d 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/doc/text/news.md
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/doc/text/news.md
@@ -1,5 +1,16 @@
# News
+## 1.1.0: 2015-05-29
+
+### Fixes
+
+ * Fixed a bug that full-width space isn't treated as blank character.
+ [groonga-dev,03215] [Reported by Shota Mitsui]
+
+### Thanks
+
+ * Shota Mitsui
+
## 1.0.9: 2015-03-29
### Improves
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/normalizers/CMakeLists.txt b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/normalizers/CMakeLists.txt
index db8ffedb082..bddda0a9295 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/normalizers/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/normalizers/CMakeLists.txt
@@ -18,9 +18,21 @@
set(NORMALIZERS_DIR "${GROONGA_PLUGINS_DIR}/normalizers")
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/mysql_sources.am MYSQL_SOURCES)
if(GROONGA_NORMALIZER_MYSQL_EMBED)
- add_convenience_library(mysql_normalizer ${MYSQL_SOURCES})
+ add_library(mysql_normalizer STATIC ${MYSQL_SOURCES})
set_property(TARGET mysql_normalizer APPEND PROPERTY
COMPILE_DEFINITIONS "GROONGA_NORMALIZER_MYSQL_EMBED")
+ set_target_properties(
+ mysql_normalizer
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+ if(NOT DEFINED CMAKE_C_COMPILE_OPTIONS_PIC)
+ # For old CMake
+ if(CMAKE_COMPILER_IS_GNUCXX)
+ set_source_files_properties(${MYSQL_SOURCES}
+ PROPERTIES
+ COMPILE_FLAGS "-fPIC")
+ endif()
+ endif()
else()
add_library(mysql_normalizer MODULE ${MYSQL_SOURCES})
set_target_properties(mysql_normalizer PROPERTIES
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/normalizers/mysql.c b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/normalizers/mysql.c
index c7eb102d0e1..e7961ee41f8 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/normalizers/mysql.c
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/normalizers/mysql.c
@@ -364,41 +364,50 @@ normalize(grn_ctx *ctx, grn_obj *string,
rest_length = original_length_in_bytes;
while (rest_length > 0) {
int character_length;
+ grn_bool custom_normalized = GRN_FALSE;
+ unsigned int normalized_character_length;
+ unsigned int previous_normalized_length_in_bytes =
+ normalized_length_in_bytes;
+ unsigned int previous_normalized_n_characters =
+ normalized_n_characters;
character_length = grn_plugin_charlen(ctx, rest, rest_length, encoding);
if (character_length == 0) {
break;
}
- if (remove_blank_p && character_length == 1 && rest[0] == ' ') {
+ if (custom_normalizer) {
+ custom_normalized = custom_normalizer(ctx,
+ rest,
+ &character_length,
+ rest_length - character_length,
+ normalize_table,
+ normalized,
+ &normalized_character_length,
+ &normalized_length_in_bytes,
+ &normalized_n_characters);
+ }
+ if (!custom_normalized) {
+ normalize_character(rest, character_length,
+ normalize_table, normalize_table_size,
+ normalized,
+ &normalized_character_length,
+ &normalized_length_in_bytes,
+ &normalized_n_characters);
+ }
+
+ if (remove_blank_p &&
+ normalized_character_length == 1 &&
+ normalized[previous_normalized_length_in_bytes] == ' ') {
if (current_type > types) {
current_type[-1] |= GRN_CHAR_BLANK;
}
if (current_check) {
current_check[0]++;
}
+ normalized_length_in_bytes = previous_normalized_length_in_bytes;
+ normalized_n_characters = previous_normalized_n_characters;
} else {
- grn_bool custom_normalized = GRN_FALSE;
- unsigned int normalized_character_length;
- if (custom_normalizer) {
- custom_normalized = custom_normalizer(ctx,
- rest,
- &character_length,
- rest_length - character_length,
- normalize_table,
- normalized,
- &normalized_character_length,
- &normalized_length_in_bytes,
- &normalized_n_characters);
- }
- if (!custom_normalized) {
- normalize_character(rest, character_length,
- normalize_table, normalize_table_size,
- normalized,
- &normalized_character_length,
- &normalized_length_in_bytes,
- &normalized_n_characters);
- }
if (current_type && normalized_character_length > 0) {
char *current_normalized;
current_normalized =
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/build-deb.sh b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/build-deb.sh
index fdfc8f52f03..a0a28b0d29b 100755
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/build-deb.sh
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/apt/build-deb.sh
@@ -22,8 +22,8 @@ case "${distribution}" in
debian)
component=main
run cat <<EOF > /etc/apt/sources.list.d/groonga.list
-deb http://packages.groonga.org/debian/ wheezy main
-deb-src http://packages.groonga.org/debian/ wheezy main
+deb http://packages.groonga.org/debian/ ${code_name} main
+deb-src http://packages.groonga.org/debian/ ${code_name} main
EOF
run apt-get update
run apt-get install -y --allow-unauthenticated groonga-keyring
@@ -54,4 +54,4 @@ run cd -
package_initial=$(echo "${PACKAGE}" | sed -e 's/\(.\).*/\1/')
pool_dir="/vagrant/repositories/${distribution}/pool/${code_name}/${component}/${package_initial}/${PACKAGE}"
run mkdir -p "${pool_dir}/"
-run cp *.tar.gz *.dsc *.deb "${pool_dir}/"
+run cp *.tar.* *.dsc *.deb "${pool_dir}/"
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/debian/changelog b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/debian/changelog
index 7fa8d1e17f0..ea07d115215 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/debian/changelog
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/debian/changelog
@@ -1,3 +1,9 @@
+groonga-normalizer-mysql (1.1.0-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Kouhei Sutou <kou@clear-code.com> Fri, 29 May 2015 00:00:00 +0900
+
groonga-normalizer-mysql (1.0.9-1) unstable; urgency=low
* New upstream release.
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/centos/groonga-normalizer-mysql.spec.in b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/centos/groonga-normalizer-mysql.spec.in
index 4084576a704..f78794f1973 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/centos/groonga-normalizer-mysql.spec.in
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/centos/groonga-normalizer-mysql.spec.in
@@ -52,6 +52,9 @@ rm $RPM_BUILD_ROOT%{_libdir}/groonga/plugins/*/*.la
%{_libdir}/pkgconfig/groonga-normalizer-mysql.pc
%changelog
+* Fri May 29 2015 Kouhei Sutou <kou@clear-code.com> - 1.1.0-1
+- new upstream release.
+
* Sun Mar 29 2015 HAYASHI Kentaro <hayashi@clear-code.com> - 1.0.9-1
- new upstream release.
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/fedora/groonga-normalizer-mysql.spec.in b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/fedora/groonga-normalizer-mysql.spec.in
index 974b7c31649..8cf379086a6 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/fedora/groonga-normalizer-mysql.spec.in
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/rpm/fedora/groonga-normalizer-mysql.spec.in
@@ -51,6 +51,9 @@ rm $RPM_BUILD_ROOT%{_libdir}/groonga/plugins/*/*.la
%{_libdir}/pkgconfig/groonga-normalizer-mysql.pc
%changelog
+* Fri May 29 2015 Kouhei Sutou <kou@clear-code.com> - 1.1.0-1
+- new upstream release.
+
* Sun Mar 29 2015 HAYASHI Kentaro <hayashi@clear-code.com> - 1.0.9-1
- new upstream release.
diff --git a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version
index e5a4a5e7d84..1cc5f657e05 100644
--- a/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version
+++ b/storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/version
@@ -1 +1 @@
-1.0.9 \ No newline at end of file
+1.1.0 \ No newline at end of file
diff --git a/storage/mroonga/version b/storage/mroonga/version
index 760b908bf87..c22ec448710 100644
--- a/storage/mroonga/version
+++ b/storage/mroonga/version
@@ -1 +1 @@
-5.02 \ No newline at end of file
+5.04 \ No newline at end of file
diff --git a/storage/mroonga/version_in_hex b/storage/mroonga/version_in_hex
index 7716095f96c..b2bfc453d0e 100644
--- a/storage/mroonga/version_in_hex
+++ b/storage/mroonga/version_in_hex
@@ -1 +1 @@
-0x0502 \ No newline at end of file
+0x0504 \ No newline at end of file
diff --git a/storage/mroonga/version_micro b/storage/mroonga/version_micro
index d8263ee9860..bf0d87ab1b2 100644
--- a/storage/mroonga/version_micro
+++ b/storage/mroonga/version_micro
@@ -1 +1 @@
-2 \ No newline at end of file
+4 \ No newline at end of file