From f5c40e8aff5d0ec33836d64dcf339c6ecd0b9cfa Mon Sep 17 00:00:00 2001 From: Ambuj Upadhyay Date: Thu, 27 Aug 2026 23:57:06 +0530 Subject: [PATCH] [fix](nereids) Prefer DATETIMEV2 over TIMESTAMPTZ when binding *_diff functions on non-literal string args All 12 *_diff scalar functions listed their TIMESTAMPTZ signature first in SIGNATURES. SearchSignature's timezone-coercion penalty only fires for literals it can inspect (ExpressionUtils.getLiteralAfterUnwrapNullable, #64127), so for a string-typed non-literal argument (varchar column, subquery projection slot, UNION-ALL output slot) every candidate signature ties and the tie-break keeps the first-listed candidate: TIMESTAMPTZ. The value is then cast through timestamptz(6), which treats it as session-local time and shifts it to UTC, so results are off-by-one under any non-UTC session time_zone. Move the TimeStampTz signature to last in each file. Literal-with-timezone arguments still route to TIMESTAMPTZ via the timeZoneCoersionScore branch, and typed TIMESTAMPTZ / DATETIMEV2 / DATEV2 arguments still bind their identical-match signatures; only the previously order-decided tie for non-literal string arguments changes, to DATETIMEV2 (wall-clock semantics). New DiffFunctionSignatureTest covers all 12 functions in both directions: varchar slots bind DATETIMEV2 (fails before this change), timestamptz slots still bind TIMESTAMPTZ. Fixes #66120 --- .../functions/scalar/DateDiff.java | 6 +- .../functions/scalar/DaysDiff.java | 4 +- .../functions/scalar/HoursDiff.java | 6 +- .../functions/scalar/MicroSecondsDiff.java | 5 +- .../functions/scalar/MilliSecondsDiff.java | 5 +- .../functions/scalar/MinutesDiff.java | 6 +- .../functions/scalar/MonthsDiff.java | 6 +- .../functions/scalar/QuartersDiff.java | 7 +- .../functions/scalar/SecondsDiff.java | 6 +- .../functions/scalar/TimeDiff.java | 6 +- .../functions/scalar/WeeksDiff.java | 6 +- .../functions/scalar/YearsDiff.java | 6 +- .../scalar/DiffFunctionSignatureTest.java | 101 ++++++++++++++++++ 13 files changed, 134 insertions(+), 36 deletions(-) create mode 100644 fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DiffFunctionSignatureTest.java diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DateDiff.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DateDiff.java index 2d766295f649b4..cea905fade0826 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DateDiff.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DateDiff.java @@ -40,11 +40,11 @@ public class DateDiff extends ScalarFunction implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullable { public static final List SIGNATURES = ImmutableList.of( - FunctionSignature.ret(IntegerType.INSTANCE) - .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD), FunctionSignature.ret(IntegerType.INSTANCE) .args(DateTimeV2Type.WILDCARD, DateTimeV2Type.WILDCARD), - FunctionSignature.ret(IntegerType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE)); + FunctionSignature.ret(IntegerType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE), + FunctionSignature.ret(IntegerType.INSTANCE) + .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD)); /** * constructor with 2 arguments. diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DaysDiff.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DaysDiff.java index 012ad7c6399c26..ae02922a63d36f 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DaysDiff.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DaysDiff.java @@ -42,9 +42,9 @@ public class DaysDiff extends ScalarFunction implements BinaryExpression, Explic PropagateNullable, DateDiffMonotonic { private static final List SIGNATURES = ImmutableList.of( - FunctionSignature.ret(BigIntType.INSTANCE).args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD), FunctionSignature.ret(BigIntType.INSTANCE).args(DateTimeV2Type.WILDCARD, DateTimeV2Type.WILDCARD), - FunctionSignature.ret(BigIntType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE)); + FunctionSignature.ret(BigIntType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE), + FunctionSignature.ret(BigIntType.INSTANCE).args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD)); /** * constructor with 2 arguments. diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HoursDiff.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HoursDiff.java index c601497c45de27..eb32eb29caedcd 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HoursDiff.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HoursDiff.java @@ -42,11 +42,11 @@ public class HoursDiff extends ScalarFunction implements BinaryExpression, Expli PropagateNullable, DateDiffMonotonic { public static final List SIGNATURES = ImmutableList.of( - FunctionSignature.ret(BigIntType.INSTANCE) - .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD), FunctionSignature.ret(BigIntType.INSTANCE) .args(DateTimeV2Type.WILDCARD, DateTimeV2Type.WILDCARD), - FunctionSignature.ret(BigIntType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE)); + FunctionSignature.ret(BigIntType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE), + FunctionSignature.ret(BigIntType.INSTANCE) + .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD)); /** * constructor with 2 arguments. diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MicroSecondsDiff.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MicroSecondsDiff.java index 26081a347a05e4..3cf8304f6e1914 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MicroSecondsDiff.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MicroSecondsDiff.java @@ -42,10 +42,9 @@ public class MicroSecondsDiff extends ScalarFunction implements BinaryExpression private static final List SIGNATURES = ImmutableList.of( FunctionSignature.ret(BigIntType.INSTANCE) - .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD), + .args(DateTimeV2Type.WILDCARD, DateTimeV2Type.WILDCARD), FunctionSignature.ret(BigIntType.INSTANCE) - .args(DateTimeV2Type.WILDCARD, DateTimeV2Type.WILDCARD) - ); + .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD)); /** * constructor with 2 arguments. diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MilliSecondsDiff.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MilliSecondsDiff.java index 9cda6cb8e4ad2e..6634cc9ec6203d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MilliSecondsDiff.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MilliSecondsDiff.java @@ -42,10 +42,9 @@ public class MilliSecondsDiff extends ScalarFunction implements BinaryExpression private static final List SIGNATURES = ImmutableList.of( FunctionSignature.ret(BigIntType.INSTANCE) - .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD), + .args(DateTimeV2Type.WILDCARD, DateTimeV2Type.WILDCARD), FunctionSignature.ret(BigIntType.INSTANCE) - .args(DateTimeV2Type.WILDCARD, DateTimeV2Type.WILDCARD) - ); + .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD)); /** * constructor with 2 arguments. diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MinutesDiff.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MinutesDiff.java index f1a320932f09d4..972e59d269d1ca 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MinutesDiff.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MinutesDiff.java @@ -42,11 +42,11 @@ public class MinutesDiff extends ScalarFunction implements BinaryExpression, Exp PropagateNullable, DateDiffMonotonic { private static final List SIGNATURES = ImmutableList.of( - FunctionSignature.ret(BigIntType.INSTANCE) - .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD), FunctionSignature.ret(BigIntType.INSTANCE) .args(DateTimeV2Type.WILDCARD, DateTimeV2Type.WILDCARD), - FunctionSignature.ret(BigIntType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE)); + FunctionSignature.ret(BigIntType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE), + FunctionSignature.ret(BigIntType.INSTANCE) + .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD)); /** * constructor with 2 arguments. diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MonthsDiff.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MonthsDiff.java index 7c11156861b87f..31a8ae3aa09850 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MonthsDiff.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MonthsDiff.java @@ -42,11 +42,11 @@ public class MonthsDiff extends ScalarFunction implements BinaryExpression, Expl PropagateNullable, DateDiffMonotonic { private static final List SIGNATURES = ImmutableList.of( - FunctionSignature.ret(BigIntType.INSTANCE) - .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD), FunctionSignature.ret(BigIntType.INSTANCE) .args(DateTimeV2Type.WILDCARD, DateTimeV2Type.WILDCARD), - FunctionSignature.ret(BigIntType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE)); + FunctionSignature.ret(BigIntType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE), + FunctionSignature.ret(BigIntType.INSTANCE) + .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD)); /** * constructor with 2 arguments. diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/QuartersDiff.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/QuartersDiff.java index ec8f889baa5621..f450454b13815d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/QuartersDiff.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/QuartersDiff.java @@ -42,12 +42,11 @@ public class QuartersDiff extends ScalarFunction implements BinaryExpression, Ex PropagateNullable, DateDiffMonotonic { private static final List SIGNATURES = ImmutableList.of( - FunctionSignature.ret(BigIntType.INSTANCE) - .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD), FunctionSignature.ret(BigIntType.INSTANCE) .args(DateTimeV2Type.WILDCARD, DateTimeV2Type.WILDCARD), - FunctionSignature.ret(BigIntType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE) - ); + FunctionSignature.ret(BigIntType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE), + FunctionSignature.ret(BigIntType.INSTANCE) + .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD)); /** * constructor with 2 arguments. diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecondsDiff.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecondsDiff.java index bb7df199d284ca..3eea019c39490a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecondsDiff.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecondsDiff.java @@ -42,11 +42,11 @@ public class SecondsDiff extends ScalarFunction implements BinaryExpression, Exp PropagateNullable, DateDiffMonotonic { private static final List SIGNATURES = ImmutableList.of( - FunctionSignature.ret(BigIntType.INSTANCE) - .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD), FunctionSignature.ret(BigIntType.INSTANCE) .args(DateTimeV2Type.WILDCARD, DateTimeV2Type.WILDCARD), - FunctionSignature.ret(BigIntType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE)); + FunctionSignature.ret(BigIntType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE), + FunctionSignature.ret(BigIntType.INSTANCE) + .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD)); /** * constructor with 2 arguments. diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/TimeDiff.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/TimeDiff.java index a25ce2d45f84bb..020e1f6978ca7c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/TimeDiff.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/TimeDiff.java @@ -40,11 +40,11 @@ public class TimeDiff extends ScalarFunction implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullable { private static final List SIGNATURES = ImmutableList.of( - FunctionSignature.ret(TimeV2Type.WILDCARD) - .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD), FunctionSignature.ret(TimeV2Type.WILDCARD) .args(DateTimeV2Type.WILDCARD, DateTimeV2Type.WILDCARD), - FunctionSignature.ret(TimeV2Type.SYSTEM_DEFAULT).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE)); + FunctionSignature.ret(TimeV2Type.SYSTEM_DEFAULT).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE), + FunctionSignature.ret(TimeV2Type.WILDCARD) + .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD)); /** * constructor with 2 arguments. diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/WeeksDiff.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/WeeksDiff.java index 771d43d2cb3da5..1fb945344cfe07 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/WeeksDiff.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/WeeksDiff.java @@ -42,11 +42,11 @@ public class WeeksDiff extends ScalarFunction implements BinaryExpression, Expli PropagateNullable, DateDiffMonotonic { private static final List SIGNATURES = ImmutableList.of( - FunctionSignature.ret(BigIntType.INSTANCE) - .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD), FunctionSignature.ret(BigIntType.INSTANCE) .args(DateTimeV2Type.WILDCARD, DateTimeV2Type.WILDCARD), - FunctionSignature.ret(BigIntType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE)); + FunctionSignature.ret(BigIntType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE), + FunctionSignature.ret(BigIntType.INSTANCE) + .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD)); /** * constructor with 2 arguments. diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/YearsDiff.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/YearsDiff.java index da227338e0ad0c..634271efc0f767 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/YearsDiff.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/YearsDiff.java @@ -42,11 +42,11 @@ public class YearsDiff extends ScalarFunction implements BinaryExpression, Expli PropagateNullable, DateDiffMonotonic { private static final List SIGNATURES = ImmutableList.of( - FunctionSignature.ret(BigIntType.INSTANCE) - .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD), FunctionSignature.ret(BigIntType.INSTANCE) .args(DateTimeV2Type.WILDCARD, DateTimeV2Type.WILDCARD), - FunctionSignature.ret(BigIntType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE)); + FunctionSignature.ret(BigIntType.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE), + FunctionSignature.ret(BigIntType.INSTANCE) + .args(TimeStampTzType.WILDCARD, TimeStampTzType.WILDCARD)); /** * constructor with 2 arguments. diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DiffFunctionSignatureTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DiffFunctionSignatureTest.java new file mode 100644 index 00000000000000..1a213626eb2579 --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DiffFunctionSignatureTest.java @@ -0,0 +1,101 @@ +// 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.catalog.FunctionSignature; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.SlotReference; +import org.apache.doris.nereids.trees.expressions.functions.ComputeSignature; +import org.apache.doris.nereids.types.DateTimeV2Type; +import org.apache.doris.nereids.types.TimeStampTzType; +import org.apache.doris.nereids.types.VarcharType; + +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.BiFunction; + +/** + * Regression tests for apache/doris#66120. + * + *

