diff --git a/lib/arel/engines/sql/compilers/postgresql_compiler.rb b/lib/arel/engines/sql/compilers/postgresql_compiler.rb index 3f814255..250d5825 100644 --- a/lib/arel/engines/sql/compilers/postgresql_compiler.rb +++ b/lib/arel/engines/sql/compilers/postgresql_compiler.rb @@ -3,7 +3,7 @@ module SqlCompiler class PostgreSQLCompiler < GenericCompiler def select_sql - if !orders.blank? && using_distinct_on? + if !relation.orders.blank? && using_distinct_on? subquery = build_query \ "SELECT #{select_clauses.kind_of?(::Array) ? select_clauses.join("") : select_clauses.to_s}", "FROM #{from_clauses}", @@ -24,7 +24,7 @@ def select_sql end def using_distinct_on? - select_clauses.any? { |x| x =~ /DISTINCT ON/ } + relation.select_clauses.any? { |x| x =~ /DISTINCT ON/ } end def aliased_orders(orders) diff --git a/lib/arel/engines/sql/relations/compiler.rb b/lib/arel/engines/sql/relations/compiler.rb index 9691c851..2fb4c784 100644 --- a/lib/arel/engines/sql/relations/compiler.rb +++ b/lib/arel/engines/sql/relations/compiler.rb @@ -1,17 +1,21 @@ module Arel module SqlCompiler class GenericCompiler - attr_reader :relation + attr_reader :relation, :engine def initialize(relation) @relation = relation @engine = relation.engine end + def christener + relation.christener + end + def select_sql if relation.projections.first.is_a?(Count) && relation.projections.size == 1 && - (taken.present? || wheres.present?) && joins(self).blank? - subquery = build_query("SELECT 1 FROM #{from_clauses}", build_clauses) + (relation.taken.present? || relation.wheres.present?) && relation.joins(self).blank? + subquery = build_query("SELECT 1 FROM #{relation.from_clauses}", build_clauses) query = "SELECT COUNT(*) AS count_id FROM (#{subquery}) AS subquery" else query = [ @@ -24,7 +28,7 @@ def select_sql end def build_clauses - joins = joins(self) + joins = relation.joins(self) wheres = relation.where_clauses groups = relation.group_clauses havings = relation.having_clauses @@ -50,9 +54,9 @@ def build_clauses def delete_sql build_query \ "DELETE", - "FROM #{table_sql}", - ("WHERE #{wheres.collect(&:to_sql).join(' AND ')}" unless wheres.blank? ), - (add_limit_on_delete(taken) unless taken.blank? ) + "FROM #{relation.table_sql}", + ("WHERE #{relation.wheres.collect { |x| x.to_sql }.join(' AND ')}" unless relation.wheres.blank? ), + (add_limit_on_delete(relation.taken) unless relation.taken.blank? ) end def add_limit_on_delete(taken) @@ -60,19 +64,19 @@ def add_limit_on_delete(taken) end def insert_sql(include_returning = true) - insertion_attributes_values_sql = if record.is_a?(Value) - record.value + insertion_attributes_values_sql = if relation.record.is_a?(Value) + relation.record.value else - attributes = record.keys.sort_by do |attribute| + attributes = relation.record.keys.sort_by do |attribute| attribute.name.to_s end first = attributes.collect do |key| - engine.connection.quote_column_name(key.name) + @engine.connection.quote_column_name(key.name) end.join(', ') second = attributes.collect do |key| - key.format(record[key]) + key.format(relation.record[key]) end.join(', ') build_query "(#{first})", "VALUES (#{second})" @@ -80,9 +84,9 @@ def insert_sql(include_returning = true) build_query \ "INSERT", - "INTO #{table_sql}", + "INTO #{relation.table_sql}", insertion_attributes_values_sql, - ("RETURNING #{engine.connection.quote_column_name(primary_key)}" if include_returning && compiler.supports_insert_with_returning?) + ("RETURNING #{engine.connection.quote_column_name(primary_key)}" if include_returning && relation.compiler.supports_insert_with_returning?) end def supports_insert_with_returning? @@ -91,18 +95,15 @@ def supports_insert_with_returning? def update_sql build_query \ - "UPDATE #{table_sql} SET", + "UPDATE #{relation.table_sql} SET", assignment_sql, build_update_conditions_sql end - protected - def method_missing(method, *args) - if block_given? - relation.send(method, *args) { |*block_args| yield(*block_args) } - else - relation.send(method, *args) - end + protected + + def locked + relation.locked end def build_query(*parts) @@ -110,25 +111,26 @@ def build_query(*parts) end def assignment_sql - if assignments.respond_to?(:collect) - attributes = assignments.keys.sort_by do |attribute| + if relation.assignments.respond_to?(:collect) + attributes = relation.assignments.keys.sort_by do |attribute| attribute.name.to_s end attributes.map do |attribute| - value = assignments[attribute] - "#{engine.connection.quote_column_name(attribute.name)} = #{attribute.format(value)}" + value = relation.assignments[attribute] + "#{@engine.connection.quote_column_name(attribute.name)} = #{attribute.format(value)}" end.join(", ") else - assignments.value + relation.assignments.value end end def build_update_conditions_sql conditions = "" - conditions << " WHERE #{wheres.collect(&:to_sql).join(' AND ')}" unless wheres.blank? - conditions << " ORDER BY #{order_clauses.join(', ')}" unless orders.blank? + conditions << " WHERE #{relation.wheres.map { |x| x.to_sql }.join(' AND ')}" unless relation.wheres.blank? + conditions << " ORDER BY #{relation.order_clauses.join(', ')}" unless relation.orders.blank? + taken = relation.taken unless taken.blank? conditions = limited_update_conditions(conditions, taken) end @@ -138,8 +140,8 @@ def build_update_conditions_sql def limited_update_conditions(conditions, taken) conditions << " LIMIT #{taken}" - quoted_primary_key = engine.connection.quote_column_name(primary_key) - "WHERE #{quoted_primary_key} IN (SELECT #{quoted_primary_key} FROM #{engine.connection.quote_table_name table.name} #{conditions})" + quoted_primary_key = @engine.connection.quote_column_name(relation.primary_key) + "WHERE #{quoted_primary_key} IN (SELECT #{quoted_primary_key} FROM #{@engine.connection.quote_table_name relation.table.name} #{conditions})" end end