From d66f579a37bb7fc3f80c2a812c30125c9bfb9e4e Mon Sep 17 00:00:00 2001 From: Nathan <148575555+nathan-artie@users.noreply.github.com> Date: Wed, 26 Jun 2024 14:44:40 -0700 Subject: [PATCH] Use `int32` for scale and precision values --- clients/bigquery/dialect/dialect_test.go | 8 ++--- clients/mssql/dialect/dialect_test.go | 4 +-- clients/redshift/dialect/dialect_test.go | 4 +-- clients/snowflake/dialect/dialect_test.go | 8 ++--- lib/cdc/util/optional_schema_test.go | 16 ++++----- lib/debezium/schema.go | 12 +++---- lib/debezium/schema_test.go | 10 +++--- lib/debezium/types.go | 4 +-- lib/debezium/types_test.go | 8 ++--- lib/maputil/map.go | 6 ++-- lib/maputil/map_test.go | 8 ++--- lib/optimization/event_update_test.go | 16 ++++----- lib/parquetutil/parse_values_test.go | 4 +-- lib/ptr/ptr.go | 4 +++ lib/typing/decimal/base.go | 2 +- lib/typing/decimal/decimal.go | 14 ++++---- lib/typing/decimal/decimal_test.go | 42 +++++++++++------------ lib/typing/decimal/details.go | 12 +++---- lib/typing/decimal/details_test.go | 6 ++-- lib/typing/numeric.go | 6 ++-- lib/typing/numeric_test.go | 14 ++++---- lib/typing/parquet.go | 4 +-- lib/typing/values/string_test.go | 2 +- 23 files changed, 109 insertions(+), 105 deletions(-) diff --git a/clients/bigquery/dialect/dialect_test.go b/clients/bigquery/dialect/dialect_test.go index 6e669d735..74fdc34b2 100644 --- a/clients/bigquery/dialect/dialect_test.go +++ b/clients/bigquery/dialect/dialect_test.go @@ -102,15 +102,15 @@ func TestBigQueryDialect_KindForDataType(t *testing.T) { kd, err := dialect.KindForDataType("numeric(5, 2)", "") assert.NoError(t, err) assert.Equal(t, typing.EDecimal.Kind, kd.Kind) - assert.Equal(t, 5, *kd.ExtendedDecimalDetails.Precision()) - assert.Equal(t, 2, kd.ExtendedDecimalDetails.Scale()) + assert.Equal(t, int32(5), *kd.ExtendedDecimalDetails.Precision()) + assert.Equal(t, int32(2), kd.ExtendedDecimalDetails.Scale()) } { kd, err := dialect.KindForDataType("bignumeric(5, 2)", "") assert.NoError(t, err) assert.Equal(t, typing.EDecimal.Kind, kd.Kind) - assert.Equal(t, 5, *kd.ExtendedDecimalDetails.Precision()) - assert.Equal(t, 2, kd.ExtendedDecimalDetails.Scale()) + assert.Equal(t, int32(5), *kd.ExtendedDecimalDetails.Precision()) + assert.Equal(t, int32(2), kd.ExtendedDecimalDetails.Scale()) } } diff --git a/clients/mssql/dialect/dialect_test.go b/clients/mssql/dialect/dialect_test.go index 7bc7d65d2..fe9402a2f 100644 --- a/clients/mssql/dialect/dialect_test.go +++ b/clients/mssql/dialect/dialect_test.go @@ -85,8 +85,8 @@ func TestMSSQLDialect_KindForDataType(t *testing.T) { kd, err := dialect.KindForDataType("numeric(5, 2)", "") assert.NoError(t, err) assert.Equal(t, typing.EDecimal.Kind, kd.Kind) - assert.Equal(t, 5, *kd.ExtendedDecimalDetails.Precision()) - assert.Equal(t, 2, kd.ExtendedDecimalDetails.Scale()) + assert.Equal(t, int32(5), *kd.ExtendedDecimalDetails.Precision()) + assert.Equal(t, int32(2), kd.ExtendedDecimalDetails.Scale()) } { kd, err := dialect.KindForDataType("char", "5") diff --git a/clients/redshift/dialect/dialect_test.go b/clients/redshift/dialect/dialect_test.go index be52ab282..734a1af7f 100644 --- a/clients/redshift/dialect/dialect_test.go +++ b/clients/redshift/dialect/dialect_test.go @@ -145,8 +145,8 @@ func TestRedshiftDialect_KindForDataType(t *testing.T) { kd, err := dialect.KindForDataType("numeric(5,2)", "") assert.NoError(t, err) assert.Equal(t, typing.EDecimal.Kind, kd.Kind) - assert.Equal(t, 5, *kd.ExtendedDecimalDetails.Precision()) - assert.Equal(t, 2, kd.ExtendedDecimalDetails.Scale()) + assert.Equal(t, int32(5), *kd.ExtendedDecimalDetails.Precision()) + assert.Equal(t, int32(2), kd.ExtendedDecimalDetails.Scale()) } } diff --git a/clients/snowflake/dialect/dialect_test.go b/clients/snowflake/dialect/dialect_test.go index 864b58e9c..a1fdcded5 100644 --- a/clients/snowflake/dialect/dialect_test.go +++ b/clients/snowflake/dialect/dialect_test.go @@ -84,15 +84,15 @@ func TestSnowflakeDialect_KindForDataType_Floats(t *testing.T) { kd, err := SnowflakeDialect{}.KindForDataType("NUMERIC(38, 2)", "") assert.NoError(t, err) assert.Equal(t, typing.EDecimal.Kind, kd.Kind) - assert.Equal(t, 38, *kd.ExtendedDecimalDetails.Precision()) - assert.Equal(t, 2, kd.ExtendedDecimalDetails.Scale()) + assert.Equal(t, int32(38), *kd.ExtendedDecimalDetails.Precision()) + assert.Equal(t, int32(2), kd.ExtendedDecimalDetails.Scale()) } { kd, err := SnowflakeDialect{}.KindForDataType("NUMBER(38, 2)", "") assert.NoError(t, err) assert.Equal(t, typing.EDecimal.Kind, kd.Kind) - assert.Equal(t, 38, *kd.ExtendedDecimalDetails.Precision()) - assert.Equal(t, 2, kd.ExtendedDecimalDetails.Scale()) + assert.Equal(t, int32(38), *kd.ExtendedDecimalDetails.Precision()) + assert.Equal(t, int32(2), kd.ExtendedDecimalDetails.Scale()) } { kd, err := SnowflakeDialect{}.KindForDataType("DECIMAL", "") diff --git a/lib/cdc/util/optional_schema_test.go b/lib/cdc/util/optional_schema_test.go index 91063b7a6..3e739a1cf 100644 --- a/lib/cdc/util/optional_schema_test.go +++ b/lib/cdc/util/optional_schema_test.go @@ -67,35 +67,35 @@ func TestGetOptionalSchema(t *testing.T) { "bit_test": typing.Boolean, "numeric_test": { Kind: typing.EDecimal.Kind, - ExtendedDecimalDetails: decimal.NewDecimalDetails(ptr.ToInt(decimal.PrecisionNotSpecified), decimal.DefaultScale), + ExtendedDecimalDetails: decimal.NewDecimalDetails(ptr.ToInt32(decimal.PrecisionNotSpecified), decimal.DefaultScale), }, "numeric_5": { Kind: typing.EDecimal.Kind, - ExtendedDecimalDetails: decimal.NewDecimalDetails(ptr.ToInt(5), 0), + ExtendedDecimalDetails: decimal.NewDecimalDetails(ptr.ToInt32(5), 0), }, "numeric_5_2": { Kind: typing.EDecimal.Kind, - ExtendedDecimalDetails: decimal.NewDecimalDetails(ptr.ToInt(5), 2), + ExtendedDecimalDetails: decimal.NewDecimalDetails(ptr.ToInt32(5), 2), }, "numeric_5_6": { Kind: typing.EDecimal.Kind, - ExtendedDecimalDetails: decimal.NewDecimalDetails(ptr.ToInt(5), 6), + ExtendedDecimalDetails: decimal.NewDecimalDetails(ptr.ToInt32(5), 6), }, "numeric_5_0": { Kind: typing.EDecimal.Kind, - ExtendedDecimalDetails: decimal.NewDecimalDetails(ptr.ToInt(5), 0), + ExtendedDecimalDetails: decimal.NewDecimalDetails(ptr.ToInt32(5), 0), }, "numeric_39_0": { Kind: typing.EDecimal.Kind, - ExtendedDecimalDetails: decimal.NewDecimalDetails(ptr.ToInt(39), 0), + ExtendedDecimalDetails: decimal.NewDecimalDetails(ptr.ToInt32(39), 0), }, "numeric_39_2": { Kind: typing.EDecimal.Kind, - ExtendedDecimalDetails: decimal.NewDecimalDetails(ptr.ToInt(39), 2), + ExtendedDecimalDetails: decimal.NewDecimalDetails(ptr.ToInt32(39), 2), }, "numeric_39_6": { Kind: typing.EDecimal.Kind, - ExtendedDecimalDetails: decimal.NewDecimalDetails(ptr.ToInt(39), 6), + ExtendedDecimalDetails: decimal.NewDecimalDetails(ptr.ToInt32(39), 6), }, }, }, diff --git a/lib/debezium/schema.go b/lib/debezium/schema.go index 5b7e8015d..d33dc90c6 100644 --- a/lib/debezium/schema.go +++ b/lib/debezium/schema.go @@ -61,20 +61,20 @@ type Field struct { Parameters map[string]any `json:"parameters"` } -func (f Field) GetScaleAndPrecision() (int, *int, error) { - scale, scaleErr := maputil.GetIntegerFromMap(f.Parameters, "scale") +func (f Field) GetScaleAndPrecision() (int32, *int32, error) { + scale, scaleErr := maputil.GetInt32FromMap(f.Parameters, "scale") if scaleErr != nil { return 0, nil, scaleErr } - var precisionPtr *int + var precisionPtr *int32 if _, isOk := f.Parameters[KafkaDecimalPrecisionKey]; isOk { - precision, precisionErr := maputil.GetIntegerFromMap(f.Parameters, KafkaDecimalPrecisionKey) + precision, precisionErr := maputil.GetInt32FromMap(f.Parameters, KafkaDecimalPrecisionKey) if precisionErr != nil { return 0, nil, precisionErr } - precisionPtr = ptr.ToInt(precision) + precisionPtr = ptr.ToInt32(precision) } return scale, precisionPtr, nil @@ -106,7 +106,7 @@ func (f Field) ToKindDetails() typing.KindDetails { // This is because scale is not specified at the column level, rather at the row level // It shouldn't matter much anyway since the column type we are creating is `TEXT` to avoid boundary errors. eDecimal := typing.EDecimal - eDecimal.ExtendedDecimalDetails = decimal.NewDecimalDetails(ptr.ToInt(decimal.PrecisionNotSpecified), decimal.DefaultScale) + eDecimal.ExtendedDecimalDetails = decimal.NewDecimalDetails(ptr.ToInt32(decimal.PrecisionNotSpecified), decimal.DefaultScale) return eDecimal } diff --git a/lib/debezium/schema_test.go b/lib/debezium/schema_test.go index d97a93a49..41ae840e9 100644 --- a/lib/debezium/schema_test.go +++ b/lib/debezium/schema_test.go @@ -19,8 +19,8 @@ func TestField_GetScaleAndPrecision(t *testing.T) { name string parameters map[string]any expectedErr string - expectedScale int - expectedPrecision *int + expectedScale int32 + expectedPrecision *int32 }{ { name: "Test Case 1: Empty Parameters", @@ -41,7 +41,7 @@ func TestField_GetScaleAndPrecision(t *testing.T) { KafkaDecimalPrecisionKey: 10, }, expectedScale: 5, - expectedPrecision: ptr.ToInt(10), + expectedPrecision: ptr.ToInt32(10), }, { name: "Test Case 4: Invalid Scale Type", @@ -89,10 +89,10 @@ func TestField_ToKindDetails(t *testing.T) { } eDecimal := typing.EDecimal - eDecimal.ExtendedDecimalDetails = decimal.NewDecimalDetails(ptr.ToInt(decimal.PrecisionNotSpecified), decimal.DefaultScale) + eDecimal.ExtendedDecimalDetails = decimal.NewDecimalDetails(ptr.ToInt32(decimal.PrecisionNotSpecified), decimal.DefaultScale) kafkaDecimalType := typing.EDecimal - kafkaDecimalType.ExtendedDecimalDetails = decimal.NewDecimalDetails(ptr.ToInt(10), 5) + kafkaDecimalType.ExtendedDecimalDetails = decimal.NewDecimalDetails(ptr.ToInt32(10), 5) tcs := []_tc{ { diff --git a/lib/debezium/types.go b/lib/debezium/types.go index c7af11e9c..137272a40 100644 --- a/lib/debezium/types.go +++ b/lib/debezium/types.go @@ -246,7 +246,7 @@ func (f Field) DecodeDebeziumVariableDecimal(value any) (*decimal.Decimal, error return nil, fmt.Errorf("value is not map[string]any type") } - scale, err := maputil.GetIntegerFromMap(valueStruct, "scale") + scale, err := maputil.GetInt32FromMap(valueStruct, "scale") if err != nil { return nil, err } @@ -261,5 +261,5 @@ func (f Field) DecodeDebeziumVariableDecimal(value any) (*decimal.Decimal, error return nil, err } _decimal := DecodeDecimal(bytes, int32(scale)) - return decimal.NewDecimal(ptr.ToInt(decimal.PrecisionNotSpecified), _decimal), nil + return decimal.NewDecimal(ptr.ToInt32(decimal.PrecisionNotSpecified), _decimal), nil } diff --git a/lib/debezium/types_test.go b/lib/debezium/types_test.go index 2cbcaef10..63dfc3e48 100644 --- a/lib/debezium/types_test.go +++ b/lib/debezium/types_test.go @@ -447,9 +447,9 @@ func TestField_DecodeDecimal(t *testing.T) { params map[string]any expectedValue string - expectedPrecision int + expectedPrecision int32 expectNilPtrPrecision bool - expectedScale int + expectedScale int32 expectBigFloat bool expectedErr string }{ @@ -638,7 +638,7 @@ func TestField_DecodeDebeziumVariableDecimal(t *testing.T) { value any expectedValue string - expectedScale int + expectedScale int32 expectedErr string } @@ -720,7 +720,7 @@ func TestField_DecodeDebeziumVariableDecimal(t *testing.T) { // It should be a string instead. _, isOk = dec.Value().(string) assert.True(t, isOk, testCase.name) - assert.Equal(t, -1, *dec.Precision(), testCase.name) + assert.Equal(t, int32(-1), *dec.Precision(), testCase.name) assert.Equal(t, testCase.expectedScale, dec.Scale(), testCase.name) assert.Equal(t, testCase.expectedValue, dec.Value(), testCase.name) } diff --git a/lib/maputil/map.go b/lib/maputil/map.go index f6f94a555..5ae02a6d5 100644 --- a/lib/maputil/map.go +++ b/lib/maputil/map.go @@ -18,7 +18,7 @@ func GetKeyFromMap(obj map[string]any, key string, defaultValue any) any { return val } -func GetIntegerFromMap(obj map[string]any, key string) (int, error) { +func GetInt32FromMap(obj map[string]any, key string) (int32, error) { if len(obj) == 0 { return 0, fmt.Errorf("object is empty") } @@ -28,10 +28,10 @@ func GetIntegerFromMap(obj map[string]any, key string) (int, error) { return 0, fmt.Errorf("key: %s does not exist in object", key) } - val, err := strconv.Atoi(fmt.Sprint(valInterface)) + val, err := strconv.ParseInt(fmt.Sprint(valInterface), 10, 32) if err != nil { return 0, fmt.Errorf("key: %s is not type integer: %w", key, err) } - return val, nil + return int32(val), nil } diff --git a/lib/maputil/map_test.go b/lib/maputil/map_test.go index 2ce640833..7d4c3d55b 100644 --- a/lib/maputil/map_test.go +++ b/lib/maputil/map_test.go @@ -27,7 +27,7 @@ func TestGetKeyFromMap(t *testing.T) { assert.Equal(t, val, "robin55") } -func TestGetIntegerFromMap(t *testing.T) { +func TestGetInt32FromMap(t *testing.T) { object := map[string]any{ "abc": "123", "abc (number)": 123, @@ -41,7 +41,7 @@ func TestGetIntegerFromMap(t *testing.T) { name string obj map[string]any key string - expectedValue int + expectedValue int32 expectedErr string }{ { @@ -89,11 +89,11 @@ func TestGetIntegerFromMap(t *testing.T) { } for _, testCase := range testCases { - value, err := GetIntegerFromMap(testCase.obj, testCase.key) + value, err := GetInt32FromMap(testCase.obj, testCase.key) if testCase.expectedErr != "" { assert.ErrorContains(t, err, testCase.expectedErr, testCase.name) } else { - assert.Equal(t, reflect.Int, reflect.TypeOf(value).Kind()) + assert.Equal(t, reflect.Int32, reflect.TypeOf(value).Kind()) assert.Equal(t, testCase.expectedValue, value) assert.NoError(t, err, testCase.name) } diff --git a/lib/optimization/event_update_test.go b/lib/optimization/event_update_test.go index 8ca525f82..b43d60377 100644 --- a/lib/optimization/event_update_test.go +++ b/lib/optimization/event_update_test.go @@ -42,7 +42,7 @@ func TestTableData_UpdateInMemoryColumnsFromDestination(t *testing.T) { tableDataCols.AddColumn(columns.NewColumn("ext_dec", typing.String)) extDecimalType := typing.EDecimal - extDecimalType.ExtendedDecimalDetails = decimal.NewDecimalDetails(ptr.ToInt(22), 2) + extDecimalType.ExtendedDecimalDetails = decimal.NewDecimalDetails(ptr.ToInt32(22), 2) tableDataCols.AddColumn(columns.NewColumn("ext_dec_filled", extDecimalType)) tableDataCols.AddColumn(columns.NewColumn(strCol, typing.String)) @@ -121,31 +121,31 @@ func TestTableData_UpdateInMemoryColumnsFromDestination(t *testing.T) { assert.Equal(t, typing.String, extDecCol.KindDetails) extDecimal := typing.EDecimal - extDecimal.ExtendedDecimalDetails = decimal.NewDecimalDetails(ptr.ToInt(30), 2) + extDecimal.ExtendedDecimalDetails = decimal.NewDecimalDetails(ptr.ToInt32(30), 2) assert.NoError(t, tableData.MergeColumnsFromDestination(columns.NewColumn("ext_dec", extDecimal))) // Now it should be ext decimal type extDecCol, isOk = tableData.inMemoryColumns.GetColumn("ext_dec") assert.True(t, isOk) assert.Equal(t, typing.EDecimal.Kind, extDecCol.KindDetails.Kind) // Check precision and scale too. - assert.Equal(t, 30, *extDecCol.KindDetails.ExtendedDecimalDetails.Precision()) - assert.Equal(t, 2, extDecCol.KindDetails.ExtendedDecimalDetails.Scale()) + assert.Equal(t, int32(30), *extDecCol.KindDetails.ExtendedDecimalDetails.Precision()) + assert.Equal(t, int32(2), extDecCol.KindDetails.ExtendedDecimalDetails.Scale()) // Testing ext_dec_filled since it's already filled out extDecColFilled, isOk := tableData.inMemoryColumns.GetColumn("ext_dec_filled") assert.True(t, isOk) assert.Equal(t, typing.EDecimal.Kind, extDecColFilled.KindDetails.Kind) // Check precision and scale too. - assert.Equal(t, 22, *extDecColFilled.KindDetails.ExtendedDecimalDetails.Precision()) - assert.Equal(t, 2, extDecColFilled.KindDetails.ExtendedDecimalDetails.Scale()) + assert.Equal(t, int32(22), *extDecColFilled.KindDetails.ExtendedDecimalDetails.Precision()) + assert.Equal(t, int32(2), extDecColFilled.KindDetails.ExtendedDecimalDetails.Scale()) assert.NoError(t, tableData.MergeColumnsFromDestination(columns.NewColumn("ext_dec_filled", extDecimal))) extDecColFilled, isOk = tableData.inMemoryColumns.GetColumn("ext_dec_filled") assert.True(t, isOk) assert.Equal(t, typing.EDecimal.Kind, extDecColFilled.KindDetails.Kind) // Check precision and scale too. - assert.Equal(t, 22, *extDecColFilled.KindDetails.ExtendedDecimalDetails.Precision()) - assert.Equal(t, 2, extDecColFilled.KindDetails.ExtendedDecimalDetails.Scale()) + assert.Equal(t, int32(22), *extDecColFilled.KindDetails.ExtendedDecimalDetails.Precision()) + assert.Equal(t, int32(2), extDecColFilled.KindDetails.ExtendedDecimalDetails.Scale()) } { tableDataCols := &columns.Columns{} diff --git a/lib/parquetutil/parse_values_test.go b/lib/parquetutil/parse_values_test.go index 5174ddb7d..06ed51d48 100644 --- a/lib/parquetutil/parse_values_test.go +++ b/lib/parquetutil/parse_values_test.go @@ -15,7 +15,7 @@ import ( func TestParseValue(t *testing.T) { eDecimal := typing.EDecimal - eDecimal.ExtendedDecimalDetails = decimal.NewDecimalDetails(ptr.ToInt(30), 5) + eDecimal.ExtendedDecimalDetails = decimal.NewDecimalDetails(ptr.ToInt32(30), 5) eTime := typing.ETime eTime.ExtendedTimeDetails = &ext.Time @@ -66,7 +66,7 @@ func TestParseValue(t *testing.T) { }, { name: "decimal", - colVal: decimal.NewDecimal(ptr.ToInt(30), numbers.MustParseDecimal("5000.22320")), + colVal: decimal.NewDecimal(ptr.ToInt32(30), numbers.MustParseDecimal("5000.22320")), colKind: columns.NewColumn("", eDecimal), expectedValue: "5000.22320", }, diff --git a/lib/ptr/ptr.go b/lib/ptr/ptr.go index ab5677616..7196fda0e 100644 --- a/lib/ptr/ptr.go +++ b/lib/ptr/ptr.go @@ -10,6 +10,10 @@ func ToInt(val int) *int { return &val } +func ToInt32(val int32) *int32 { + return &val +} + func ToInt64(val int64) *int64 { return &val } diff --git a/lib/typing/decimal/base.go b/lib/typing/decimal/base.go index 484777acc..bc435ff99 100644 --- a/lib/typing/decimal/base.go +++ b/lib/typing/decimal/base.go @@ -34,7 +34,7 @@ func (d *DecimalDetails) isBigNumeric() bool { return numbers.BetweenEq(max(1, d.scale), d.scale+38, *d.precision) } -func (d *DecimalDetails) toKind(maxPrecision int, exceededKind string) string { +func (d *DecimalDetails) toKind(maxPrecision int32, exceededKind string) string { precision := maxPrecision if d.precision != nil { precision = *d.precision diff --git a/lib/typing/decimal/decimal.go b/lib/typing/decimal/decimal.go index 00ba25949..d53dde072 100644 --- a/lib/typing/decimal/decimal.go +++ b/lib/typing/decimal/decimal.go @@ -10,7 +10,7 @@ import ( // Decimal is Artie's wrapper around [*apd.Decimal] which can store large numbers w/ no precision loss. type Decimal struct { - precision *int + precision *int32 value *apd.Decimal } @@ -22,15 +22,15 @@ const ( MaxPrecisionBeforeString = 38 ) -func NewDecimal(precision *int, value *apd.Decimal) *Decimal { +func NewDecimal(precision *int32, value *apd.Decimal) *Decimal { if precision != nil { - scale := int(-value.Exponent) + scale := -value.Exponent if scale > *precision && *precision != -1 { // 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 = ptr.ToInt(scale + 1) + precision = ptr.ToInt32(scale + 1) } } @@ -40,11 +40,11 @@ func NewDecimal(precision *int, value *apd.Decimal) *Decimal { } } -func (d *Decimal) Scale() int { - return int(-d.value.Exponent) +func (d *Decimal) Scale() int32 { + return -d.value.Exponent } -func (d *Decimal) Precision() *int { +func (d *Decimal) Precision() *int32 { return d.precision } diff --git a/lib/typing/decimal/decimal_test.go b/lib/typing/decimal/decimal_test.go index 666761b20..c0403fe23 100644 --- a/lib/typing/decimal/decimal_test.go +++ b/lib/typing/decimal/decimal_test.go @@ -12,23 +12,23 @@ func TestNewDecimal(t *testing.T) { // Nil precision: assert.Equal(t, "0", NewDecimal(nil, numbers.MustParseDecimal("0")).String()) // Precision = -1 (PrecisionNotSpecified): - assert.Equal(t, DecimalDetails{scale: 2, precision: ptr.ToInt(-1)}, NewDecimal(ptr.ToInt(-1), numbers.MustParseDecimal("12.34")).Details()) + assert.Equal(t, DecimalDetails{scale: 2, precision: ptr.ToInt32(-1)}, NewDecimal(ptr.ToInt32(-1), numbers.MustParseDecimal("12.34")).Details()) // Precision = scale: - assert.Equal(t, DecimalDetails{scale: 2, precision: ptr.ToInt(2)}, NewDecimal(ptr.ToInt(2), numbers.MustParseDecimal("12.34")).Details()) + assert.Equal(t, DecimalDetails{scale: 2, precision: ptr.ToInt32(2)}, NewDecimal(ptr.ToInt32(2), numbers.MustParseDecimal("12.34")).Details()) // Precision < scale: - assert.Equal(t, DecimalDetails{scale: 2, precision: ptr.ToInt(3)}, NewDecimal(ptr.ToInt(1), numbers.MustParseDecimal("12.34")).Details()) + assert.Equal(t, DecimalDetails{scale: 2, precision: ptr.ToInt32(3)}, NewDecimal(ptr.ToInt32(1), numbers.MustParseDecimal("12.34")).Details()) // Precision > scale: - assert.Equal(t, DecimalDetails{scale: 2, precision: ptr.ToInt(4)}, NewDecimal(ptr.ToInt(4), numbers.MustParseDecimal("12.34")).Details()) + assert.Equal(t, DecimalDetails{scale: 2, precision: ptr.ToInt32(4)}, NewDecimal(ptr.ToInt32(4), numbers.MustParseDecimal("12.34")).Details()) } func TestDecimal_Scale(t *testing.T) { - assert.Equal(t, 0, NewDecimal(nil, numbers.MustParseDecimal("0")).Scale()) - assert.Equal(t, 0, NewDecimal(nil, numbers.MustParseDecimal("12345")).Scale()) - assert.Equal(t, 0, NewDecimal(nil, numbers.MustParseDecimal("12300")).Scale()) - assert.Equal(t, 1, NewDecimal(nil, numbers.MustParseDecimal("12300.0")).Scale()) - assert.Equal(t, 2, NewDecimal(nil, numbers.MustParseDecimal("12300.00")).Scale()) - assert.Equal(t, 2, NewDecimal(nil, numbers.MustParseDecimal("12345.12")).Scale()) - assert.Equal(t, 3, NewDecimal(nil, numbers.MustParseDecimal("-12345.123")).Scale()) + assert.Equal(t, int32(0), NewDecimal(nil, numbers.MustParseDecimal("0")).Scale()) + assert.Equal(t, int32(0), NewDecimal(nil, numbers.MustParseDecimal("12345")).Scale()) + assert.Equal(t, int32(0), NewDecimal(nil, numbers.MustParseDecimal("12300")).Scale()) + assert.Equal(t, int32(1), NewDecimal(nil, numbers.MustParseDecimal("12300.0")).Scale()) + assert.Equal(t, int32(2), NewDecimal(nil, numbers.MustParseDecimal("12300.00")).Scale()) + assert.Equal(t, int32(2), NewDecimal(nil, numbers.MustParseDecimal("12345.12")).Scale()) + assert.Equal(t, int32(3), NewDecimal(nil, numbers.MustParseDecimal("-12345.123")).Scale()) } func TestDecimal_Details(t *testing.T) { @@ -40,16 +40,16 @@ func TestDecimal_Details(t *testing.T) { assert.Equal(t, DecimalDetails{scale: 3}, NewDecimal(nil, numbers.MustParseDecimal("-12345.123")).Details()) // -1 precision (PrecisionNotSpecified): - assert.Equal(t, DecimalDetails{scale: 0, precision: ptr.ToInt(-1)}, NewDecimal(ptr.ToInt(-1), numbers.MustParseDecimal("0")).Details()) - assert.Equal(t, DecimalDetails{scale: 0, precision: ptr.ToInt(-1)}, NewDecimal(ptr.ToInt(-1), numbers.MustParseDecimal("12345")).Details()) - assert.Equal(t, DecimalDetails{scale: 0, precision: ptr.ToInt(-1)}, NewDecimal(ptr.ToInt(-1), numbers.MustParseDecimal("-12")).Details()) - assert.Equal(t, DecimalDetails{scale: 2, precision: ptr.ToInt(-1)}, NewDecimal(ptr.ToInt(-1), numbers.MustParseDecimal("12345.12")).Details()) - assert.Equal(t, DecimalDetails{scale: 3, precision: ptr.ToInt(-1)}, NewDecimal(ptr.ToInt(-1), numbers.MustParseDecimal("-12345.123")).Details()) + assert.Equal(t, DecimalDetails{scale: 0, precision: ptr.ToInt32(-1)}, NewDecimal(ptr.ToInt32(-1), numbers.MustParseDecimal("0")).Details()) + assert.Equal(t, DecimalDetails{scale: 0, precision: ptr.ToInt32(-1)}, NewDecimal(ptr.ToInt32(-1), numbers.MustParseDecimal("12345")).Details()) + assert.Equal(t, DecimalDetails{scale: 0, precision: ptr.ToInt32(-1)}, NewDecimal(ptr.ToInt32(-1), numbers.MustParseDecimal("-12")).Details()) + assert.Equal(t, DecimalDetails{scale: 2, precision: ptr.ToInt32(-1)}, NewDecimal(ptr.ToInt32(-1), numbers.MustParseDecimal("12345.12")).Details()) + assert.Equal(t, DecimalDetails{scale: 3, precision: ptr.ToInt32(-1)}, NewDecimal(ptr.ToInt32(-1), numbers.MustParseDecimal("-12345.123")).Details()) // 10 precision: - assert.Equal(t, DecimalDetails{scale: 0, precision: ptr.ToInt(10)}, NewDecimal(ptr.ToInt(10), numbers.MustParseDecimal("0")).Details()) - assert.Equal(t, DecimalDetails{scale: 0, precision: ptr.ToInt(10)}, NewDecimal(ptr.ToInt(10), numbers.MustParseDecimal("12345")).Details()) - assert.Equal(t, DecimalDetails{scale: 0, precision: ptr.ToInt(10)}, NewDecimal(ptr.ToInt(10), numbers.MustParseDecimal("-12")).Details()) - assert.Equal(t, DecimalDetails{scale: 2, precision: ptr.ToInt(10)}, NewDecimal(ptr.ToInt(10), numbers.MustParseDecimal("12345.12")).Details()) - assert.Equal(t, DecimalDetails{scale: 3, precision: ptr.ToInt(10)}, NewDecimal(ptr.ToInt(10), numbers.MustParseDecimal("-12345.123")).Details()) + assert.Equal(t, DecimalDetails{scale: 0, precision: ptr.ToInt32(10)}, NewDecimal(ptr.ToInt32(10), numbers.MustParseDecimal("0")).Details()) + assert.Equal(t, DecimalDetails{scale: 0, precision: ptr.ToInt32(10)}, NewDecimal(ptr.ToInt32(10), numbers.MustParseDecimal("12345")).Details()) + assert.Equal(t, DecimalDetails{scale: 0, precision: ptr.ToInt32(10)}, NewDecimal(ptr.ToInt32(10), numbers.MustParseDecimal("-12")).Details()) + assert.Equal(t, DecimalDetails{scale: 2, precision: ptr.ToInt32(10)}, NewDecimal(ptr.ToInt32(10), numbers.MustParseDecimal("12345.12")).Details()) + assert.Equal(t, DecimalDetails{scale: 3, precision: ptr.ToInt32(10)}, NewDecimal(ptr.ToInt32(10), numbers.MustParseDecimal("-12345.123")).Details()) } diff --git a/lib/typing/decimal/details.go b/lib/typing/decimal/details.go index e27f51e64..85e93688a 100644 --- a/lib/typing/decimal/details.go +++ b/lib/typing/decimal/details.go @@ -7,18 +7,18 @@ import ( ) type DecimalDetails struct { - scale int - precision *int + scale int32 + precision *int32 } -func NewDecimalDetails(precision *int, scale int) *DecimalDetails { +func NewDecimalDetails(precision *int32, scale int32) *DecimalDetails { if precision != nil { if scale > *precision && *precision != -1 { // 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 = ptr.ToInt(scale + 1) + precision = ptr.ToInt32(scale + 1) } } @@ -28,11 +28,11 @@ func NewDecimalDetails(precision *int, scale int) *DecimalDetails { } } -func (d DecimalDetails) Scale() int { +func (d DecimalDetails) Scale() int32 { return d.scale } -func (d DecimalDetails) Precision() *int { +func (d DecimalDetails) Precision() *int32 { return d.precision } diff --git a/lib/typing/decimal/details_test.go b/lib/typing/decimal/details_test.go index 69445d0a3..20b8fb36f 100644 --- a/lib/typing/decimal/details_test.go +++ b/lib/typing/decimal/details_test.go @@ -11,8 +11,8 @@ import ( func TestDecimalDetailsKind(t *testing.T) { type _testCase struct { Name string - Precision int - Scale int + Precision int32 + Scale int32 ExpectedSnowflakeKind string ExpectedRedshiftKind string @@ -70,7 +70,7 @@ func TestDecimalDetailsKind(t *testing.T) { } for _, testCase := range testCases { - d := NewDecimalDetails(ptr.ToInt(testCase.Precision), testCase.Scale) + d := NewDecimalDetails(ptr.ToInt32(testCase.Precision), testCase.Scale) assert.Equal(t, testCase.ExpectedSnowflakeKind, d.SnowflakeKind(), testCase.Name) assert.Equal(t, testCase.ExpectedRedshiftKind, d.RedshiftKind(), testCase.Name) assert.Equal(t, testCase.ExpectedBigQueryKind, d.BigQueryKind(), testCase.Name) diff --git a/lib/typing/numeric.go b/lib/typing/numeric.go index b3bc7594d..9378d0a09 100644 --- a/lib/typing/numeric.go +++ b/lib/typing/numeric.go @@ -12,14 +12,14 @@ func ParseNumeric(parts []string) KindDetails { return Invalid } - var parsedNumbers []int + var parsedNumbers []int32 for _, part := range parts { - parsedNumber, err := strconv.Atoi(strings.TrimSpace(part)) + parsedNumber, err := strconv.ParseInt(strings.TrimSpace(part), 10, 32) if err != nil { return Invalid } - parsedNumbers = append(parsedNumbers, parsedNumber) + parsedNumbers = append(parsedNumbers, int32(parsedNumber)) } // If scale is 0 or not specified, then number is an int. diff --git a/lib/typing/numeric_test.go b/lib/typing/numeric_test.go index 4960fc73a..a20600532 100644 --- a/lib/typing/numeric_test.go +++ b/lib/typing/numeric_test.go @@ -12,8 +12,8 @@ func TestParseNumeric(t *testing.T) { type _testCase struct { parameters []string expectedKindDetails KindDetails - expectedPrecision *int // Using a pointer to int so we can differentiate between unset (nil) and set (0 included) - expectedScale int + expectedPrecision *int32 // Using a pointer to int32 so we can differentiate between unset (nil) and set (0 included) + expectedScale int32 } testCases := []_testCase{ @@ -40,31 +40,31 @@ func TestParseNumeric(t *testing.T) { { parameters: []string{"5", " 2"}, expectedKindDetails: EDecimal, - expectedPrecision: ptr.ToInt(5), + expectedPrecision: ptr.ToInt32(5), expectedScale: 2, }, { parameters: []string{"5", "2"}, expectedKindDetails: EDecimal, - expectedPrecision: ptr.ToInt(5), + expectedPrecision: ptr.ToInt32(5), expectedScale: 2, }, { parameters: []string{"39", "6"}, expectedKindDetails: EDecimal, - expectedPrecision: ptr.ToInt(39), + expectedPrecision: ptr.ToInt32(39), expectedScale: 6, }, { parameters: []string{"5"}, expectedKindDetails: Integer, - expectedPrecision: ptr.ToInt(5), + expectedPrecision: ptr.ToInt32(5), expectedScale: 0, }, { parameters: []string{"5", "0"}, expectedKindDetails: Integer, - expectedPrecision: ptr.ToInt(5), + expectedPrecision: ptr.ToInt32(5), expectedScale: 0, }, } diff --git a/lib/typing/parquet.go b/lib/typing/parquet.go index dad312911..4a0378302 100644 --- a/lib/typing/parquet.go +++ b/lib/typing/parquet.go @@ -132,8 +132,8 @@ func (k *KindDetails) ParquetAnnotation(colName string) (*Field, error) { InName: &colName, Type: ptr.ToString("BYTE_ARRAY"), ConvertedType: ptr.ToString("DECIMAL"), - Precision: precision, - Scale: ptr.ToInt(scale), + Precision: ptr.ToInt(int(*precision)), + Scale: ptr.ToInt(int(scale)), }.String(), }, nil case Boolean.Kind: diff --git a/lib/typing/values/string_test.go b/lib/typing/values/string_test.go index 945a8f756..7ec8d0cce 100644 --- a/lib/typing/values/string_test.go +++ b/lib/typing/values/string_test.go @@ -123,7 +123,7 @@ func TestToString(t *testing.T) { assert.Equal(t, "123.45", val) // Decimals - value := decimal.NewDecimal(ptr.ToInt(38), numbers.MustParseDecimal("585692791691858.25")) + value := decimal.NewDecimal(ptr.ToInt32(38), numbers.MustParseDecimal("585692791691858.25")) val, err = ToString(value, columns.Column{KindDetails: typing.EDecimal}, nil) assert.NoError(t, err) assert.Equal(t, "585692791691858.25", val)