All 12 Nereids {@code *_diff} scalar functions used to list their TIMESTAMPTZ signature + * FIRST in SIGNATURES. {@code SearchSignature}'s timezone-coercion tie-break only fires for + * inspectable literals ({@code ExpressionUtils.getLiteralAfterUnwrapNullable}), so a + * non-literal VARCHAR-typed argument (varchar column, subquery slot, UNION slot) ties across + * every candidate signature and the tie-break falls through to "keep the first-listed + * candidate" - which was always TIMESTAMPTZ. Casting a plain varchar through timestamptz(6) + * silently UTC-shifts the value whenever the session {@code time_zone} is not UTC. + * + *

The fix moves each file's TimeStampTz signature to LAST in SIGNATURES, so the tie + * resolves to DATETIMEV2 instead. Non-literal TIMESTAMPTZ-typed arguments must still bind to + * the TimeStampTzType signature - this class also guards against that regressing. + */ +public class DiffFunctionSignatureTest { + + private static final List DIFF_CONSTRUCTORS = ImmutableList.of( + new NamedDiffConstructor("DateDiff", DateDiff::new), + new NamedDiffConstructor("DaysDiff", DaysDiff::new), + new NamedDiffConstructor("HoursDiff", HoursDiff::new), + new NamedDiffConstructor("MicroSecondsDiff", MicroSecondsDiff::new), + new NamedDiffConstructor("MilliSecondsDiff", MilliSecondsDiff::new), + new NamedDiffConstructor("MinutesDiff", MinutesDiff::new), + new NamedDiffConstructor("MonthsDiff", MonthsDiff::new), + new NamedDiffConstructor("QuartersDiff", QuartersDiff::new), + new NamedDiffConstructor("SecondsDiff", SecondsDiff::new), + new NamedDiffConstructor("TimeDiff", TimeDiff::new), + new NamedDiffConstructor("WeeksDiff", WeeksDiff::new), + new NamedDiffConstructor("YearsDiff", YearsDiff::new)); + + @Test + public void testVarcharSlotsBindToDateTimeV2NotTimeStampTz() { + SlotReference left = SlotReference.of("a", VarcharType.SYSTEM_DEFAULT); + SlotReference right = SlotReference.of("b", VarcharType.SYSTEM_DEFAULT); + for (NamedDiffConstructor c : DIFF_CONSTRUCTORS) { + FunctionSignature signature = c.constructor.apply(left, right).getSignature(); + Assertions.assertInstanceOf(DateTimeV2Type.class, signature.getArgType(0), + c.name + ": varchar arg0 should bind to DateTimeV2Type, not TimeStampTzType (issue #66120)"); + Assertions.assertInstanceOf(DateTimeV2Type.class, signature.getArgType(1), + c.name + ": varchar arg1 should bind to DateTimeV2Type, not TimeStampTzType (issue #66120)"); + } + } + + @Test + public void testTimeStampTzSlotsStillBindToTimeStampTz() { + SlotReference left = SlotReference.of("a", TimeStampTzType.of(6)); + SlotReference right = SlotReference.of("b", TimeStampTzType.of(6)); + for (NamedDiffConstructor c : DIFF_CONSTRUCTORS) { + FunctionSignature signature = c.constructor.apply(left, right).getSignature(); + Assertions.assertInstanceOf(TimeStampTzType.class, signature.getArgType(0), + c.name + ": timestamptz arg0 should still bind to TimeStampTzType"); + Assertions.assertInstanceOf(TimeStampTzType.class, signature.getArgType(1), + c.name + ": timestamptz arg1 should still bind to TimeStampTzType"); + } + } + + private static final class NamedDiffConstructor { + private final String name; + private final BiFunction constructor; + + private NamedDiffConstructor(String name, BiFunction constructor) { + this.name = name; + this.constructor = constructor; + } + } +}