diff --git a/CHANGELOG.md b/CHANGELOG.md index 8af191153e4..807c5d72bcf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ - PR #6652 Add support for struct columns in concatenate - PR #6675 Add DecimalDtype to cuDF - PR #6739 Add Java bindings for is_timestamp +- PR #6808 Add support for reading decimal32 and decimal64 from parquet - PR #6781 Add serial murmur3 hashing - PR #6811 First class support for unbounded window function bounds - PR #6768 Add support for scatter() on list columns diff --git a/cpp/include/cudf/fixed_point/fixed_point.hpp b/cpp/include/cudf/fixed_point/fixed_point.hpp index 4d33107417a..abf7e3bcf90 100644 --- a/cpp/include/cudf/fixed_point/fixed_point.hpp +++ b/cpp/include/cudf/fixed_point/fixed_point.hpp @@ -515,6 +515,19 @@ class fixed_point { Rep const value = detail::shift(_value, scale_type{scale - _scale}); return fixed_point{scaled_integer{value, scale}}; } + + /** + * @brief Returns a string representation of the fixed_point value. + */ + explicit operator std::string() const + { + int const n = std::pow(10, -_scale); + int const f = _value % n; + auto const num_zeros = std::max(0, (-_scale - static_cast(std::to_string(f).size()))); + auto const zeros = num_zeros <= 0 ? std::string("") : std::string(num_zeros, '0'); + return std::to_string(_value / n) + std::string(".") + zeros + + std::to_string(std::abs(_value) % n); + } }; // namespace numeric /** @brief Function that converts Rep to `std::string` diff --git a/cpp/include/cudf/io/parquet.hpp b/cpp/include/cudf/io/parquet.hpp index f66b1d2f4c4..6fd2d65dee2 100644 --- a/cpp/include/cudf/io/parquet.hpp +++ b/cpp/include/cudf/io/parquet.hpp @@ -64,6 +64,10 @@ class parquet_reader_options { // Cast timestamp columns to a specific type data_type _timestamp_type{type_id::EMPTY}; + // force decimal reading to error if resorting to + // doubles for storage of types unsupported by cudf + bool _strict_decimal_types = false; + /** * @brief Constructor from source info. * @@ -130,6 +134,12 @@ class parquet_reader_options { */ data_type get_timestamp_type() const { return _timestamp_type; } + /** + * @brief Returns true if strict decimal types is set, which errors if reading + * a decimal type that is unsupported. + */ + bool is_enabled_strict_decimal_types() const { return _strict_decimal_types; } + /** * @brief Sets names of the columns to be read. * @@ -199,6 +209,14 @@ class parquet_reader_options { * @param type The timestamp data_type to which all timestamp columns need to be cast. */ void set_timestamp_type(data_type type) { _timestamp_type = type; } + + /** + * @brief Enables/disables strict decimal type checking. + * + * @param val If true, cudf will error if reading a decimal type that is unsupported. If false, + * cudf will convert unsupported types to double. + */ + void set_strict_decimal_types(bool val) { _strict_decimal_types = val; } }; class parquet_reader_options_builder { @@ -303,6 +321,18 @@ class parquet_reader_options_builder { return *this; } + /** + * @brief Sets to enable/disable error with unsupported decimal types. + * + * @param val Boolean value whether to error with unsupported decimal types. + * @return this for chaining. + */ + parquet_reader_options_builder& use_strict_decimal_types(bool val) + { + options._strict_decimal_types = val; + return *this; + } + /** * @brief move parquet_reader_options member once it's built. */ diff --git a/cpp/include/cudf_test/column_wrapper.hpp b/cpp/include/cudf_test/column_wrapper.hpp index a5f88f7d3e5..86059c5622b 100644 --- a/cpp/include/cudf_test/column_wrapper.hpp +++ b/cpp/include/cudf_test/column_wrapper.hpp @@ -527,6 +527,55 @@ class fixed_point_column_wrapper : public detail::column_wrapper { : fixed_point_column_wrapper(std::cbegin(values), std::cend(values), scale) { } + + /** + * @brief Construct a nullable column of the fixed-point elements from a range. + * + * Constructs a nullable column of the fixed-point elements in the range `[begin,end)` using the + * range `[v, v + distance(begin,end))` interpreted as Booleans to indicate the validity of each + * element. + * + * If `v[i] == true`, element `i` is valid, else it is null. + * + * Example: + * @code{.cpp} + * // Creates a nullable column of DECIMAL32 elements with 5 elements: {null, 100, null, 300, + * null} + * auto elements = make_counting_transform_iterator(0, [](auto i){ return i; }); + * auto validity = make_counting_transform_iterator(0, [](auto i){ return i%2; }); + * fixed_point_column_wrapper w(elements, elements + 5, validity, 2); + * @endcode + * + * Note: similar to `std::vector`, this "range" constructor should be used + * with parentheses `()` and not braces `{}`. The latter should only + * be used for the `initializer_list` constructors + * + * @param begin The beginning of the sequence of elements + * @param end The end of the sequence of elements + * @param v The beginning of the sequence of validity indicators + * @param scale The scale of the elements in the column + */ + template + fixed_point_column_wrapper(FixedPointRepIterator begin, + FixedPointRepIterator end, + ValidityIterator v, + numeric::scale_type scale) + : column_wrapper{} + { + CUDF_EXPECTS(numeric::is_supported_representation_type(), "not valid representation type"); + + auto const size = cudf::distance(begin, end); + auto const elements = thrust::host_vector(begin, end); + auto const is_decimal32 = std::is_same::value; + auto const id = is_decimal32 ? type_id::DECIMAL32 : type_id::DECIMAL64; + auto const data_type = cudf::data_type{id, static_cast(scale)}; + + wrapped.reset(new cudf::column{data_type, + size, + rmm::device_buffer{elements.data(), size * sizeof(Rep)}, + detail::make_null_mask(v, v + size), + cudf::UNKNOWN_NULL_COUNT}); + } }; /** diff --git a/cpp/src/io/parquet/page_data.cu b/cpp/src/io/parquet/page_data.cu index 9b40c431fdb..02d8e75e028 100644 --- a/cpp/src/io/parquet/page_data.cu +++ b/cpp/src/io/parquet/page_data.cu @@ -745,10 +745,10 @@ static const __device__ __constant__ double kPow10[40] = { * @param[in] dst Pointer to row output data * @param[in] dtype Stored data type */ -inline __device__ void gpuOutputDecimal(volatile page_state_s *s, - int src_pos, - double *dst, - int dtype) +inline __device__ void gpuOutputDecimalAsFloat(volatile page_state_s *s, + int src_pos, + double *dst, + int dtype) { const uint8_t *dict; uint32_t dict_pos, dict_size = s->dict_size, dtype_len_in; @@ -983,15 +983,16 @@ static __device__ bool setupLocalPageInfo(page_state_s *const s, break; } // Special check for downconversions - s->dtype_len_in = s->dtype_len; - if (s->col.converted_type == DECIMAL) { - s->dtype_len = 8; // Convert DECIMAL to 64-bit float - } else if ((s->col.data_type & 7) == INT32) { + s->dtype_len_in = s->dtype_len; + uint16_t const data_type = s->col.data_type & 7; + if (s->col.converted_type == DECIMAL && data_type != INT32 && data_type != INT64) { + s->dtype_len = 8; // FLOAT output + } else if (data_type == INT32) { if (dtype_len_out == 1) s->dtype_len = 1; // INT8 output if (dtype_len_out == 2) s->dtype_len = 2; // INT16 output - } else if ((s->col.data_type & 7) == BYTE_ARRAY && dtype_len_out == 4) { + } else if (data_type == BYTE_ARRAY && dtype_len_out == 4) { s->dtype_len = 4; // HASH32 output - } else if ((s->col.data_type & 7) == INT96) { + } else if (data_type == INT96) { s->dtype_len = 8; // Convert to 64-bit timestamp } @@ -1685,9 +1686,13 @@ extern "C" __global__ void __launch_bounds__(block_size) gpuOutputString(s, src_pos, dst); else if (dtype == BOOLEAN) gpuOutputBoolean(s, src_pos, static_cast(dst)); - else if (s->col.converted_type == DECIMAL) - gpuOutputDecimal(s, src_pos, static_cast(dst), dtype); - else if (dtype == INT96) + else if (s->col.converted_type == DECIMAL) { + switch (dtype) { + case INT32: gpuOutputFast(s, src_pos, static_cast(dst)); break; + case INT64: gpuOutputFast(s, src_pos, static_cast(dst)); break; + default: gpuOutputDecimalAsFloat(s, src_pos, static_cast(dst), dtype); break; + } + } else if (dtype == INT96) gpuOutputInt96Timestamp(s, src_pos, static_cast(dst)); else if (dtype_len == 8) { if (s->ts_scale) diff --git a/cpp/src/io/parquet/reader_impl.cu b/cpp/src/io/parquet/reader_impl.cu index 0746ba848c1..988674789c1 100644 --- a/cpp/src/io/parquet/reader_impl.cu +++ b/cpp/src/io/parquet/reader_impl.cu @@ -98,7 +98,8 @@ parquet::ConvertedType logical_type_to_converted_type(parquet::LogicalType const */ type_id to_type_id(SchemaElement const &schema, bool strings_to_categorical, - type_id timestamp_type_id) + type_id timestamp_type_id, + bool strict_decimal_types) { parquet::Type physical = schema.type; parquet::ConvertedType converted_type = schema.converted_type; @@ -132,7 +133,12 @@ type_id to_type_id(SchemaElement const &schema, return (timestamp_type_id != type_id::EMPTY) ? timestamp_type_id : type_id::TIMESTAMP_MILLISECONDS; case parquet::DECIMAL: - if (decimal_scale != 0 || (physical != parquet::INT32 && physical != parquet::INT64)) { + if (physical == parquet::INT32) + return type_id::DECIMAL32; + else if (physical == parquet::INT64) + return type_id::DECIMAL64; + else { + CUDF_EXPECTS(strict_decimal_types == false, "Unsupported decimal type read!"); return type_id::FLOAT64; } break; @@ -215,8 +221,9 @@ std::tuple conversion_info(type_id column_type_id, } int8_t converted_type = converted; - if (converted_type == parquet::DECIMAL && column_type_id != type_id::FLOAT64) { - converted_type = parquet::UNKNOWN; // Not converting to float64 + if (converted_type == parquet::DECIMAL && column_type_id != type_id::FLOAT64 && + column_type_id != type_id::DECIMAL32 && column_type_id != type_id::DECIMAL64) { + converted_type = parquet::UNKNOWN; // Not converting to float64 or decimal } return std::make_tuple(type_width, clock_rate, converted_type); } @@ -443,7 +450,7 @@ class aggregate_metadata { R"(\])" // Match closing square brackets }; std::smatch sm; - if (std::regex_search(it->second, sm, index_columns_expr)) { return std::move(sm[1].str()); } + if (std::regex_search(it->second, sm, index_columns_expr)) { return sm[1].str(); } } return ""; } @@ -463,7 +470,7 @@ class aggregate_metadata { if (sm.size() == 2) { // 2 = whole match, first item if (std::find(names.begin(), names.end(), sm[1].str()) == names.end()) { std::regex esc_quote{R"(\\")"}; - names.emplace_back(std::move(std::regex_replace(sm[1].str(), esc_quote, R"(")"))); + names.emplace_back(std::regex_replace(sm[1].str(), esc_quote, R"(")")); } } str = sm.suffix(); @@ -549,6 +556,7 @@ class aggregate_metadata { * reproduce the linear list of output columns that correspond to an input column. * @param[in] strings_to_categorical Type conversion parameter * @param[in] timestamp_type_id Type conversion parameter + * @param[in] strict_decimal_types True if it is an error to load an unsupported decimal type * */ void build_column_info(int &schema_idx, @@ -556,7 +564,8 @@ class aggregate_metadata { std::vector &output_columns, std::deque &nesting, bool strings_to_categorical, - type_id timestamp_type_id) const + type_id timestamp_type_id, + bool strict_decimal_types) const { int start_schema_idx = schema_idx; auto const &schema = get_schema(schema_idx); @@ -571,16 +580,19 @@ class aggregate_metadata { output_columns, nesting, strings_to_categorical, - timestamp_type_id); + timestamp_type_id, + strict_decimal_types); return; } // if we're at the root, this is a new output column - int index = (int)output_columns.size(); nesting.push_back(static_cast(output_columns.size())); - output_columns.emplace_back( - data_type{to_type_id(schema, strings_to_categorical, timestamp_type_id)}, - schema.repetition_type == OPTIONAL ? true : false); + auto const col_type = + to_type_id(schema, strings_to_categorical, timestamp_type_id, strict_decimal_types); + auto const dtype = col_type == type_id::DECIMAL32 || col_type == type_id::DECIMAL64 + ? data_type{col_type, numeric::scale_type{-schema.decimal_scale}} + : data_type{col_type}; + output_columns.emplace_back(dtype, schema.repetition_type == OPTIONAL ? true : false); column_buffer &output_col = output_columns.back(); output_col.name = schema.name; @@ -591,7 +603,8 @@ class aggregate_metadata { output_col.children, nesting, strings_to_categorical, - timestamp_type_id); + timestamp_type_id, + strict_decimal_types); } // if I have no children, we're at a leaf and I'm an input column (that is, one with actual @@ -619,7 +632,8 @@ class aggregate_metadata { auto select_columns(std::vector const &use_names, bool include_index, bool strings_to_categorical, - type_id timestamp_type_id) const + type_id timestamp_type_id, + bool strict_decimal_types) const { auto const &pfm = per_file_metadata[0]; @@ -670,7 +684,8 @@ class aggregate_metadata { output_columns, nesting, strings_to_categorical, - timestamp_type_id); + timestamp_type_id, + strict_decimal_types); } return std::make_tuple( @@ -1343,6 +1358,8 @@ reader::impl::impl(std::vector> &&sources, _timestamp_type = options.get_timestamp_type(); } + _strict_decimal_types = options.is_enabled_strict_decimal_types(); + // Strings may be returned as either string or categorical columns _strings_to_categorical = options.is_enabled_convert_strings_to_categories(); @@ -1351,7 +1368,8 @@ reader::impl::impl(std::vector> &&sources, _metadata->select_columns(options.get_columns(), options.is_enabled_use_pandas_metadata(), _strings_to_categorical, - _timestamp_type.id()); + _timestamp_type.id(), + _strict_decimal_types); } table_with_metadata reader::impl::read(size_type skip_rows, @@ -1418,12 +1436,12 @@ table_with_metadata reader::impl::read(size_type skip_rows, int32_t clock_rate; int8_t converted_type; - std::tie(type_width, clock_rate, converted_type) = - conversion_info(to_type_id(schema, _strings_to_categorical, _timestamp_type.id()), - _timestamp_type.id(), - schema.type, - schema.converted_type, - schema.type_length); + std::tie(type_width, clock_rate, converted_type) = conversion_info( + to_type_id(schema, _strings_to_categorical, _timestamp_type.id(), _strict_decimal_types), + _timestamp_type.id(), + schema.type, + schema.converted_type, + schema.type_length); column_chunk_offsets[chunks.size()] = (col_meta.dictionary_page_offset != 0) diff --git a/cpp/src/io/parquet/reader_impl.hpp b/cpp/src/io/parquet/reader_impl.hpp index f6df8f9e460..137fca03bfd 100644 --- a/cpp/src/io/parquet/reader_impl.hpp +++ b/cpp/src/io/parquet/reader_impl.hpp @@ -210,6 +210,7 @@ class reader::impl { bool _strings_to_categorical = false; data_type _timestamp_type{type_id::EMPTY}; + bool _strict_decimal_types = false; }; } // namespace parquet diff --git a/cpp/tests/io/parquet_test.cpp b/cpp/tests/io/parquet_test.cpp index 856af7e3f97..af8dfcce9d3 100644 --- a/cpp/tests/io/parquet_test.cpp +++ b/cpp/tests/io/parquet_test.cpp @@ -1725,4 +1725,212 @@ TEST_F(ParquetReaderTest, ReorderedColumns) } } +TEST_F(ParquetReaderTest, DecimalRead) +{ + /* We could add a dataset to include this file, but we don't want tests in cudf to have data. This + test is a temporary test until python gains the ability to write decimal, so we're embedding + a parquet file directly into the code here to prevent issues with finding the file */ + const unsigned char decimals_parquet[] = { + 0x50, 0x41, 0x52, 0x31, 0x15, 0x00, 0x15, 0xb0, 0x03, 0x15, 0xb8, 0x03, 0x2c, 0x15, 0x6a, 0x15, + 0x00, 0x15, 0x06, 0x15, 0x08, 0x1c, 0x36, 0x02, 0x28, 0x04, 0x7f, 0x96, 0x98, 0x00, 0x18, 0x04, + 0x81, 0x69, 0x67, 0xff, 0x00, 0x00, 0x00, 0xd8, 0x01, 0xf0, 0xd7, 0x04, 0x00, 0x00, 0x00, 0x64, + 0x01, 0x03, 0x06, 0x68, 0x12, 0xdc, 0xff, 0xbd, 0x18, 0xfd, 0xff, 0x64, 0x13, 0x80, 0x00, 0xb3, + 0x5d, 0x62, 0x00, 0x90, 0x35, 0xa9, 0xff, 0xa2, 0xde, 0xe3, 0xff, 0xe9, 0xbf, 0x96, 0xff, 0x1f, + 0x8a, 0x98, 0xff, 0xb1, 0x50, 0x34, 0x00, 0x88, 0x24, 0x59, 0x00, 0x2a, 0x33, 0xbe, 0xff, 0xd5, + 0x16, 0xbc, 0xff, 0x13, 0x50, 0x8d, 0xff, 0xcb, 0x63, 0x2d, 0x00, 0x80, 0x8f, 0xbe, 0xff, 0x82, + 0x40, 0x10, 0x00, 0x84, 0x68, 0x70, 0xff, 0x9b, 0x69, 0x78, 0x00, 0x14, 0x6c, 0x10, 0x00, 0x50, + 0xd9, 0xe1, 0xff, 0xaa, 0xcd, 0x6a, 0x00, 0xcf, 0xb1, 0x28, 0x00, 0x77, 0x57, 0x8d, 0x00, 0xee, + 0x05, 0x79, 0x00, 0xf0, 0x15, 0xeb, 0xff, 0x02, 0xe2, 0x06, 0x00, 0x87, 0x43, 0x86, 0x00, 0xf8, + 0x2d, 0x2e, 0x00, 0xee, 0x2e, 0x98, 0xff, 0x39, 0xcb, 0x4d, 0x00, 0x1e, 0x6b, 0xea, 0xff, 0x80, + 0x8e, 0x6c, 0xff, 0x97, 0x25, 0x26, 0x00, 0x4d, 0x0d, 0x0a, 0x00, 0xca, 0x64, 0x7f, 0x00, 0xf4, + 0xbe, 0xa1, 0xff, 0xe2, 0x12, 0x6c, 0xff, 0xbd, 0x77, 0xae, 0xff, 0xf9, 0x4b, 0x36, 0x00, 0xb0, + 0xe3, 0x79, 0xff, 0xa2, 0x2a, 0x29, 0x00, 0xcd, 0x06, 0xbc, 0xff, 0x2d, 0xa3, 0x7e, 0x00, 0xa9, + 0x08, 0xa1, 0xff, 0xbf, 0x81, 0xd0, 0xff, 0x4f, 0x03, 0x73, 0x00, 0xb0, 0x99, 0x0c, 0x00, 0xbd, + 0x6f, 0xf8, 0xff, 0x6b, 0x02, 0x05, 0x00, 0xc1, 0xe1, 0xba, 0xff, 0x81, 0x69, 0x67, 0xff, 0x7f, + 0x96, 0x98, 0x00, 0x15, 0x00, 0x15, 0xd0, 0x06, 0x15, 0xda, 0x06, 0x2c, 0x15, 0x6a, 0x15, 0x00, + 0x15, 0x06, 0x15, 0x08, 0x1c, 0x36, 0x02, 0x28, 0x08, 0xff, 0x3f, 0x7a, 0x10, 0xf3, 0x5a, 0x00, + 0x00, 0x18, 0x08, 0x01, 0xc0, 0x85, 0xef, 0x0c, 0xa5, 0xff, 0xff, 0x00, 0x00, 0x00, 0xa8, 0x03, + 0xf4, 0xa7, 0x01, 0x04, 0x00, 0x00, 0x00, 0x64, 0x01, 0x03, 0x06, 0x55, 0x6f, 0xc5, 0xe4, 0x9f, + 0x1a, 0x00, 0x00, 0x47, 0x89, 0x0a, 0xe8, 0x58, 0xf0, 0xff, 0xff, 0x63, 0xee, 0x21, 0xdd, 0xdd, + 0xca, 0xff, 0xff, 0xbe, 0x6f, 0x3b, 0xaa, 0xe9, 0x3d, 0x00, 0x00, 0xd6, 0x91, 0x2a, 0xb7, 0x08, + 0x02, 0x00, 0x00, 0x75, 0x45, 0x2c, 0xd7, 0x76, 0x0c, 0x00, 0x00, 0x54, 0x49, 0x92, 0x44, 0x9c, + 0xbf, 0xff, 0xff, 0x41, 0xa9, 0x6d, 0xec, 0x7a, 0xd0, 0xff, 0xff, 0x27, 0xa0, 0x23, 0x41, 0x44, + 0xc1, 0xff, 0xff, 0x18, 0xd4, 0xe1, 0x30, 0xd3, 0xe0, 0xff, 0xff, 0x59, 0xac, 0x14, 0xf4, 0xec, + 0x58, 0x00, 0x00, 0x2c, 0x17, 0x29, 0x57, 0x44, 0x13, 0x00, 0x00, 0xa2, 0x0d, 0x4a, 0xcc, 0x63, + 0xff, 0xff, 0xff, 0x81, 0x33, 0xbc, 0xda, 0xd5, 0xda, 0xff, 0xff, 0x4c, 0x05, 0xf4, 0x78, 0x19, + 0xea, 0xff, 0xff, 0x06, 0x71, 0x25, 0xde, 0x5a, 0xaf, 0xff, 0xff, 0x95, 0x32, 0x5f, 0x76, 0x98, + 0xb3, 0xff, 0xff, 0xf1, 0x34, 0x3c, 0xbf, 0xa8, 0xbe, 0xff, 0xff, 0x27, 0x73, 0x40, 0x0c, 0x7d, + 0xcd, 0xff, 0xff, 0x68, 0xa9, 0xc2, 0xe9, 0x2c, 0x03, 0x00, 0x00, 0x3f, 0x79, 0xd9, 0x04, 0x8c, + 0xe5, 0xff, 0xff, 0x91, 0xb4, 0x9b, 0xe3, 0x8f, 0x21, 0x00, 0x00, 0xb8, 0x20, 0xc8, 0xc2, 0x4d, + 0xa6, 0xff, 0xff, 0x47, 0xfa, 0xde, 0x36, 0x4a, 0xf3, 0xff, 0xff, 0x72, 0x80, 0x94, 0x59, 0xdd, + 0x4e, 0x00, 0x00, 0x29, 0xe4, 0xd6, 0x43, 0xb0, 0xf0, 0xff, 0xff, 0x68, 0x36, 0xbc, 0x2d, 0xd1, + 0xa9, 0xff, 0xff, 0xbc, 0xe4, 0xbe, 0xd7, 0xed, 0x1b, 0x00, 0x00, 0x02, 0x8b, 0xcb, 0xd7, 0xed, + 0x47, 0x00, 0x00, 0x3c, 0x06, 0xe4, 0xda, 0xc7, 0x47, 0x00, 0x00, 0xf3, 0x39, 0x55, 0x28, 0x97, + 0xba, 0xff, 0xff, 0x07, 0x79, 0x38, 0x4e, 0xe0, 0x21, 0x00, 0x00, 0xde, 0xed, 0x1c, 0x23, 0x09, + 0x49, 0x00, 0x00, 0x49, 0x46, 0x49, 0x5d, 0x8f, 0x34, 0x00, 0x00, 0x38, 0x18, 0x50, 0xf6, 0xa1, + 0x11, 0x00, 0x00, 0xdf, 0xb8, 0x19, 0x14, 0xd1, 0xe1, 0xff, 0xff, 0x2c, 0x56, 0x72, 0x93, 0x64, + 0x3f, 0x00, 0x00, 0x1c, 0xe0, 0xbe, 0x87, 0x7d, 0xf9, 0xff, 0xff, 0x73, 0x0e, 0x3c, 0x01, 0x91, + 0xf9, 0xff, 0xff, 0xb2, 0x37, 0x85, 0x81, 0x5f, 0x54, 0x00, 0x00, 0x58, 0x44, 0xb0, 0x1a, 0xac, + 0xbb, 0xff, 0xff, 0x36, 0xbf, 0xbe, 0x5e, 0x22, 0xff, 0xff, 0xff, 0x06, 0x20, 0xa0, 0x23, 0x0d, + 0x3b, 0x00, 0x00, 0x19, 0xc6, 0x49, 0x0a, 0x00, 0xcf, 0xff, 0xff, 0x4f, 0xcd, 0xc6, 0x95, 0x4b, + 0xf1, 0xff, 0xff, 0xa3, 0x59, 0xaf, 0x65, 0xec, 0xe9, 0xff, 0xff, 0x58, 0xef, 0x05, 0x50, 0x63, + 0xe4, 0xff, 0xff, 0xc7, 0x6a, 0x9e, 0xf1, 0x69, 0x20, 0x00, 0x00, 0xd1, 0xb3, 0xc9, 0x14, 0xb2, + 0x29, 0x00, 0x00, 0x1d, 0x48, 0x16, 0x70, 0xf0, 0x40, 0x00, 0x00, 0x01, 0xc0, 0x85, 0xef, 0x0c, + 0xa5, 0xff, 0xff, 0xff, 0x3f, 0x7a, 0x10, 0xf3, 0x5a, 0x00, 0x00, 0x15, 0x00, 0x15, 0x90, 0x0d, + 0x15, 0x9a, 0x0d, 0x2c, 0x15, 0x6a, 0x15, 0x00, 0x15, 0x06, 0x15, 0x08, 0x1c, 0x36, 0x02, 0x28, + 0x10, 0x4b, 0x3b, 0x4c, 0xa8, 0x5a, 0x86, 0xc4, 0x7a, 0x09, 0x8a, 0x22, 0x3f, 0xff, 0xff, 0xff, + 0xff, 0x18, 0x10, 0xb4, 0xc4, 0xb3, 0x57, 0xa5, 0x79, 0x3b, 0x85, 0xf6, 0x75, 0xdd, 0xc0, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc8, 0x06, 0xf4, 0x47, 0x03, 0x04, 0x00, 0x00, 0x00, 0x64, + 0x01, 0x03, 0x06, 0x05, 0x49, 0xf7, 0xfc, 0x89, 0x3d, 0x3e, 0x20, 0x07, 0x72, 0x3e, 0xa1, 0x66, + 0x81, 0x67, 0x80, 0x23, 0x78, 0x06, 0x68, 0x0e, 0x78, 0xf5, 0x08, 0xed, 0x20, 0xcd, 0x0e, 0x7f, + 0x9c, 0x70, 0xa0, 0xb9, 0x16, 0x44, 0xb2, 0x41, 0x62, 0xba, 0x82, 0xad, 0xe1, 0x12, 0x9b, 0xa6, + 0x53, 0x8d, 0x20, 0x27, 0xd5, 0x84, 0x63, 0xb8, 0x07, 0x4b, 0x5b, 0xa4, 0x1c, 0xa4, 0x1c, 0x17, + 0xbf, 0x4b, 0x00, 0x24, 0x04, 0x56, 0xa8, 0x52, 0xaf, 0x33, 0xf7, 0xad, 0x7c, 0xc8, 0x83, 0x25, + 0x13, 0xaf, 0x80, 0x25, 0x6f, 0xbd, 0xd1, 0x15, 0x69, 0x64, 0x20, 0x7b, 0xd7, 0x33, 0xba, 0x66, + 0x29, 0x8a, 0x00, 0xda, 0x42, 0x07, 0x2c, 0x6c, 0x39, 0x76, 0x9f, 0xdc, 0x17, 0xad, 0xb6, 0x58, + 0xdf, 0x5f, 0x00, 0x18, 0x3a, 0xae, 0x1c, 0xd6, 0x5f, 0x9d, 0x78, 0x8d, 0x73, 0xdd, 0x3e, 0xd6, + 0x18, 0x33, 0x40, 0xe4, 0x36, 0xde, 0xb0, 0xb7, 0x33, 0x2a, 0x6b, 0x08, 0x03, 0x6c, 0x6d, 0x8f, + 0x13, 0x93, 0xd0, 0xd7, 0x87, 0x62, 0x63, 0x53, 0xfb, 0xd8, 0xbb, 0xc9, 0x54, 0x90, 0xd6, 0xa9, + 0x8f, 0xc8, 0x60, 0xbd, 0xec, 0x75, 0x23, 0x9a, 0x21, 0xec, 0xe4, 0x86, 0x43, 0xd7, 0xc1, 0x88, + 0xdc, 0x82, 0x00, 0x32, 0x79, 0xc9, 0x2b, 0x70, 0x85, 0xb7, 0x25, 0xa1, 0xcc, 0x7d, 0x0b, 0x29, + 0x03, 0xea, 0x80, 0xff, 0x9b, 0xf3, 0x24, 0x7f, 0xd1, 0xff, 0xf0, 0x22, 0x65, 0x85, 0x99, 0x17, + 0x63, 0xc2, 0xc0, 0xb7, 0x62, 0x05, 0xda, 0x7a, 0xa0, 0xc3, 0x2a, 0x6f, 0x1f, 0xee, 0x1f, 0x31, + 0xa8, 0x42, 0x80, 0xe4, 0xb7, 0x6c, 0xf6, 0xac, 0x47, 0xb0, 0x17, 0x69, 0xcb, 0xff, 0x66, 0x8a, + 0xd6, 0x25, 0x00, 0xf3, 0xcf, 0x0a, 0xaf, 0xf8, 0x92, 0x8a, 0xa0, 0xdf, 0x71, 0x13, 0x8d, 0x9d, + 0xff, 0x7e, 0xe0, 0x0a, 0x52, 0xf1, 0x97, 0x01, 0xa9, 0x73, 0x27, 0xfd, 0x63, 0x58, 0x00, 0x32, + 0xa6, 0xf6, 0x78, 0xb8, 0xe4, 0xfd, 0x20, 0x7c, 0x90, 0xee, 0xad, 0x8c, 0xc9, 0x71, 0x35, 0x66, + 0x71, 0x3c, 0xe0, 0xe4, 0x0b, 0xbb, 0xa0, 0x50, 0xe9, 0xf2, 0x81, 0x1d, 0x3a, 0x95, 0x94, 0x00, + 0xd5, 0x49, 0x00, 0x07, 0xdf, 0x21, 0x53, 0x36, 0x8d, 0x9e, 0xd9, 0xa5, 0x52, 0x4d, 0x0d, 0x29, + 0x74, 0xf0, 0x40, 0xbd, 0xda, 0x63, 0x4e, 0xdd, 0x91, 0x8e, 0xa6, 0xa7, 0xf6, 0x78, 0x58, 0x3b, + 0x0a, 0x5c, 0x60, 0x3c, 0x15, 0x34, 0xf8, 0x2c, 0x21, 0xe3, 0x56, 0x1b, 0x9e, 0xd9, 0x56, 0xd3, + 0x13, 0x2e, 0x80, 0x2c, 0x36, 0xda, 0x1d, 0xc8, 0xfb, 0x52, 0xee, 0x17, 0xb3, 0x2b, 0xf3, 0xd2, + 0xeb, 0x29, 0xa0, 0x37, 0xa0, 0x12, 0xce, 0x1c, 0x50, 0x6a, 0xf4, 0x11, 0xcd, 0x96, 0x88, 0x3f, + 0x43, 0x78, 0xc0, 0x2c, 0x53, 0x6c, 0xa6, 0xdf, 0xb9, 0x9e, 0x93, 0xd4, 0x1e, 0xa9, 0x7f, 0x67, + 0xa6, 0xc1, 0x80, 0x46, 0x0f, 0x63, 0x7d, 0x15, 0xf2, 0x4c, 0xc5, 0xda, 0x11, 0x9a, 0x20, 0x67, + 0x27, 0xe8, 0x00, 0xec, 0x03, 0x1d, 0x15, 0xa7, 0x92, 0xb3, 0x1f, 0xda, 0x20, 0x92, 0xd8, 0x00, + 0xfb, 0x06, 0x80, 0xeb, 0x4b, 0x0c, 0xc1, 0x1f, 0x49, 0x40, 0x06, 0x8d, 0x8a, 0xf8, 0x34, 0xb1, + 0x0c, 0x1d, 0x20, 0xd0, 0x47, 0xe5, 0xb1, 0x7e, 0xf7, 0xe4, 0xb4, 0x7e, 0x9c, 0x84, 0x18, 0x61, + 0x32, 0x4f, 0xc0, 0xc2, 0xb2, 0xcc, 0x63, 0xf6, 0xe1, 0x16, 0xd6, 0xd9, 0x4b, 0x74, 0x13, 0x01, + 0xa1, 0xe2, 0x00, 0xb7, 0x9e, 0xc1, 0x3a, 0xc5, 0xaf, 0xe8, 0x54, 0x07, 0x2a, 0x20, 0xfd, 0x2c, + 0x6f, 0xb9, 0x80, 0x18, 0x92, 0x87, 0xa0, 0x81, 0x24, 0x60, 0x47, 0x17, 0x4f, 0xbc, 0xbe, 0xf5, + 0x03, 0x69, 0x80, 0xe3, 0x10, 0x54, 0xd6, 0x68, 0x7d, 0x75, 0xd3, 0x0a, 0x45, 0x38, 0x9e, 0xa9, + 0xfd, 0x05, 0x40, 0xd2, 0x1e, 0x6f, 0x5c, 0x30, 0x10, 0xfe, 0x9b, 0x9f, 0x6d, 0xc0, 0x9d, 0x6c, + 0x17, 0x7d, 0x00, 0x09, 0xb6, 0x8a, 0x31, 0x8e, 0x1b, 0x6b, 0x84, 0x1e, 0x79, 0xce, 0x10, 0x55, + 0x59, 0x6a, 0x40, 0x16, 0xdc, 0x9a, 0xcf, 0x4d, 0xb0, 0x8f, 0xac, 0xe3, 0x8d, 0xee, 0xd2, 0xef, + 0x01, 0x8c, 0xe0, 0x2b, 0x24, 0xe5, 0xb4, 0xe1, 0x86, 0x72, 0x00, 0x30, 0x07, 0xce, 0x02, 0x23, + 0x41, 0x33, 0x40, 0xf0, 0x9b, 0xc2, 0x2d, 0x30, 0xec, 0x3b, 0x17, 0xb2, 0x8f, 0x64, 0x7d, 0xcd, + 0x70, 0x9e, 0x80, 0x22, 0xb5, 0xdf, 0x6d, 0x2a, 0x43, 0xd4, 0x2b, 0x5a, 0xf6, 0x96, 0xa6, 0xea, + 0x91, 0x62, 0x80, 0x39, 0xf2, 0x5a, 0x8e, 0xc0, 0xb9, 0x29, 0x99, 0x17, 0xe7, 0x35, 0x2c, 0xf6, + 0x4d, 0x18, 0x00, 0x48, 0x10, 0x85, 0xb4, 0x3f, 0x89, 0x60, 0x49, 0x6e, 0xf0, 0xcd, 0x9d, 0x92, + 0xeb, 0x96, 0x80, 0xcf, 0xf9, 0xf1, 0x46, 0x1d, 0xc0, 0x49, 0xb3, 0x36, 0x2e, 0x24, 0xc8, 0xdb, + 0x41, 0x72, 0x20, 0xf5, 0xde, 0x5c, 0xf9, 0x4a, 0x6e, 0xa0, 0x0b, 0x13, 0xfc, 0x2d, 0x17, 0x07, + 0x16, 0x5e, 0x00, 0x3c, 0x54, 0x41, 0x0e, 0xa2, 0x0d, 0xf3, 0x48, 0x12, 0x2e, 0x7c, 0xab, 0x3c, + 0x59, 0x1c, 0x40, 0xca, 0xb0, 0x71, 0xc7, 0x29, 0xf0, 0xbb, 0x9f, 0xf4, 0x3f, 0x25, 0x49, 0xad, + 0xc2, 0x8f, 0x80, 0x04, 0x38, 0x6d, 0x35, 0x02, 0xca, 0xe6, 0x02, 0x83, 0x89, 0x4e, 0x74, 0xdb, + 0x08, 0x5a, 0x80, 0x13, 0x99, 0xd4, 0x26, 0xc1, 0x27, 0xce, 0xb0, 0x98, 0x99, 0xca, 0xf6, 0x3e, + 0x50, 0x49, 0xd0, 0xbf, 0xcb, 0x6f, 0xbe, 0x5b, 0x92, 0x63, 0xde, 0x94, 0xd3, 0x8f, 0x07, 0x06, + 0x0f, 0x2b, 0x80, 0x36, 0xf1, 0x77, 0xf6, 0x29, 0x33, 0x13, 0xa9, 0x4a, 0x55, 0x3d, 0x6c, 0xca, + 0xdb, 0x4e, 0x40, 0xc4, 0x95, 0x54, 0xf4, 0xe2, 0x8c, 0x1b, 0xa0, 0xfe, 0x30, 0x50, 0x9d, 0x62, + 0xbc, 0x5c, 0x00, 0xb4, 0xc4, 0xb3, 0x57, 0xa5, 0x79, 0x3b, 0x85, 0xf6, 0x75, 0xdd, 0xc0, 0x00, + 0x00, 0x00, 0x01, 0x4b, 0x3b, 0x4c, 0xa8, 0x5a, 0x86, 0xc4, 0x7a, 0x09, 0x8a, 0x22, 0x3f, 0xff, + 0xff, 0xff, 0xff, 0x15, 0x02, 0x19, 0x4c, 0x48, 0x0c, 0x73, 0x70, 0x61, 0x72, 0x6b, 0x5f, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x15, 0x06, 0x00, 0x15, 0x02, 0x25, 0x02, 0x18, 0x06, 0x64, 0x65, + 0x63, 0x37, 0x70, 0x34, 0x25, 0x0a, 0x15, 0x08, 0x15, 0x0e, 0x00, 0x15, 0x04, 0x25, 0x02, 0x18, + 0x07, 0x64, 0x65, 0x63, 0x31, 0x34, 0x70, 0x35, 0x25, 0x0a, 0x15, 0x0a, 0x15, 0x1c, 0x00, 0x15, + 0x0e, 0x15, 0x20, 0x15, 0x02, 0x18, 0x08, 0x64, 0x65, 0x63, 0x33, 0x38, 0x70, 0x31, 0x38, 0x25, + 0x0a, 0x15, 0x24, 0x15, 0x4c, 0x00, 0x16, 0x6a, 0x19, 0x1c, 0x19, 0x3c, 0x26, 0x08, 0x1c, 0x15, + 0x02, 0x19, 0x35, 0x06, 0x08, 0x00, 0x19, 0x18, 0x06, 0x64, 0x65, 0x63, 0x37, 0x70, 0x34, 0x15, + 0x02, 0x16, 0x6a, 0x16, 0xf6, 0x03, 0x16, 0xfe, 0x03, 0x26, 0x08, 0x3c, 0x36, 0x02, 0x28, 0x04, + 0x7f, 0x96, 0x98, 0x00, 0x18, 0x04, 0x81, 0x69, 0x67, 0xff, 0x00, 0x19, 0x1c, 0x15, 0x00, 0x15, + 0x00, 0x15, 0x02, 0x00, 0x00, 0x00, 0x26, 0x86, 0x04, 0x1c, 0x15, 0x04, 0x19, 0x35, 0x06, 0x08, + 0x00, 0x19, 0x18, 0x07, 0x64, 0x65, 0x63, 0x31, 0x34, 0x70, 0x35, 0x15, 0x02, 0x16, 0x6a, 0x16, + 0xa6, 0x07, 0x16, 0xb0, 0x07, 0x26, 0x86, 0x04, 0x3c, 0x36, 0x02, 0x28, 0x08, 0xff, 0x3f, 0x7a, + 0x10, 0xf3, 0x5a, 0x00, 0x00, 0x18, 0x08, 0x01, 0xc0, 0x85, 0xef, 0x0c, 0xa5, 0xff, 0xff, 0x00, + 0x19, 0x1c, 0x15, 0x00, 0x15, 0x00, 0x15, 0x02, 0x00, 0x00, 0x00, 0x26, 0xb6, 0x0b, 0x1c, 0x15, + 0x0e, 0x19, 0x35, 0x06, 0x08, 0x00, 0x19, 0x18, 0x08, 0x64, 0x65, 0x63, 0x33, 0x38, 0x70, 0x31, + 0x38, 0x15, 0x02, 0x16, 0x6a, 0x16, 0x86, 0x0e, 0x16, 0x90, 0x0e, 0x26, 0xb6, 0x0b, 0x3c, 0x36, + 0x02, 0x28, 0x10, 0x4b, 0x3b, 0x4c, 0xa8, 0x5a, 0x86, 0xc4, 0x7a, 0x09, 0x8a, 0x22, 0x3f, 0xff, + 0xff, 0xff, 0xff, 0x18, 0x10, 0xb4, 0xc4, 0xb3, 0x57, 0xa5, 0x79, 0x3b, 0x85, 0xf6, 0x75, 0xdd, + 0xc0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x19, 0x1c, 0x15, 0x00, 0x15, 0x00, 0x15, 0x02, 0x00, 0x00, + 0x00, 0x16, 0xa2, 0x19, 0x16, 0x6a, 0x00, 0x19, 0x2c, 0x18, 0x18, 0x6f, 0x72, 0x67, 0x2e, 0x61, + 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x33, 0x2e, 0x30, 0x2e, 0x31, 0x00, 0x18, 0x29, 0x6f, 0x72, 0x67, + 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x72, 0x6b, 0x2e, 0x73, 0x71, + 0x6c, 0x2e, 0x70, 0x61, 0x72, 0x71, 0x75, 0x65, 0x74, 0x2e, 0x72, 0x6f, 0x77, 0x2e, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0xf4, 0x01, 0x7b, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, + 0x3a, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x22, 0x2c, 0x22, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x73, 0x22, 0x3a, 0x5b, 0x7b, 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x22, 0x64, 0x65, 0x63, + 0x37, 0x70, 0x34, 0x22, 0x2c, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x22, 0x64, 0x65, 0x63, + 0x69, 0x6d, 0x61, 0x6c, 0x28, 0x37, 0x2c, 0x34, 0x29, 0x22, 0x2c, 0x22, 0x6e, 0x75, 0x6c, 0x6c, + 0x61, 0x62, 0x6c, 0x65, 0x22, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x22, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x7b, 0x7d, 0x7d, 0x2c, 0x7b, 0x22, 0x6e, 0x61, 0x6d, 0x65, + 0x22, 0x3a, 0x22, 0x64, 0x65, 0x63, 0x31, 0x34, 0x70, 0x35, 0x22, 0x2c, 0x22, 0x74, 0x79, 0x70, + 0x65, 0x22, 0x3a, 0x22, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x28, 0x31, 0x34, 0x2c, 0x35, + 0x29, 0x22, 0x2c, 0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x3a, 0x74, 0x72, + 0x75, 0x65, 0x2c, 0x22, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x7b, 0x7d, + 0x7d, 0x2c, 0x7b, 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x22, 0x64, 0x65, 0x63, 0x33, 0x38, + 0x70, 0x31, 0x38, 0x22, 0x2c, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x22, 0x64, 0x65, 0x63, + 0x69, 0x6d, 0x61, 0x6c, 0x28, 0x33, 0x38, 0x2c, 0x31, 0x38, 0x29, 0x22, 0x2c, 0x22, 0x6e, 0x75, + 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x22, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x7b, 0x7d, 0x7d, 0x5d, 0x7d, 0x00, 0x18, 0x4a, + 0x70, 0x61, 0x72, 0x71, 0x75, 0x65, 0x74, 0x2d, 0x6d, 0x72, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x31, 0x2e, 0x31, 0x30, 0x2e, 0x31, 0x20, 0x28, 0x62, 0x75, 0x69, 0x6c, 0x64, + 0x20, 0x61, 0x38, 0x39, 0x64, 0x66, 0x38, 0x66, 0x39, 0x39, 0x33, 0x32, 0x62, 0x36, 0x65, 0x66, + 0x36, 0x36, 0x33, 0x33, 0x64, 0x30, 0x36, 0x30, 0x36, 0x39, 0x65, 0x35, 0x30, 0x63, 0x39, 0x62, + 0x37, 0x39, 0x37, 0x30, 0x62, 0x65, 0x62, 0x64, 0x31, 0x29, 0x19, 0x3c, 0x1c, 0x00, 0x00, 0x1c, + 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0xd3, 0x02, 0x00, 0x00, 0x50, 0x41, 0x52, 0x31}; + unsigned int decimals_parquet_len = 2366; + + cudf_io::parquet_reader_options read_opts = cudf_io::parquet_reader_options::builder( + cudf_io::source_info{reinterpret_cast(decimals_parquet), decimals_parquet_len}); + auto result = cudf_io::read_parquet(read_opts); + + auto validity = cudf::test::make_counting_transform_iterator(0, [](auto i) { return i != 50; }); + + EXPECT_EQ(result.tbl->view().num_columns(), 3); + + int32_t col0_data[] = { + -2354584, -190275, 8393572, 6446515, -5687920, -1843550, -6897687, -6780385, 3428529, + 5842056, -4312278, -4450603, -7516141, 2974667, -4288640, 1065090, -9410428, 7891355, + 1076244, -1975984, 6999466, 2666959, 9262967, 7931374, -1370640, 451074, 8799111, + 3026424, -6803730, 5098297, -1414370, -9662848, 2499991, 658765, 8348874, -6177036, + -9694494, -5343299, 3558393, -8789072, 2697890, -4454707, 8299309, -6223703, -3112513, + 7537487, 825776, -495683, 328299, -4529727, 0, -9999999, 9999999}; + + EXPECT_EQ(result.tbl->view().column(0).size(), sizeof(col0_data) / sizeof(col0_data[0])); + cudf::test::fixed_point_column_wrapper col0( + std::begin(col0_data), std::end(col0_data), validity, numeric::scale_type{-4}); + cudf::test::expect_columns_equal(result.tbl->view().column(0), col0); + + int64_t col1_data[] = {29274040266581, -17210335917753, -58420730139037, + 68073792696254, 2236456014294, 13704555677045, + -70797090469548, -52248605513407, -68976081919961, + -34277313883112, 97774730521689, 21184241014572, + -670882460254, -40862944054399, -24079852370612, + -88670167797498, -84007574359403, -71843004533519, + -55538016554201, 3491435293032, -29085437167297, + 36901882672273, -98622066122568, -13974902998457, + 86712597643378, -16835133643735, -94759096142232, + 30708340810940, 79086853262082, 78923696440892, + -76316597208589, 37247268714759, 80303592631774, + 57790350050889, 19387319851064, -33186875066145, + 69701203023404, -7157433049060, -7073790423437, + 92769171617714, -75127120182184, -951893180618, + 64927618310150, -53875897154023, -16168039035569, + -24273449166429, -30359781249192, 35639397345991, + 45844829680593, 71401416837149, 0, + -99999999999999, 99999999999999}; + + EXPECT_EQ(result.tbl->view().column(1).size(), sizeof(col1_data) / sizeof(col1_data[0])); + cudf::test::fixed_point_column_wrapper col1( + std::begin(col1_data), std::end(col1_data), validity, numeric::scale_type{-5}); + cudf::test::expect_columns_equal(result.tbl->view().column(1), col1); + + cudf_io::parquet_reader_options read_strict_opts = read_opts; + read_strict_opts.set_strict_decimal_types(true); + EXPECT_THROW(cudf_io::read_parquet(read_strict_opts), cudf::logic_error); + + read_strict_opts.set_columns({"dec7p4", "dec14p5"}); + EXPECT_NO_THROW(cudf_io::read_parquet(read_strict_opts)); +} CUDF_TEST_PROGRAM_MAIN() diff --git a/cpp/tests/utilities/column_utilities.cu b/cpp/tests/utilities/column_utilities.cu index efd34816522..48d368cb36e 100644 --- a/cpp/tests/utilities/column_utilities.cu +++ b/cpp/tests/utilities/column_utilities.cu @@ -579,10 +579,21 @@ struct column_view_printer { std::string const& indent) { auto const h_data = cudf::test::to_host(col); - std::transform(std::cbegin(h_data.first), - std::cend(h_data.first), - std::back_inserter(out), - [](auto const& fp) { return std::to_string(static_cast(fp)); }); + if (col.nullable()) { + std::transform(thrust::make_counting_iterator(size_type{0}), + thrust::make_counting_iterator(col.size()), + std::back_inserter(out), + [&h_data](auto idx) { + return h_data.second.empty() || bit_is_set(h_data.second.data(), idx) + ? static_cast(h_data.first[idx]) + : std::string("NULL"); + }); + } else { + std::transform(std::cbegin(h_data.first), + std::cend(h_data.first), + std::back_inserter(out), + [col](auto const& fp) { return static_cast(fp); }); + } } template