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


##########
be/src/format_v2/orc/orc_search_argument.cpp:
##########
@@ -1250,11 +1265,78 @@ void build_equals(const OrcSargComparison& comparison,
     build_equals(comparison.column, comparison.literal, builder);
 }
 
+::orc::Literal shift_timestamp_literal(const ::orc::Literal& literal, int32_t 
nanos_delta) {
+    constexpr int64_t NANOS_PER_SECOND = 1000000000;
+    const auto timestamp = literal.getTimestamp();
+    int64_t seconds = timestamp.second;
+    int64_t nanos = timestamp.nanos + nanos_delta;
+    if (nanos < 0) {
+        --seconds;
+        nanos += NANOS_PER_SECOND;
+    } else if (nanos >= NANOS_PER_SECOND) {
+        ++seconds;
+        nanos -= NANOS_PER_SECOND;
+    }
+    return ::orc::Literal(seconds, cast_set<int32_t>(nanos));
+}
+
+std::pair<::orc::Literal, ::orc::Literal> timestamp_rounding_bounds(const 
::orc::Literal& literal) {
+    constexpr int32_t HALF_MICROSECOND_NANOS = 500;
+    // All raw ORC values in [literal - 500ns, literal + 500ns) round half-up 
to this Doris
+    // microsecond. SARG predicates must use this interval or they may prune 
rows that row decoding
+    // subsequently rounds to the requested value.
+    return {shift_timestamp_literal(literal, -HALF_MICROSECOND_NANOS),
+            shift_timestamp_literal(literal, HALF_MICROSECOND_NANOS)};
+}
+
+void build_timestamp_equals(const OrcSargColumn& column, const ::orc::Literal& 
literal,
+                            std::unique_ptr<::orc::SearchArgumentBuilder>& 
builder) {
+    const auto [lower_bound, upper_bound] = timestamp_rounding_bounds(literal);
+    builder->startAnd();
+    builder->startNot();
+    build_less_than(column, lower_bound, builder);
+    builder->end();
+    build_less_than(column, upper_bound, builder);
+    builder->end();
+}
+
 void build_comparison_predicate(const format::FileScanRequest& request,
                                 const ::orc::Type& root_type, const VExprSPtr& 
expr,
                                 const cctz::time_zone& timezone,
                                 std::unique_ptr<::orc::SearchArgumentBuilder>& 
builder) {
     const auto comparison = *sarg_comparison_for_expr(request, root_type, 
timezone, expr);

Review Comment:
   The new timestamp SARG branch still consumes `comparison.literal`, but that 
literal is built in `make_orc_literal` with UTC for plain ORC `timestamp` while 
row decoding uses the session timezone (`decode_timestamp_orc_values(..., 
*view.timezone)`) and aggregate min/max does the same. In a non-UTC session 
this can drop matching stripes before Doris row filtering runs: for the 
existing two-stripe helper with raw seconds 0 and 3600, `Asia/Shanghai` decodes 
them as 08:00:00.123 and 09:00:00.123, so `timestamp_col > '1970-01-01 
08:30:00'` should keep the second stripe, but the SARG literal is converted as 
UTC second 30600 and can reject both stripes. Please build plain `TIMESTAMP` 
SARG literals with the same session timezone used by row decoding, or disable 
timestamp SARG pruning for that case, and add a non-UTC plain `timestamp` SARG 
regression test.



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