Class: ActiveRecord::Materialized::PartitionSnapshot Private

Inherits:
Object
  • Object
show all
Defined in:
lib/activerecord/materialized/partition_snapshot.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Reads a relation (via ActiveRecord, not raw SQL) into { group-key tuple => value-signature tally } for DataVerifier.

Both keys and values are cast through the cache model's own attribute types, so the cache and the recomputed source are compared in a single type system — an integer, string, date, or scaled-decimal column can't masquerade as drift just because the two sides read it through different type casts. A float aggregate is additionally canonicalized to a fixed significance, since an order-dependent SUM/AVG can differ from a re-aggregation in the last bit without any real drift (see FLOAT_SIGNIFICANT_DIGITS).

Rows are tallied per key, so two cache rows for one partition are detected as a count difference rather than silently collapsed.

Constant Summary collapse

SEPARATOR =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

ASCII unit separator between digested values

"\x1f"
FLOAT_SIGNIFICANT_DIGITS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Significant digits a float aggregate is rounded to before comparison. A SUM/AVG over a float column is order-dependent — the DB may re-aggregate base rows in a different order than the maintained value accumulated, so the two differ in the last bit (0.1+0.2+0.3 => 0.6000000000000001 but 0.3+0.2+0.1 => 0.6). Rounding to a fixed significance absorbs that float noise so it does not read as data drift, while any real divergence (a missed write moves the value by far more than a ULP) is still caught. Integer/COUNT and fixed-scale decimal columns already compare exactly after the type cast, so this only touches floats. ~12 of a double's ~15-16 significant digits leaves a safe margin for accumulated rounding without masking a meaningful difference.

12

Instance Method Summary collapse

Constructor Details

#initialize(model, key_columns, value_columns, mode) ⇒ PartitionSnapshot

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of PartitionSnapshot.



35
36
37
38
39
40
# File 'lib/activerecord/materialized/partition_snapshot.rb', line 35

def initialize(model, key_columns, value_columns, mode)
  @model = model
  @key_columns = key_columns
  @value_columns = value_columns
  @mode = mode
end

Instance Method Details

#of(relation) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



42
43
44
45
46
# File 'lib/activerecord/materialized/partition_snapshot.rb', line 42

def of(relation)
  relation.to_a
          .group_by { |record| key_tuple(record) }
          .transform_values { |records| records.map { |record| value_signature(record) }.tally }
end