diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java index f00c4c5f9d2..3dbc6be3231 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java @@ -974,11 +974,14 @@ static RelDataType deriveTypeSplit(SqlOperatorBinding operatorBinding, SqlTypeFamily.ANY)); /** The "DATE_TRUNC(date, timeUnit)" function (BigQuery); - * truncates a DATE value to the beginning of a timeUnit. */ + * truncates a DATE value to the beginning of a timeUnit. + * + * TODO(CALCITE-5290): Add `DATE_TRUNC` function consistent with Postgres. Currently, Postgres + * style calls can be parsed but fail validation. */ @LibraryOperator(libraries = {BIG_QUERY}) public static final SqlFunction DATE_TRUNC = SqlBasicFunction.create("DATE_TRUNC", - ReturnTypes.DATE_NULLABLE, + ReturnTypes.FIRST_DATETIME_ARG, OperandTypes.sequence("'DATE_TRUNC(, )'", OperandTypes.DATE, OperandTypes.dateInterval()), SqlFunctionCategory.TIMEDATE) diff --git a/core/src/main/java/org/apache/calcite/sql/type/ReturnTypes.java b/core/src/main/java/org/apache/calcite/sql/type/ReturnTypes.java index ab4aac17843..fa795d044eb 100644 --- a/core/src/main/java/org/apache/calcite/sql/type/ReturnTypes.java +++ b/core/src/main/java/org/apache/calcite/sql/type/ReturnTypes.java @@ -275,6 +275,23 @@ public static SqlCall stripSeparator(SqlCall call) { return type1; }; + /** + * Type-inference strategy that uses the first operand that is a member of + * {@link SqlTypeFamily#DATETIME} as the return type. + */ + public static final SqlReturnTypeInference FIRST_DATETIME_ARG = + opBinding -> { + final int n = opBinding.getOperandCount(); + RelDataType type1 = null; + for (int i = 0; i < n; i++) { + type1 = opBinding.getOperandType(i); + if (SqlTypeUtil.isDatetime(type1)) { + break; + } + } + return type1; + }; + /** * Type-inference strategy whereby the result type of a call is a nullable * Boolean.