activerecord-turntable 2.2.2 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bf0ede019f3de7c07755243eef39d924ba553535
4
- data.tar.gz: 7790c3e307778292759c3683c5381b7f1c8c1525
3
+ metadata.gz: 0183e069709e21d8fd4f93be3b443e9dab8ae88c
4
+ data.tar.gz: c2f793eebeaa9d49278d09892eef7060fddcd757
5
5
  SHA512:
6
- metadata.gz: 22af41085ea74b9b442dec5f7e26b5ddff9086e404486ec6e16c2b56dd2febd333d90b29dfcc912b3d409cec185a1970577db66deead6827dcc3787ff2b1787c
7
- data.tar.gz: 2b5292a67a7c018733515d79fb52ce3ee0474d7b67a551d5f6be159643c780f1187a336caf1b5bbed46651c49b6a37d514b963baed8b7512fe931228ebeb1ae4
6
+ metadata.gz: 3e2305795803f74373a78c8bae47f24054b8abc358d54e49b106f09993b262e96ea8081d37268db7e7c38b5c56a4701720b1c2a3d09669bc5655d38cf20e6b22
7
+ data.tar.gz: c17da81b6c308cb370183d96edfff8b39a9f4431f9af6e76b3e2778c80f414c6cdab1172db34ff0e7e62899bb64619961f658915a24f7988bb2d4cb4151639af
data/.travis.yml CHANGED
@@ -15,3 +15,5 @@ script: bundle exec rake spec
15
15
  matrix:
16
16
  allow_failures:
17
17
  - rvm: ruby-head
18
+ sudo: false
19
+ cache: bundler
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## activerecord-turntable 2.3.0 ##
2
+
3
+ ### Features
4
+
5
+ * Support index hint
6
+
1
7
  ## activerecord-turntable 2.2.2 ##
2
8
 
3
9
  ### Bugfix
@@ -9,14 +9,22 @@ module SQLTree
9
9
  end
10
10
 
11
11
  class SQLTree::Token
12
- KEYWORDS << 'BINARY'
13
- KEYWORDS << 'LIMIT'
14
- KEYWORDS << 'OFFSET'
15
- const_set('BINARY', Class.new(SQLTree::Token::Keyword))
16
- const_set('LIMIT', Class.new(SQLTree::Token::Keyword))
17
- const_set('OFFSET', Class.new(SQLTree::Token::Keyword))
12
+ extended_keywords = ['BINARY', 'LIMIT', 'OFFSET', 'INDEX', 'KEY', 'USE', 'FORCE', 'IGNORE']
13
+ KEYWORDS.concat(extended_keywords)
14
+
15
+ extended_keywords.each do |kwd|
16
+ const_set(kwd, Class.new(SQLTree::Token::Keyword))
17
+ end
18
18
 
19
19
  BINARY_ESCAPE = Class.new(SQLTree::Token).new('x')
20
+
21
+ def possible_index_hint?
22
+ [SQLTree::Token::USE, SQLTree::Token::FORCE, SQLTree::Token::IGNORE].include?(self.class)
23
+ end
24
+
25
+ def index_keyword?
26
+ [SQLTree::Token::INDEX, SQLTree::Token::KEY].include?(self.class)
27
+ end
20
28
  end
21
29
 
22
30
  class SQLTree::Tokenizer
@@ -141,9 +149,16 @@ module SQLTree::Node
141
149
  end
142
150
 
143
151
  class TableReference < Base
152
+ leaf :index_hint
153
+
154
+ def initialize(table, table_alias = nil, index_hint = nil)
155
+ @table, @table_alias, @index_hint = table, table_alias, index_hint
156
+ end
157
+
144
158
  def to_sql(options={})
145
159
  sql = (SQLTree::Node::SubQuery === table) ? table.to_sql : quote_field_name(table)
146
160
  sql << " AS " << quote_field_name(table_alias) if table_alias
161
+ sql << " " << index_hint.to_sql if index_hint
147
162
  return sql
148
163
  end
149
164
 
@@ -151,10 +166,14 @@ module SQLTree::Node
151
166
  if SQLTree::Token::Identifier === tokens.peek
