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


##########
be/src/format_v2/expr/cast.cpp:
##########
@@ -116,6 +148,13 @@ Status Cast::_do_execute(VExprContext* context, const 
Block* block, const Select
     ColumnPtr tmp_arg_column;
     RETURN_IF_ERROR(_children[0]->execute_column(context, block, selector, 
count, tmp_arg_column));
     auto arg_type = _children[0]->execute_type(block);
+    if (_truncate_datetimev2_precision && 
can_truncate_datetimev2_precision(arg_type, _data_type)) {
+        auto result = _data_type->create_column();
+        result->insert_range_from(*tmp_arg_column, 0, count);

Review Comment:
   [P1] Handle source/target nullability before copying here. Paimon 
intentionally exposes every top-level Doris column as nullable, while a 
historical `NOT NULL TIMESTAMP(6)` file leaf is non-nullable. When that field 
is narrowed to p0, `_data_type->create_column()` returns `ColumnNullable`, but 
`tmp_arg_column` is `ColumnDateTimeV2`; `ColumnNullable::insert_range_from` 
assert-casts the source to `ColumnNullable` and the scan fails with FatalError. 
The runtime-nullability fallback does not catch required source -> nullable 
target. Please make this copy wrapper-aware and add a NOT NULL 
precision-evolution case.



##########
be/src/format_v2/column_mapper.cpp:
##########
@@ -2898,6 +2901,12 @@ Status TableColumnMapper::_create_direct_mapping(const 
ColumnDefinition& table_c
     mapping->projected_file_children = file_field.children;
     mapping->timestamp_is_adjusted_to_utc = 
file_field.timestamp_is_adjusted_to_utc;
     mapping->file_type = file_field.type;
+    const auto file_type = remove_nullable(mapping->file_type);
+    const auto table_type = remove_nullable(mapping->table_type);
+    mapping->truncate_datetimev2_precision = 
_options.truncate_datetimev2_precision_for_paimon &&
+                                             file_type->get_primitive_type() 
== TYPE_DATETIMEV2 &&

Review Comment:
   [P1] Apply the Paimon rule to TIMESTAMPTZ narrowing too. With 
`enable.mapping.timestamp_tz=true`, FE maps `TIMESTAMP_LTZ` to 
TIMESTAMPTZ(scale), and the native Paimon schema keeps that primitive. This 
DATETIMEV2-only gate stays false; V2 then treats same-primitive TIMESTAMPTZ 
scale mismatches as trivial pass-through, and V1 selects `ConsistentConverter`. 
An old p6 LTZ value ending in `.600000` therefore remains fractional under a p0 
schema on both native routes while JNI truncates it. Please carry the 
Paimon-specific rule through TIMESTAMPTZ without changing ordinary SQL CAST 
semantics, and test LTZ evolution with the option enabled.



##########
fe/be-java-extensions/paimon-scanner/src/main/java/org/apache/doris/paimon/PaimonColumnValue.java:
##########
@@ -167,7 +168,8 @@ public LocalDate getDate() {
 
     @Override
     public LocalDateTime getDateTime() {
-        Timestamp ts = record.getTimestamp(idx, dorisType.getPrecision());
+        Timestamp ts = DateTimeUtils.truncate(

Review Comment:
   [P1] Avoid Paimon's truncation helper for evolved JNI timestamps. The pinned 
1.3.1 implementation checks the decimal length of an unpadded nanosecond value 
and truncates epoch milliseconds with Java division toward zero. Consequently a 
p6 value ending in `.000001` remains `.000001` when narrowed to p4/p5, and 
`1969-12-31 23:59:59.600` narrowed to p0 becomes the epoch instead of 
`23:59:59`. Both changed getters take this path (including nested/LTZ uses), 
while the added tests only cover a positive `.600` -> p0 case. Please use 
fixed-width fractional truncation with floor-safe negative handling and cover 
these two boundaries.



##########
be/src/format/column_type_convert.cpp:
##########
@@ -373,6 +373,11 @@ std::unique_ptr<ColumnTypeConverter> 
ColumnTypeConverter::get_converter(const Da
         return _decimal_converter(src_type, dst_type);
     }
 
+    if (src_primitive_type == TYPE_DATETIMEV2 && dst_primitive_type == 
TYPE_DATETIMEV2 &&
+        src_type->get_scale() > dst_type->get_scale()) {
+        return 
std::make_unique<DateTimeV2PrecisionConverter>(dst_type->get_scale());

Review Comment:
   [P1] Disable V1 predicate pushdown when this converter changes timestamp 
values. Conversion happens after file pruning, while Parquet `_type_matches()` 
only compares primitive types and ORC still builds a TIMESTAMP search argument. 
For an old p6 row `...01.600000` evolved to p0, `WHERE ts = ...01` should match 
after truncation, but raw Parquet min/max or an ORC SARG can discard its 
group/stripe first. V2 marks this mapping `FINALIZE_ONLY`; V1 needs equivalent 
raw metadata/page pushdown gating plus filtered Parquet/ORC regressions.



-- 
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