Record Class NumberValue

java.lang.Object
java.lang.Record
com.darkcollective.relix.value.NumberValue
Record Components:
value - the numeric value; must not be null
All Implemented Interfaces:
Value

public record NumberValue(BigDecimal value) extends Record implements Value
A runtime numeric value, stored as an arbitrary-precision BigDecimal.

Use of(String) to parse a numeric literal string (as produced by NumberOperand.value()).

Two numbers are the same value when they are numerically equal, whatever scale they were written or computed at: 5 and 5.0 are one value. That is not what a record gives — BigDecimal.equals(java.lang.Object) is scale-sensitive — and the difference is the whole reason this is written out. Comparison has always been numeric, so leaving identity to the record left the engine holding two incompatible answers to are these the same number, and which one applied depended on the operator: σ x = 5 kept both rows while δ kept them apart, so DISTINCT returned the same displayed number twice. Everything that hashes or sets a value — δ, γ keys, the deduplicating set operations, join hash keys, a closure's nodes — reads this, and every one of them now agrees with =.

The scale itself is kept. It is what the source supplied and it survives a round trip; it simply does not decide identity, exactly as it does not decide order.

  • Constructor Details

    • NumberValue

      public NumberValue(BigDecimal value)
      Creates an instance of a NumberValue record class.
      Parameters:
      value - the value for the value record component
  • Method Details

    • of

      public static NumberValue of(String text)
      Parses a numeric literal string into a NumberValue.
      Parameters:
      text - the numeric literal, e.g. "42" or "3.14"
      Returns:
      a new NumberValue
      Throws:
      NumberFormatException - if text is not a valid decimal
    • equals

      public boolean equals(Object obj)
      Returns whether obj is a numerically equal number. Scale is not part of the answer, so 5 equals 5.0.
      Specified by:
      equals in class Record
      Parameters:
      obj - the value to compare against
      Returns:
      whether obj is a numerically equal number
    • hashCode

      public int hashCode()
      Returns a hash over the scale-normalised number, agreeing with equals(java.lang.Object).
      Specified by:
      hashCode in class Record
      Returns:
      a hash over the scale-normalised number, agreeing with equals(java.lang.Object)
    • isNull

      public boolean isNull()
      Description copied from interface: Value
      Returns true if this value is null (absent).
      Specified by:
      isNull in interface Value
      Returns:
      whether this is a NullValue
    • type

      public ScalarType type()
      Description copied from interface: Value
      Returns the ScalarType that describes this value's kind. NullValue returns ScalarType.ANY.
      Specified by:
      type in interface Value
      Returns:
      the scalar type
    • asDisplayString

      public String asDisplayString()
      Returns the number as a plain decimal string with no trailing zeros and no scientific notation, e.g. "42", "3.14", "0".
      Specified by:
      asDisplayString in interface Value
      Returns:
      plain decimal string
    • toString

      public final String toString()
      Returns a string representation of this record class. The representation contains the name of the class, followed by the name and value of each of the record components.
      Specified by:
      toString in class Record
      Returns:
      a string representation of this object
    • value

      public BigDecimal value()
      Returns the value of the value record component.
      Returns:
      the value of the value record component