Skip to content

Commit

Permalink
Handle case of select_prepend after select_append
Browse files Browse the repository at this point in the history
This previously failed on databases that don't support
SELECT column, *. Fix it by scanning the current selection list
for the WILDCARD object, and replacing it with qualified selections
(SELECT column, table.*), which all databases should support.
  • Loading branch information
jeremyevans committed Mar 29, 2024
1 parent bbfb80e commit 5780c78
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 2 deletions.
18 changes: 16 additions & 2 deletions lib/sequel/dataset/query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1367,14 +1367,28 @@ def _current_select(allow_plain_wildcard)
cur_sel = if allow_plain_wildcard && supports_select_all_and_column?
[WILDCARD].freeze
else
tables = Array(@opts[:from]) + Array(@opts[:join])
tables.map{|t| i, a = split_alias(t); a || i}.map!{|t| SQL::ColumnAll.new(t)}.freeze
_current_select_column_all
end
elsif !allow_plain_wildcard && cur_sel.include?(WILDCARD)
cur_sel = cur_sel.dup
index = cur_sel.index(WILDCARD)
cur_sel.delete(WILDCARD)
_current_select_column_all.each_with_index do |ca, i|
cur_sel.insert(index+i, ca)
end
cur_sel.freeze
end

cur_sel
end

# An array of SQL::ColumnAll objects for all FROM and JOIN tables. Used for select_append
# and select_prepend.
def _current_select_column_all
tables = Array(@opts[:from]) + Array(@opts[:join])
tables.map{|t| i, a = split_alias(t); a || i}.map!{|t| SQL::ColumnAll.new(t)}.freeze
end

# If invert is true, invert the condition.
def _invert_filter(cond, invert)
if invert
Expand Down
5 changes: 5 additions & 0 deletions spec/core/dataset_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1507,6 +1507,11 @@ def supports_cte_in_subselect?; false end
@d.select(Sequel::SQL::ColumnAll.new(:a)).select_prepend(Sequel::SQL::ColumnAll.new(:b)).sql.must_equal 'SELECT b.*, a.* FROM test'
end

it "should work with an explicit selection of *" do
@d.select_append(:a).select_prepend(:b).sql.must_equal 'SELECT b, test.*, a FROM test'
@d.from(:t1, :t2).natural_join(:t3).select_append(:a).select_prepend(:b).sql.must_equal 'SELECT b, t1.*, t2.*, t3.*, a FROM t1, t2 NATURAL JOIN t3'
end

it "should accept a block that yields a virtual row" do
@d.select(:a).select_prepend{|o| o.b}.sql.must_equal 'SELECT b, a FROM test'
@d.select(Sequel::SQL::ColumnAll.new(:a)).select_prepend(Sequel::SQL::ColumnAll.new(:b)){b(1)}.sql.must_equal 'SELECT b.*, b(1), a.* FROM test'
Expand Down
1 change: 1 addition & 0 deletions spec/integration/dataset_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@

it "should support select_prepend and select_append" do
@ds.select_prepend{number.as(:n)}.select_append{id.as(:i)}.first.to_a.must_equal [[:n, 10], [:id, 1], [:number, 10], [:i, 1]]
@ds.select_append{id.as(:i)}.select_prepend{number.as(:n)}.first.to_a.must_equal [[:n, 10], [:id, 1], [:number, 10], [:i, 1]]
end

it "should skip locked rows correctly" do
Expand Down

0 comments on commit 5780c78

Please sign in to comment.