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


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/TimeExtract.java:
##########
@@ -0,0 +1,73 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.functions;
+
+import org.apache.doris.catalog.FunctionSignature;
+import org.apache.doris.nereids.trees.expressions.Cast;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.TryCast;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.Coalesce;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.TimeFormat;
+import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
+import org.apache.doris.nereids.types.DateTimeV2Type;
+import org.apache.doris.nereids.types.TimeV2Type;
+import org.apache.doris.nereids.util.ExpressionUtils;
+import org.apache.doris.nereids.util.TypeCoercionUtils;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/**
+ * Composite time extraction using the existing TIME formatter.
+ */
+public interface TimeExtract extends ExplicitlyCastableSignature, 
RewriteWhenAnalyze {
+    String getTimeFormat();
+
+    @Override
+    default FunctionSignature searchSignature(List<FunctionSignature> 
signatures) {
+        // Let temporal literals select their precise type. String expressions 
need both parsers
+        // because their values, unlike literals, are only available during 
execution.
+        // Keep other types and volatile expressions on their historical 
conversion path.
+        // The string fallback evaluates its source in two casts, so it must 
be deterministic.
+        if (!getArgumentType(0).isStringLikeType() || 
getArgument(0).containsVolatileExpression()
+                || 
ExpressionUtils.getLiteralAfterUnwrapNullable(getArgument(0)).isPresent()) {
+            signatures = signatures.stream()
+                    .filter(signature -> 
!signature.getArgType(0).isStringLikeType())
+                    .collect(ImmutableList.toImmutableList());
+        }
+        return ExplicitlyCastableSignature.super.searchSignature(signatures);
+    }
+
+    @Override
+    default Expression rewriteWhenAnalyze() {
+        Expression argument = getArgument(0);
+        if (argument.getDataType().isStringLikeType()) {
+            // Preserve DATETIME parsing (including dates and timezone 
suffixes), then accept
+            // time-only strings. Failed probes must return NULL even in 
strict mode, because
+            // COALESCE can evaluate both branches for a block containing NULL 
rows.
+            // Both parsers use six digits so column values retain 
microseconds.
+            argument = new Coalesce(
+                    new Cast(new TryCast(argument, DateTimeV2Type.MAX), 
TimeV2Type.MAX),

Review Comment:
   [P1] Parse time-only strings before the DATETIME fallback. With 
`enable_strict_cast=false`, the first probe accepts `01:02:03` as the date 
2001-02-03, so this `COALESCE` returns midnight and `hour_minute(time_str)` 
becomes `00:00`; with strict casting enabled, or with the same value as a 
literal, it returns `01:02`. The new regression output records this discrepancy 
for row 4. Other valid times with minute <= 12 and second <= 31 have the same 
problem. Route time-only forms to TIMEV2 first and correct the non-strict 
oracle.



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/TimeExtract.java:
##########
@@ -0,0 +1,73 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.functions;
+
+import org.apache.doris.catalog.FunctionSignature;
+import org.apache.doris.nereids.trees.expressions.Cast;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.TryCast;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.Coalesce;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.TimeFormat;
+import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
+import org.apache.doris.nereids.types.DateTimeV2Type;
+import org.apache.doris.nereids.types.TimeV2Type;
+import org.apache.doris.nereids.util.ExpressionUtils;
+import org.apache.doris.nereids.util.TypeCoercionUtils;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/**
+ * Composite time extraction using the existing TIME formatter.
+ */
+public interface TimeExtract extends ExplicitlyCastableSignature, 
RewriteWhenAnalyze {
+    String getTimeFormat();
+
+    @Override
+    default FunctionSignature searchSignature(List<FunctionSignature> 
signatures) {
+        // Let temporal literals select their precise type. String expressions 
need both parsers
+        // because their values, unlike literals, are only available during 
execution.
+        // Keep other types and volatile expressions on their historical 
conversion path.
+        // The string fallback evaluates its source in two casts, so it must 
be deterministic.
+        if (!getArgumentType(0).isStringLikeType() || 
getArgument(0).containsVolatileExpression()
+                || 
ExpressionUtils.getLiteralAfterUnwrapNullable(getArgument(0)).isPresent()) {
+            signatures = signatures.stream()
+                    .filter(signature -> 
!signature.getArgType(0).isStringLikeType())
+                    .collect(ImmutableList.toImmutableList());
+        }
+        return ExplicitlyCastableSignature.super.searchSignature(signatures);
+    }
+
+    @Override
+    default Expression rewriteWhenAnalyze() {
+        Expression argument = getArgument(0);
+        if (argument.getDataType().isStringLikeType()) {
+            // Preserve DATETIME parsing (including dates and timezone 
suffixes), then accept
+            // time-only strings. Failed probes must return NULL even in 
strict mode, because
+            // COALESCE can evaluate both branches for a block containing NULL 
rows.
+            // Both parsers use six digits so column values retain 
microseconds.
+            argument = new Coalesce(

Review Comment:
   [P2] Avoid retrying the DATETIME probe row by row for time-only columns. For 
a VARCHAR value such as `12:34:56`, the first DATETIMEV2 probe fails in a 
strict-cast session. BE `TryCastExpr` then retries the entire block one row at 
a time, allocating a one-row block and rerunning the cast for every row before 
the TIMEV2 branch is reached. If the argument is an expression such as 
`regexp_extract(...)`, the two branches also evaluate that source twice. This 
makes the new common case expensive on large scans; classify time-only values 
or use one conversion that reads the source once and tries both formats without 
the per-row failure path.



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