Skip to content

Commit facc48e

Browse files
committed
Remove the MTI query if doing a calculation.
1 parent 2d35332 commit facc48e

2 files changed

Lines changed: 77 additions & 4 deletions

File tree

lib/active_record/mti/calculations.rb

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,79 @@ module Calculations
44

55
private
66

7+
def execute_grouped_calculation(operation, column_name, distinct) #:nodoc:
8+
group_attrs = group_values
9+
10+
if group_attrs.first.respond_to?(:to_sym)
11+
association = @klass._reflect_on_association(group_attrs.first)
12+
associated = group_attrs.size == 1 && association && association.belongs_to? # only count belongs_to associations
13+
group_fields = Array(associated ? association.foreign_key : group_attrs)
14+
else
15+
group_fields = group_attrs
16+
end
17+
group_fields = arel_columns(group_fields)
18+
19+
group_aliases = group_fields.map { |field|
20+
column_alias_for(field)
21+
}
22+
group_columns = group_aliases.zip(group_fields).map { |aliaz,field|
23+
[aliaz, field]
24+
}
25+
26+
group = group_fields
27+
28+
if operation == 'count' && column_name == :all
29+
aggregate_alias = 'count_all'
30+
else
31+
aggregate_alias = column_alias_for([operation, column_name].join(' '))
32+
end
33+
34+
select_values = [
35+
operation_over_aggregate_column(
36+
aggregate_column(column_name),
37+
operation,
38+
distinct).as(aggregate_alias)
39+
]
40+
select_values += select_values unless having_values.empty?
41+
42+
select_values.concat group_fields.zip(group_aliases).map { |field,aliaz|
43+
if field.respond_to?(:as)
44+
field.as(aliaz)
45+
else
46+
"#{field} AS #{aliaz}"
47+
end
48+
}
49+
50+
relation = except(:group)
51+
relation.group_values = group
52+
relation.select_values = select_values
53+
54+
# Remove our cast otherwise PSQL will insist that it be included in the GROUP
55+
relation.arel.projections.select!{ |p| p.to_s != "cast(\"#{klass.table_name}\".\"tableoid\"::regclass as text)" } if @klass.using_multi_table_inheritance?
56+
57+
calculated_data = @klass.connection.select_all(relation, nil, relation.arel.bind_values + bind_values)
58+
59+
if association
60+
key_ids = calculated_data.collect { |row| row[group_aliases.first] }
61+
key_records = association.klass.base_class.find(key_ids)
62+
key_records = Hash[key_records.map { |r| [r.id, r] }]
63+
end
64+
65+
Hash[calculated_data.map do |row|
66+
key = group_columns.map { |aliaz, col_name|
67+
column = calculated_data.column_types.fetch(aliaz) do
68+
type_for(col_name)
69+
end
70+
type_cast_calculated_value(row[aliaz], column)
71+
}
72+
key = key.first if key.size == 1
73+
key = key_records[key] if associated
74+
75+
column_type = calculated_data.column_types.fetch(aggregate_alias) { type_for(column_name) }
76+
[key, type_cast_calculated_value(row[aggregate_alias], column_type, operation)]
77+
end]
78+
end
79+
780
def execute_simple_calculation(operation, column_name, distinct) #:nodoc:
881
# Postgresql doesn't like ORDER BY when there are no GROUP BY
982
relation = unscope(:order)
@@ -27,9 +100,9 @@ def execute_simple_calculation(operation, column_name, distinct) #:nodoc:
27100
column_alias ||= @klass.connection.column_name_for_operation(operation, select_value)
28101
relation.select_values = [select_value]
29102

30-
# Only use the last projection (probably the COUNT(*)) all others don't matter
31-
# relation.arel.projections = [relation.arel.projections.last].compact if @klass.using_multi_table_inheritance?
32-
relation.arel.projections.shift if @klass.using_multi_table_inheritance?
103+
# Remove our cast otherwise PSQL will insist that it be included in the GROUP
104+
# Somewhere between line 82 and 101 relation.arel.projections gets reset :/
105+
relation.arel.projections.select!{ |p| p.to_s != "cast(\"#{klass.table_name}\".\"tableoid\"::regclass as text)" } if @klass.using_multi_table_inheritance?
33106

34107
query_builder = relation.arel
35108
bind_values = query_builder.bind_values + relation.bind_values

lib/active_record/mti/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module ActiveRecord
22
module MTI
3-
VERSION = "0.0.2"
3+
VERSION = '0.0.5'
44
end
55
end

0 commit comments

Comments
 (0)