このコミットが含まれているのは:
@@ -1,4 +1,4 @@
|
||||
# Re-aggregate the population, never add up already grouped cells (multi-value axes overlap).
|
||||
# Re-aggregate distinct membership; tag row tuples alone use additive contributions.
|
||||
class CountsPivotTotals
|
||||
def initialize(population, axes, row_headers, column_headers)
|
||||
@population = population
|
||||
@@ -8,8 +8,12 @@ class CountsPivotTotals
|
||||
end
|
||||
|
||||
def call
|
||||
# MySQL's unlimited LIMIT prevents CTE merging: authorise once for all branches.
|
||||
basis = @population.scope.except(:select, :order).select('v.*')
|
||||
# Materialise full-cell membership once, including omitted multi-value axes.
|
||||
membership = @population.scope.except(:select, :order)
|
||||
joins = @axes.joins
|
||||
membership = membership.joins(joins) unless joins.empty?
|
||||
# Retain exactly the records contributing a full cell, including changed_field.
|
||||
basis = membership.select('v.*').distinct
|
||||
.limit(18_446_744_073_709_551_615).to_sql
|
||||
queries = @rows.flat_map do |row_depth, headers|
|
||||
@columns.filter_map do |column_depth, columns|
|
||||
@@ -18,7 +22,7 @@ class CountsPivotTotals
|
||||
indexes = (0...row_depth).to_a +
|
||||
(0...column_depth).map { @axes.rows.length + _1 }
|
||||
expressions = indexes.map { @axes.expressions[_1] }
|
||||
scope = @population.scope.except(:select, :order, :where, :from).from('authorised v')
|
||||
scope = @population.scope.except(:select, :order, :where, :from).from('population_members v')
|
||||
additive = @axes.rows.any? { _1['field'] == 'tags' }
|
||||
retained = additive ? (0...@axes.rows.length).to_a | indexes : indexes
|
||||
joins = @axes.joins(retained.map { @axes.all[_1].fetch('field') })
|
||||
@@ -47,9 +51,12 @@ class CountsPivotTotals
|
||||
if additive
|
||||
# Sum full row tuples, not page cells; preserve DISTINCT inside each tuple.
|
||||
leaf = retained.map { @axes.expressions[_1] }
|
||||
selected = leaf.each_with_index.map { |expression, index| "#{ expression } AS k#{ index }" }
|
||||
selected = leaf.each_with_index.map do |expression, index|
|
||||
"#{ expression } AS k#{ index }"
|
||||
end
|
||||
selected << "#{ @axes.count_expression } AS count"
|
||||
inner = scope.group(*leaf.map { Arel.sql(_1) })
|
||||
.select(Arel.sql((selected + ["#{ @axes.count_expression } AS count"]).join(', '))).to_sql
|
||||
.select(Arel.sql(selected.join(', '))).to_sql
|
||||
coordinates = indexes.map { "k#{ retained.index(_1) }" }
|
||||
projected = coordinates.each_with_index.map { |key, index| "#{ key } AS v#{ index }" }
|
||||
output = ["#{ row_depth } AS row_depth", "#{ column_depth } AS column_depth"] +
|
||||
@@ -67,7 +74,7 @@ class CountsPivotTotals
|
||||
|
||||
sql = queries.map { "(#{ _1 })" }.join(' UNION ALL ')
|
||||
@population.definition.model.connection.select_all(
|
||||
"WITH authorised AS (#{ basis }) " +
|
||||
"WITH population_members AS (#{ basis }) " +
|
||||
"SELECT /*+ MAX_EXECUTION_TIME(10000) */ * FROM (#{ sql }) totals").map do |record|
|
||||
row_depth = record['row_depth'].to_i
|
||||
column_depth = record['column_depth'].to_i
|
||||
|
||||
新しいイシューから参照
ユーザーをブロックする