module Sequel::EmulateOffsetWithReverseAndCount

  1. lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb

Public Instance methods

empty?()

Make empty? work with an offset with an order. By default it would break since the order would be based on a column that empty does not select.

[show source]
   # File lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb
 8 def empty?
 9   if o = @opts[:offset]
10     unlimited.count <= o
11   else
12     super
13   end
14 end
select_sql()

Emulate OFFSET support using reverse order in a subselect, requiring a count of the number of rows.

If offset is used, an order must be provided, since it needs to be reversed in the subselect. Note that the order needs to be unambiguous to work correctly, and you must select all columns that you are ordering on.

[show source]
   # File lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb
22 def select_sql
23   return super if @opts[:sql]
24   return super unless o = @opts[:offset]
25 
26   order = @opts[:order] || default_offset_order
27   if order.nil? || order.empty?
28     raise(Error, "#{db.database_type} requires an order be provided if using an offset")
29   end
30 
31   ds = unlimited
32   row_count = @opts[:offset_total_count] || ds.clone(:append_sql=>String.new, :placeholder_literal_null=>true).count
33   dsa1 = dataset_alias(1)
34 
35   if o.is_a?(Symbol) && @opts[:bind_vars] && /\A\$(.*)\z/ =~ o
36     # Handle use of bound variable offsets.  Unfortunately, prepared statement
37     # bound variable offsets cannot be handled, since the bound variable value
38     # isn't available until later.
39     o = prepared_arg($1.to_sym)
40   end
41 
42   reverse_offset = row_count - o
43   ds = if reverse_offset > 0
44     ds.limit(reverse_offset).
45       reverse(*order).
46       from_self(:alias=>dsa1).
47       limit(@opts[:limit]).
48       order(*order)
49   else
50     # Sequel doesn't allow a nonpositive limit.  If the offset
51     # is greater than the number of rows, the empty result set
52     # shuld be returned, so use a condition that is always false.
53     ds.where(1=>0)
54   end
55   sql = @opts[:append_sql] || String.new
56   subselect_sql_append(sql, ds)
57   sql
58 end
supports_offsets_in_correlated_subqueries?()

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

[show source]
   # File lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb
62 def supports_offsets_in_correlated_subqueries?
63   false
64 end