Skip to content

Commit bee6e1d

Browse files
aidanharanAidan Haran
andauthored
Added visit method for HomogeneousIn Arel type (#879)
* Added visit method for HomogeneousIn * Updated changelog * Removed method that has same definition as the parent Abstract adapter Co-authored-by: Aidan Haran <aharan@fusioneer.com>
1 parent 2fbded9 commit bee6e1d

File tree

2 files changed

+55
-24
lines changed

2 files changed

+55
-24
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- [#873](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/873) Various fixes to get the tests running for Rails 6.1
88
- [#874](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/874) Deduplicate schema cache structures
99
- [#875](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/875) Handle default boolean column values when deduplicating
10+
- [#879](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/879) Added visit method for HomogeneousIn
1011

1112
#### Changed
1213

lib/arel/visitors/sqlserver.rb

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ class SQLServer < Arel::Visitors::ToSql
1111

1212
private
1313

14-
# SQLServer ToSql/Visitor (Overides)
14+
# SQLServer ToSql/Visitor (Overrides)
1515

16-
def visit_Arel_Nodes_BindParam o, collector
17-
collector.add_bind(o.value) { |i| "@#{i - 1}" }
18-
end
16+
BIND_BLOCK = proc { |i| "@#{i - 1}" }
17+
private_constant :BIND_BLOCK
18+
19+
def bind_block; BIND_BLOCK; end
1920

20-
def visit_Arel_Nodes_Bin o, collector
21+
def visit_Arel_Nodes_Bin(o, collector)
2122
visit o.expr, collector
2223
collector << " #{ActiveRecord::ConnectionAdapters::SQLServerAdapter.cs_equality_operator} "
2324
end
@@ -28,26 +29,26 @@ def visit_Arel_Nodes_Concat(o, collector)
2829
visit o.right, collector
2930
end
3031

31-
def visit_Arel_Nodes_UpdateStatement(o, a)
32+
def visit_Arel_Nodes_UpdateStatement(o, collector)
3233
if o.orders.any? && o.limit.nil?
3334
o.limit = Nodes::Limit.new(9_223_372_036_854_775_807)
3435
end
3536
super
3637
end
3738

38-
def visit_Arel_Nodes_Lock o, collector
39+
def visit_Arel_Nodes_Lock(o, collector)
3940
o.expr = Arel.sql("WITH(UPDLOCK)") if o.expr.to_s =~ /FOR UPDATE/
4041
collector << " "
4142
visit o.expr, collector
4243
end
4344

44-
def visit_Arel_Nodes_Offset o, collector
45+
def visit_Arel_Nodes_Offset(o, collector)
4546
collector << OFFSET
4647
visit o.expr, collector
4748
collector << ROWS
4849
end
4950

50-
def visit_Arel_Nodes_Limit o, collector
51+
def visit_Arel_Nodes_Limit(o, collector)
5152
if node_value(o) == 0
5253
collector << FETCH0
5354
collector << ROWS_ONLY
@@ -63,7 +64,36 @@ def visit_Arel_Nodes_Grouping(o, collector)
6364
super
6465
end
6566

66-
def visit_Arel_Nodes_SelectStatement o, collector
67+
def visit_Arel_Nodes_HomogeneousIn(o, collector)
68+
collector.preparable = false
69+
70+
collector << quote_table_name(o.table_name) << "." << quote_column_name(o.column_name)
71+
72+
if o.type == :in
73+
collector << " IN ("
74+
else
75+
collector << " NOT IN ("
76+
end
77+
78+
values = o.casted_values
79+
80+
if values.empty?
81+
collector << @connection.quote(nil)
82+
else
83+
# Monkey-patch start. Add query attribute bindings rather than just values.
84+
column_name = o.column_name
85+
column_type = o.attribute.relation.type_for_attribute(o.column_name)
86+
attrs = values.map { |value| ActiveRecord::Relation::QueryAttribute.new(column_name, value, column_type) }
87+
88+
collector.add_binds(attrs, &bind_block)
89+
# Monkey-patch end.
90+
end
91+
92+
collector << ")"
93+
collector
94+
end
95+
96+
def visit_Arel_Nodes_SelectStatement(o, collector)
6797
@select_statement = o
6898
distinct_One_As_One_Is_So_Not_Fetch o
6999
if o.with
@@ -90,7 +120,7 @@ def visit_Arel_Nodes_OptimizerHints(o, collector)
90120
collector << "OPTION (#{hints})"
91121
end
92122

93-
def visit_Arel_Table o, collector
123+
def visit_Arel_Table(o, collector)
94124
# Apparently, o.engine.connection can actually be a different adapter
95125
# than sqlserver. Can be removed if fixed in ActiveRecord. See:
96126
# github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues/450
@@ -112,7 +142,7 @@ def visit_Arel_Table o, collector
112142
end
113143
end
114144

115-
def visit_Arel_Nodes_JoinSource o, collector
145+
def visit_Arel_Nodes_JoinSource(o, collector)
116146
if o.left
117147
collector = visit o.left, collector
118148
collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector
@@ -124,7 +154,7 @@ def visit_Arel_Nodes_JoinSource o, collector
124154
collector
125155
end
126156

127-
def visit_Arel_Nodes_InnerJoin o, collector
157+
def visit_Arel_Nodes_InnerJoin(o, collector)
128158
if o.left.is_a?(Arel::Nodes::As) && o.left.left.is_a?(Arel::Nodes::Lateral)
129159
collector << "CROSS "
130160
visit o.left, collector
@@ -141,7 +171,7 @@ def visit_Arel_Nodes_InnerJoin o, collector
141171
end
142172
end
143173

144-
def visit_Arel_Nodes_OuterJoin o, collector
174+
def visit_Arel_Nodes_OuterJoin(o, collector)
145175
if o.left.is_a?(Arel::Nodes::As) && o.left.left.is_a?(Arel::Nodes::Lateral)
146176
collector << "OUTER "
147177
visit o.left, collector
@@ -170,15 +200,15 @@ def collect_optimizer_hints(o, collector)
170200

171201
# SQLServer ToSql/Visitor (Additions)
172202

173-
def visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, options = {}
203+
def visit_Arel_Nodes_SelectStatement_SQLServer_Lock(collector, options = {})
174204
if select_statement_lock?
175205
collector = visit @select_statement.lock, collector
176206
collector << " " if options[:space]
177207
end
178208
collector
179209
end
180210

181-
def visit_Orders_And_Let_Fetch_Happen o, collector
211+
def visit_Orders_And_Let_Fetch_Happen(o, collector)
182212
make_Fetch_Possible_And_Deterministic o
183213
unless o.orders.empty?
184214
collector << " ORDER BY "
@@ -191,14 +221,14 @@ def visit_Orders_And_Let_Fetch_Happen o, collector
191221
collector
192222
end
193223

194-
def visit_Make_Fetch_Happen o, collector
224+
def visit_Make_Fetch_Happen(o, collector)
195225
o.offset = Nodes::Offset.new(0) if o.limit && !o.offset
196226
collector = visit o.offset, collector if o.offset
197227
collector = visit o.limit, collector if o.limit
198228
collector
199229
end
200230

201-
def visit_Arel_Nodes_Lateral o, collector
231+
def visit_Arel_Nodes_Lateral(o, collector)
202232
collector << "APPLY"
203233
collector << " "
204234
if o.expr.is_a?(Arel::Nodes::SelectStatement)
@@ -226,7 +256,7 @@ def select_statement_lock?
226256
@select_statement && @select_statement.lock
227257
end
228258

229-
def make_Fetch_Possible_And_Deterministic o
259+
def make_Fetch_Possible_And_Deterministic(o)
230260
return if o.limit.nil? && o.offset.nil?
231261

232262
t = table_From_Statement o
@@ -239,7 +269,7 @@ def make_Fetch_Possible_And_Deterministic o
239269
end
240270
end
241271

242-
def distinct_One_As_One_Is_So_Not_Fetch o
272+
def distinct_One_As_One_Is_So_Not_Fetch(o)
243273
core = o.cores.first
244274
distinct = Nodes::Distinct === core.set_quantifier
245275
oneasone = core.projections.all? { |x| x == ActiveRecord::FinderMethods::ONE_AS_ONE }
@@ -250,7 +280,7 @@ def distinct_One_As_One_Is_So_Not_Fetch o
250280
end
251281
end
252282

253-
def table_From_Statement o
283+
def table_From_Statement(o)
254284
core = o.cores.first
255285
if Arel::Table === core.from
256286
core.from
@@ -261,15 +291,15 @@ def table_From_Statement o
261291
end
262292
end
263293

264-
def primary_Key_From_Table t
294+
def primary_Key_From_Table(t)
265295
return unless t
266296

267297
column_name = @connection.schema_cache.primary_keys(t.name) ||
268-
@connection.schema_cache.columns_hash(t.name).first.try(:second).try(:name)
298+
@connection.schema_cache.columns_hash(t.name).first.try(:second).try(:name)
269299
column_name ? t[column_name] : nil
270300
end
271301

272-
def remote_server_table_name o
302+
def remote_server_table_name(o)
273303
ActiveRecord::ConnectionAdapters::SQLServer::Utils.extract_identifiers(
274304
"#{o.class.engine.connection.database_prefix}#{o.name}"
275305
).quoted

0 commit comments

Comments
 (0)