Class: Arel::Visitors::SQLServer

Inherits:
ToSql
  • Object
show all
Includes:
ArJdbc::MsSQL::LimitHelpers::SqlServerReplaceLimitOffset, ArJdbc::MsSQL::LockHelpers::SqlServerAddLock
Defined in:
lib/arel/visitors/sql_server.rb

Direct Known Subclasses

SQLServer2000

Instance Method Summary collapse

Methods included from ArJdbc::MsSQL::LockHelpers::SqlServerAddLock

#add_lock!

Methods included from ArJdbc::MsSQL::LimitHelpers::SqlServerReplaceLimitOffset

replace_limit_offset!

Methods included from ArJdbcCompat

#limit_for

Instance Method Details

#select_count?(o) ⇒ Boolean

Returns:

  • (Boolean)


9
10
11
12
13
# File 'lib/arel/visitors/sql_server.rb', line 9

def select_count? o
  sel = o.cores.length == 1 && o.cores.first
  projections = sel && sel.projections.length == 1 && sel.projections
  projections && Arel::Nodes::Count === projections.first
end

#visit_Arel_Nodes_Lock(o) ⇒ Object

MS-SQL doesn’t support “SELECT…FOR UPDATE”. Instead, it needs WITH(ROWLOCK,UPDLOCK) specified after each table in the FROM clause.

So, we return nothing here and add the appropriate stuff using add_lock! above.



48
49
# File 'lib/arel/visitors/sql_server.rb', line 48

def visit_Arel_Nodes_Lock o
end

#visit_Arel_Nodes_SelectStatement(o) ⇒ Object

Need to mimic the subquery logic in ARel 1.x for select count with limit See arel/engines/sql/compilers/mssql_compiler.rb for details



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/arel/visitors/sql_server.rb', line 17

def visit_Arel_Nodes_SelectStatement o
  if !o.limit && o.offset
    raise ActiveRecord::ActiveRecordError, "You must specify :limit with :offset."
  end
  order = "ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?
  if o.limit
    if select_count?(o)
      subquery = true
      sql = o.cores.map do |x|
        x = x.dup
        x.projections = [Arel::Nodes::SqlLiteral.new("*")]
        visit_Arel_Nodes_SelectCore x
      end.join
    else
      sql = o.cores.map { |x| visit_Arel_Nodes_SelectCore x }.join
    end

    order ||= "ORDER BY #{@connection.determine_order_clause(sql)}"
    replace_limit_offset!(sql, limit_for(o.limit).to_i, o.offset && o.offset.value.to_i, order)
    sql = "SELECT COUNT(*) AS count_id FROM (#{sql}) AS subquery" if subquery
  else
    sql = super
  end
  add_lock!(sql, :lock => o.lock && true)
  sql
end