diff --git a/lib/debezium/types_test.go b/lib/debezium/types_test.go index 8dfdcbcfa..61d9f7550 100644 --- a/lib/debezium/types_test.go +++ b/lib/debezium/types_test.go @@ -609,8 +609,8 @@ func TestField_DecodeDecimal(t *testing.T) { assert.NoError(t, err) assert.Equal(t, testCase.expectedValue, dec.String(), testCase.name) - assert.Equal(t, testCase.expectedPrecision, dec.Precision(), testCase.name) - assert.Equal(t, testCase.expectedScale, dec.Scale(), testCase.name) + assert.Equal(t, testCase.expectedPrecision, dec.Details().Precision(), testCase.name) + assert.Equal(t, testCase.expectedScale, dec.Details().Scale(), testCase.name) } } @@ -695,8 +695,8 @@ func TestField_DecodeDebeziumVariableDecimal(t *testing.T) { continue } - assert.Equal(t, int32(-1), dec.Precision(), testCase.name) - assert.Equal(t, testCase.expectedScale, dec.Scale(), testCase.name) + assert.Equal(t, int32(-1), dec.Details().Precision(), testCase.name) + assert.Equal(t, testCase.expectedScale, dec.Details().Scale(), testCase.name) assert.Equal(t, testCase.expectedValue, dec.String(), testCase.name) } diff --git a/lib/typing/decimal/decimal.go b/lib/typing/decimal/decimal.go index c220c353b..cefa1617f 100644 --- a/lib/typing/decimal/decimal.go +++ b/lib/typing/decimal/decimal.go @@ -4,30 +4,15 @@ import ( "github.com/cockroachdb/apd/v3" ) +const PrecisionNotSpecified int32 = -1 + // Decimal is Artie's wrapper around [*apd.Decimal] which can store large numbers w/ no precision loss. type Decimal struct { precision int32 value *apd.Decimal } -const ( - DefaultScale int32 = 5 - PrecisionNotSpecified int32 = -1 - // MaxPrecisionBeforeString - if the precision is greater than 38, we'll cast it as a string. - // This is because Snowflake and BigQuery both do not have NUMERIC data types that go beyond 38. - MaxPrecisionBeforeString int32 = 38 -) - func NewDecimalWithPrecision(value *apd.Decimal, precision int32) *Decimal { - scale := -value.Exponent - if scale > precision && precision != PrecisionNotSpecified { - // Note: -1 precision means it's not specified. - - // This is typically not possible, but Postgres has a design flaw that allows you to do things like: NUMERIC(5, 6) which actually equates to NUMERIC(7, 6) - // We are setting precision to be scale + 1 to account for the leading zero for decimal numbers. - precision = scale + 1 - } - return &Decimal{ precision: precision, value: value, @@ -38,14 +23,6 @@ func NewDecimal(value *apd.Decimal) *Decimal { return NewDecimalWithPrecision(value, PrecisionNotSpecified) } -func (d *Decimal) Scale() int32 { - return -d.value.Exponent -} - -func (d *Decimal) Precision() int32 { - return d.precision -} - func (d *Decimal) Value() *apd.Decimal { return d.value } @@ -58,5 +35,5 @@ func (d *Decimal) String() string { } func (d *Decimal) Details() Details { - return Details{scale: d.Scale(), precision: d.precision} + return NewDetails(d.precision, -d.value.Exponent) } diff --git a/lib/typing/decimal/decimal_test.go b/lib/typing/decimal/decimal_test.go index 2fc86aa60..78c4dae33 100644 --- a/lib/typing/decimal/decimal_test.go +++ b/lib/typing/decimal/decimal_test.go @@ -24,16 +24,6 @@ func TestNewDecimalWithPrecision(t *testing.T) { assert.Equal(t, Details{scale: 2, precision: 4}, NewDecimalWithPrecision(numbers.MustParseDecimal("12.34"), 4).Details()) } -func TestDecimal_Scale(t *testing.T) { - assert.Equal(t, int32(0), NewDecimal(numbers.MustParseDecimal("0")).Scale()) - assert.Equal(t, int32(0), NewDecimal(numbers.MustParseDecimal("12345")).Scale()) - assert.Equal(t, int32(0), NewDecimal(numbers.MustParseDecimal("12300")).Scale()) - assert.Equal(t, int32(1), NewDecimal(numbers.MustParseDecimal("12300.0")).Scale()) - assert.Equal(t, int32(2), NewDecimal(numbers.MustParseDecimal("12300.00")).Scale()) - assert.Equal(t, int32(2), NewDecimal(numbers.MustParseDecimal("12345.12")).Scale()) - assert.Equal(t, int32(3), NewDecimal(numbers.MustParseDecimal("-12345.123")).Scale()) -} - func TestDecimal_Details(t *testing.T) { // -1 precision (PrecisionNotSpecified): assert.Equal(t, Details{scale: 0, precision: -1}, NewDecimal(numbers.MustParseDecimal("0")).Details()) diff --git a/lib/typing/decimal/details.go b/lib/typing/decimal/details.go index 688046866..dd348c9b6 100644 --- a/lib/typing/decimal/details.go +++ b/lib/typing/decimal/details.go @@ -4,6 +4,13 @@ import ( "fmt" ) +const ( + DefaultScale int32 = 5 + // MaxPrecisionBeforeString - if the precision is greater than 38, we'll cast it as a string. + // This is because Snowflake and BigQuery both do not have NUMERIC data types that go beyond 38. + MaxPrecisionBeforeString int32 = 38 +) + type Details struct { scale int32 precision int32