11module Arel
2-
2+
33 module Nodes
4-
4+
55 # See the SelectManager#lock method on why this custom class is needed.
66 class LockWithSQLServer < Arel ::Nodes ::Unary
77 end
8-
9- # In versions of ActiveRecord prior to v3.0.3 limits and offset were always integers via
10- # a #to_i. Somewhere between ActiveRecord and ARel this is not happening anymore nor are they
11- # in agreement which should be responsible. Since we need to make sure that these are visited
8+
9+ # In versions of ActiveRecord prior to v3.0.3 limits and offset were always integers via
10+ # a #to_i. Somewhere between ActiveRecord and ARel this is not happening anymore nor are they
11+ # in agreement which should be responsible. Since we need to make sure that these are visited
1212 # correctly and that we can do math with them, these are here to cast to integers.
1313 class Limit < Arel ::Nodes ::Unary
1414 def initialize expr
@@ -20,7 +20,7 @@ def initialize expr
2020 @expr = expr . to_i
2121 end
2222 end
23-
23+
2424 # Extending the Ordering class to be comparrison friendly which allows us to call #uniq on a
2525 # collection of them. See SelectManager#order for more details.
2626 class Ordering < Arel ::Nodes ::Binary
@@ -33,16 +33,16 @@ def ==(other)
3333 def eql? ( other )
3434 self == other
3535 end
36- end
37-
36+ end
37+
3838 end
39-
39+
4040 class SelectManager < Arel ::TreeManager
41-
41+
4242 alias :lock_without_sqlserver :lock
43-
44- # Getting real Ordering objects is very important for us. We need to be able to call #uniq on
45- # a colleciton of them reliably as well as using their true object attributes to mutate them
43+
44+ # Getting real Ordering objects is very important for us. We need to be able to call #uniq on
45+ # a colleciton of them reliably as well as using their true object attributes to mutate them
4646 # to grouping objects for the inner sql during a select statment with an offset/rownumber. So this
4747 # is here till ActiveRecord & ARel does this for us instead of using SqlLiteral objects.
4848 def order ( *exprs )
@@ -67,8 +67,8 @@ def order(*exprs)
6767 } . flatten )
6868 self
6969 end
70-
71- # A friendly over ride that allows us to put a special lock object that can have a default or pass
70+
71+ # A friendly over ride that allows us to put a special lock object that can have a default or pass
7272 # custom string hints down. See the visit_Arel_Nodes_LockWithSQLServer delegation method.
7373 def lock ( locking = true )
7474 if Arel ::Visitors ::SQLServer === @visitor
@@ -78,16 +78,16 @@ def lock(locking=true)
7878 lock_without_sqlserver ( locking )
7979 end
8080 end
81-
81+
8282 end
83-
83+
8484 module Visitors
8585 class SQLServer < Arel ::Visitors ::ToSql
86-
86+
8787 private
88-
88+
8989 # SQLServer ToSql/Visitor (Overides)
90-
90+
9191 def visit_Arel_Nodes_SelectStatement ( o )
9292 if complex_count_sql? ( o )
9393 visit_Arel_Nodes_SelectStatementForComplexCount ( o )
@@ -97,19 +97,19 @@ def visit_Arel_Nodes_SelectStatement(o)
9797 visit_Arel_Nodes_SelectStatementWithOutOffset ( o )
9898 end
9999 end
100-
100+
101101 def visit_Arel_Nodes_Offset ( o )
102102 "WHERE [__rnt].[__rn] > #{ visit o . expr } "
103103 end
104-
104+
105105 def visit_Arel_Nodes_Limit ( o )
106106 "TOP (#{ visit o . expr } )"
107107 end
108-
108+
109109 def visit_Arel_Nodes_Lock o
110110 "WITH(HOLDLOCK, ROWLOCK)"
111111 end
112-
112+
113113 def visit_Arel_Nodes_LockWithSQLServer o
114114 case o . expr
115115 when TrueClass
@@ -120,10 +120,10 @@ def visit_Arel_Nodes_LockWithSQLServer o
120120 ""
121121 end
122122 end
123-
124-
123+
124+
125125 # SQLServer ToSql/Visitor (Additions)
126-
126+
127127 def visit_Arel_Nodes_SelectStatementWithOutOffset ( o , windowed = false )
128128 find_and_fix_uncorrelated_joins_in_select_statement ( o )
129129 core = o . cores . first
@@ -150,7 +150,7 @@ def visit_Arel_Nodes_SelectStatementWithOutOffset(o, windowed=false)
150150 ( "ORDER BY #{ orders . map { |x | visit ( x ) } . join ( ', ' ) } " if !orders . empty? && !windowed )
151151 ] . compact . join ' '
152152 end
153-
153+
154154 def visit_Arel_Nodes_SelectStatementWithOffset ( o )
155155 orders = rowtable_orders ( o )
156156 [ "SELECT" ,
@@ -163,7 +163,7 @@ def visit_Arel_Nodes_SelectStatementWithOffset(o)
163163 ( visit ( o . offset ) if o . offset ) ,
164164 ] . compact . join ' '
165165 end
166-
166+
167167 def visit_Arel_Nodes_SelectStatementForComplexCount ( o )
168168 core = o . cores . first
169169 o . limit . expr = o . limit . expr + ( o . offset ? o . offset . expr : 0 ) if o . limit
@@ -183,23 +183,23 @@ def visit_Arel_Nodes_SelectStatementForComplexCount(o)
183183 ( visit ( o . offset ) if o . offset )
184184 ] . compact . join ' '
185185 end
186-
187-
186+
187+
188188 # SQLServer Helpers
189-
189+
190190 def source_with_lock_for_select_statement ( o )
191191 # TODO: [ARel 2.2] Use #from/#source vs. #froms
192192 core = o . cores . first
193193 source = "FROM #{ visit core . froms } " if core . froms
194194 if source && o . lock
195195 lock = visit o . lock
196196 index = source . match ( /FROM [\w \[ \] \. ]+/ ) [ 0 ] . length
197- source . insert index , " #{ lock } "
197+ source . insert index , " #{ lock } "
198198 else
199199 source
200200 end
201201 end
202-
202+
203203 def table_from_select_statement ( o )
204204 core = o . cores . first
205205 # TODO: [ARel 2.2] Use #from/#source vs. #froms
@@ -220,49 +220,49 @@ def table_from_select_statement(o)
220220 table_finder . call ( x . left )
221221 end
222222 }
223- table_finder . call ( core . froms )
223+ table_finder . call ( core . froms )
224224 end
225-
225+
226226 def single_distinct_select_statement? ( o )
227227 projections = o . cores . first . projections
228228 p1 = projections . first
229- projections . size == 1 &&
230- ( ( p1 . respond_to? ( :distinct ) && p1 . distinct ) ||
229+ projections . size == 1 &&
230+ ( ( p1 . respond_to? ( :distinct ) && p1 . distinct ) ||
231231 p1 . respond_to? ( :include? ) && p1 . include? ( 'DISTINCT' ) )
232232 end
233-
233+
234234 def all_projections_aliased_in_select_statement? ( o )
235235 projections = o . cores . first . projections
236236 projections . all? do |x |
237237 x . split ( ',' ) . all? { |y | y . include? ( ' AS ' ) }
238238 end
239239 end
240-
240+
241241 def function_select_statement? ( o )
242242 core = o . cores . first
243243 core . projections . any? { |x | Arel ::Nodes ::Function === x }
244244 end
245-
245+
246246 def eager_limiting_select_statement? ( o )
247247 core = o . cores . first
248248 single_distinct_select_statement? ( o ) && ( o . limit && !o . offset ) && core . groups . empty?
249249 end
250-
250+
251251 def join_in_select_statement? ( o )
252252 core = o . cores . first
253253 # TODO: [ARel 2.2] Use #from/#source vs. #froms
254254 # core.source.right.any? { |x| Arel::Nodes::Join === x }
255255 Arel ::Nodes ::Join === core . froms
256256 end
257-
257+
258258 def complex_count_sql? ( o )
259259 core = o . cores . first
260260 core . projections . size == 1 &&
261- Arel ::Nodes ::Count === core . projections . first &&
261+ Arel ::Nodes ::Count === core . projections . first &&
262262 ( o . limit || !core . wheres . empty? ) &&
263263 !join_in_select_statement? ( o )
264264 end
265-
265+
266266 def find_and_fix_uncorrelated_joins_in_select_statement ( o )
267267 core = o . cores . first
268268 # TODO: [ARel 2.2] Use #from/#source vs. #froms
@@ -287,7 +287,7 @@ def find_and_fix_uncorrelated_joins_in_select_statement(o)
287287 j2 . insert on_index , " AS [#{ j2_tn } _crltd]"
288288 j2 . sub! "[#{ j2_tn } ]." , "[#{ j2_tn } _crltd]."
289289 end
290-
290+
291291 def rowtable_projections ( o )
292292 core = o . cores . first
293293 if single_distinct_select_statement? ( o )
@@ -305,13 +305,13 @@ def rowtable_projections(o)
305305 end
306306 elsif function_select_statement? ( o )
307307 # TODO: [ARel 2.2] Use Arel.star
308- [ Arel ::Nodes ::SqlLiteral . new '*' ]
308+ [ Arel ::Nodes ::SqlLiteral . new ( '*' ) ]
309309 else
310310 tn = table_from_select_statement ( o ) . name
311311 core . projections . map { |x | x . gsub /\[ #{ tn } \] \. / , '[__rnt].' }
312312 end
313313 end
314-
314+
315315 def rowtable_orders ( o )
316316 core = o . cores . first
317317 if !o . orders . empty?
@@ -322,7 +322,7 @@ def rowtable_orders(o)
322322 [ table_from_select_statement ( o ) . primary_key . asc ]
323323 end . uniq
324324 end
325-
325+
326326 # TODO: We use this for grouping too, maybe make Grouping objects vs SqlLiteral.
327327 def projection_without_expression ( projection )
328328 Arel ::Nodes ::SqlLiteral . new ( projection . split ( ',' ) . map do |x |
@@ -333,10 +333,10 @@ def projection_without_expression(projection)
333333 x . strip
334334 end . join ( ', ' ) )
335335 end
336-
336+
337337 end
338338 end
339-
339+
340340end
341341
342342Arel ::Visitors ::VISITORS [ 'sqlserver' ] = Arel ::Visitors ::SQLServer
0 commit comments