Module: Sequel::EmulateOffsetWithRowNumber

Included in:
DB2::DatasetMethods, MSSQL::DatasetMethods
Defined in:
lib/sequel/adapters/utils/emulate_offset_with_row_number.rb

Instance Method Summary collapse

Instance Method Details

#empty?Boolean

If the offset must be emulated with ROW_NUMBER, don’t remove any ordering, because it can cause invalid queries to be issued if an offset is required when ordering.

Returns:

  • (Boolean)


8
9
10
11
# File 'lib/sequel/adapters/utils/emulate_offset_with_row_number.rb', line 8

def empty?
  return super unless emulate_offset_with_row_number?
  select(Dataset::EMPTY_SELECT).limit(1).single_value!.nil?
end

#select_sqlObject

Emulate OFFSET support with the ROW_NUMBER window function

The implementation is ugly, cloning the current dataset and modifying the clone to add a ROW_NUMBER window function (and some other things), then using the modified clone in a subselect which is selected from.

If offset is used, an order must be provided, because the use of ROW_NUMBER requires an order.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/sequel/adapters/utils/emulate_offset_with_row_number.rb', line 21

def select_sql
  return super unless emulate_offset_with_row_number?

  offset = @opts[:offset]
  order = @opts[:order]
  if require_offset_order?
    order ||= default_offset_order
    if order.nil? || order.empty?
      raise(Error, "#{db.database_type} requires an order be provided if using an offset")
    end
  end

  columns = clone(:append_sql=>String.new, :placeholder_literal_null=>true).columns
  dsa1 = dataset_alias(1)
  rn = row_number_column
  sql = @opts[:append_sql] || String.new
  subselect_sql_append(sql, unlimited.
    unordered.
    select_append(Sequel.function(:ROW_NUMBER).over(:order=>order).as(rn)).
    from_self(:alias=>dsa1).
    select(*columns).
    limit(@opts[:limit]).
    where(SQL::Identifier.new(rn) > offset).
    order(rn))
  sql
end

#supports_offsets_in_correlated_subqueries?Boolean

This does not support offsets in correlated subqueries, as it requires a query to get the columns that will be invalid if a correlated subquery is used.

Returns:

  • (Boolean)


50
51
52
# File 'lib/sequel/adapters/utils/emulate_offset_with_row_number.rb', line 50

def supports_offsets_in_correlated_subqueries?
  false
end