152
167
  tokens.next
153
168
  table_reference = self.new(tokens.current.literal)
154
- if SQLTree::Token::AS === tokens.peek || SQLTree::Token::Identifier === tokens.peek
169
+ if tokens.peek && !tokens.peek.possible_index_hint? &&
170
+ (SQLTree::Token::AS === tokens.peek || SQLTree::Token::Identifier === tokens.peek)
155
171
  tokens.consume(SQLTree::Token::AS) if SQLTree::Token::AS === tokens.peek
156
172
  table_reference.table_alias = tokens.next.literal
157
173
  end
174
+ if tokens.peek && tokens.peek.possible_index_hint? && tokens.peek(2).index_keyword?
175
+ table_reference.index_hint = SQLTree::Node::IndexHint.parse(tokens)
176
+ end
158
177
  return table_reference
159
178
  elsif SQLTree::Token::SELECT === tokens.peek(2)
160
179
  table_reference = self.new(SQLTree::Node::SubQuery.parse(tokens))
@@ -169,6 +188,35 @@ module SQLTree::Node
169
188
  end
170
189
  end
171
190
 
191
+ class IndexHint < Base
192
+ leaf :hint_method
193
+ leaf :hint_key
194
+ leaf :index_list
195
+
196
+ def initialize(hint_method, hint_key, index_list)
197
+ @hint_method, @hint_key, @index_list = hint_method, hint_key, index_list
198
+ end
199
+
200
+ def to_sql(options={})
201
+ sql = "#{hint_method} #{hint_key} "
202
+ sql << "(#{index_list.map {|idx| idx.to_sql }.join(' ')})"
203
+ sql
204
+ end
205
+
206
+ def self.parse(tokens)
207
+ hint_method = tokens.next.literal
208
+ if tokens.peek.index_keyword?
209
+ hint_key = tokens.next.literal
210
+ tokens.consume(SQLTree::Token::LPAREN)
211
+ index_list = parse_list(tokens, SQLTree::Node::Expression::Field)
212
+ tokens.consume(SQLTree::Token::RPAREN)
213
+ self.new(hint_method, hint_key, index_list)
214
+ else
215
+ raise SQLTree::Parser::UnexpectedToken.new(tokens.current)
216
+ end
217
+ end
218
+ end
219
+
172
220
  class Expression < Base
173
221
  class BinaryOperator < SQLTree::Node::Expression
174
222
  TOKEN_PRECEDENCE[2] << SQLTree::Token::BETWEEN
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module Turntable
3
- VERSION = "2.2.2"
3
+ VERSION = "2.3.0"
4
4
  end
5
5
  end
@@ -11,4 +11,24 @@ describe SQLTree do
11
11
  it { expect { subject }.to_not raise_error }
12
12
  its(:to_sql) { is_expected.to include("x'deadbeef") }
13
13
  end
14
+
15
+ context "Select query with index hint" do
16
+ ["FORCE INDEX", "IGNORE INDEX", "USE INDEX"].each do |hint|
17
+ context hint do
18
+ subject { SQLTree["SELECT * FROM table #{hint} (`foo`) WHERE field = 'value'"] }
19
+ it { expect { subject }.to_not raise_error }
20
+ its(:to_sql) { is_expected.to include("#{hint} (`foo`)") }
21
+ end
22
+ end
23
+ end
24
+
25
+ context "Select query without index hint" do
26
+ subject { SQLTree["SELECT * FROM table WHERE field = 'value'"] }
27
+ it { expect { subject }.to_not raise_error }
28
+ end
29
+
30
+ context "Delete query" do
31
+ subject { SQLTree["DELETE FROM table"] }
32
+ it { expect { subject }.to_not raise_error }
33
+ end
14
34
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-turntable
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.2
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - gussan
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-06-24 00:00:00.000000000 Z
12
+ date: 2015-07-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -522,4 +522,3 @@ test_files:
522
522
  - spec/spec_helper.rb
523
523
  - spec/support/matchers/be_saved_to.rb
524
524
  - spec/support/turntable_helper.rb
525
- has_rdoc: