Class: ClickhouseRuby::Types::Decimal

Inherits:
Base
  • Object
show all
Defined in:
lib/clickhouse_ruby/types/decimal.rb

Overview

Type handler for ClickHouse Decimal types

Handles: Decimal(P, S), Decimal32(S), Decimal64(S), Decimal128(S), Decimal256(S)

Uses BigDecimal for arbitrary precision arithmetic to avoid floating point errors. Validates precision and scale according to ClickHouse constraints.

Constant Summary collapse

PRECISION_LIMITS =

Precision limits for each Decimal variant

{
  32 => 9,
  64 => 18,
  128 => 38,
  256 => 76,
}.freeze

Instance Attribute Summary collapse

Attributes inherited from Base

#name

Instance Method Summary collapse

Methods inherited from Base

#==, #hash, #nullable?, #to_s

Constructor Details

#initialize(name, precision: nil, scale: nil, arg_types: nil) ⇒ Decimal

Initializes a Decimal type

Parameters:

  • name (String)

    the ClickHouse type name (e.g., ‘Decimal(18, 4)’)

  • precision (Integer, nil) (defaults to: nil)

    optional precision override

  • scale (Integer, nil) (defaults to: nil)

    optional scale override

  • arg_types (Array, nil) (defaults to: nil)

    optional parsed argument types (ignored for Decimal)

Raises:



34
35
36
37
38
# File 'lib/clickhouse_ruby/types/decimal.rb', line 34

def initialize(name, precision: nil, scale: nil, arg_types: nil)
  super(name)
  @precision, @scale = parse_decimal_params(name, precision, scale)
  validate_params!
end

Instance Attribute Details

#precisionInteger (readonly)

Returns the precision (total number of significant digits).

Returns:

  • (Integer)

    the precision (total number of significant digits)



22
23
24
# File 'lib/clickhouse_ruby/types/decimal.rb', line 22

def precision
  @precision
end

#scaleInteger (readonly)

Returns the scale (number of digits after decimal point).

Returns:

  • (Integer)

    the scale (number of digits after decimal point)



25
26
27
# File 'lib/clickhouse_ruby/types/decimal.rb', line 25

def scale
  @scale
end

Instance Method Details

#cast(value) ⇒ BigDecimal?

Converts a Ruby value to BigDecimal

Parameters:

  • value (Object)

    the value to convert

Returns:

  • (BigDecimal, nil)

    the BigDecimal value

Raises:



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/clickhouse_ruby/types/decimal.rb', line 45

def cast(value)
  return nil if value.nil?

  bd = case value
       when ::BigDecimal
         value
       when ::Integer
         BigDecimal(value)
       when ::Float
         BigDecimal(value.to_s)
       when ::String
         BigDecimal(value)
       else
         raise_cast_error(value)
       end

  validate_value!(bd)
  bd
end

#deserialize(value) ⇒ BigDecimal?

Converts a value from ClickHouse response to Ruby BigDecimal

Parameters:

  • value (Object)

    the value from ClickHouse

Returns:

  • (BigDecimal, nil)

    the BigDecimal value



69
70
71
72
73
# File 'lib/clickhouse_ruby/types/decimal.rb', line 69

def deserialize(value)
  return nil if value.nil?

  BigDecimal(value.to_s)
end

#internal_typeSymbol

Returns the internal ClickHouse type based on precision

Returns:

  • (Symbol)

    the internal type (:Decimal32, :Decimal64, :Decimal128, or :Decimal256)



90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/clickhouse_ruby/types/decimal.rb', line 90

def internal_type
  case precision
  when 1..9
    :Decimal32
  when 10..18
    :Decimal64
  when 19..38
    :Decimal128
  when 39..76
    :Decimal256
  end
end

#serialize(value) ⇒ String

Converts a BigDecimal to ClickHouse SQL literal

Parameters:

  • value (BigDecimal, nil)

    the value to serialize

Returns:

  • (String)

    the SQL literal



79
80
81
82
83
84
85
# File 'lib/clickhouse_ruby/types/decimal.rb', line 79

def serialize(value)
  return "NULL" if value.nil?

  bd = cast(value)
  # Use 'F' format to preserve precision (fixed-point notation)
  bd.to_s("F")
end