aboutsummaryrefslogtreecommitdiffstats
path: root/lib/arel/relations
diff options
context:
space:
mode:
Diffstat (limited to 'lib/arel/relations')
-rw-r--r--lib/arel/relations/alias.rb12
-rw-r--r--lib/arel/relations/compound.rb4
-rw-r--r--lib/arel/relations/grouping.rb8
-rw-r--r--lib/arel/relations/join.rb42
-rw-r--r--lib/arel/relations/nil.rb1
-rw-r--r--lib/arel/relations/relation.rb37
-rw-r--r--lib/arel/relations/table.rb12
7 files changed, 69 insertions, 47 deletions
diff --git a/lib/arel/relations/alias.rb b/lib/arel/relations/alias.rb
index 329f94638e..b4e8965625 100644
--- a/lib/arel/relations/alias.rb
+++ b/lib/arel/relations/alias.rb
@@ -1,13 +1,19 @@
module Arel
class Alias < Compound
- attr_reader :alias
-
def initialize(relation)
@relation = relation
end
def ==(other)
- self.equal? other
+ equal? other
+ end
+
+ def table
+ self
+ end
+
+ def relation_for(attribute)
+ self[attribute] and self
end
end
end \ No newline at end of file
diff --git a/lib/arel/relations/compound.rb b/lib/arel/relations/compound.rb
index 735f586114..7367e60a2d 100644
--- a/lib/arel/relations/compound.rb
+++ b/lib/arel/relations/compound.rb
@@ -5,8 +5,8 @@ module Arel
hash_on :relation
delegate :joins, :selects, :orders, :groupings, :inserts, :taken,
- :skipped, :name, :alias, :aggregation?, :prefix_for, :column_for,
- :engine, :name_for,
+ :skipped, :name, :alias, :aggregation?, :column_for,
+ :engine, :name_for, :table, :relation_for,
:to => :relation
def attributes
diff --git a/lib/arel/relations/grouping.rb b/lib/arel/relations/grouping.rb
index 2815f62b79..e3686f7f28 100644
--- a/lib/arel/relations/grouping.rb
+++ b/lib/arel/relations/grouping.rb
@@ -15,5 +15,13 @@ module Arel
def aggregation?
true
end
+
+ def table_sql(formatter = Sql::TableReference.new(self))
+ to_sql(formatter)
+ end
+
+ def name
+ table.name + '_aggregation'
+ end
end
end \ No newline at end of file
diff --git a/lib/arel/relations/join.rb b/lib/arel/relations/join.rb
index cb24ab7717..20c19e0848 100644
--- a/lib/arel/relations/join.rb
+++ b/lib/arel/relations/join.rb
@@ -23,10 +23,6 @@ module Arel
externalize(relation2).attributes).collect { |a| a.bind(self) }
end
- def prefix_for(attribute)
- externalize(relation_for(attribute)).prefix_for(attribute)
- end
-
# TESTME: Not sure which scenario needs this method, was driven by failing tests in ActiveRecord
def column_for(attribute)
(relation1[attribute] || relation2[attribute]).column
@@ -35,7 +31,11 @@ module Arel
def joins(formatter = Sql::TableReference.new(self))
this_join = [
join_sql,
- externalize(relation2).table_sql(formatter),
+ if relation2.aggregation?
+ relation2.to_sql(formatter)
+ else
+ relation2.table.table_sql(formatter)
+ end,
("ON" unless predicates.blank?),
predicates.collect { |p| p.bind(formatter.christener).to_sql }.join(' AND ')
].compact.join(" ")
@@ -46,10 +46,6 @@ module Arel
(externalize(relation1).selects + externalize(relation2).selects).collect { |s| s.bind(self) }
end
- def table_sql(formatter = Sql::TableReference.new(self))
- externalize(relation1).table_sql(formatter)
- end
-
def name_for(relation)
@used_names ||= Hash.new(0)
@relation_names ||= Hash.new do |h, k|
@@ -59,11 +55,21 @@ module Arel
@relation_names[relation]
end
- protected
+ def table
+ relation1.aggregation?? relation1 : relation1.table
+ end
+
+ delegate :name, :to => :relation1
+
def relation_for(attribute)
- [relation1[attribute], relation2[attribute]].select { |a| a =~ attribute }.min do |a1, a2|
+ x = [relation1[attribute], relation2[attribute]].select { |a| a =~ attribute }.min do |a1, a2|
(attribute % a1).size <=> (attribute % a2).size
- end.relation.relation_for(attribute)
+ end.relation
+ if x.aggregation?
+ x
+ else
+ x.relation_for(attribute) # FIXME @demeter
+ end
end
private
@@ -74,14 +80,6 @@ module Arel
Externalizer = Struct.new(:christener, :relation) do
delegate :engine, :to => :relation
- def table_sql(formatter = Sql::TableReference.new(self))
- if relation.aggregation?
- relation.to_sql(formatter) + ' AS ' + engine.quote_table_name(formatter.name_for(relation) + (relation.aggregation?? '_aggregation' : ''))
- else
- relation.table_sql(formatter)
- end
- end
-
def selects
relation.aggregation?? [] : relation.selects
end
@@ -89,10 +87,6 @@ module Arel
def attributes
relation.aggregation?? relation.attributes.collect(&:to_attribute) : relation.attributes
end
-
- def prefix_for(attribute)
- christener.name_for(relation) + (relation.aggregation?? '_aggregation' : '')
- end
end
end
end \ No newline at end of file
diff --git a/lib/arel/relations/nil.rb b/lib/arel/relations/nil.rb
index 67eb2d3a62..258f60f478 100644
--- a/lib/arel/relations/nil.rb
+++ b/lib/arel/relations/nil.rb
@@ -1,5 +1,6 @@
module Arel
class Nil < Relation
+ def table; self end
def table_sql(formatter = nil); '' end
def name; '' end
def to_s; '' end
diff --git a/lib/arel/relations/relation.rb b/lib/arel/relations/relation.rb
index 7b414b9768..e08123eaf5 100644
--- a/lib/arel/relations/relation.rb
+++ b/lib/arel/relations/relation.rb
@@ -99,36 +99,40 @@ module Arel
def aggregation?
false
end
-
- def relation_for(attribute)
- self[attribute] and self
- end
def name_for(relation)
relation.name
end
def table_sql(formatter = Sql::TableReference.new(self))
- formatter.table name, formatter.name_for(self)
+ formatter.table self
end
end
include Externalizable
- def to_sql(formatter = Sql::SelectStatement.new(engine))
- tr = Sql::TableReference.new(self)
+ def to_sql(formatter = Sql::SelectStatement.new(self))
formatter.select [
- "SELECT #{attributes.collect { |a| a.to_sql(Sql::SelectClause.new(engine)) }.join(', ')}",
- "FROM #{table_sql(tr)}",
- (joins(tr) unless joins.blank? ),
- ("WHERE #{selects.collect { |s| s.to_sql(Sql::WhereClause.new(engine)) }.join("\n\tAND ")}" unless selects.blank? ),
- ("ORDER BY #{orders.collect { |o| o.to_sql(Sql::OrderClause.new(engine)) }.join(', ')}" unless orders.blank? ),
+ "SELECT #{attributes.collect { |a| a.to_sql(Sql::SelectClause.new(self)) }.join(', ')}",
+ "FROM #{thing}",
+ (joins(Sql::TableReference.new(self)) unless joins.blank? ),
+ ("WHERE #{selects.collect { |s| s.to_sql(Sql::WhereClause.new(self)) }.join("\n\tAND ")}" unless selects.blank? ),
+ ("ORDER BY #{orders.collect { |o| o.to_sql(Sql::OrderClause.new(self)) }.join(', ')}" unless orders.blank? ),
("GROUP BY #{groupings.collect(&:to_sql)}" unless groupings.blank? ),
("LIMIT #{taken}" unless taken.blank? ),
("OFFSET #{skipped}" unless skipped.blank? )
- ].compact.join("\n")
+ ].compact.join("\n"), name
end
alias_method :to_s, :to_sql
+ # FIXME
+ def thing
+ if table.aggregation?
+ table.to_sql(Sql::TableReference.new(self))
+ else
+ table.table_sql(Sql::TableReference.new(self))
+ end
+ end
+
def inclusion_predicate_sql
"IN"
end
@@ -159,8 +163,13 @@ module Arel
self
end
+ # INVESTIGATE
def format(object)
- object.to_sql(Sql::WhereCondition.new(engine))
+ object.to_sql(Sql::WhereCondition.new(self))
+ end
+
+ def christener
+ self
end
def attributes; [] end
diff --git a/lib/arel/relations/table.rb b/lib/arel/relations/table.rb
index 9c7d90d4fc..fcde94b595 100644
--- a/lib/arel/relations/table.rb
+++ b/lib/arel/relations/table.rb
@@ -15,14 +15,18 @@ module Arel
end
end
- def prefix_for(attribute)
- self[attribute] and name
- end
-
def column_for(attribute)
self[attribute] and columns.detect { |c| c.name == attribute.name.to_s }
end
+ def table
+ self
+ end
+
+ def relation_for(attribute)
+ self[attribute] and self
+ end
+
def ==(other)
self.class == other.class and
name == other.name