github-actions[bot] commented on code in PR #68649:
URL: https://github.com/apache/doris/pull/68649#discussion_r4146799308


##########
be/src/core/data_type_serde/data_type_datev2_serde.cpp:
##########
@@ -278,12 +295,20 @@ Status 
DataTypeDateV2SerDe::read_column_from_arrow(IColumn& column, const arrow:
         const auto* base_ptr = reinterpret_cast<const 
uint8_t*>(concrete_array->raw_values());
         const size_t element_size = sizeof(int32_t);
         for (auto value_i = start; value_i < end; ++value_i) {
-            int32_t date_value = 0;
+            // A null slot has no calendar value and its payload may be 
outside the DATE range.
+            if (concrete_array->IsNull(value_i)) {
+                col_data.emplace_back(DateV2Value<DateV2ValueType>());
+                continue;
+            }
             const uint8_t* raw_byte_ptr = base_ptr + value_i * element_size;
-            memcpy(&date_value, raw_byte_ptr, element_size);
+            auto date_value = unaligned_load<int32_t>(raw_byte_ptr);
 
             DateV2Value<DateV2ValueType> v;
-            v.get_date_from_daynr(date_value + date_threshold);
+            if (const auto status = decode_epoch_days(date_value, &v); 
!status.ok()) {
+                return Status::InvalidArgument(
+                        "Arrow Date32 value is outside the Doris DATE range: 
row={}, days={}",
+                        value_i, date_value);
+            }
             col_data.emplace_back(v);
         }

Review Comment:
   [P1] Preserve a read path for DATE files written by the prior Doris encoder. 
A Parquet or ORC file exported or committed to Iceberg before this change 
stores `0000-01-01` as -719527 and `0000-02-28` as -719469 through the old 
`daynr - 719528` encoder; the prior readers recovered both dates. This shared 
decoder returns `0000-01-02` for the first and rejects or nulls the second, so 
upgrading the BE changes results for existing files. This is the reverse 
direction of the open v1/older-BE thread: fixing those readers does not fix 
historical files on this reader. The release note asks for re-export, but 
already committed files remain silently readable with wrong values. Provide an 
explicit legacy-file read/migration path, with fixtures written by the old 
encoder, before making the new interpretation the only default.



##########
be/src/format_v2/orc/orc_reader.cpp:
##########
@@ -2275,6 +2370,17 @@ Status OrcReader::get_aggregate_result(const 
format::FileAggregateRequest& reque
                 
_state->root_type->getSubtype(static_cast<uint64_t>(count_projection.local_id()));
         DORIS_CHECK(count_type != nullptr);
 
+        std::vector<uint32_t> date_column_ids;
+        const auto collect_dates = [&](auto&& self, const ::orc::Type& type) 
-> void {
+            if (type.getKind() == ::orc::TypeKind::DATE) {
+                
date_column_ids.push_back(cast_set<uint32_t>(type.getColumnId()));
+            }
+            for (uint64_t i = 0; i < type.getSubtypeCount(); ++i) {
+                self(self, *type.getSubtype(i));
+            }
+        };
+        collect_dates(collect_dates, *count_type);
+

Review Comment:
   [P1] Check the stripe-statistics column count before looking up nested DATE 
IDs. For `COUNT(s)` on `struct<id:int,s:struct<d:date>>`, a stripe with 
complete footer schema, only three metadata `colStats` entries (IDs 0-2), and 
no `ROW_INDEX` streams passes the earlier checks and `getStripeStatistics`; the 
prior top-level COUNT lookup of `s` (ID 2) stays in range. This new loop calls 
`getColumnStatistics(3)` for `d`, while the pinned ORC SDK indexes its 
three-element `colStats` vector without a bounds check, so malformed external 
metadata can crash or corrupt the BE instead of falling back to row validation. 
Check `column_id < stripe_statistics->getNumberOfColumns()` and return 
`NotSupported` or corruption before the lookup; cover truncated nested DATE 
statistics in a regression.



##########
be/src/format_v2/orc/orc_reader.cpp:
##########
@@ -1670,8 +1722,39 @@ Status OrcReader::_select_stripe_ranges_by_statistics() {
     }
 
     std::vector<int> sarg_needed_stripes;
+    std::set<uint64_t> unsafe_date_stripes;
     try {

Review Comment:
   [P1] Avoid loading row indexes for every stripe during DATE preflight. With 
a projected DATE and a selective `id` SARG, this call runs on every split 
stripe before `getNeedReadStripes` can discard safe stripes. The pinned ORC SDK 
fetches each stripe footer and parses every `ROW_INDEX` stream, including 
unprojected columns. A valid nonempty index in an otherwise pruned stripe whose 
stream column ID is changed from 3 to 100 passes earlier footer checks but 
reaches the SDK's unchecked `indexStats[stream.column()]` access, which can 
corrupt memory or crash before Doris's exception fallback. Even valid remote 
files pay index I/O and parsing for skipped stripes. Read DATE bounds from 
metadata without loading row indexes; if this SDK path remains, validate the 
stream column ID and cover the malformed pruned stripe and I/O counts.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to