This is an automated email from the ASF dual-hosted git repository. jhyde pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/calcite.git
commit bb94122fa43df86a2ef57fa375e3dc7792666eac Author: Julian Hyde <[email protected]> AuthorDate: Fri Jun 28 19:16:23 2024 -0700 Rework [CALCITE-5869] LEAST_RESTRICTIVE does not use inner type of MEASURE for comparisons --- .../java/org/apache/calcite/sql/SqlOperator.java | 6 ------ .../org/apache/calcite/sql/SqlOperatorBinding.java | 22 ++++++++++++++++++++++ .../calcite/sql/fun/SqlLibraryOperators.java | 3 ++- .../org/apache/calcite/sql/type/ReturnTypes.java | 16 ++++++++++++---- .../apache/calcite/sql/type/SqlTypeTransform.java | 5 +++++ .../apache/calcite/sql/type/SqlTypeTransforms.java | 8 ++++++++ 6 files changed, 49 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/org/apache/calcite/sql/SqlOperator.java b/core/src/main/java/org/apache/calcite/sql/SqlOperator.java index 58fc0e5b5b..342113b306 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlOperator.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlOperator.java @@ -48,7 +48,6 @@ import java.util.Objects; import java.util.function.Supplier; import static org.apache.calcite.linq4j.Nullness.castNonNull; -import static org.apache.calcite.sql.type.SqlTypeUtil.isMeasure; import static org.apache.calcite.util.Static.RESOURCE; import static java.util.Objects.requireNonNull; @@ -538,11 +537,6 @@ public abstract class SqlOperator { + opBinding.collectOperandTypes()); } - // MEASURE wrapper should be removed, e.g. MEASURE<DOUBLE> should just be DOUBLE - if (isMeasure(returnType) && returnType.getMeasureElementType() != null) { - returnType = Objects.requireNonNull(returnType.getMeasureElementType()); - } - if (operandTypeInference != null && opBinding instanceof SqlCallBinding && this instanceof SqlFunction) { diff --git a/core/src/main/java/org/apache/calcite/sql/SqlOperatorBinding.java b/core/src/main/java/org/apache/calcite/sql/SqlOperatorBinding.java index 439ddb6ead..17c9e84e30 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlOperatorBinding.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlOperatorBinding.java @@ -23,6 +23,7 @@ import org.apache.calcite.rel.type.RelDataTypeFactoryImpl; import org.apache.calcite.runtime.CalciteException; import org.apache.calcite.runtime.Resources; import org.apache.calcite.sql.type.SqlTypeName; +import org.apache.calcite.sql.type.SqlTypeTransform; import org.apache.calcite.sql.validate.SqlMonotonicity; import org.apache.calcite.sql.validate.SqlValidatorException; import org.apache.calcite.util.NlsString; @@ -299,4 +300,25 @@ public abstract class SqlOperatorBinding { */ public abstract CalciteException newError( Resources.ExInst<SqlValidatorException> e); + + /** Returns an operator binding equivalent that is equivalent to this + * except that a transform has been applied to each operand type. */ + public SqlOperatorBinding transform(SqlTypeTransform typeTransform) { + final SqlOperatorBinding operatorBinding = this; + return new SqlOperatorBinding(typeFactory, sqlOperator) { + @Override public int getOperandCount() { + return operatorBinding.getOperandCount(); + } + + @Override public RelDataType getOperandType(int ordinal) { + return typeTransform.transformType(operatorBinding, + operatorBinding.getOperandType(ordinal)); + } + + @Override public CalciteException newError( + Resources.ExInst<SqlValidatorException> e) { + return operatorBinding.newError(e); + } + }; + } } 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 8d98f3fbe3..7d7795b63b 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 @@ -98,7 +98,8 @@ public abstract class SqlLibraryOperators { @LibraryOperator(libraries = {CALCITE}) public static final SqlFunction AGGREGATE = SqlBasicAggFunction.create("AGGREGATE", SqlKind.AGGREGATE_FN, - ReturnTypes.ARG0, OperandTypes.MEASURE); + ReturnTypes.ARG0.andThen(SqlTypeTransforms.FROM_MEASURE), + OperandTypes.MEASURE); /** The "CONVERT_TIMEZONE(tz1, tz2, datetime)" function; * converts the timezone of {@code datetime} from {@code tz1} to {@code tz2}. 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 f8aaff072c..ea8cd95cfa 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 @@ -34,6 +34,8 @@ import org.apache.calcite.sql.validate.SqlValidatorNamespace; import org.apache.calcite.util.Glossary; import org.apache.calcite.util.Util; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.AbstractList; import java.util.Arrays; import java.util.List; @@ -570,8 +572,14 @@ public abstract class ReturnTypes { * @see Glossary#SQL99 SQL:1999 Part 2 Section 9.3 */ public static final SqlReturnTypeInference LEAST_RESTRICTIVE = - opBinding -> opBinding.getTypeFactory().leastRestrictive( - opBinding.collectOperandTypes()); + andThen(SqlTypeTransforms.FROM_MEASURE_IF::apply, + ReturnTypes::leastRestrictive); + + private static @Nullable RelDataType leastRestrictive( + SqlOperatorBinding opBinding) { + return opBinding.getTypeFactory() + .leastRestrictive(opBinding.collectOperandTypes()); + } /** * Type-inference strategy for NVL2 function. It returns the least restrictive type @@ -1412,6 +1420,6 @@ public abstract class ReturnTypes { } }; - public static final SqlReturnTypeInference PERCENTILE_DISC_CONT = opBinding -> - opBinding.getCollationType(); + public static final SqlReturnTypeInference PERCENTILE_DISC_CONT = + SqlOperatorBinding::getCollationType; } diff --git a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeTransform.java b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeTransform.java index ffdd96812d..9c555080b1 100644 --- a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeTransform.java +++ b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeTransform.java @@ -44,4 +44,9 @@ public interface SqlTypeTransform { RelDataType transformType( SqlOperatorBinding opBinding, RelDataType typeToTransform); + + /** Creates an operand type transform. */ + default SqlOperatorBinding apply(SqlOperatorBinding operatorBinding) { + return operatorBinding.transform(this); + } } diff --git a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeTransforms.java b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeTransforms.java index 2004125261..0c3c064586 100644 --- a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeTransforms.java +++ b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeTransforms.java @@ -256,6 +256,14 @@ public abstract class SqlTypeTransforms { (opBinding, typeToTransform) -> ((MeasureSqlType) typeToTransform).types.get(0); + /** Parameter type-inference transform that transforms {@code MEASURE<T>} to + * {@code T} for some type T, and does nothing to other types. */ + public static final SqlTypeTransform FROM_MEASURE_IF = + (opBinding, typeToTransform) -> + SqlTypeUtil.isMeasure(typeToTransform) + ? ((MeasureSqlType) typeToTransform).types.get(0) + : typeToTransform; + /** * Parameter type-inference transform strategy that wraps a given type in an array or * wraps a field of the given type in an array if the given type is struct with one field.
