Skip to content

Commit f88cbf3

Browse files
pnomolosEdward Paget
authored and
Edward Paget
committedMay 11, 2016
Fix some issues when looking up aliased tables
The lookup for whether or not a column is an array fails in certain cases when using aliased tables. This fixes that issues.
1 parent 4e767ef commit f88cbf3

File tree

5 files changed

+44
-26
lines changed

5 files changed

+44
-26
lines changed
 

‎Gemfile

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@ source 'https://rubygems.org'
33
# Specify your gem's dependencies in postgres_ext.gemspec
44
gemspec
55
unless ENV['CI']
6-
if RUBY_PLATFORM =~ /java/
7-
gem 'ruby-debug'
8-
else
9-
gem 'byebug'
10-
end
6+
gem 'byebug'
117
end
128
gem 'fivemat'

‎lib/postgres_ext/active_record/relation/predicate_builder.rb

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,34 @@ class PredicateBuilder # :nodoc:
55
def self.build(attribute, value)
66
case value
77
when Array
8-
engine = attribute.relation.engine
9-
column = engine.connection.schema_cache.columns(attribute.relation.name).detect{ |col| col.name.to_s == attribute.name.to_s }
8+
column = case attribute.try(:relation)
9+
when Arel::Nodes::TableAlias, NilClass
10+
else
11+
cache = attribute.relation.engine.connection.schema_cache
12+
if cache.table_exists? attribute.relation.name
13+
cache.columns(attribute.relation.name).detect{ |col| col.name.to_s == attribute.name.to_s }
14+
end
15+
end
1016
if column && column.respond_to?(:array) && column.array
1117
attribute.eq(value)
1218
else
1319
values = value.to_a.map {|x| x.is_a?(Base) ? x.id : x}
1420
ranges, values = values.partition {|v| v.is_a?(Range)}
1521

1622
values_predicate = if values.include?(nil)
17-
values = values.compact
23+
values = values.compact
1824

19-
case values.length
20-
when 0
21-
attribute.eq(nil)
22-
when 1
23-
attribute.eq(values.first).or(attribute.eq(nil))
24-
else
25-
attribute.in(values).or(attribute.eq(nil))
26-
end
27-
else
28-
attribute.in(values)
29-
end
25+
case values.length
26+
when 0
27+
attribute.eq(nil)
28+
when 1
29+
attribute.eq(values.first).or(attribute.eq(nil))
30+
else
31+
attribute.in(values).or(attribute.eq(nil))
32+
end
33+
else
34+
attribute.in(values)
35+
end
3036

3137
array_predicates = ranges.map { |range| attribute.in(range) }
3238
array_predicates << values_predicate

‎lib/postgres_ext/active_record/relation/predicate_builder/array_handler.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,14 @@ module ArrayHandlerPatch
1010

1111
included do
1212
def call_with_feature(attribute, value)
13-
engine = attribute.relation.engine
14-
column = engine.connection.schema_cache.columns(attribute.relation.name).detect{ |col| col.name.to_s == attribute.name.to_s }
13+
column = case attribute.try(:relation)
14+
when Arel::Nodes::TableAlias, NilClass
15+
else
16+
cache = attribute.relation.engine.connection.schema_cache
17+
if cache.table_exists? attribute.relation.name
18+
cache.columns(attribute.relation.name).detect{ |col| col.name.to_s == attribute.name.to_s }
19+
end
20+
end
1521
if column && column.respond_to?(:array) && column.array
1622
attribute.eq(value)
1723
else

‎lib/postgres_ext/arel/4.1/visitors/postgresql.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ def visit_Array o, a
1212
# which won't exist for aliased table when used with Single Table
1313
# Inheritance. see dockyard/postgres_ext#154
1414
else
15-
a.relation.engine.connection.schema_cache.columns(a.relation.name)
16-
.find { |col| col.name == a.name.to_s }
15+
cache = a.relation.engine.connection.schema_cache
16+
if cache.table_exists? a.relation.name
17+
cache.columns(a.relation.name).find { |col| col.name == a.name.to_s }
18+
end
1719
end
18-
20+
1921
if column && column.respond_to?(:array) && column.array
2022
quoted o, a
2123
else
@@ -25,14 +27,14 @@ def visit_Array o, a
2527

2628
def visit_Arel_Nodes_Contains o, a = nil
2729
left_column = o.left.relation.engine.columns.find { |col| col.name == o.left.name.to_s }
28-
30+
2931
if left_column && (left_column.type == :hstore || (left_column.respond_to?(:array) && left_column.array))
3032
"#{visit o.left, a} @> #{visit o.right, o.left}"
3133
else
3234
"#{visit o.left, a} >> #{visit o.right, o.left}"
3335
end
3436
end
35-
37+
3638
def visit_Arel_Nodes_ContainedWithin o, a = nil
3739
"#{visit o.left, a} << #{visit o.right, o.left}"
3840
end

‎test/queries/alias_test.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
require 'test_helper'
2+
3+
describe 'Joining with an alias' do
4+
it "Works properly" do
5+
ChildTag.includes(:parent_tag).references(:parent_tag)
6+
.where("parent_tags_tags.id" => [2,3,4]).to_sql.must_match /"parent_tags_tags"."id" IN \(2, 3, 4\)/
7+
end
8+
end

0 commit comments

Comments
 (0)