Skip to content

Commit b8f9061

Browse files
committed
Support writing numerics with larger scale than precision
1 parent 4637490 commit b8f9061

File tree

2 files changed

+18
-11
lines changed

2 files changed

+18
-11
lines changed

src/pgrx_tests/copy_type_roundtrip.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,15 @@ mod tests {
987987
test_table.assert_expected_and_result_rows();
988988
}
989989

990+
#[pg_test]
991+
fn test_numeric_with_larger_scale() {
992+
let test_table = TestTable::<AnyNumeric>::new("numeric(5, 8)".into());
993+
test_table.insert(
994+
"INSERT INTO test_expected (a) VALUES (0.00012345), (0.00012340), (-0.00012345), (-0.00012340), (null), (0);",
995+
);
996+
test_table.assert_expected_and_result_rows();
997+
}
998+
990999
#[pg_test]
9911000
#[should_panic = "Special numeric values like NaN, Inf, -Inf are not allowed"]
9921001
fn test_numeric_nan() {

src/type_compat/pg_arrow_type_conversions.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -322,9 +322,16 @@ pub(crate) fn extract_precision_and_scale_from_numeric_typmod(typmod: i32) -> (u
322322
let mut precision = extract_precision_from_numeric_typmod(typmod);
323323
let mut scale = extract_scale_from_numeric_typmod(typmod);
324324

325-
// Even if PG allows negative scale, arrow does not. We adjust precision by adding scale to it.
325+
// Even if PG allows negative scale, arrow does not.
326+
// We adjust precision by adding scale to it and set scale to 0.
326327
if scale < 0 {
327-
adjust_precision_and_scale_if_negative_scale(&mut precision, &mut scale);
328+
precision += scale.abs();
329+
scale = 0;
330+
}
331+
332+
// Even if PG allows scale to be greater than precision, arrow does not. We set precision to scale.
333+
if scale > precision {
334+
precision = scale;
328335
}
329336

330337
debug_assert!(precision >= 0);
@@ -345,15 +352,6 @@ fn extract_scale_from_numeric_typmod(typmod: i32) -> i32 {
345352
(((typmod - pg_sys::VARHDRSZ as i32) & 0x7ff) ^ 1024) - 1024
346353
}
347354

348-
// adjust_precision_and_scale_if_negative_scale adjusts precision and scale if scale is negative.
349-
// Even if PG allows negative scale, arrow does not. We adjust precision by adding scale to it.
350-
fn adjust_precision_and_scale_if_negative_scale(precision: &mut i32, scale: &mut i32) {
351-
if *scale < 0 {
352-
*precision += scale.abs();
353-
*scale = 0;
354-
}
355-
}
356-
357355
fn is_unbounded_numeric_typmod(typmod: i32) -> bool {
358356
typmod == -1
359357
}

0 commit comments

Comments
 (0)