From 37ad4664392744d305e7b7ace9e09184965a9c04 Mon Sep 17 00:00:00 2001 From: Senad Uka Date: Fri, 7 Feb 2020 16:09:57 +0100 Subject: [PATCH] Upstream sync --- Gemfile | 4 +- Gemfile.lock | 4 +- lib/grammar.y | 2 + lib/parser.rb | 60 +++++++++++++++++++++-------- lib/text_to_sql_query.rb | 1 + pkg/pg_searchable_regex-1.0.21.gem | Bin 20992 -> 0 bytes spec/lib/query_lexer_spec.rb | 2 +- spec/lib/query_parser_spec.rb | 2 +- spec/lib/text_to_sql_query_spec.rb | 40 +++++++++---------- spec/schema.rb | 7 ++++ spec/support/models.rb | 6 +++ version.rb | 2 +- 12 files changed, 86 insertions(+), 44 deletions(-) delete mode 100644 pkg/pg_searchable_regex-1.0.21.gem diff --git a/Gemfile b/Gemfile index 54ad0fd..2283ebe 100644 --- a/Gemfile +++ b/Gemfile @@ -23,6 +23,6 @@ group :development do gem 'rubocop', '~> 0.54', require: false gem 'rubocop-rspec', '~> 1.23', require: false gem 'simplecov', '~> 0.16', require: false - gem "rexical" - gem "racc" + gem "rexical", '~> 1.0', require: false + gem "racc", '~> 1.4', require: false end diff --git a/Gemfile.lock b/Gemfile.lock index ca4785b..d3ec410 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -134,9 +134,9 @@ DEPENDENCIES juwelier (~> 2.1) pg (~> 0.15) pry (~> 0.12) - racc + racc (~> 1.4) rdoc (~> 3.12) - rexical + rexical (~> 1.0) rspec (~> 3.8) rubocop (~> 0.54) rubocop-rspec (~> 1.23) diff --git a/lib/grammar.y b/lib/grammar.y index 5484994..2eed955 100644 --- a/lib/grammar.y +++ b/lib/grammar.y @@ -14,7 +14,9 @@ class Query | TERM_WITHOUT_QUOTES COLON TERM_WITH_QUOTES { result = {val[0] => val[2]} } | expression OPERATOR_OR expression { result = {:OPERATOR_OR => [val[0], val[2]]} } | expression OPERATOR_AND expression { result = {:OPERATOR_AND => [val[0], val[2]]} } + | OPERATOR_NOT expression { result = {:OPERATOR_NOT => val[1]} } | L_BRACKET expression R_BRACKET { result = val[1] } + | expression expression { result = {:OPERATOR_OR => [val[0], val[1]]} } end ---- header diff --git a/lib/parser.rb b/lib/parser.rb index 58fc3c7..165b293 100644 --- a/lib/parser.rb +++ b/lib/parser.rb @@ -10,7 +10,7 @@ require 'racc/parser.rb' class Query < Racc::Parser -module_eval(<<'...end grammar.y/module_eval...', 'grammar.y', 24) +module_eval(<<'...end grammar.y/module_eval...', 'grammar.y', 26) def parse(input) scan_str(input) end @@ -18,34 +18,44 @@ module_eval(<<'...end grammar.y/module_eval...', 'grammar.y', 24) ##### State transition tables begin ### racc_action_table = [ - 8, 7, 3, 4, 11, 5, 16, 3, 4, 9, - 5, 3, 4, 6, 5, 3, 4, 8, 5, 8, - 7, 14, 15 ] + 5, 10, 9, 3, 4, 5, 6, 19, 3, 4, + 7, 6, 5, 10, 9, 3, 4, 5, 6, 11, + 3, 4, 5, 6, 14, 3, 4, nil, 6, 5, + 10, 9, 3, 4, 5, 6, nil, 3, 4, 5, + 6, nil, 3, 4, nil, 6, 5, 10, nil, 3, + 4, 5, 6, nil, 3, 4, nil, 6, 3, 4, + nil, 6, 17, 18 ] racc_action_check = [ - 10, 10, 8, 8, 6, 8, 10, 0, 0, 3, - 0, 5, 5, 1, 5, 7, 7, 12, 7, 2, - 2, 9, 9 ] + 13, 13, 13, 13, 13, 0, 13, 13, 0, 0, + 1, 0, 2, 2, 2, 2, 2, 5, 2, 3, + 5, 5, 6, 5, 7, 6, 6, nil, 6, 8, + 8, 8, 8, 8, 9, 8, nil, 9, 9, 10, + 9, nil, 10, 10, nil, 10, 15, 15, nil, 15, + 15, 16, 15, nil, 16, 16, nil, 16, 12, 12, + nil, 12, 11, 11 ] racc_action_pointer = [ - 2, 13, 16, 2, nil, 6, 4, 10, -3, 16, - -3, nil, 14, nil, nil, nil, nil ] + 3, 10, 10, 12, nil, 15, 20, 24, 27, 32, + 37, 57, 53, -2, nil, 44, 49, nil, nil, nil ] racc_action_default = [ - -2, -10, -1, -3, -4, -10, -10, -10, -10, -10, - -10, 17, -7, -8, -5, -6, -9 ] + -2, -12, -1, -3, -4, -12, -12, -12, -11, -12, + -12, -12, -9, -12, 20, -7, -8, -5, -6, -10 ] racc_goto_table = [ - 2, 1, nil, nil, nil, 10, nil, 12, 13 ] + 2, 1, nil, nil, nil, 12, 13, nil, nil, 15, + 16 ] racc_goto_check = [ - 2, 1, nil, nil, nil, 2, nil, 2, 2 ] + 2, 1, nil, nil, nil, 2, 2, nil, nil, 2, + 2 ] racc_goto_pointer = [ nil, 1, 0 ] racc_goto_default = [ - nil, nil, nil ] + nil, nil, 8 ] racc_reduce_table = [ 0, 0, :racc_error, @@ -57,11 +67,13 @@ racc_reduce_table = [ 3, 12, :_reduce_6, 3, 12, :_reduce_7, 3, 12, :_reduce_8, - 3, 12, :_reduce_9 ] + 2, 12, :_reduce_9, + 3, 12, :_reduce_10, + 2, 12, :_reduce_11 ] -racc_reduce_n = 10 +racc_reduce_n = 12 -racc_shift_n = 17 +racc_shift_n = 20 racc_token_table = { false => 0, @@ -169,11 +181,25 @@ module_eval(<<'.,.,', 'grammar.y', 15) module_eval(<<'.,.,', 'grammar.y', 16) def _reduce_9(val, _values, result) + result = {:OPERATOR_NOT => val[1]} + result + end +.,., + +module_eval(<<'.,.,', 'grammar.y', 17) + def _reduce_10(val, _values, result) result = val[1] result end .,., +module_eval(<<'.,.,', 'grammar.y', 18) + def _reduce_11(val, _values, result) + result = {:OPERATOR_OR => [val[0], val[1]]} + result + end +.,., + def _reduce_none(val, _values, result) val[0] end diff --git a/lib/text_to_sql_query.rb b/lib/text_to_sql_query.rb index c7cc6f8..d473f48 100644 --- a/lib/text_to_sql_query.rb +++ b/lib/text_to_sql_query.rb @@ -42,6 +42,7 @@ class TextToSqlQuery end not_expression = not_array.shift + not_params = not_array ["NOT #{not_expression}"] + not_params diff --git a/pkg/pg_searchable_regex-1.0.21.gem b/pkg/pg_searchable_regex-1.0.21.gem deleted file mode 100644 index 1d3941a04648ee27c64e502e1a7e7ca7117282d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20992 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