This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.2
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.2 by this push:
new 53eb16adfac branch-4.2: [fix](fe) Support time strings in composite
time extraction #68830 (#70031)
53eb16adfac is described below
commit 53eb16adfac03135b196772777330cc2d452109c
Author: morrySnow <[email protected]>
AuthorDate: Tue Nov 3 17:08:10 2026 +0800
branch-4.2: [fix](fe) Support time strings in composite time extraction
#68830 (#70031)
picked from master #68830
Co-authored-by: TengJianPing <[email protected]>
---
.../expressions/functions/scalar/HourMinute.java | 18 +-
.../expressions/functions/scalar/HourSecond.java | 18 +-
.../expressions/functions/scalar/MinuteSecond.java | 18 +-
.../functions/scalar/SecondMicrosecond.java | 18 +-
.../functions/scalar/CompositeTimeExtractTest.java | 93 +++++
.../test_composite_time_extract.out | 445 +++++++++++++++++++++
.../test_composite_time_extract.groovy | 127 ++++++
7 files changed, 729 insertions(+), 8 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HourMinute.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HourMinute.java
index 75c756695a7..47c89c6399f 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HourMinute.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HourMinute.java
@@ -21,11 +21,15 @@ import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.trees.expressions.Expression;
import
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
+import org.apache.doris.nereids.trees.expressions.functions.RewriteWhenAnalyze;
+import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.DateTimeV2Type;
import org.apache.doris.nereids.types.TimeStampNsType;
+import org.apache.doris.nereids.types.TimeV2Type;
import org.apache.doris.nereids.types.VarcharType;
+import org.apache.doris.nereids.util.TypeCoercionUtils;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
@@ -36,11 +40,12 @@ import java.util.List;
* ScalarFunction 'hour_minute'.
*/
public class HourMinute extends ScalarFunction
- implements UnaryExpression, ExplicitlyCastableSignature,
PropagateNullable {
+ implements UnaryExpression, ExplicitlyCastableSignature,
PropagateNullable, RewriteWhenAnalyze {
private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(DateTimeV2Type.WILDCARD),
-
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(TimeStampNsType.INSTANCE));
+
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(TimeStampNsType.INSTANCE),
+
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(TimeV2Type.WILDCARD));
public HourMinute(Expression arg) {
super("hour_minute", arg);
@@ -56,6 +61,15 @@ public class HourMinute extends ScalarFunction
return new HourMinute(getFunctionParams(children));
}
+ @Override
+ public Expression rewriteWhenAnalyze() {
+ Expression argument = getArgument(0);
+ if (!(argument.getDataType() instanceof TimeV2Type)) {
+ return this;
+ }
+ return TypeCoercionUtils.processBoundFunction(new TimeFormat(argument,
new VarcharLiteral("%H:%i")));
+ }
+
@Override
public List<FunctionSignature> getSignatures() {
return SIGNATURES;
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HourSecond.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HourSecond.java
index 2921c4533cf..eae8d1015e3 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HourSecond.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HourSecond.java
@@ -21,11 +21,15 @@ import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.trees.expressions.Expression;
import
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
+import org.apache.doris.nereids.trees.expressions.functions.RewriteWhenAnalyze;
+import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.DateTimeV2Type;
import org.apache.doris.nereids.types.TimeStampNsType;
+import org.apache.doris.nereids.types.TimeV2Type;
import org.apache.doris.nereids.types.VarcharType;
+import org.apache.doris.nereids.util.TypeCoercionUtils;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
@@ -36,11 +40,12 @@ import java.util.List;
* ScalarFunction 'hour_second'.
*/
public class HourSecond extends ScalarFunction
- implements UnaryExpression, ExplicitlyCastableSignature,
PropagateNullable {
+ implements UnaryExpression, ExplicitlyCastableSignature,
PropagateNullable, RewriteWhenAnalyze {
private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(DateTimeV2Type.WILDCARD),
-
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(TimeStampNsType.INSTANCE));
+
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(TimeStampNsType.INSTANCE),
+
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(TimeV2Type.WILDCARD));
public HourSecond(Expression arg) {
super("hour_second", arg);
@@ -56,6 +61,15 @@ public class HourSecond extends ScalarFunction
return new HourSecond(getFunctionParams(children));
}
+ @Override
+ public Expression rewriteWhenAnalyze() {
+ Expression argument = getArgument(0);
+ if (!(argument.getDataType() instanceof TimeV2Type)) {
+ return this;
+ }
+ return TypeCoercionUtils.processBoundFunction(new TimeFormat(argument,
new VarcharLiteral("%H:%i:%s")));
+ }
+
@Override
public List<FunctionSignature> getSignatures() {
return SIGNATURES;
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MinuteSecond.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MinuteSecond.java
index e5567debd98..a63324c099d 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MinuteSecond.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MinuteSecond.java
@@ -21,11 +21,15 @@ import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.trees.expressions.Expression;
import
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
+import org.apache.doris.nereids.trees.expressions.functions.RewriteWhenAnalyze;
+import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.DateTimeV2Type;
import org.apache.doris.nereids.types.TimeStampNsType;
+import org.apache.doris.nereids.types.TimeV2Type;
import org.apache.doris.nereids.types.VarcharType;
+import org.apache.doris.nereids.util.TypeCoercionUtils;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
@@ -36,11 +40,12 @@ import java.util.List;
* ScalarFunction 'minute_second'.
*/
public class MinuteSecond extends ScalarFunction
- implements UnaryExpression, ExplicitlyCastableSignature,
PropagateNullable {
+ implements UnaryExpression, ExplicitlyCastableSignature,
PropagateNullable, RewriteWhenAnalyze {
private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(DateTimeV2Type.WILDCARD),
-
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(TimeStampNsType.INSTANCE));
+
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(TimeStampNsType.INSTANCE),
+
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(TimeV2Type.WILDCARD));
public MinuteSecond(Expression arg) {
super("minute_second", arg);
@@ -56,6 +61,15 @@ public class MinuteSecond extends ScalarFunction
return new MinuteSecond(getFunctionParams(children));
}
+ @Override
+ public Expression rewriteWhenAnalyze() {
+ Expression argument = getArgument(0);
+ if (!(argument.getDataType() instanceof TimeV2Type)) {
+ return this;
+ }
+ return TypeCoercionUtils.processBoundFunction(new TimeFormat(argument,
new VarcharLiteral("%i:%s")));
+ }
+
@Override
public List<FunctionSignature> getSignatures() {
return SIGNATURES;
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecondMicrosecond.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecondMicrosecond.java
index f521e0ff891..ea38c4701dd 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecondMicrosecond.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecondMicrosecond.java
@@ -21,11 +21,15 @@ import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.trees.expressions.Expression;
import
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
+import org.apache.doris.nereids.trees.expressions.functions.RewriteWhenAnalyze;
+import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.DateTimeV2Type;
import org.apache.doris.nereids.types.TimeStampNsType;
+import org.apache.doris.nereids.types.TimeV2Type;
import org.apache.doris.nereids.types.VarcharType;
+import org.apache.doris.nereids.util.TypeCoercionUtils;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
@@ -36,11 +40,12 @@ import java.util.List;
* ScalarFunction 'second_microsecond'.
*/
public class SecondMicrosecond extends ScalarFunction
- implements UnaryExpression, ExplicitlyCastableSignature,
PropagateNullable {
+ implements UnaryExpression, ExplicitlyCastableSignature,
PropagateNullable, RewriteWhenAnalyze {
private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(DateTimeV2Type.WILDCARD),
-
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(TimeStampNsType.INSTANCE));
+
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(TimeStampNsType.INSTANCE),
+
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(TimeV2Type.WILDCARD));
public SecondMicrosecond(Expression arg) {
super("second_microsecond", arg);
@@ -56,6 +61,15 @@ public class SecondMicrosecond extends ScalarFunction
return new SecondMicrosecond(getFunctionParams(children));
}
+ @Override
+ public Expression rewriteWhenAnalyze() {
+ Expression argument = getArgument(0);
+ if (!(argument.getDataType() instanceof TimeV2Type)) {
+ return this;
+ }
+ return TypeCoercionUtils.processBoundFunction(new TimeFormat(argument,
new VarcharLiteral("%s.%f")));
+ }
+
@Override
public List<FunctionSignature> getSignatures() {
return SIGNATURES;
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CompositeTimeExtractTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CompositeTimeExtractTest.java
new file mode 100644
index 00000000000..82da17161a8
--- /dev/null
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CompositeTimeExtractTest.java
@@ -0,0 +1,93 @@
+// 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.scalar;
+
+import org.apache.doris.nereids.parser.NereidsParser;
+import org.apache.doris.nereids.rules.analysis.ExpressionAnalyzer;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.SlotReference;
+import org.apache.doris.nereids.trees.expressions.functions.RewriteWhenAnalyze;
+import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
+import org.apache.doris.nereids.types.DataType;
+import org.apache.doris.nereids.types.DateTimeV2Type;
+import org.apache.doris.nereids.types.TimeStampNsType;
+import org.apache.doris.nereids.types.TimeV2Type;
+
+import com.google.common.collect.ImmutableList;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+import java.util.function.Function;
+
+class CompositeTimeExtractTest {
+ private static final List<Function<Expression, ScalarFunction>> FUNCTIONS
= ImmutableList.of(
+ HourMinute::new, HourSecond::new, MinuteSecond::new,
SecondMicrosecond::new);
+
+ @Test
+ void testTimePrecisionAndExistingTemporalSignatures() {
+ for (Function<Expression, ScalarFunction> factory : FUNCTIONS) {
+ for (int scale = 0; scale <= 6; scale++) {
+ TimeV2Type timeType = TimeV2Type.of(scale);
+ ScalarFunction function = factory.apply(SlotReference.of("t",
timeType));
+ Assertions.assertEquals(timeType,
function.getSignature().getArgType(0));
+ Expression rewritten = ((RewriteWhenAnalyze)
function).rewriteWhenAnalyze();
+ Assertions.assertInstanceOf(TimeFormat.class, rewritten);
+ Assertions.assertEquals(timeType,
rewritten.child(0).getDataType());
+ }
+ for (DataType type :
ImmutableList.of(DateTimeV2Type.SYSTEM_DEFAULT,
+ DateTimeV2Type.MAX, TimeStampNsType.INSTANCE)) {
+ ScalarFunction function = factory.apply(SlotReference.of("dt",
type));
+ Assertions.assertEquals(type,
function.getSignature().getArgType(0));
+ Assertions.assertSame(function, ((RewriteWhenAnalyze)
function).rewriteWhenAnalyze());
+ }
+ }
+ }
+
+ @Test
+ void testTimeLiteralsSelectTimeInsteadOfDateTime() {
+ for (Function<Expression, ScalarFunction> factory : FUNCTIONS) {
+ for (String value : ImmutableList.of("12:34:56", "12:34:56.789123",
+ "00:00:00.000001", "-00:00:01.5", "123:34:56.123456")) {
+ ScalarFunction function = factory.apply(new
VarcharLiteral(value));
+ Assertions.assertTrue(function.getSignature().getArgType(0)
instanceof TimeV2Type, value);
+ }
+ ScalarFunction dateTime = factory.apply(new
VarcharLiteral("2024-01-02 12:34:56.789123"));
+ Assertions.assertEquals(DateTimeV2Type.MAX,
dateTime.getSignature().getArgType(0));
+ }
+ }
+
+ @Test
+ void testDirectAndExtractSyntaxUseTheSameTimeFormatter() {
+ NereidsParser parser = new NereidsParser();
+ for (String name : ImmutableList.of("hour_minute", "hour_second",
"minute_second", "second_microsecond")) {
+ for (String argument : ImmutableList.of("'12:34:56.789123'",
+ "cast('12:34:56.789123' as time(6))")) {
+ Expression direct = ExpressionAnalyzer.analyzeFunction(null,
null,
+ parser.parseExpression(name + "(" + argument + ")"));
+ Expression extract = ExpressionAnalyzer.analyzeFunction(null,
null,
+ parser.parseExpression("extract(" + name + " from " +
argument + ")"));
+ Assertions.assertInstanceOf(TimeFormat.class, direct);
+ Assertions.assertEquals(direct, extract);
+ Assertions.assertEquals(TimeV2Type.MAX,
direct.child(0).getDataType());
+ Assertions.assertTrue(direct.checkInputDataTypes().success());
+ }
+ }
+ }
+
+}
diff --git
a/regression-test/data/query_p0/sql_functions/datetime_functions/test_composite_time_extract.out
b/regression-test/data/query_p0/sql_functions/datetime_functions/test_composite_time_extract.out
new file mode 100644
index 00000000000..46b4a575eaf
--- /dev/null
+++
b/regression-test/data/query_p0/sql_functions/datetime_functions/test_composite_time_extract.out
@@ -0,0 +1,445 @@
+-- This file is automatically generated. You should know what you did if you
want to edit this
+-- !fe_literal_0 --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !fe_literal_1 --
+00:00 00:00:00 00:00 00.000001 00:00 00:00:00 00:00
00.000001
+
+-- !fe_literal_2 --
+23:59 23:59:59 59:59 59.999999 23:59 23:59:59 59:59
59.999999
+
+-- !fe_literal_3 --
+01:02 01:02:03 02:03 03.000000 01:02 01:02:03 02:03
03.000000
+
+-- !fe_literal_4 --
+12:34 12:34:56 34:56 56.700000 12:34 12:34:56 34:56
56.700000
+
+-- !fe_literal_5 --
+123:34 123:34:56 34:56 56.789123 123:34 123:34:56 34:56
56.789123
+
+-- !fe_literal_6 --
+-12:34 -12:34:56 -34:56 -56.789123 -12:34 -12:34:56 -34:56
-56.789123
+
+-- !fe_literal_7 --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !fe_literal_8 --
+\N \N \N \N \N \N \N \N
+
+-- !fe_literal_9 --
+\N \N \N \N \N \N \N \N
+
+-- !fe_explicit_time --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !fe_time_zero_scale --
+12:34 12:34:56 34:56 56.000000 12:34 12:34:56 34:56
56.000000
+
+-- !fe_timestamp_ns --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !fe_string_column --
+1 \N \N \N \N \N \N \N \N
+10 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+11 \N \N \N \N \N \N \N \N
+12 \N \N \N \N \N \N \N \N
+13 \N \N \N \N \N \N \N \N
+2 \N \N \N \N \N \N \N \N
+3 \N \N \N \N \N \N \N \N
+4 00:00 00:00:00 00:00 00.000000 00:00 00:00:00
00:00 00.000000
+5 \N \N \N \N \N \N \N \N
+6 \N \N \N \N \N \N \N \N
+7 \N \N \N \N \N \N \N \N
+8 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+9 00:00 00:00:00 00:00 00.000000 00:00 00:00:00
00:00 00.000000
+
+-- !fe_string_type --
+1 \N \N \N \N \N \N \N \N
+10 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+11 \N \N \N \N \N \N \N \N
+12 \N \N \N \N \N \N \N \N
+13 \N \N \N \N \N \N \N \N
+2 \N \N \N \N \N \N \N \N
+3 \N \N \N \N \N \N \N \N
+4 00:00 00:00:00 00:00 00.000000 00:00 00:00:00
00:00 00.000000
+5 \N \N \N \N \N \N \N \N
+6 \N \N \N \N \N \N \N \N
+7 \N \N \N \N \N \N \N \N
+8 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+9 00:00 00:00:00 00:00 00.000000 00:00 00:00:00
00:00 00.000000
+
+-- !fe_char_type --
+1 \N \N \N \N \N \N \N \N
+10 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+11 \N \N \N \N \N \N \N \N
+12 \N \N \N \N \N \N \N \N
+13 \N \N \N \N \N \N \N \N
+2 \N \N \N \N \N \N \N \N
+3 \N \N \N \N \N \N \N \N
+4 00:00 00:00:00 00:00 00.000000 00:00 00:00:00
00:00 00.000000
+5 \N \N \N \N \N \N \N \N
+6 \N \N \N \N \N \N \N \N
+7 \N \N \N \N \N \N \N \N
+8 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+9 00:00 00:00:00 00:00 00.000000 00:00 00:00:00
00:00 00.000000
+
+-- !fe_time_column --
+1 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+10 \N \N \N \N \N \N \N \N
+11 \N \N \N \N \N \N \N \N
+12 \N \N \N \N \N \N \N \N
+13 \N \N \N \N \N \N \N \N
+2 00:00 00:00:00 00:00 00.000001 00:00 00:00:00
00:00 00.000001
+3 23:59 23:59:59 59:59 59.999999 23:59 23:59:59
59:59 59.999999
+4 01:02 01:02:03 02:03 03.000000 01:02 01:02:03
02:03 03.000000
+5 12:34 12:34:56 34:56 56.700000 12:34 12:34:56
34:56 56.700000
+6 123:34 123:34:56 34:56 56.789123 123:34 123:34:56
34:56 56.789123
+7 -12:34 -12:34:56 -34:56 -56.789123 -12:34 -12:34:56
-34:56 -56.789123
+8 \N \N \N \N \N \N \N \N
+9 \N \N \N \N \N \N \N \N
+
+-- !fe_datetime_column --
+1 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+10 \N \N \N \N \N \N \N \N
+11 \N \N \N \N \N \N \N \N
+12 \N \N \N \N \N \N \N \N
+13 \N \N \N \N \N \N \N \N
+2 00:00 00:00:00 00:00 00.000001 00:00 00:00:00
00:00 00.000001
+3 23:59 23:59:59 59:59 59.999999 23:59 23:59:59
59:59 59.999999
+4 01:02 01:02:03 02:03 03.000000 01:02 01:02:03
02:03 03.000000
+5 \N \N \N \N \N \N \N \N
+6 \N \N \N \N \N \N \N \N
+7 \N \N \N \N \N \N \N \N
+8 \N \N \N \N \N \N \N \N
+9 \N \N \N \N \N \N \N \N
+
+-- !fe_wrapped_0 --
+\N \N \N \N \N \N \N \N
+
+-- !fe_wrapped_1 --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !fe_wrapped_2 --
+\N \N \N \N \N \N \N \N
+
+-- !fe_wrapped_3 --
+\N \N \N \N \N \N \N \N
+
+-- !be_literal_0 --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !be_literal_1 --
+00:00 00:00:00 00:00 00.000001 00:00 00:00:00 00:00
00.000001
+
+-- !be_literal_2 --
+23:59 23:59:59 59:59 59.999999 23:59 23:59:59 59:59
59.999999
+
+-- !be_literal_3 --
+01:02 01:02:03 02:03 03.000000 01:02 01:02:03 02:03
03.000000
+
+-- !be_literal_4 --
+12:34 12:34:56 34:56 56.700000 12:34 12:34:56 34:56
56.700000
+
+-- !be_literal_5 --
+123:34 123:34:56 34:56 56.789123 123:34 123:34:56 34:56
56.789123
+
+-- !be_literal_6 --
+-12:34 -12:34:56 -34:56 -56.789123 -12:34 -12:34:56 -34:56
-56.789123
+
+-- !be_literal_7 --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !be_literal_8 --
+\N \N \N \N \N \N \N \N
+
+-- !be_literal_9 --
+\N \N \N \N \N \N \N \N
+
+-- !be_explicit_time --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !be_time_zero_scale --
+12:34 12:34:56 34:56 56.000000 12:34 12:34:56 34:56
56.000000
+
+-- !be_timestamp_ns --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !be_string_column --
+1 \N \N \N \N \N \N \N \N
+10 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+11 \N \N \N \N \N \N \N \N
+12 \N \N \N \N \N \N \N \N
+13 \N \N \N \N \N \N \N \N
+2 \N \N \N \N \N \N \N \N
+3 \N \N \N \N \N \N \N \N
+4 00:00 00:00:00 00:00 00.000000 00:00 00:00:00
00:00 00.000000
+5 \N \N \N \N \N \N \N \N
+6 \N \N \N \N \N \N \N \N
+7 \N \N \N \N \N \N \N \N
+8 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+9 00:00 00:00:00 00:00 00.000000 00:00 00:00:00
00:00 00.000000
+
+-- !be_string_type --
+1 \N \N \N \N \N \N \N \N
+10 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+11 \N \N \N \N \N \N \N \N
+12 \N \N \N \N \N \N \N \N
+13 \N \N \N \N \N \N \N \N
+2 \N \N \N \N \N \N \N \N
+3 \N \N \N \N \N \N \N \N
+4 00:00 00:00:00 00:00 00.000000 00:00 00:00:00
00:00 00.000000
+5 \N \N \N \N \N \N \N \N
+6 \N \N \N \N \N \N \N \N
+7 \N \N \N \N \N \N \N \N
+8 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+9 00:00 00:00:00 00:00 00.000000 00:00 00:00:00
00:00 00.000000
+
+-- !be_char_type --
+1 \N \N \N \N \N \N \N \N
+10 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+11 \N \N \N \N \N \N \N \N
+12 \N \N \N \N \N \N \N \N
+13 \N \N \N \N \N \N \N \N
+2 \N \N \N \N \N \N \N \N
+3 \N \N \N \N \N \N \N \N
+4 00:00 00:00:00 00:00 00.000000 00:00 00:00:00
00:00 00.000000
+5 \N \N \N \N \N \N \N \N
+6 \N \N \N \N \N \N \N \N
+7 \N \N \N \N \N \N \N \N
+8 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+9 00:00 00:00:00 00:00 00.000000 00:00 00:00:00
00:00 00.000000
+
+-- !be_time_column --
+1 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+10 \N \N \N \N \N \N \N \N
+11 \N \N \N \N \N \N \N \N
+12 \N \N \N \N \N \N \N \N
+13 \N \N \N \N \N \N \N \N
+2 00:00 00:00:00 00:00 00.000001 00:00 00:00:00
00:00 00.000001
+3 23:59 23:59:59 59:59 59.999999 23:59 23:59:59
59:59 59.999999
+4 01:02 01:02:03 02:03 03.000000 01:02 01:02:03
02:03 03.000000
+5 12:34 12:34:56 34:56 56.700000 12:34 12:34:56
34:56 56.700000
+6 123:34 123:34:56 34:56 56.789123 123:34 123:34:56
34:56 56.789123
+7 -12:34 -12:34:56 -34:56 -56.789123 -12:34 -12:34:56
-34:56 -56.789123
+8 \N \N \N \N \N \N \N \N
+9 \N \N \N \N \N \N \N \N
+
+-- !be_datetime_column --
+1 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+10 \N \N \N \N \N \N \N \N
+11 \N \N \N \N \N \N \N \N
+12 \N \N \N \N \N \N \N \N
+13 \N \N \N \N \N \N \N \N
+2 00:00 00:00:00 00:00 00.000001 00:00 00:00:00
00:00 00.000001
+3 23:59 23:59:59 59:59 59.999999 23:59 23:59:59
59:59 59.999999
+4 01:02 01:02:03 02:03 03.000000 01:02 01:02:03
02:03 03.000000
+5 \N \N \N \N \N \N \N \N
+6 \N \N \N \N \N \N \N \N
+7 \N \N \N \N \N \N \N \N
+8 \N \N \N \N \N \N \N \N
+9 \N \N \N \N \N \N \N \N
+
+-- !be_wrapped_0 --
+\N \N \N \N \N \N \N \N
+
+-- !be_wrapped_1 --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !be_wrapped_2 --
+\N \N \N \N \N \N \N \N
+
+-- !be_wrapped_3 --
+\N \N \N \N \N \N \N \N
+
+-- !runtime_literal_0 --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !runtime_literal_1 --
+00:00 00:00:00 00:00 00.000001 00:00 00:00:00 00:00
00.000001
+
+-- !runtime_literal_2 --
+23:59 23:59:59 59:59 59.999999 23:59 23:59:59 59:59
59.999999
+
+-- !runtime_literal_3 --
+01:02 01:02:03 02:03 03.000000 01:02 01:02:03 02:03
03.000000
+
+-- !runtime_literal_4 --
+12:34 12:34:56 34:56 56.700000 12:34 12:34:56 34:56
56.700000
+
+-- !runtime_literal_5 --
+123:34 123:34:56 34:56 56.789123 123:34 123:34:56 34:56
56.789123
+
+-- !runtime_literal_6 --
+-12:34 -12:34:56 -34:56 -56.789123 -12:34 -12:34:56 -34:56
-56.789123
+
+-- !runtime_literal_7 --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !runtime_literal_8 --
+\N \N \N \N \N \N \N \N
+
+-- !runtime_literal_9 --
+\N \N \N \N \N \N \N \N
+
+-- !runtime_explicit_time --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !runtime_time_zero_scale --
+12:34 12:34:56 34:56 56.000000 12:34 12:34:56 34:56
56.000000
+
+-- !runtime_timestamp_ns --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !runtime_string_column --
+1 \N \N \N \N \N \N \N \N
+10 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+11 \N \N \N \N \N \N \N \N
+12 \N \N \N \N \N \N \N \N
+13 \N \N \N \N \N \N \N \N
+2 \N \N \N \N \N \N \N \N
+3 \N \N \N \N \N \N \N \N
+4 00:00 00:00:00 00:00 00.000000 00:00 00:00:00
00:00 00.000000
+5 \N \N \N \N \N \N \N \N
+6 \N \N \N \N \N \N \N \N
+7 \N \N \N \N \N \N \N \N
+8 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+9 00:00 00:00:00 00:00 00.000000 00:00 00:00:00
00:00 00.000000
+
+-- !runtime_string_type --
+1 \N \N \N \N \N \N \N \N
+10 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+11 \N \N \N \N \N \N \N \N
+12 \N \N \N \N \N \N \N \N
+13 \N \N \N \N \N \N \N \N
+2 \N \N \N \N \N \N \N \N
+3 \N \N \N \N \N \N \N \N
+4 00:00 00:00:00 00:00 00.000000 00:00 00:00:00
00:00 00.000000
+5 \N \N \N \N \N \N \N \N
+6 \N \N \N \N \N \N \N \N
+7 \N \N \N \N \N \N \N \N
+8 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+9 00:00 00:00:00 00:00 00.000000 00:00 00:00:00
00:00 00.000000
+
+-- !runtime_char_type --
+1 \N \N \N \N \N \N \N \N
+10 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+11 \N \N \N \N \N \N \N \N
+12 \N \N \N \N \N \N \N \N
+13 \N \N \N \N \N \N \N \N
+2 \N \N \N \N \N \N \N \N
+3 \N \N \N \N \N \N \N \N
+4 00:00 00:00:00 00:00 00.000000 00:00 00:00:00
00:00 00.000000
+5 \N \N \N \N \N \N \N \N
+6 \N \N \N \N \N \N \N \N
+7 \N \N \N \N \N \N \N \N
+8 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+9 00:00 00:00:00 00:00 00.000000 00:00 00:00:00
00:00 00.000000
+
+-- !runtime_time_column --
+1 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+10 \N \N \N \N \N \N \N \N
+11 \N \N \N \N \N \N \N \N
+12 \N \N \N \N \N \N \N \N
+13 \N \N \N \N \N \N \N \N
+2 00:00 00:00:00 00:00 00.000001 00:00 00:00:00
00:00 00.000001
+3 23:59 23:59:59 59:59 59.999999 23:59 23:59:59
59:59 59.999999
+4 01:02 01:02:03 02:03 03.000000 01:02 01:02:03
02:03 03.000000
+5 12:34 12:34:56 34:56 56.700000 12:34 12:34:56
34:56 56.700000
+6 123:34 123:34:56 34:56 56.789123 123:34 123:34:56
34:56 56.789123
+7 -12:34 -12:34:56 -34:56 -56.789123 -12:34 -12:34:56
-34:56 -56.789123
+8 \N \N \N \N \N \N \N \N
+9 \N \N \N \N \N \N \N \N
+
+-- !runtime_datetime_column --
+1 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+10 \N \N \N \N \N \N \N \N
+11 \N \N \N \N \N \N \N \N
+12 \N \N \N \N \N \N \N \N
+13 \N \N \N \N \N \N \N \N
+2 00:00 00:00:00 00:00 00.000001 00:00 00:00:00
00:00 00.000001
+3 23:59 23:59:59 59:59 59.999999 23:59 23:59:59
59:59 59.999999
+4 01:02 01:02:03 02:03 03.000000 01:02 01:02:03
02:03 03.000000
+5 \N \N \N \N \N \N \N \N
+6 \N \N \N \N \N \N \N \N
+7 \N \N \N \N \N \N \N \N
+8 \N \N \N \N \N \N \N \N
+9 \N \N \N \N \N \N \N \N
+
+-- !runtime_wrapped_0 --
+\N \N \N \N \N \N \N \N
+
+-- !runtime_wrapped_1 --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !runtime_wrapped_2 --
+\N \N \N \N \N \N \N \N
+
+-- !runtime_wrapped_3 --
+\N \N \N \N \N \N \N \N
+
+-- !strict_fe_time_literal --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !strict_fe_explicit_time --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !strict_fe_datetime_and_null --
+13 \N \N \N \N \N \N \N \N
+8 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+
+-- !strict_fe_time_column --
+1 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+2 00:00 00:00:00 00:00 00.000001 00:00 00:00:00
00:00 00.000001
+3 23:59 23:59:59 59:59 59.999999 23:59 23:59:59
59:59 59.999999
+4 01:02 01:02:03 02:03 03.000000 01:02 01:02:03
02:03 03.000000
+5 12:34 12:34:56 34:56 56.700000 12:34 12:34:56
34:56 56.700000
+6 123:34 123:34:56 34:56 56.789123 123:34 123:34:56
34:56 56.789123
+7 -12:34 -12:34:56 -34:56 -56.789123 -12:34 -12:34:56
-34:56 -56.789123
+
+-- !strict_fe_wrapped_datetime --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !strict_be_time_literal --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !strict_be_explicit_time --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !strict_be_datetime_and_null --
+13 \N \N \N \N \N \N \N \N
+8 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+
+-- !strict_be_time_column --
+1 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+2 00:00 00:00:00 00:00 00.000001 00:00 00:00:00
00:00 00.000001
+3 23:59 23:59:59 59:59 59.999999 23:59 23:59:59
59:59 59.999999
+4 01:02 01:02:03 02:03 03.000000 01:02 01:02:03
02:03 03.000000
+5 12:34 12:34:56 34:56 56.700000 12:34 12:34:56
34:56 56.700000
+6 123:34 123:34:56 34:56 56.789123 123:34 123:34:56
34:56 56.789123
+7 -12:34 -12:34:56 -34:56 -56.789123 -12:34 -12:34:56
-34:56 -56.789123
+
+-- !strict_be_wrapped_datetime --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !strict_runtime_time_literal --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !strict_runtime_explicit_time --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
+-- !strict_runtime_datetime_and_null --
+13 \N \N \N \N \N \N \N \N
+8 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+
+-- !strict_runtime_time_column --
+1 12:34 12:34:56 34:56 56.789123 12:34 12:34:56
34:56 56.789123
+2 00:00 00:00:00 00:00 00.000001 00:00 00:00:00
00:00 00.000001
+3 23:59 23:59:59 59:59 59.999999 23:59 23:59:59
59:59 59.999999
+4 01:02 01:02:03 02:03 03.000000 01:02 01:02:03
02:03 03.000000
+5 12:34 12:34:56 34:56 56.700000 12:34 12:34:56
34:56 56.700000
+6 123:34 123:34:56 34:56 56.789123 123:34 123:34:56
34:56 56.789123
+7 -12:34 -12:34:56 -34:56 -56.789123 -12:34 -12:34:56
-34:56 -56.789123
+
+-- !strict_runtime_wrapped_datetime --
+12:34 12:34:56 34:56 56.789123 12:34 12:34:56 34:56
56.789123
+
diff --git
a/regression-test/suites/query_p0/sql_functions/datetime_functions/test_composite_time_extract.groovy
b/regression-test/suites/query_p0/sql_functions/datetime_functions/test_composite_time_extract.groovy
new file mode 100644
index 00000000000..bb64a54e157
--- /dev/null
+++
b/regression-test/suites/query_p0/sql_functions/datetime_functions/test_composite_time_extract.groovy
@@ -0,0 +1,127 @@
+// 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.
+
+suite("test_composite_time_extract") {
+ sql "set enable_strict_cast = false"
+ sql "drop table if exists test_composite_time_extract"
+ sql """
+ create table test_composite_time_extract (
+ id int,
+ time_str varchar(64),
+ date_time datetimev2(6)
+ ) duplicate key(id)
+ distributed by hash(id) buckets 1
+ properties("replication_num" = "1")
+ """
+ sql """
+ insert into test_composite_time_extract values
+ (1, '12:34:56.789123', '2024-01-02 12:34:56.789123'),
+ (2, '00:00:00.000001', '2024-01-02 00:00:00.000001'),
+ (3, '23:59:59.999999', '2024-01-02 23:59:59.999999'),
+ (4, '01:02:03', '2024-01-02 01:02:03'),
+ (5, '12:34:56.7', null),
+ (6, '123:34:56.789123', null),
+ (7, '-12:34:56.789123', null),
+ (8, '2024-01-02 12:34:56.789123', null),
+ (9, '2024-01-02', null),
+ (10, '2024-01-02 12:34:56.789123+08:00', null),
+ (11, 'invalid_time', null),
+ (12, '12:60:56.789123', null),
+ (13, null, null)
+ """
+
+ def fields = ['hour_minute', 'hour_second', 'minute_second',
'second_microsecond']
+ def selections = { argument ->
+ fields.collect { "${it}(${argument})" } +
+ fields.collect { "extract(${it} from ${argument})" }
+ }
+ def literals = ["'12:34:56.789123'", "'00:00:00.000001'",
"'23:59:59.999999'",
+ "'01:02:03'", "'12:34:56.7'", "'123:34:56.789123'",
"'-12:34:56.789123'",
+ "'2024-01-02 12:34:56.789123'", "'invalid_time'", "null"]
+
+ // Exercise FE folding, BE folding, and execution without constant folding.
+ ['fe', 'be', 'runtime'].each { mode ->
+ sql "set enable_fold_constant_by_be = ${mode == 'be'}"
+ sql "set debug_skip_fold_constant = ${mode == 'runtime'}"
+ literals.eachWithIndex { literal, i ->
+ "order_qt_${mode}_literal_${i}"("select " +
selections(literal).join(', '))
+ }
+ "order_qt_${mode}_explicit_time"("select " +
+ selections("cast('12:34:56.789123' as time(6))").join(', '))
+ "order_qt_${mode}_time_zero_scale"("select " +
+ selections("cast('12:34:56' as time)").join(', '))
+ "order_qt_${mode}_timestamp_ns"("select " +
+ selections("cast('2024-01-02 12:34:56.789123456' as
timestamp_ns)").join(', '))
+ "order_qt_${mode}_string_column"("select id, " +
selections('time_str').join(', ') +
+ " from test_composite_time_extract")
+ "order_qt_${mode}_string_type"("select id, " +
+ selections('cast(time_str as string)').join(', ') + " from
test_composite_time_extract")
+ "order_qt_${mode}_char_type"("select id, " +
+ selections('cast(time_str as char(64))').join(', ') + " from
test_composite_time_extract")
+ "order_qt_${mode}_time_column"("select id, " +
+ selections('cast(time_str as time(6))').join(', ') + " from
test_composite_time_extract")
+ "order_qt_${mode}_datetime_column"("select id, " +
selections('date_time').join(', ') +
+ " from test_composite_time_extract")
+ ["concat('12:34:56', '.789123')", "concat('2024-01-02 ',
'12:34:56.789123')",
+ "concat('invalid_', 'time')", "concat(null, '')"].eachWithIndex {
argument, i ->
+ "order_qt_${mode}_wrapped_${i}"("select " +
selections(argument).join(', '))
+ }
+ }
+
+ // String columns and expressions use the same DATETIME conversion as
simple
+ // extraction functions. TIME literals and explicit TIME casts still
select TIME.
+ sql "set enable_strict_cast = true"
+ ['fe', 'be', 'runtime'].each { mode ->
+ sql "set enable_fold_constant_by_be = ${mode == 'be'}"
+ sql "set debug_skip_fold_constant = ${mode == 'runtime'}"
+ "order_qt_strict_${mode}_time_literal"("select " +
selections("'12:34:56.789123'").join(', '))
+ "order_qt_strict_${mode}_explicit_time"("select " +
+ selections("cast('12:34:56.789123' as time(6))").join(', '))
+ "order_qt_strict_${mode}_datetime_and_null"("select id, " +
selections('time_str').join(', ') +
+ " from test_composite_time_extract where id in (8, 13)")
+ "order_qt_strict_${mode}_time_column"("select id, " +
+ selections('cast(time_str as time(6))').join(', ') +
+ " from test_composite_time_extract where id between 1 and 7")
+ "order_qt_strict_${mode}_wrapped_datetime"("select " +
+ selections("concat('2024-01-02 ', '12:34:56.789123')").join(',
'))
+ ['time_str', 'cast(time_str as string)', 'cast(time_str as
char(64))'].each { argument ->
+ selections(argument).each { expression ->
+ test {
+ sql "select ${expression} from test_composite_time_extract
where id = 1"
+ exception "12:34:56.789123"
+ }
+ }
+ }
+ ["'invalid_time'": 'invalid_time',
+ "concat('12:34:56', '.789123')": '12:34:56.789123'].each { argument,
value ->
+ selections(argument).each { expression ->
+ test {
+ sql "select ${expression}"
+ exception value
+ }
+ }
+ }
+ // Aggregate normalization deep-folds constant keys before ordinary
+ // expression rewrites. A failed source CAST must remain an error.
+ selections("cast(cast('bad' as int) as varchar(20))").each {
expression ->
+ test {
+ sql "select count(*) from test_composite_time_extract group by
${expression}"
+ exception "bad can't cast to"
+ }
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]