From 5bc71959492b2379e5b80eaf367352d3a09ff220 Mon Sep 17 00:00:00 2001 From: skymanbp <57272723+skymanbp@users.noreply.github.com> Date: Fri, 25 Sep 2026 01:14:17 -0400 Subject: [PATCH] fix: keep nulls in nullable int32 and int64 decimal parquet columns --- dataframe-parquet/src/DataFrame/IO/Parquet.hs | 16 ++++++---------- tests/Parquet.hs | 14 ++++++++++++++ tests/data/nullable_int_decimal.parquet | Bin 0 -> 812 bytes 3 files changed, 20 insertions(+), 10 deletions(-) create mode 100644 tests/data/nullable_int_decimal.parquet diff --git a/dataframe-parquet/src/DataFrame/IO/Parquet.hs b/dataframe-parquet/src/DataFrame/IO/Parquet.hs index bbfb774d..71f1d8cf 100644 --- a/dataframe-parquet/src/DataFrame/IO/Parquet.hs +++ b/dataframe-parquet/src/DataFrame/IO/Parquet.hs @@ -674,18 +674,14 @@ applyLogicalType (Just (LT_DECIMAL f)) col = scale = unField dt.decimal_scale precision = unField dt.decimal_precision in if precision <= 9 - then case DI.toVector @Int32 @VU.Vector col of - Right xs -> - DI.fromUnboxedVector $ - VU.map (\raw -> fromIntegral @Int32 @Double raw / 10 ^ scale) xs - Left _ -> col + then + fromRight col $ + DI.mapColumn (\raw -> fromIntegral @Int32 @Double raw / 10 ^ scale) col else if precision <= 18 - then case DI.toVector @Int64 @VU.Vector col of - Right xs -> - DI.fromUnboxedVector $ - VU.map (\raw -> fromIntegral @Int64 @Double raw / 10 ^ scale) xs - Left _ -> col + then + fromRight col $ + DI.mapColumn (\raw -> fromIntegral @Int64 @Double raw / 10 ^ scale) col else col applyLogicalType _ col = col diff --git a/tests/Parquet.hs b/tests/Parquet.hs index 5e48e136..dcb2dd30 100644 --- a/tests/Parquet.hs +++ b/tests/Parquet.hs @@ -823,6 +823,19 @@ int64Decimal = ) ) +nullableIntDecimal :: Test +nullableIntDecimal = testBothReadParquetPaths $ \readParquet -> + TestCase + ( assertEqual + "nullableIntDecimal" + ( D.fromNamedColumns + [ ("int32_dec", D.fromList [Just (1 :: Double), Nothing, Just 2.5, Just 0.75]) + , ("int64_dec", D.fromList [Nothing, Just (1234.5 :: Double), Nothing, Just (-5)]) + ] + ) + (unsafePerformIO (readParquet "./tests/data/nullable_int_decimal.parquet")) + ) + byteArrayDecimal :: Test byteArrayDecimal = TestCase @@ -1394,6 +1407,7 @@ tests = , -- Group 7: decimal types int32Decimal , int64Decimal + , nullableIntDecimal , byteArrayDecimal , fixedLengthDecimal , fixedLengthDecimalLegacy diff --git a/tests/data/nullable_int_decimal.parquet b/tests/data/nullable_int_decimal.parquet new file mode 100644 index 0000000000000000000000000000000000000000..a3daa296ce642a034c1cbedcb63f96881fed9f54 GIT binary patch literal 812 zcmaJ=%}(1u5MFOqmWx0N5o7I2KKM{9Dj7;sXranwoB(Zs7Ux2XDpjcyxd<9UfCf1A zX*lvEoOuYusmESmWn}io2E73;h>{RZA;cfr>$E|@6imh7 zL6J~5(25bQ81v=KP&7G7N0N47LKdD1q6{J2Aj6ckYf>bqw|7>EwgjaiT5ph{y+Mwz zW=5PomKk#j5|pVd3hf?c-&;Q#pajTish{k&k6)I*He1>B7&YL`EDE=1hKPVr|H7daRU+^I&tPJn8YDknkxb>8Ya;1V1?E;m-2FBz z_m$&cInj+1T{?jtG50@TV`Md@c%I+V_acvsFo7P&di~?}oBm7bU-CK2>l{f^RwV0) zJxp?3Ma;2kAxsj)O$Muo@7Pj2uoSVISe(u&^PEVR$XR*2!g11LZC!Q{_h=`bZ|$`F zVRd>l z&iOuFrFkCntt)icX><=yTF0|lr!(8=b`N^t&sO(n_n;k?7v|>Y=1m+3K}+QHU2oBU Fat}~Ov-|)6 literal 0 HcmV?d00001