From ba496831d530f6c09f6cf736cffd742a460320c9 Mon Sep 17 00:00:00 2001 From: Vladimir Sitnikov Date: Mon, 31 Aug 2020 01:16:09 +0300 Subject: [PATCH] WIP: core nullability --- .../calcite/adapter/clone/ColumnLoader.java | 2 +- .../calcite/adapter/jdbc/JdbcSchema.java | 6 +- .../calcite/adapter/jdbc/JdbcTable.java | 4 +- .../calcite/adapter/jdbc/JdbcUtils.java | 2 +- .../interpreter/BindableConvention.java | 4 +- .../apache/calcite/interpreter/Context.java | 4 +- .../calcite/jdbc/CachingCalciteSchema.java | 6 +- .../apache/calcite/jdbc/CalcitePrepare.java | 16 +++-- .../apache/calcite/jdbc/CalciteSchema.java | 28 +++++--- .../apache/calcite/jdbc/JavaCollation.java | 9 ++- .../java/org/apache/calcite/package-info.java | 7 ++ .../org/apache/calcite/plan/Contexts.java | 4 +- .../org/apache/calcite/plan/Convention.java | 4 +- .../calcite/plan/RelOptAbstractTable.java | 4 +- .../apache/calcite/plan/RelOptPlanner.java | 3 +- .../org/apache/calcite/plan/RelOptRule.java | 4 +- .../apache/calcite/plan/RelOptRuleCall.java | 9 +-- .../calcite/plan/RelOptRuleOperand.java | 12 ++-- .../org/apache/calcite/plan/RelOptSchema.java | 4 +- .../org/apache/calcite/plan/RelTrait.java | 4 +- .../org/apache/calcite/plan/RelTraitSet.java | 16 +++-- .../apache/calcite/plan/hep/HepPlanner.java | 4 +- .../calcite/plan/volcano/VolcanoPlanner.java | 3 +- .../calcite/prepare/CalciteCatalogReader.java | 8 ++- .../calcite/prepare/RelOptTableImpl.java | 6 +- .../apache/calcite/rel/AbstractRelNode.java | 16 +++-- .../java/org/apache/calcite/rel/RelNode.java | 9 +-- .../calcite/rel/convert/ConverterRule.java | 6 +- .../rel/convert/TraitMatchingRule.java | 4 +- .../apache/calcite/rel/core/Aggregate.java | 4 +- .../org/apache/calcite/rel/core/Calc.java | 4 +- .../apache/calcite/rel/core/Correlate.java | 6 +- .../org/apache/calcite/rel/core/Filter.java | 3 +- .../org/apache/calcite/rel/core/Join.java | 3 +- .../org/apache/calcite/rel/core/Project.java | 11 +-- .../org/apache/calcite/rel/core/Snapshot.java | 4 +- .../apache/calcite/rel/core/TableModify.java | 4 +- .../apache/calcite/rel/core/TableScan.java | 4 +- .../apache/calcite/rel/core/TableSpool.java | 4 +- .../org/apache/calcite/rel/core/Window.java | 2 +- .../calcite/rel/hint/HintStrategyTable.java | 4 +- .../rel/metadata/RelMetadataQuery.java | 70 ++++++++++--------- .../calcite/rel/rules/CoerceInputsRule.java | 4 +- .../calcite/rel/rules/ReduceDecimalsRule.java | 4 +- .../rel/type/DelegatingTypeSystem.java | 4 +- .../calcite/rel/type/RelDataTypeField.java | 2 + .../calcite/rel/type/RelDataTypeSystem.java | 12 ++-- .../rel/type/RelDataTypeSystemImpl.java | 4 +- .../java/org/apache/calcite/rex/RexCall.java | 2 +- .../org/apache/calcite/rex/RexChecker.java | 8 ++- .../org/apache/calcite/rex/RexLiteral.java | 10 +-- .../java/org/apache/calcite/rex/RexNode.java | 8 ++- .../org/apache/calcite/rex/RexSimplify.java | 4 +- .../java/org/apache/calcite/rex/RexUtil.java | 21 +++--- .../apache/calcite/rex/RexVisitorImpl.java | 4 +- .../runtime/CalciteContextException.java | 19 +++-- .../calcite/runtime/CalciteException.java | 1 + .../org/apache/calcite/runtime/FlatLists.java | 13 ++-- .../org/apache/calcite/runtime/Resources.java | 31 ++++---- .../org/apache/calcite/runtime/Utilities.java | 21 +++--- .../org/apache/calcite/schema/Schema.java | 6 +- .../org/apache/calcite/schema/SchemaPlus.java | 4 +- .../org/apache/calcite/schema/Wrapper.java | 4 +- .../calcite/schema/impl/AbstractSchema.java | 6 +- .../calcite/schema/impl/AbstractTable.java | 4 +- .../calcite/schema/impl/DelegatingSchema.java | 6 +- .../schema/impl/ModifiableViewTable.java | 4 +- .../sql/SqlAbstractDateTimeLiteral.java | 4 +- .../apache/calcite/sql/SqlAggFunction.java | 4 +- .../org/apache/calcite/sql/SqlBasicCall.java | 8 ++- .../apache/calcite/sql/SqlBinaryOperator.java | 13 ++-- .../java/org/apache/calcite/sql/SqlCall.java | 4 +- .../org/apache/calcite/sql/SqlCollation.java | 11 +-- .../apache/calcite/sql/SqlDescribeSchema.java | 4 +- .../apache/calcite/sql/SqlDescribeTable.java | 4 +- .../org/apache/calcite/sql/SqlDialect.java | 52 +++++++------- .../org/apache/calcite/sql/SqlExplain.java | 4 +- .../org/apache/calcite/sql/SqlFunction.java | 24 ++++--- .../org/apache/calcite/sql/SqlInsert.java | 5 +- .../calcite/sql/SqlIntervalQualifier.java | 16 +++-- .../calcite/sql/SqlJdbcFunctionCall.java | 4 +- .../java/org/apache/calcite/sql/SqlJoin.java | 4 +- .../org/apache/calcite/sql/SqlLiteral.java | 62 ++++++++-------- .../apache/calcite/sql/SqlMatchRecognize.java | 4 +- .../apache/calcite/sql/SqlNumericLiteral.java | 16 +++-- .../org/apache/calcite/sql/SqlOperator.java | 40 +++++------ .../apache/calcite/sql/SqlOperatorTable.java | 4 +- .../org/apache/calcite/sql/SqlOrderBy.java | 4 +- .../calcite/sql/SqlPostfixOperator.java | 10 +-- .../apache/calcite/sql/SqlPrefixOperator.java | 10 +-- .../org/apache/calcite/sql/SqlSelect.java | 36 +++++----- .../apache/calcite/sql/SqlSelectOperator.java | 4 +- .../org/apache/calcite/sql/SqlSetOption.java | 4 +- .../org/apache/calcite/sql/SqlSnapshot.java | 4 +- .../calcite/sql/SqlUnresolvedFunction.java | 10 +-- .../java/org/apache/calcite/sql/SqlUtil.java | 16 +++-- .../org/apache/calcite/sql/SqlWindow.java | 4 +- .../calcite/sql/SqlWindowTableFunction.java | 4 +- .../java/org/apache/calcite/sql/SqlWith.java | 4 +- .../org/apache/calcite/sql/SqlWithItem.java | 4 +- .../sql/dialect/BigQuerySqlDialect.java | 5 +- .../sql/dialect/ClickHouseSqlDialect.java | 4 +- .../calcite/sql/dialect/HiveSqlDialect.java | 6 +- .../sql/dialect/JethroDataSqlDialect.java | 3 +- .../calcite/sql/dialect/MssqlSqlDialect.java | 5 +- .../calcite/sql/dialect/MysqlSqlDialect.java | 6 +- .../calcite/sql/dialect/OracleSqlDialect.java | 3 +- .../sql/dialect/PostgresqlSqlDialect.java | 4 +- .../calcite/sql/dialect/PrestoSqlDialect.java | 6 +- .../calcite/sql/fun/SqlBitOpAggFunction.java | 4 +- .../calcite/sql/fun/SqlCaseOperator.java | 4 +- .../calcite/sql/fun/SqlCountAggFunction.java | 4 +- .../sql/fun/SqlJsonArrayAggAggFunction.java | 4 +- .../calcite/sql/fun/SqlJsonArrayFunction.java | 8 ++- .../calcite/sql/fun/SqlJsonDepthFunction.java | 6 +- .../sql/fun/SqlJsonObjectFunction.java | 8 ++- .../sql/fun/SqlJsonPrettyFunction.java | 6 +- .../calcite/sql/fun/SqlJsonQueryFunction.java | 6 +- .../calcite/sql/fun/SqlJsonTypeFunction.java | 6 +- .../calcite/sql/fun/SqlMinMaxAggFunction.java | 4 +- .../sql/fun/SqlPosixRegexOperator.java | 4 +- .../calcite/sql/fun/SqlSumAggFunction.java | 4 +- .../sql/fun/SqlSumEmptyIsZeroAggFunction.java | 4 +- .../calcite/sql/fun/SqlTrimFunction.java | 4 +- .../calcite/sql/parser/SqlParserPos.java | 4 +- .../apache/calcite/sql/type/SqlTypeName.java | 18 ++--- .../apache/calcite/sql/type/SqlTypeUtil.java | 4 +- .../sql/util/ChainedSqlOperatorTable.java | 4 +- .../sql/util/ListSqlOperatorTable.java | 4 +- .../sql/util/ReflectiveSqlOperatorTable.java | 4 +- .../calcite/sql/util/SqlBasicVisitor.java | 4 +- .../DelegatingSqlValidatorCatalogReader.java | 4 +- .../validate/SqlUserDefinedAggFunction.java | 4 +- .../sql/validate/SqlUserDefinedFunction.java | 4 +- .../validate/SqlUserDefinedTableMacro.java | 4 +- .../validate/SqlValidatorCatalogReader.java | 4 +- .../sql/validate/SqlValidatorUtil.java | 4 +- .../org/apache/calcite/tools/RelBuilder.java | 52 +++++++------- .../apache/calcite/util/ImmutableBitSet.java | 14 +++- .../apache/calcite/util/ImmutableIntList.java | 9 ++- .../java/org/apache/calcite/util/Litmus.java | 13 ++-- .../org/apache/calcite/util/NlsString.java | 28 ++++---- .../java/org/apache/calcite/util/Util.java | 45 ++++++------ .../apache/calcite/util/mapping/Mappings.java | 14 ++-- .../checkerframework/GuavaFunction.astub | 29 ++++++++ 145 files changed, 823 insertions(+), 503 deletions(-) create mode 100644 src/main/config/checkerframework/GuavaFunction.astub diff --git a/core/src/main/java/org/apache/calcite/adapter/clone/ColumnLoader.java b/core/src/main/java/org/apache/calcite/adapter/clone/ColumnLoader.java index a276722b6bc1..5fc77a56bd71 100644 --- a/core/src/main/java/org/apache/calcite/adapter/clone/ColumnLoader.java +++ b/core/src/main/java/org/apache/calcite/adapter/clone/ColumnLoader.java @@ -196,7 +196,7 @@ public int size() { // We have discovered a the first unique key in the table. sort[0] = pair.i; final Comparable[] values = - valueSet.values.toArray(new Comparable[list.size()]); + valueSet.values.toArray(new Comparable[0]); final Kev[] kevs = new Kev[list.size()]; for (int i = 0; i < kevs.length; i++) { kevs[i] = new Kev(i, values[i]); diff --git a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcSchema.java b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcSchema.java index 90ce7226598d..52d324159712 100644 --- a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcSchema.java +++ b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcSchema.java @@ -48,6 +48,8 @@ import com.google.common.collect.Multimap; import com.google.common.collect.Ordering; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; @@ -481,7 +483,7 @@ protected Map getTypes() { return ImmutableMap.of(); } - @Override public RelProtoDataType getType(String name) { + @Override public @Nullable RelProtoDataType getType(String name) { return getTypes().get(name); } @@ -489,7 +491,7 @@ protected Map getTypes() { return getTypes().keySet(); } - public Schema getSubSchema(String name) { + public @Nullable Schema getSubSchema(String name) { // JDBC does not support sub-schemas. return null; } diff --git a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcTable.java b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcTable.java index 3a8eff582eee..6d79de3802b2 100644 --- a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcTable.java +++ b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcTable.java @@ -56,6 +56,8 @@ import com.google.common.collect.Lists; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; @@ -100,7 +102,7 @@ public String toString() { return jdbcTableType; } - @Override public C unwrap(Class aClass) { + @Override public @Nullable C unwrap(Class aClass) { if (aClass.isInstance(jdbcSchema.getDataSource())) { return aClass.cast(jdbcSchema.getDataSource()); } else if (aClass.isInstance(jdbcSchema.dialect)) { diff --git a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcUtils.java b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcUtils.java index b104b73179f8..c6d48db492e3 100644 --- a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcUtils.java +++ b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcUtils.java @@ -117,7 +117,7 @@ public static Function1> factory( try { return new ObjectArrayRowBuilder( resultSet, - Pair.left(list).toArray(new ColumnMetaData.Rep[list.size()]), + Pair.left(list).toArray(new ColumnMetaData.Rep[0]), Ints.toArray(Pair.right(list))); } catch (SQLException e) { throw new RuntimeException(e); diff --git a/core/src/main/java/org/apache/calcite/interpreter/BindableConvention.java b/core/src/main/java/org/apache/calcite/interpreter/BindableConvention.java index 31a4cba19632..aafba2722742 100644 --- a/core/src/main/java/org/apache/calcite/interpreter/BindableConvention.java +++ b/core/src/main/java/org/apache/calcite/interpreter/BindableConvention.java @@ -24,6 +24,8 @@ import org.apache.calcite.plan.RelTraitSet; import org.apache.calcite.rel.RelNode; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * Calling convention that returns results as an * {@link org.apache.calcite.linq4j.Enumerable} of object arrays. @@ -52,7 +54,7 @@ public String getName() { return "BINDABLE"; } - @Override public RelNode enforce(RelNode input, RelTraitSet required) { + @Override public @Nullable RelNode enforce(RelNode input, RelTraitSet required) { return null; } diff --git a/core/src/main/java/org/apache/calcite/interpreter/Context.java b/core/src/main/java/org/apache/calcite/interpreter/Context.java index d44d9c215c04..2f7525851ef1 100644 --- a/core/src/main/java/org/apache/calcite/interpreter/Context.java +++ b/core/src/main/java/org/apache/calcite/interpreter/Context.java @@ -18,6 +18,8 @@ import org.apache.calcite.DataContext; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * Context for executing a scalar expression in an interpreter. */ @@ -25,7 +27,7 @@ public class Context { public final DataContext root; /** Values of incoming columns from all inputs. */ - public Object[] values; + public Object @Nullable [] values; Context(DataContext root) { this.root = root; diff --git a/core/src/main/java/org/apache/calcite/jdbc/CachingCalciteSchema.java b/core/src/main/java/org/apache/calcite/jdbc/CachingCalciteSchema.java index 57494bd41143..9a14f03cabca 100644 --- a/core/src/main/java/org/apache/calcite/jdbc/CachingCalciteSchema.java +++ b/core/src/main/java/org/apache/calcite/jdbc/CachingCalciteSchema.java @@ -33,6 +33,8 @@ import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.ImmutableSortedSet; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.Collection; import java.util.List; import java.util.Set; @@ -50,11 +52,11 @@ class CachingCalciteSchema extends CalciteSchema { private boolean cache = true; /** Creates a CachingCalciteSchema. */ - CachingCalciteSchema(CalciteSchema parent, Schema schema, String name) { + CachingCalciteSchema(@Nullable CalciteSchema parent, Schema schema, String name) { this(parent, schema, name, null, null, null, null, null, null, null, null); } - private CachingCalciteSchema(CalciteSchema parent, Schema schema, + private CachingCalciteSchema(@Nullable CalciteSchema parent, Schema schema, String name, NameMap subSchemaMap, NameMap tableMap, NameMap latticeMap, NameMap typeMap, NameMultimap functionMap, NameSet functionNames, diff --git a/core/src/main/java/org/apache/calcite/jdbc/CalcitePrepare.java b/core/src/main/java/org/apache/calcite/jdbc/CalcitePrepare.java index 638f62519925..1986a4fb06d9 100644 --- a/core/src/main/java/org/apache/calcite/jdbc/CalcitePrepare.java +++ b/core/src/main/java/org/apache/calcite/jdbc/CalcitePrepare.java @@ -50,6 +50,8 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; @@ -58,6 +60,8 @@ import java.util.List; import java.util.Map; +import static org.apache.calcite.linq4j.Nullness.assertNonNull; + /** * API for a service that prepares statements for execution. */ @@ -172,7 +176,7 @@ private static SparkHandler createHandler() { final Class clazz = Class.forName("org.apache.calcite.adapter.spark.SparkHandlerImpl"); Method method = clazz.getMethod("instance"); - return (CalcitePrepare.SparkHandler) method.invoke(null); + return (CalcitePrepare.SparkHandler) assertNonNull(method.invoke(null)); } catch (ClassNotFoundException e) { return new TrivialSparkHandler(); } catch (IllegalAccessException @@ -341,7 +345,7 @@ public CalciteSignature(String sql, List collationList, long maxRowCount, Bindable bindable, - Meta.StatementType statementType) { + Meta.@Nullable StatementType statementType) { super(columns, sql, parameterList, internalParameters, cursorFactory, statementType); this.rowType = rowType; @@ -372,11 +376,11 @@ public List getCollationList() { * * @param element type */ class Query { - public final String sql; - public final Queryable queryable; - public final RelNode rel; + public final @Nullable String sql; + public final @Nullable Queryable queryable; + public final @Nullable RelNode rel; - private Query(String sql, Queryable queryable, RelNode rel) { + private Query(@Nullable String sql, @Nullable Queryable queryable, @Nullable RelNode rel) { this.sql = sql; this.queryable = queryable; this.rel = rel; diff --git a/core/src/main/java/org/apache/calcite/jdbc/CalciteSchema.java b/core/src/main/java/org/apache/calcite/jdbc/CalciteSchema.java index 88f8f41ca5b3..ed90883fc1f4 100644 --- a/core/src/main/java/org/apache/calcite/jdbc/CalciteSchema.java +++ b/core/src/main/java/org/apache/calcite/jdbc/CalciteSchema.java @@ -41,6 +41,8 @@ import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Lists; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -58,7 +60,7 @@ */ public abstract class CalciteSchema { - private final CalciteSchema parent; + private final @Nullable CalciteSchema parent; public final Schema schema; public final String name; /** Tables explicitly defined in this schema. Does not include tables in @@ -70,14 +72,18 @@ public abstract class CalciteSchema { protected final NameSet functionNames; protected final NameMap nullaryFunctionMap; protected final NameMap subSchemaMap; - private List> path; - - protected CalciteSchema(CalciteSchema parent, Schema schema, - String name, NameMap subSchemaMap, - NameMap tableMap, NameMap latticeMap, NameMap typeMap, - NameMultimap functionMap, NameSet functionNames, - NameMap nullaryFunctionMap, - List> path) { + private @Nullable List> path; + + protected CalciteSchema(@Nullable CalciteSchema parent, Schema schema, + String name, + @Nullable NameMap subSchemaMap, + @Nullable NameMap tableMap, + @Nullable NameMap latticeMap, + @Nullable NameMap typeMap, + @Nullable NameMultimap functionMap, + @Nullable NameSet functionNames, + @Nullable NameMap nullaryFunctionMap, + @Nullable List> path) { this.parent = parent; this.schema = schema; this.name = name; @@ -662,7 +668,7 @@ public NavigableSet getTableNames() { return CalciteSchema.this.getTableNames(); } - @Override public RelProtoDataType getType(String name) { + @Override public @Nullable RelProtoDataType getType(String name) { final TypeEntry entry = CalciteSchema.this.getType(name, true); return entry == null ? null : entry.getType(); } @@ -679,7 +685,7 @@ public NavigableSet getFunctionNames() { return CalciteSchema.this.getFunctionNames(); } - public SchemaPlus getSubSchema(String name) { + public @Nullable SchemaPlus getSubSchema(String name) { final CalciteSchema subSchema = CalciteSchema.this.getSubSchema(name, true); return subSchema == null ? null : subSchema.plus(); diff --git a/core/src/main/java/org/apache/calcite/jdbc/JavaCollation.java b/core/src/main/java/org/apache/calcite/jdbc/JavaCollation.java index 468c40fe4647..5d2ee5381ad6 100644 --- a/core/src/main/java/org/apache/calcite/jdbc/JavaCollation.java +++ b/core/src/main/java/org/apache/calcite/jdbc/JavaCollation.java @@ -18,6 +18,9 @@ import org.apache.calcite.sql.SqlCollation; +import org.checkerframework.checker.initialization.qual.UnderInitialization; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.nio.charset.Charset; import java.text.Collator; import java.util.Locale; @@ -55,11 +58,13 @@ private static String getStrengthString(int strengthValue) { } } - @Override protected String generateCollationName(Charset charset) { + @Override protected String generateCollationName( + @UnderInitialization(SqlCollation.class) JavaCollation this, + Charset charset) { return super.generateCollationName(charset) + "$JAVA_COLLATOR"; } - @Override public Collator getCollator() { + @Override public @Nullable Collator getCollator() { return collator; } } diff --git a/core/src/main/java/org/apache/calcite/package-info.java b/core/src/main/java/org/apache/calcite/package-info.java index 2b1b922d4dc2..26fe6fec14dc 100644 --- a/core/src/main/java/org/apache/calcite/package-info.java +++ b/core/src/main/java/org/apache/calcite/package-info.java @@ -18,4 +18,11 @@ /** * Main package for Calcite, the dynamic data management platform. */ +@DefaultQualifier(value = NonNull.class, locations = TypeUseLocation.FIELD) +@DefaultQualifier(value = NonNull.class, locations = TypeUseLocation.PARAMETER) +@DefaultQualifier(value = NonNull.class, locations = TypeUseLocation.RETURN) package org.apache.calcite; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; +import org.checkerframework.framework.qual.TypeUseLocation; diff --git a/core/src/main/java/org/apache/calcite/plan/Contexts.java b/core/src/main/java/org/apache/calcite/plan/Contexts.java index 05343d863304..84df7065d301 100644 --- a/core/src/main/java/org/apache/calcite/plan/Contexts.java +++ b/core/src/main/java/org/apache/calcite/plan/Contexts.java @@ -20,6 +20,8 @@ import com.google.common.collect.ImmutableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -144,7 +146,7 @@ private static final class ChainContext implements Context { } } - @Override public T unwrap(Class clazz) { + @Override public @Nullable T unwrap(Class clazz) { for (Context context : contexts) { final T t = context.unwrap(clazz); if (t != null) { diff --git a/core/src/main/java/org/apache/calcite/plan/Convention.java b/core/src/main/java/org/apache/calcite/plan/Convention.java index 61cf9f12ee25..ba660a750308 100644 --- a/core/src/main/java/org/apache/calcite/plan/Convention.java +++ b/core/src/main/java/org/apache/calcite/plan/Convention.java @@ -19,6 +19,8 @@ import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.core.RelFactories; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * Calling convention trait. */ @@ -48,7 +50,7 @@ public interface Convention extends RelTrait { * or {@code null} if trait enforcement is not allowed or the * required traitSet can't be satisfied. */ - default RelNode enforce(RelNode input, RelTraitSet required) { + default @Nullable RelNode enforce(RelNode input, RelTraitSet required) { throw new RuntimeException(getClass().getName() + "#enforce() is not implemented."); } diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptAbstractTable.java b/core/src/main/java/org/apache/calcite/plan/RelOptAbstractTable.java index ebee046a9cb3..9c8affb32d86 100644 --- a/core/src/main/java/org/apache/calcite/plan/RelOptAbstractTable.java +++ b/core/src/main/java/org/apache/calcite/plan/RelOptAbstractTable.java @@ -31,6 +31,8 @@ import com.google.common.collect.ImmutableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.Collections; import java.util.List; @@ -86,7 +88,7 @@ public RelDistribution getDistribution() { return RelDistributions.BROADCAST_DISTRIBUTED; } - public T unwrap(Class clazz) { + public @Nullable T unwrap(Class clazz) { return clazz.isInstance(this) ? clazz.cast(this) : null; diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptPlanner.java b/core/src/main/java/org/apache/calcite/plan/RelOptPlanner.java index 2114f73de34d..13e2e0b3f554 100644 --- a/core/src/main/java/org/apache/calcite/plan/RelOptPlanner.java +++ b/core/src/main/java/org/apache/calcite/plan/RelOptPlanner.java @@ -24,6 +24,7 @@ import org.apache.calcite.util.CancelFlag; import org.apache.calcite.util.trace.CalciteTrace; +import org.checkerframework.checker.nullness.qual.Nullable; import org.slf4j.Logger; import java.util.List; @@ -249,7 +250,7 @@ RelNode register( * @param equivRel Relational expression it is equivalent to (may be null) * @return Registered relational expression */ - RelNode ensureRegistered(RelNode rel, RelNode equivRel); + RelNode ensureRegistered(RelNode rel, @Nullable RelNode equivRel); /** * Determines whether a relational expression has been registered. diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptRule.java b/core/src/main/java/org/apache/calcite/plan/RelOptRule.java index 20d03dec20b2..d2ad4d8c7a55 100644 --- a/core/src/main/java/org/apache/calcite/plan/RelOptRule.java +++ b/core/src/main/java/org/apache/calcite/plan/RelOptRule.java @@ -550,7 +550,7 @@ public boolean matches(RelOptRuleCall call) { * @return Convention of the result of firing this rule, null if * not known */ - public Convention getOutConvention() { + public @Nullable Convention getOutConvention() { return null; } @@ -561,7 +561,7 @@ public Convention getOutConvention() { * @return Trait which will be modified as a result of firing this rule, * or null if the rule is not a converter rule */ - public RelTrait getOutTrait() { + public @Nullable RelTrait getOutTrait() { return null; } diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptRuleCall.java b/core/src/main/java/org/apache/calcite/plan/RelOptRuleCall.java index c0dfdfa57c51..fa4c4773028b 100644 --- a/core/src/main/java/org/apache/calcite/plan/RelOptRuleCall.java +++ b/core/src/main/java/org/apache/calcite/plan/RelOptRuleCall.java @@ -26,6 +26,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import org.checkerframework.checker.nullness.qual.Nullable; import org.slf4j.Logger; import java.util.HashMap; @@ -54,7 +55,7 @@ public abstract class RelOptRuleCall { public final RelOptRule rule; public final RelNode[] rels; private final RelOptPlanner planner; - private final List parents; + private final @Nullable List parents; //~ Constructors ----------------------------------------------------------- @@ -77,7 +78,7 @@ protected RelOptRuleCall( RelOptRuleOperand operand, RelNode[] rels, Map> nodeInputs, - List parents) { + @Nullable List parents) { this.id = nextId++; this.planner = planner; this.operand0 = operand; @@ -171,7 +172,7 @@ public T rel(int ordinal) { * @param rel Relational expression * @return Children of relational expression */ - public List getChildRels(RelNode rel) { + public @Nullable List getChildRels(RelNode rel) { return nodeInputs.get(rel); } @@ -221,7 +222,7 @@ public RelMetadataQuery getMetadataQuery() { /** * Returns a list of parents of the first relational expression. */ - public List getParents() { + public @Nullable List getParents() { return parents; } diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptRuleOperand.java b/core/src/main/java/org/apache/calcite/plan/RelOptRuleOperand.java index 4f774ba1f434..53811dfc2f05 100644 --- a/core/src/main/java/org/apache/calcite/plan/RelOptRuleOperand.java +++ b/core/src/main/java/org/apache/calcite/plan/RelOptRuleOperand.java @@ -40,7 +40,7 @@ public class RelOptRuleOperand { //~ Instance fields -------------------------------------------------------- - private RelOptRuleOperand parent; + private @Nullable RelOptRuleOperand parent; private RelOptRule rule; private final Predicate predicate; @@ -49,7 +49,7 @@ public class RelOptRuleOperand { public int[] solveOrder; public int ordinalInParent; public int ordinalInRule; - public final RelTrait trait; + public final @Nullable RelTrait trait; private final Class clazz; private final ImmutableList children; @@ -99,9 +99,11 @@ protected RelOptRuleOperand( * and add constructor parameters for them. See * [CALCITE-1166] * Disallow sub-classes of RelOptRuleOperand. */ + @SuppressWarnings({"initialization.fields.uninitialized", + "initialization.invalid.field.write.initialized"}) RelOptRuleOperand( Class clazz, - RelTrait trait, + @Nullable RelTrait trait, Predicate predicate, RelOptRuleOperandChildPolicy childPolicy, ImmutableList children) { @@ -137,7 +139,7 @@ RelOptRuleOperand( * * @return parent operand */ - public RelOptRuleOperand getParent() { + public @Nullable RelOptRuleOperand getParent() { return parent; } @@ -146,7 +148,7 @@ public RelOptRuleOperand getParent() { * * @param parent Parent operand */ - public void setParent(RelOptRuleOperand parent) { + public void setParent(@Nullable RelOptRuleOperand parent) { this.parent = parent; } diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptSchema.java b/core/src/main/java/org/apache/calcite/plan/RelOptSchema.java index fdf151cde4b9..c130d6854fd5 100644 --- a/core/src/main/java/org/apache/calcite/plan/RelOptSchema.java +++ b/core/src/main/java/org/apache/calcite/plan/RelOptSchema.java @@ -18,6 +18,8 @@ import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -38,7 +40,7 @@ public interface RelOptSchema { * * @param names Qualified name */ - RelOptTable getTableForMember(List names); + @Nullable RelOptTable getTableForMember(List names); /** * Returns the {@link RelDataTypeFactory type factory} used to generate diff --git a/core/src/main/java/org/apache/calcite/plan/RelTrait.java b/core/src/main/java/org/apache/calcite/plan/RelTrait.java index 37440a275c9f..5cd89c2dccb9 100644 --- a/core/src/main/java/org/apache/calcite/plan/RelTrait.java +++ b/core/src/main/java/org/apache/calcite/plan/RelTrait.java @@ -20,6 +20,8 @@ import org.apache.calcite.rel.core.Project; import org.apache.calcite.util.mapping.Mappings; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * RelTrait represents the manifestation of a relational expression trait within * a trait definition. For example, a {@code CallingConvention.JAVA} is a trait @@ -53,7 +55,7 @@ public interface RelTrait { /** * See note about equals() and hashCode(). */ - boolean equals(Object o); + @Override boolean equals(@Nullable Object o); /** * Returns whether this trait satisfies a given trait. diff --git a/core/src/main/java/org/apache/calcite/plan/RelTraitSet.java b/core/src/main/java/org/apache/calcite/plan/RelTraitSet.java index eee0aa17730e..8233f9955fd5 100644 --- a/core/src/main/java/org/apache/calcite/plan/RelTraitSet.java +++ b/core/src/main/java/org/apache/calcite/plan/RelTraitSet.java @@ -44,7 +44,7 @@ public final class RelTraitSet extends AbstractList { private final Cache cache; private final RelTrait[] traits; - private String string; + private @Nullable String string; /** Caches the hash code for the traits. */ private int hash; // Default to 0 @@ -127,7 +127,7 @@ public boolean isEnabled(RelTraitDef traitDef) { * @return the RelTrait, or null if not found */ @CheckReturnValue - public T getTrait(RelTraitDef traitDef) { + public @Nullable T getTrait(RelTraitDef traitDef) { int index = findIndex(traitDef); if (index >= 0) { //noinspection unchecked @@ -146,7 +146,7 @@ public T getTrait(RelTraitDef traitDef) { * @return the RelTrait, or null if not found */ @CheckReturnValue - public List getTraits( + public @Nullable List getTraits( RelTraitDef traitDef) { int index = findIndex(traitDef); if (index >= 0) { @@ -369,7 +369,7 @@ public RelTraitSet getDefaultSansConvention() { * {@link ConventionTraitDef#INSTANCE} is not registered * in this traitSet. */ - public Convention getConvention() { + public @Nullable Convention getConvention() { return getTrait(ConventionTraitDef.INSTANCE); } @@ -379,7 +379,7 @@ public Convention getConvention() { * {@link RelDistributionTraitDef#INSTANCE} is not registered * in this traitSet. */ - public T getDistribution() { + public @Nullable T getDistribution() { //noinspection unchecked return (T) getTrait(RelDistributionTraitDef.INSTANCE); } @@ -390,7 +390,7 @@ public T getDistribution() { * {@link RelCollationTraitDef#INSTANCE} is not registered * in this traitSet. */ - public T getCollation() { + public @Nullable T getCollation() { //noinspection unchecked return (T) getTrait(RelCollationTraitDef.INSTANCE); } @@ -415,7 +415,9 @@ public int size() { @CheckReturnValue public T canonize(T trait) { if (trait == null) { - return null; + // Return "trait" makes the input type to be the same as the output type, + // so checkerframework is happy + return trait; } if (trait instanceof RelCompositeTrait) { diff --git a/core/src/main/java/org/apache/calcite/plan/hep/HepPlanner.java b/core/src/main/java/org/apache/calcite/plan/hep/HepPlanner.java index 77a11559d716..e9fce11df7c3 100644 --- a/core/src/main/java/org/apache/calcite/plan/hep/HepPlanner.java +++ b/core/src/main/java/org/apache/calcite/plan/hep/HepPlanner.java @@ -53,6 +53,8 @@ import com.google.common.collect.ImmutableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -774,7 +776,7 @@ public RelNode register( } // implement RelOptPlanner - public RelNode ensureRegistered(RelNode rel, RelNode equivRel) { + public RelNode ensureRegistered(RelNode rel, @Nullable RelNode equivRel) { return rel; } diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java b/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java index fa26892cb973..6a1123001609 100644 --- a/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java +++ b/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java @@ -61,6 +61,7 @@ import com.google.common.collect.Multimap; import org.apiguardian.api.API; +import org.checkerframework.checker.nullness.qual.Nullable; import java.io.PrintWriter; import java.io.StringWriter; @@ -589,7 +590,7 @@ public RelSubset register( return registerImpl(rel, set); } - public RelSubset ensureRegistered(RelNode rel, RelNode equivRel) { + public RelSubset ensureRegistered(RelNode rel, @Nullable RelNode equivRel) { RelSubset result; final RelSubset subset = getSubset(rel); if (subset != null) { diff --git a/core/src/main/java/org/apache/calcite/prepare/CalciteCatalogReader.java b/core/src/main/java/org/apache/calcite/prepare/CalciteCatalogReader.java index e0f2f5cb2b00..63892fb95d48 100644 --- a/core/src/main/java/org/apache/calcite/prepare/CalciteCatalogReader.java +++ b/core/src/main/java/org/apache/calcite/prepare/CalciteCatalogReader.java @@ -65,6 +65,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashSet; @@ -113,7 +115,7 @@ public CalciteCatalogReader withSchemaPath(List schemaPath) { ImmutableList.of(schemaPath, ImmutableList.of()), typeFactory, config); } - public Prepare.PreparingTable getTable(final List names) { + public Prepare.@Nullable PreparingTable getTable(final List names) { // First look in the default schema, if any. // If not found, look in the root schema. CalciteSchema.TableEntry entry = SqlValidatorUtil.getTableEntry(this, names); @@ -225,7 +227,7 @@ public List> getSchemaPaths() { return schemaPaths; } - public Prepare.PreparingTable getTableForMember(List names) { + public Prepare.@Nullable PreparingTable getTableForMember(List names) { return getTable(names); } @@ -246,7 +248,7 @@ public RelDataType createTypeFromProjection(final RelDataType type, } public void lookupOperatorOverloads(final SqlIdentifier opName, - SqlFunctionCategory category, + @Nullable SqlFunctionCategory category, SqlSyntax syntax, List operatorList, SqlNameMatcher nameMatcher) { diff --git a/core/src/main/java/org/apache/calcite/prepare/RelOptTableImpl.java b/core/src/main/java/org/apache/calcite/prepare/RelOptTableImpl.java index 5a0fe57c1529..84b7169df37e 100644 --- a/core/src/main/java/org/apache/calcite/prepare/RelOptTableImpl.java +++ b/core/src/main/java/org/apache/calcite/prepare/RelOptTableImpl.java @@ -273,7 +273,7 @@ public RelNode toRel(ToRelContext context) { final RelOptTable relOptTable = new RelOptTableImpl(this.schema, b.build(), this.names, this.table, this.expressionFunction, this.rowCount) { - @Override public T unwrap(Class clazz) { + @Override public @Nullable T unwrap(Class clazz) { if (clazz.isAssignableFrom(InitializerExpressionFactory.class)) { return clazz.cast(NullInitializerExpressionFactory.INSTANCE); } @@ -444,7 +444,7 @@ public static MySchemaPlus create(Path path) { return name; } - @Override public SchemaPlus getSubSchema(String name) { + @Override public @Nullable SchemaPlus getSubSchema(String name) { final Schema subSchema = schema.getSubSchema(name); return subSchema == null ? null : new MySchemaPlus(this, name, subSchema); } @@ -498,7 +498,7 @@ public static MySchemaPlus create(Path path) { return schema.getTableNames(); } - @Override public RelProtoDataType getType(String name) { + @Override public @Nullable RelProtoDataType getType(String name) { return schema.getType(name); } diff --git a/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java b/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java index d46eedcfdfd7..74f93eafd8bb 100644 --- a/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java +++ b/core/src/main/java/org/apache/calcite/rel/AbstractRelNode.java @@ -51,6 +51,8 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; +import static org.apache.calcite.linq4j.Nullness.assertNonNull; + /** * Base class for every relational expression ({@link RelNode}). */ @@ -67,7 +69,7 @@ public abstract class AbstractRelNode implements RelNode { /** * Cached type of this relational expression. */ - protected RelDataType rowType; + protected @Nullable RelDataType rowType; /** * The digest that uniquely identifies the node. @@ -123,7 +125,7 @@ public final RelOptCluster getCluster() { return cluster; } - public final Convention getConvention() { + public final @Nullable Convention getConvention() { return traitSet.getTrait(ConventionTraitDef.INSTANCE); } @@ -131,7 +133,7 @@ public RelTraitSet getTraitSet() { return traitSet; } - public String getCorrelVariable() { + public @Nullable String getCorrelVariable() { return null; } @@ -160,7 +162,7 @@ public String getRelTypeName() { return cn; } - public boolean isValid(Litmus litmus, Context context) { + public boolean isValid(Litmus litmus, @Nullable Context context) { return litmus.succeed(); } @@ -311,7 +313,7 @@ public final RelDigest getRelDigest() { return digest; } - public RelOptTable getTable() { + public @Nullable RelOptTable getTable() { return null; } @@ -449,7 +451,7 @@ private class InnerRelDigest implements RelDigest { @Override public String toString() { RelDigestWriter rdw = new RelDigestWriter(); explain(rdw); - return rdw.digest; + return assertNonNull(rdw.digest); } } @@ -465,7 +467,7 @@ private static final class RelDigestWriter implements RelWriter { private final List> attrs = new ArrayList<>(); - String digest = null; + @Nullable String digest = null; @Override public void explain(final RelNode rel, final List> valueList) { throw new IllegalStateException("Should not be called for computing digest"); diff --git a/core/src/main/java/org/apache/calcite/rel/RelNode.java b/core/src/main/java/org/apache/calcite/rel/RelNode.java index 54aae1f850a3..bc272beb8737 100644 --- a/core/src/main/java/org/apache/calcite/rel/RelNode.java +++ b/core/src/main/java/org/apache/calcite/rel/RelNode.java @@ -32,6 +32,7 @@ import org.apache.calcite.util.Litmus; import org.apiguardian.api.API; +import org.checkerframework.checker.nullness.qual.Nullable; import java.util.List; import java.util.Set; @@ -86,7 +87,7 @@ public interface RelNode extends RelOptNode, Cloneable { * * @return this RelNode's CallingConvention */ - Convention getConvention(); + @Nullable Convention getConvention(); /** * Returns the name of the variable which is to be implicitly set at runtime @@ -95,7 +96,7 @@ public interface RelNode extends RelOptNode, Cloneable { * * @return Name of correlating variable, or null */ - String getCorrelVariable(); + @Nullable String getCorrelVariable(); /** * Returns the ith input relational expression. @@ -303,7 +304,7 @@ void replaceInput( * @return If this relational expression represents an access to a table, * returns that table, otherwise returns null */ - RelOptTable getTable(); + @Nullable RelOptTable getTable(); /** * Returns the name of this relational expression's class, sans package @@ -335,7 +336,7 @@ void replaceInput( * @throws AssertionError if this relational expression is invalid and * litmus is THROW */ - boolean isValid(Litmus litmus, Context context); + boolean isValid(Litmus litmus, @Nullable Context context); /** * Creates a copy of this relational expression, perhaps changing traits and diff --git a/core/src/main/java/org/apache/calcite/rel/convert/ConverterRule.java b/core/src/main/java/org/apache/calcite/rel/convert/ConverterRule.java index 0d78259110a9..b66a05fc01aa 100644 --- a/core/src/main/java/org/apache/calcite/rel/convert/ConverterRule.java +++ b/core/src/main/java/org/apache/calcite/rel/convert/ConverterRule.java @@ -26,6 +26,8 @@ import org.apache.calcite.tools.RelBuilderFactory; import org.apache.calcite.util.ImmutableBeans; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.Locale; import java.util.Objects; import java.util.function.Function; @@ -120,11 +122,11 @@ public ConverterRule(Class clazz, //~ Methods ---------------------------------------------------------------- - @Override public Convention getOutConvention() { + @Override public @Nullable Convention getOutConvention() { return (Convention) outTrait; } - public RelTrait getOutTrait() { + public @Nullable RelTrait getOutTrait() { return outTrait; } diff --git a/core/src/main/java/org/apache/calcite/rel/convert/TraitMatchingRule.java b/core/src/main/java/org/apache/calcite/rel/convert/TraitMatchingRule.java index affb18615238..a07045ff9114 100644 --- a/core/src/main/java/org/apache/calcite/rel/convert/TraitMatchingRule.java +++ b/core/src/main/java/org/apache/calcite/rel/convert/TraitMatchingRule.java @@ -26,6 +26,8 @@ import org.apache.calcite.tools.RelBuilderFactory; import org.apache.calcite.util.ImmutableBeans; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * TraitMatchingRule adapts a converter rule, restricting it to fire only when * its input already matches the expected output trait. This can be used with @@ -73,7 +75,7 @@ public TraitMatchingRule(ConverterRule converterRule, //~ Methods ---------------------------------------------------------------- - @Override public Convention getOutConvention() { + @Override public @Nullable Convention getOutConvention() { return config.converterRule().getOutConvention(); } diff --git a/core/src/main/java/org/apache/calcite/rel/core/Aggregate.java b/core/src/main/java/org/apache/calcite/rel/core/Aggregate.java index 634e0fbeeff8..6f33a6fbfd86 100644 --- a/core/src/main/java/org/apache/calcite/rel/core/Aggregate.java +++ b/core/src/main/java/org/apache/calcite/rel/core/Aggregate.java @@ -50,6 +50,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.math.IntMath; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -416,7 +418,7 @@ public static RelDataType deriveRowType(RelDataTypeFactory typeFactory, return builder.build(); } - public boolean isValid(Litmus litmus, Context context) { + public boolean isValid(Litmus litmus, @Nullable Context context) { return super.isValid(litmus, context) && litmus.check(Util.isDistinct(getRowType().getFieldNames()), "distinct field names: {}", getRowType()); diff --git a/core/src/main/java/org/apache/calcite/rel/core/Calc.java b/core/src/main/java/org/apache/calcite/rel/core/Calc.java index 4f1f208cee7c..ac79f1b6a991 100644 --- a/core/src/main/java/org/apache/calcite/rel/core/Calc.java +++ b/core/src/main/java/org/apache/calcite/rel/core/Calc.java @@ -43,6 +43,8 @@ import com.google.common.collect.ImmutableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -136,7 +138,7 @@ public final boolean containsOver() { return RexOver.containsOver(program); } - public boolean isValid(Litmus litmus, Context context) { + public boolean isValid(Litmus litmus, @Nullable Context context) { if (!RelOptUtil.equal( "program's input type", program.getInputRowType(), diff --git a/core/src/main/java/org/apache/calcite/rel/core/Correlate.java b/core/src/main/java/org/apache/calcite/rel/core/Correlate.java index c80e31f359c0..f5d1db9c917d 100644 --- a/core/src/main/java/org/apache/calcite/rel/core/Correlate.java +++ b/core/src/main/java/org/apache/calcite/rel/core/Correlate.java @@ -34,6 +34,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; import java.util.Objects; import java.util.Set; @@ -115,7 +117,7 @@ public Correlate(RelInput input) { //~ Methods ---------------------------------------------------------------- - @Override public boolean isValid(Litmus litmus, Context context) { + @Override public boolean isValid(Litmus litmus, @Nullable Context context) { return super.isValid(litmus, context) && RelOptUtil.notContainsCorrelation(left, correlationId, litmus); } @@ -170,7 +172,7 @@ public CorrelationId getCorrelationId() { return correlationId; } - @Override public String getCorrelVariable() { + @Override public @Nullable String getCorrelVariable() { return correlationId.getName(); } diff --git a/core/src/main/java/org/apache/calcite/rel/core/Filter.java b/core/src/main/java/org/apache/calcite/rel/core/Filter.java index e3ba20aa19da..0f961e87f2fc 100644 --- a/core/src/main/java/org/apache/calcite/rel/core/Filter.java +++ b/core/src/main/java/org/apache/calcite/rel/core/Filter.java @@ -36,6 +36,7 @@ import org.apache.calcite.util.Litmus; import org.apiguardian.api.API; +import org.checkerframework.checker.nullness.qual.Nullable; import java.util.List; import java.util.Objects; @@ -114,7 +115,7 @@ public final boolean containsOver() { return RexOver.containsOver(condition); } - @Override public boolean isValid(Litmus litmus, Context context) { + @Override public boolean isValid(Litmus litmus, @Nullable Context context) { if (RexUtil.isNullabilityCast(getCluster().getTypeFactory(), condition)) { return litmus.fail("Cast for just nullability not allowed"); } diff --git a/core/src/main/java/org/apache/calcite/rel/core/Join.java b/core/src/main/java/org/apache/calcite/rel/core/Join.java index be2d47bfecd5..43efd24d9c0c 100644 --- a/core/src/main/java/org/apache/calcite/rel/core/Join.java +++ b/core/src/main/java/org/apache/calcite/rel/core/Join.java @@ -42,6 +42,7 @@ import com.google.common.collect.ImmutableSet; import org.apiguardian.api.API; +import org.checkerframework.checker.nullness.qual.Nullable; import java.util.Collections; import java.util.List; @@ -144,7 +145,7 @@ public JoinRelType getJoinType() { return joinType; } - @Override public boolean isValid(Litmus litmus, Context context) { + @Override public boolean isValid(Litmus litmus, @Nullable Context context) { if (!super.isValid(litmus, context)) { return false; } diff --git a/core/src/main/java/org/apache/calcite/rel/core/Project.java b/core/src/main/java/org/apache/calcite/rel/core/Project.java index 47ca1c43f947..462286da5e2c 100644 --- a/core/src/main/java/org/apache/calcite/rel/core/Project.java +++ b/core/src/main/java/org/apache/calcite/rel/core/Project.java @@ -48,6 +48,7 @@ import com.google.common.collect.Lists; import org.apiguardian.api.API; +import org.checkerframework.checker.nullness.qual.Nullable; import java.util.HashSet; import java.util.List; @@ -163,7 +164,7 @@ public RelNode accept(RexShuttle shuttle) { RexUtil.createStructType( getInput().getCluster().getTypeFactory(), exps, - this.rowType.getFieldNames(), + getRowType().getFieldNames(), null); return copy(traitSet, getInput(), exps, rowType); } @@ -201,7 +202,7 @@ public final boolean containsOver() { return RexOver.containsOver(getProjects(), null); } - public boolean isValid(Litmus litmus, Context context) { + public boolean isValid(Litmus litmus, @Nullable Context context) { if (!super.isValid(litmus, context)) { return litmus.fail(null); } @@ -218,7 +219,7 @@ public boolean isValid(Litmus litmus, Context context) { checker.getFailureCount(), exp); } } - if (!Util.isDistinct(rowType.getFieldNames())) { + if (!Util.isDistinct(getRowType().getFieldNames())) { return litmus.fail("field names not distinct: {}", rowType); } //CHECKSTYLE: IGNORE 1 @@ -278,10 +279,10 @@ public RelWriter explainTerms(RelWriter pw) { } if (pw.nest()) { - pw.item("fields", rowType.getFieldNames()); + pw.item("fields", getRowType().getFieldNames()); pw.item("exprs", exps); } else { - for (Ord field : Ord.zip(rowType.getFieldList())) { + for (Ord field : Ord.zip(getRowType().getFieldList())) { String fieldName = field.e.getName(); if (fieldName == null) { fieldName = "field#" + field.i; diff --git a/core/src/main/java/org/apache/calcite/rel/core/Snapshot.java b/core/src/main/java/org/apache/calcite/rel/core/Snapshot.java index eaba15dd6004..0a2774c7e8e8 100644 --- a/core/src/main/java/org/apache/calcite/rel/core/Snapshot.java +++ b/core/src/main/java/org/apache/calcite/rel/core/Snapshot.java @@ -28,6 +28,8 @@ import org.apache.calcite.sql.type.SqlTypeName; import org.apache.calcite.util.Litmus; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; import java.util.Objects; @@ -91,7 +93,7 @@ public RexNode getPeriod() { return period; } - @Override public boolean isValid(Litmus litmus, Context context) { + @Override public boolean isValid(Litmus litmus, @Nullable Context context) { RelDataType dataType = period.getType(); if (dataType.getSqlTypeName() != SqlTypeName.TIMESTAMP) { return litmus.fail("The system time period specification expects Timestamp type but is '" diff --git a/core/src/main/java/org/apache/calcite/rel/core/TableModify.java b/core/src/main/java/org/apache/calcite/rel/core/TableModify.java index 162eb2df8157..106c98f3eb4d 100644 --- a/core/src/main/java/org/apache/calcite/rel/core/TableModify.java +++ b/core/src/main/java/org/apache/calcite/rel/core/TableModify.java @@ -37,6 +37,8 @@ import com.google.common.base.Preconditions; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; import java.util.Objects; @@ -158,7 +160,7 @@ public Prepare.CatalogReader getCatalogReader() { return catalogReader; } - public RelOptTable getTable() { + public @Nullable RelOptTable getTable() { return table; } diff --git a/core/src/main/java/org/apache/calcite/rel/core/TableScan.java b/core/src/main/java/org/apache/calcite/rel/core/TableScan.java index 7f6dd3599bc2..b27a40d63ea0 100644 --- a/core/src/main/java/org/apache/calcite/rel/core/TableScan.java +++ b/core/src/main/java/org/apache/calcite/rel/core/TableScan.java @@ -39,6 +39,8 @@ import com.google.common.collect.ImmutableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -91,7 +93,7 @@ protected TableScan(RelInput input) { return table.getRowCount(); } - @Override public RelOptTable getTable() { + @Override public @Nullable RelOptTable getTable() { return table; } diff --git a/core/src/main/java/org/apache/calcite/rel/core/TableSpool.java b/core/src/main/java/org/apache/calcite/rel/core/TableSpool.java index cb7ec14ba0d4..75be44b0650c 100644 --- a/core/src/main/java/org/apache/calcite/rel/core/TableSpool.java +++ b/core/src/main/java/org/apache/calcite/rel/core/TableSpool.java @@ -23,6 +23,8 @@ import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.RelWriter; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.Objects; /** @@ -42,7 +44,7 @@ protected TableSpool(RelOptCluster cluster, RelTraitSet traitSet, this.table = Objects.requireNonNull(table); } - public RelOptTable getTable() { + public @Nullable RelOptTable getTable() { return table; } diff --git a/core/src/main/java/org/apache/calcite/rel/core/Window.java b/core/src/main/java/org/apache/calcite/rel/core/Window.java index d5f255efeceb..b410590fedba 100644 --- a/core/src/main/java/org/apache/calcite/rel/core/Window.java +++ b/core/src/main/java/org/apache/calcite/rel/core/Window.java @@ -88,7 +88,7 @@ public Window(RelOptCluster cluster, RelTraitSet traitSet, RelNode input, this.groups = ImmutableList.copyOf(groups); } - @Override public boolean isValid(Litmus litmus, Context context) { + @Override public boolean isValid(Litmus litmus, @Nullable Context context) { // In the window specifications, an aggregate call such as // 'SUM(RexInputRef #10)' refers to expression #10 of inputProgram. // (Not its projections.) diff --git a/core/src/main/java/org/apache/calcite/rel/hint/HintStrategyTable.java b/core/src/main/java/org/apache/calcite/rel/hint/HintStrategyTable.java index 14dcacac1229..3d8453fb622e 100644 --- a/core/src/main/java/org/apache/calcite/rel/hint/HintStrategyTable.java +++ b/core/src/main/java/org/apache/calcite/rel/hint/HintStrategyTable.java @@ -230,7 +230,7 @@ public static class HintErrorLogger implements Litmus { public static final HintErrorLogger INSTANCE = new HintErrorLogger(); - public boolean fail(String message, Object... args) { + public boolean fail(@Nullable String message, Object... args) { LOGGER.warn(message, args); return false; } @@ -239,7 +239,7 @@ public boolean succeed() { return true; } - public boolean check(boolean condition, String message, Object... args) { + public boolean check(boolean condition, @Nullable String message, Object... args) { if (condition) { return succeed(); } else { diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java index f27b08500fec..f4873eaffb39 100644 --- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java +++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java @@ -32,6 +32,8 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Multimap; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.Collections; import java.util.List; import java.util.Objects; @@ -206,7 +208,7 @@ public Multimap, RelNode> getNodeTypes(RelNode rel) { * @return estimated row count, or null if no reliable estimate can be * determined */ - public Double getRowCount(RelNode rel) { + public @Nullable Double getRowCount(RelNode rel) { for (;;) { try { Double result = rowCountHandler.getRowCount(rel, this); @@ -225,7 +227,7 @@ public Double getRowCount(RelNode rel) { * @param rel the relational expression * @return max row count */ - public Double getMaxRowCount(RelNode rel) { + public @Nullable Double getMaxRowCount(RelNode rel) { for (;;) { try { return maxRowCountHandler.getMaxRowCount(rel, this); @@ -244,7 +246,7 @@ public Double getMaxRowCount(RelNode rel) { * @param rel the relational expression * @return max row count */ - public Double getMinRowCount(RelNode rel) { + public @Nullable Double getMinRowCount(RelNode rel) { for (;;) { try { return minRowCountHandler.getMinRowCount(rel, this); @@ -263,7 +265,7 @@ public Double getMinRowCount(RelNode rel) { * @param rel the relational expression * @return estimated cost, or null if no reliable estimate can be determined */ - public RelOptCost getCumulativeCost(RelNode rel) { + public @Nullable RelOptCost getCumulativeCost(RelNode rel) { for (;;) { try { return cumulativeCostHandler.getCumulativeCost(rel, this); @@ -282,7 +284,7 @@ public RelOptCost getCumulativeCost(RelNode rel) { * @param rel the relational expression * @return estimated cost, or null if no reliable estimate can be determined */ - public RelOptCost getNonCumulativeCost(RelNode rel) { + public @Nullable RelOptCost getNonCumulativeCost(RelNode rel) { for (;;) { try { return nonCumulativeCostHandler.getNonCumulativeCost(rel, this); @@ -302,7 +304,7 @@ public RelOptCost getNonCumulativeCost(RelNode rel) { * @return estimated percentage (between 0.0 and 1.0), or null if no * reliable estimate can be determined */ - public Double getPercentageOriginalRows(RelNode rel) { + public @Nullable Double getPercentageOriginalRows(RelNode rel) { for (;;) { try { Double result = @@ -326,7 +328,7 @@ public Double getPercentageOriginalRows(RelNode rel) { * determined (whereas empty set indicates definitely no origin columns at * all) */ - public Set getColumnOrigins(RelNode rel, int column) { + public @Nullable Set getColumnOrigins(RelNode rel, int column) { for (;;) { try { return columnOriginHandler.getColumnOrigins(rel, this, column); @@ -350,7 +352,7 @@ public Set getColumnOrigins(RelNode rel, int column) { * @return the origin of a column provided it's a simple column; otherwise, * returns null */ - public RelColumnOrigin getColumnOrigin(RelNode rel, int column) { + public @Nullable RelColumnOrigin getColumnOrigin(RelNode rel, int column) { final Set origins = getColumnOrigins(rel, column); if (origins == null || origins.size() != 1) { return null; @@ -362,7 +364,7 @@ public RelColumnOrigin getColumnOrigin(RelNode rel, int column) { /** * Determines the origin of a column. */ - public Set getExpressionLineage(RelNode rel, RexNode expression) { + public @Nullable Set getExpressionLineage(RelNode rel, RexNode expression) { for (;;) { try { return expressionLineageHandler.getExpressionLineage(rel, this, expression); @@ -376,7 +378,7 @@ public Set getExpressionLineage(RelNode rel, RexNode expression) { /** * Determines the tables used by a plan. */ - public Set getTableReferences(RelNode rel) { + public @Nullable Set getTableReferences(RelNode rel) { for (;;) { try { return tableReferencesHandler.getTableReferences(rel, this); @@ -395,7 +397,7 @@ public Set getTableReferences(RelNode rel) { * * @return the table, if the RelNode is a simple table; otherwise null */ - public RelOptTable getTableOrigin(RelNode rel) { + public @Nullable RelOptTable getTableOrigin(RelNode rel) { // Determine the simple origin of the first column in the // RelNode. If it's simple, then that means that the underlying // table is also simple, even if the column itself is derived. @@ -420,7 +422,7 @@ public RelOptTable getTableOrigin(RelNode rel) { * @return estimated selectivity (between 0.0 and 1.0), or null if no * reliable estimate can be determined */ - public Double getSelectivity(RelNode rel, RexNode predicate) { + public @Nullable Double getSelectivity(RelNode rel, RexNode predicate) { for (;;) { try { Double result = selectivityHandler.getSelectivity(rel, this, predicate); @@ -441,7 +443,7 @@ public Double getSelectivity(RelNode rel, RexNode predicate) { * @return set of keys, or null if this information cannot be determined * (whereas empty set indicates definitely no keys at all) */ - public Set getUniqueKeys(RelNode rel) { + public @Nullable Set getUniqueKeys(RelNode rel) { return getUniqueKeys(rel, false); } @@ -457,7 +459,7 @@ public Set getUniqueKeys(RelNode rel) { * @return set of keys, or null if this information cannot be determined * (whereas empty set indicates definitely no keys at all) */ - public Set getUniqueKeys(RelNode rel, + public @Nullable Set getUniqueKeys(RelNode rel, boolean ignoreNulls) { for (;;) { try { @@ -480,7 +482,7 @@ public Set getUniqueKeys(RelNode rel, * @return true or false depending on whether the rows are unique, or * null if not enough information is available to make that determination */ - public Boolean areRowsUnique(RelNode rel) { + public @Nullable Boolean areRowsUnique(RelNode rel) { final ImmutableBitSet columns = ImmutableBitSet.range(rel.getRowType().getFieldCount()); return areColumnsUnique(rel, columns, false); @@ -498,7 +500,7 @@ public Boolean areRowsUnique(RelNode rel) { * @return true or false depending on whether the columns are unique, or * null if not enough information is available to make that determination */ - public Boolean areColumnsUnique(RelNode rel, ImmutableBitSet columns) { + public @Nullable Boolean areColumnsUnique(RelNode rel, ImmutableBitSet columns) { return areColumnsUnique(rel, columns, false); } @@ -515,7 +517,7 @@ public Boolean areColumnsUnique(RelNode rel, ImmutableBitSet columns) { * @return true or false depending on whether the columns are unique, or * null if not enough information is available to make that determination */ - public Boolean areColumnsUnique(RelNode rel, ImmutableBitSet columns, + public @Nullable Boolean areColumnsUnique(RelNode rel, ImmutableBitSet columns, boolean ignoreNulls) { for (;;) { try { @@ -537,7 +539,7 @@ public Boolean areColumnsUnique(RelNode rel, ImmutableBitSet columns, * @return List of sorted column combinations, or * null if not enough information is available to make that determination */ - public ImmutableList collations(RelNode rel) { + public @Nullable ImmutableList collations(RelNode rel) { for (;;) { try { return collationHandler.collations(rel, this); @@ -556,7 +558,7 @@ public ImmutableList collations(RelNode rel) { * @return List of sorted column combinations, or * null if not enough information is available to make that determination */ - public RelDistribution distribution(RelNode rel) { + public @Nullable RelDistribution distribution(RelNode rel) { for (;;) { try { return distributionHandler.distribution(rel, this); @@ -579,7 +581,7 @@ public RelDistribution distribution(RelNode rel) { * estimate can be determined * */ - public Double getPopulationSize(RelNode rel, + public @Nullable Double getPopulationSize(RelNode rel, ImmutableBitSet groupKey) { for (;;) { try { @@ -601,7 +603,7 @@ public Double getPopulationSize(RelNode rel, * @param rel the relational expression * @return average size of a row, in bytes, or null if not known */ - public Double getAverageRowSize(RelNode rel) { + public @Nullable Double getAverageRowSize(RelNode rel) { for (;;) { try { return sizeHandler.averageRowSize(rel, this); @@ -621,7 +623,7 @@ public Double getAverageRowSize(RelNode rel) { * value, in bytes. Each value or the entire list may be null if the * metadata is not available */ - public List getAverageColumnSizes(RelNode rel) { + public @Nullable List getAverageColumnSizes(RelNode rel) { for (;;) { try { return sizeHandler.averageColumnSizes(rel, this); @@ -633,7 +635,7 @@ public List getAverageColumnSizes(RelNode rel) { /** As {@link #getAverageColumnSizes(org.apache.calcite.rel.RelNode)} but * never returns a null list, only ever a list of nulls. */ - public List getAverageColumnSizesNotNull(RelNode rel) { + public @Nullable List getAverageColumnSizesNotNull(RelNode rel) { final List averageColumnSizes = getAverageColumnSizes(rel); return averageColumnSizes == null ? Collections.nCopies(rel.getRowType().getFieldCount(), null) @@ -650,7 +652,7 @@ public List getAverageColumnSizesNotNull(RelNode rel) { * expression belongs to a different process than its inputs, or null if not * known */ - public Boolean isPhaseTransition(RelNode rel) { + public @Nullable Boolean isPhaseTransition(RelNode rel) { for (;;) { try { return parallelismHandler.isPhaseTransition(rel, this); @@ -669,7 +671,7 @@ public Boolean isPhaseTransition(RelNode rel) { * @param rel the relational expression * @return the number of distinct splits of the data, or null if not known */ - public Integer splitCount(RelNode rel) { + public @Nullable Integer splitCount(RelNode rel) { for (;;) { try { return parallelismHandler.splitCount(rel, this); @@ -690,7 +692,7 @@ public Integer splitCount(RelNode rel) { * operator implementing this relational expression, across all splits, * or null if not known */ - public Double memory(RelNode rel) { + public @Nullable Double memory(RelNode rel) { for (;;) { try { return memoryHandler.memory(rel, this); @@ -710,7 +712,7 @@ public Double memory(RelNode rel) { * physical operator implementing this relational expression, and all other * operators within the same phase, across all splits, or null if not known */ - public Double cumulativeMemoryWithinPhase(RelNode rel) { + public @Nullable Double cumulativeMemoryWithinPhase(RelNode rel) { for (;;) { try { return memoryHandler.cumulativeMemoryWithinPhase(rel, this); @@ -730,7 +732,7 @@ public Double cumulativeMemoryWithinPhase(RelNode rel) { * the physical operator implementing this relational expression, and all * operators within the same phase, within each split, or null if not known */ - public Double cumulativeMemoryWithinPhaseSplit(RelNode rel) { + public @Nullable Double cumulativeMemoryWithinPhaseSplit(RelNode rel) { for (;;) { try { return memoryHandler.cumulativeMemoryWithinPhaseSplit(rel, this); @@ -751,7 +753,7 @@ public Double cumulativeMemoryWithinPhaseSplit(RelNode rel) { * @return distinct row count for groupKey, filtered by predicate, or null * if no reliable estimate can be determined */ - public Double getDistinctRowCount( + public @Nullable Double getDistinctRowCount( RelNode rel, ImmutableBitSet groupKey, RexNode predicate) { @@ -776,7 +778,7 @@ public Double getDistinctRowCount( * @param rel the relational expression * @return Predicates that can be pulled above this RelNode */ - public RelOptPredicateList getPulledUpPredicates(RelNode rel) { + public @Nullable RelOptPredicateList getPulledUpPredicates(RelNode rel) { for (;;) { try { return predicatesHandler.getPredicates(rel, this); @@ -794,7 +796,7 @@ public RelOptPredicateList getPulledUpPredicates(RelNode rel) { * @param rel the relational expression * @return All predicates within and below this RelNode */ - public RelOptPredicateList getAllPredicates(RelNode rel) { + public @Nullable RelOptPredicateList getAllPredicates(RelNode rel) { for (;;) { try { return allPredicatesHandler.getAllPredicates(rel, this); @@ -814,7 +816,7 @@ public RelOptPredicateList getAllPredicates(RelNode rel) { * @return true for visible, false for invisible; if no metadata is available, * defaults to true */ - public boolean isVisibleInExplain(RelNode rel, + public @Nullable Boolean isVisibleInExplain(RelNode rel, SqlExplainLevel explainLevel) { for (;;) { try { @@ -838,7 +840,7 @@ public boolean isVisibleInExplain(RelNode rel, * @return description of how the rows in the relational expression are * physically distributed */ - public RelDistribution getDistribution(RelNode rel) { + public @Nullable RelDistribution getDistribution(RelNode rel) { for (;;) { try { return distributionHandler.distribution(rel, this); @@ -851,7 +853,7 @@ public RelDistribution getDistribution(RelNode rel) { /** * Returns the lower bound cost of a RelNode. */ - public RelOptCost getLowerBoundCost(RelNode rel, VolcanoPlanner planner) { + public @Nullable RelOptCost getLowerBoundCost(RelNode rel, VolcanoPlanner planner) { for (;;) { try { return lowerBoundCostHandler.getLowerBoundCost(rel, this, planner); diff --git a/core/src/main/java/org/apache/calcite/rel/rules/CoerceInputsRule.java b/core/src/main/java/org/apache/calcite/rel/rules/CoerceInputsRule.java index ea5b5ca2bd4a..4d8d057166b3 100644 --- a/core/src/main/java/org/apache/calcite/rel/rules/CoerceInputsRule.java +++ b/core/src/main/java/org/apache/calcite/rel/rules/CoerceInputsRule.java @@ -25,6 +25,8 @@ import org.apache.calcite.tools.RelBuilderFactory; import org.apache.calcite.util.ImmutableBeans; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.ArrayList; import java.util.List; @@ -66,7 +68,7 @@ public CoerceInputsRule(Class consumerRelClass, //~ Methods ---------------------------------------------------------------- - @Override public Convention getOutConvention() { + @Override public @Nullable Convention getOutConvention() { return Convention.NONE; } diff --git a/core/src/main/java/org/apache/calcite/rel/rules/ReduceDecimalsRule.java b/core/src/main/java/org/apache/calcite/rel/rules/ReduceDecimalsRule.java index bbf1c8442b12..874d044a89ed 100644 --- a/core/src/main/java/org/apache/calcite/rel/rules/ReduceDecimalsRule.java +++ b/core/src/main/java/org/apache/calcite/rel/rules/ReduceDecimalsRule.java @@ -42,6 +42,8 @@ import com.google.common.collect.ImmutableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.math.BigDecimal; import java.math.BigInteger; import java.util.HashMap; @@ -84,7 +86,7 @@ public ReduceDecimalsRule(RelBuilderFactory relBuilderFactory) { //~ Methods ---------------------------------------------------------------- - @Override public Convention getOutConvention() { + @Override public @Nullable Convention getOutConvention() { return Convention.NONE; } diff --git a/core/src/main/java/org/apache/calcite/rel/type/DelegatingTypeSystem.java b/core/src/main/java/org/apache/calcite/rel/type/DelegatingTypeSystem.java index ba3b45b9ca5f..a4b8389e3e83 100644 --- a/core/src/main/java/org/apache/calcite/rel/type/DelegatingTypeSystem.java +++ b/core/src/main/java/org/apache/calcite/rel/type/DelegatingTypeSystem.java @@ -18,6 +18,8 @@ import org.apache.calcite.sql.type.SqlTypeName; +import org.checkerframework.checker.nullness.qual.Nullable; + /** Implementation of {@link org.apache.calcite.rel.type.RelDataTypeSystem} * that sends all methods to an underlying object. */ public class DelegatingTypeSystem implements RelDataTypeSystem { @@ -48,7 +50,7 @@ public int getMaxNumericPrecision() { return typeSystem.getMaxNumericPrecision(); } - public String getLiteral(SqlTypeName typeName, boolean isPrefix) { + public @Nullable String getLiteral(SqlTypeName typeName, boolean isPrefix) { return typeSystem.getLiteral(typeName, isPrefix); } diff --git a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeField.java b/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeField.java index 7fceec70d5d0..da4e079a7aef 100644 --- a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeField.java +++ b/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeField.java @@ -36,6 +36,7 @@ public interface RelDataTypeField extends Map.Entry { * @deprecated Use {@code RelDataTypeField::getIndex} */ @Deprecated // to be removed before 2.0 + @SuppressWarnings("nullability") class ToFieldIndex implements com.google.common.base.Function { @Override public Integer apply(RelDataTypeField o) { @@ -50,6 +51,7 @@ class ToFieldIndex * @deprecated Use {@code RelDataTypeField::getName} */ @Deprecated // to be removed before 2.0 + @SuppressWarnings("nullability") class ToFieldName implements com.google.common.base.Function { @Override public String apply(RelDataTypeField o) { diff --git a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystem.java b/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystem.java index 03189fe895d4..5f6095da7632 100644 --- a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystem.java +++ b/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystem.java @@ -20,6 +20,8 @@ import org.apache.calcite.sql.type.SqlTypeUtil; import org.apache.calcite.util.Glossary; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * Type system. * @@ -59,7 +61,7 @@ public interface RelDataTypeSystem { int getMaxNumericPrecision(); /** Returns the LITERAL string for the type, either PREFIX/SUFFIX. */ - String getLiteral(SqlTypeName typeName, boolean isPrefix); + @Nullable String getLiteral(SqlTypeName typeName, boolean isPrefix); /** Returns whether the type is case sensitive. */ boolean isCaseSensitive(SqlTypeName typeName); @@ -145,7 +147,7 @@ default boolean shouldUseDoubleMultiplication( * @param type2 Type of the second operand * @return Result type for a decimal addition */ - default RelDataType deriveDecimalPlusType(RelDataTypeFactory typeFactory, + default @Nullable RelDataType deriveDecimalPlusType(RelDataTypeFactory typeFactory, RelDataType type1, RelDataType type2) { if (SqlTypeUtil.isExactNumeric(type1) && SqlTypeUtil.isExactNumeric(type2)) { @@ -214,7 +216,7 @@ default RelDataType deriveDecimalPlusType(RelDataTypeFactory typeFactory, * @return Result type for a decimal multiplication, or null if decimal * multiplication should not be applied to the operands */ - default RelDataType deriveDecimalMultiplyType(RelDataTypeFactory typeFactory, + default @Nullable RelDataType deriveDecimalMultiplyType(RelDataTypeFactory typeFactory, RelDataType type1, RelDataType type2) { if (SqlTypeUtil.isExactNumeric(type1) && SqlTypeUtil.isExactNumeric(type2)) { @@ -286,7 +288,7 @@ default RelDataType deriveDecimalMultiplyType(RelDataTypeFactory typeFactory, * @return Result type for a decimal division, or null if decimal * division should not be applied to the operands */ - default RelDataType deriveDecimalDivideType(RelDataTypeFactory typeFactory, + default @Nullable RelDataType deriveDecimalDivideType(RelDataTypeFactory typeFactory, RelDataType type1, RelDataType type2) { if (SqlTypeUtil.isExactNumeric(type1) @@ -368,7 +370,7 @@ default RelDataType deriveDecimalDivideType(RelDataTypeFactory typeFactory, * @return Result type for a decimal modulus, or null if decimal * modulus should not be applied to the operands */ - default RelDataType deriveDecimalModType(RelDataTypeFactory typeFactory, + default @Nullable RelDataType deriveDecimalModType(RelDataTypeFactory typeFactory, RelDataType type1, RelDataType type2) { if (SqlTypeUtil.isExactNumeric(type1) && SqlTypeUtil.isExactNumeric(type2)) { diff --git a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystemImpl.java b/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystemImpl.java index 32cbc34edce1..8eeb75d11e46 100644 --- a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystemImpl.java +++ b/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystemImpl.java @@ -20,6 +20,8 @@ import org.apache.calcite.sql.type.SqlTypeFamily; import org.apache.calcite.sql.type.SqlTypeName; +import org.checkerframework.checker.nullness.qual.Nullable; + /** Default implementation of * {@link org.apache.calcite.rel.type.RelDataTypeSystem}, * providing parameters from the SQL standard. @@ -154,7 +156,7 @@ public int getMaxScale(SqlTypeName typeName) { return 19; } - @Override public String getLiteral(SqlTypeName typeName, boolean isPrefix) { + @Override public @Nullable String getLiteral(SqlTypeName typeName, boolean isPrefix) { switch (typeName) { case VARBINARY: case VARCHAR: diff --git a/core/src/main/java/org/apache/calcite/rex/RexCall.java b/core/src/main/java/org/apache/calcite/rex/RexCall.java index 2ea5a05b9bec..b93960775615 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexCall.java +++ b/core/src/main/java/org/apache/calcite/rex/RexCall.java @@ -68,7 +68,7 @@ public class RexCall extends RexNode { /** * Cache of normalized variables used for #equals and #hashCode. */ - private Pair> normalized; + private @Nullable Pair> normalized; //~ Constructors ----------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/rex/RexChecker.java b/core/src/main/java/org/apache/calcite/rex/RexChecker.java index d35299241653..30f7a876154d 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexChecker.java +++ b/core/src/main/java/org/apache/calcite/rex/RexChecker.java @@ -22,6 +22,8 @@ import org.apache.calcite.rel.type.RelDataTypeField; import org.apache.calcite.util.Litmus; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -57,7 +59,7 @@ public class RexChecker extends RexVisitorImpl { //~ Instance fields -------------------------------------------------------- - protected final RelNode.Context context; + protected final RelNode.@Nullable Context context; protected final Litmus litmus; protected final List inputTypeList; protected int failCount; @@ -77,7 +79,7 @@ public class RexChecker extends RexVisitorImpl { * @param context Context of the enclosing {@link RelNode}, or null * @param litmus What to do if an invalid node is detected */ - public RexChecker(final RelDataType inputRowType, RelNode.Context context, + public RexChecker(final RelDataType inputRowType, RelNode.@Nullable Context context, Litmus litmus) { this(RelOptUtil.getFieldTypeList(inputRowType), context, litmus); } @@ -95,7 +97,7 @@ public RexChecker(final RelDataType inputRowType, RelNode.Context context, * @param context Context of the enclosing {@link RelNode}, or null * @param litmus What to do if an error is detected */ - public RexChecker(List inputTypeList, RelNode.Context context, + public RexChecker(List inputTypeList, RelNode.@Nullable Context context, Litmus litmus) { super(true); this.inputTypeList = inputTypeList; diff --git a/core/src/main/java/org/apache/calcite/rex/RexLiteral.java b/core/src/main/java/org/apache/calcite/rex/RexLiteral.java index 972d7fa8b85c..4333a84fbca3 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexLiteral.java +++ b/core/src/main/java/org/apache/calcite/rex/RexLiteral.java @@ -183,7 +183,7 @@ public class RexLiteral extends RexNode { * represented by a {@link BigDecimal}. But since this field is private, it * doesn't really matter how the values are stored. */ - private final Comparable value; + private final @Nullable Comparable value; /** * The real type of this literal, as reported by {@link #getType}. @@ -873,7 +873,7 @@ public Comparable getValue() { * Returns the value of this literal, in the form that the calculator * program builder wants it. */ - public Object getValue2() { + public @Nullable Object getValue2() { if (value == null) { return null; } @@ -897,7 +897,7 @@ public Object getValue2() { * Returns the value of this literal, in the form that the rex-to-lix * translator wants it. */ - public Object getValue3() { + public @Nullable Object getValue3() { if (value == null) { return null; } @@ -914,7 +914,7 @@ public Object getValue3() { * Returns the value of this literal, in the form that {@link RexInterpreter} * wants it. */ - public Comparable getValue4() { + public @Nullable Comparable getValue4() { if (value == null) { return null; } @@ -1112,7 +1112,7 @@ public static int intValue(RexNode node) { return ((Number) value).intValue(); } - public static String stringValue(RexNode node) { + public static @Nullable String stringValue(RexNode node) { final Comparable value = findValue(node); return (value == null) ? null : ((NlsString) value).getValue(); } diff --git a/core/src/main/java/org/apache/calcite/rex/RexNode.java b/core/src/main/java/org/apache/calcite/rex/RexNode.java index 92f92cd8f78e..38a32fbfbdd6 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexNode.java +++ b/core/src/main/java/org/apache/calcite/rex/RexNode.java @@ -19,8 +19,12 @@ import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.sql.SqlKind; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.Collection; +import static org.apache.calcite.linq4j.Nullness.assertNonNull; + /** * Row expression. * @@ -40,7 +44,7 @@ public abstract class RexNode { //~ Instance fields -------------------------------------------------------- // Effectively final. Set in each sub-class constructor, and never re-set. - protected String digest; + protected @Nullable String digest; //~ Methods ---------------------------------------------------------------- @@ -80,7 +84,7 @@ public SqlKind getKind() { } public String toString() { - return digest; + return assertNonNull(digest); } /** Returns the number of nodes in this expression. diff --git a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java index b48fd7e78294..4f4ff7143050 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java +++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java @@ -46,6 +46,8 @@ import com.google.common.collect.Sets; import com.google.common.collect.TreeRangeSet; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.ArrayList; import java.util.BitSet; import java.util.Collection; @@ -2483,7 +2485,7 @@ private static boolean isLowerBound(final RexNode e) { * @param predicates Filter condition predicates * @return simplified conjunction of predicates for the filter, null if always false */ - public RexNode simplifyFilterPredicates(Iterable predicates) { + public @Nullable RexNode simplifyFilterPredicates(Iterable predicates) { final RexNode simplifiedAnds = withPredicateElimination(Bug.CALCITE_2401_FIXED) .simplifyUnknownAsFalse( diff --git a/core/src/main/java/org/apache/calcite/rex/RexUtil.java b/core/src/main/java/org/apache/calcite/rex/RexUtil.java index ec42695b9430..878fba99a589 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexUtil.java +++ b/core/src/main/java/org/apache/calcite/rex/RexUtil.java @@ -51,6 +51,7 @@ import com.google.common.collect.Lists; import org.apiguardian.api.API; +import org.checkerframework.checker.nullness.qual.Nullable; import java.util.ArrayList; import java.util.Arrays; @@ -86,7 +87,7 @@ private RexUtil() { * selectivity of 1.0) * @return guessed selectivity */ - public static double getSelectivity(RexNode exp) { + public static double getSelectivity(@Nullable RexNode exp) { if ((exp == null) || exp.isAlwaysTrue()) { return 1d; } @@ -1009,8 +1010,8 @@ public static RelDataType createStructType( public static RelDataType createStructType( RelDataTypeFactory typeFactory, final List exprs, - List names, - SqlValidatorUtil.Suggester suggester) { + @Nullable List names, + SqlValidatorUtil.@Nullable Suggester suggester) { if (names != null && suggester != null) { names = SqlValidatorUtil.uniquify(names, suggester, typeFactory.getTypeSystem().isSchemaCaseSensitive()); @@ -1316,7 +1317,7 @@ public static RelCollation apply( * @param fieldCollation Field collation * @return collation with mapping applied */ - public static RelFieldCollation apply( + public static @Nullable RelFieldCollation apply( Mappings.TargetMapping mapping, RelFieldCollation fieldCollation) { final int target = @@ -1393,7 +1394,7 @@ public static T[] apply( public static void apply( RexVisitor visitor, RexNode[] exprs, - RexNode expr) { + @Nullable RexNode expr) { for (RexNode e : exprs) { e.accept(visitor); } @@ -1413,7 +1414,7 @@ public static void apply( public static void apply( RexVisitor visitor, List exprs, - RexNode expr) { + @Nullable RexNode expr) { for (RexNode e : exprs) { e.accept(visitor); } @@ -2119,8 +2120,8 @@ public static RexNode swapColumnReferences(final RexBuilder rexBuilder, * in the second map (in particular, the first element of the set in the map value). */ public static RexNode swapTableColumnReferences(final RexBuilder rexBuilder, - final RexNode node, final Map tableMapping, - final Map> ec) { + final RexNode node, final @Nullable Map tableMapping, + final Map> ec) { RexShuttle visitor = new RexShuttle() { @Override public RexNode visitTableInputRef(RexTableInputRef inputRef) { @@ -2149,8 +2150,8 @@ public static RexNode swapTableColumnReferences(final RexBuilder rexBuilder, * {@link RexTableInputRef} using the contents in the second map. */ public static RexNode swapColumnTableReferences(final RexBuilder rexBuilder, - final RexNode node, final Map> ec, - final Map tableMapping) { + final RexNode node, final Map> ec, + final @Nullable Map tableMapping) { RexShuttle visitor = new RexShuttle() { @Override public RexNode visitTableInputRef(RexTableInputRef inputRef) { diff --git a/core/src/main/java/org/apache/calcite/rex/RexVisitorImpl.java b/core/src/main/java/org/apache/calcite/rex/RexVisitorImpl.java index c4808786a795..7a3f8b801c17 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexVisitorImpl.java +++ b/core/src/main/java/org/apache/calcite/rex/RexVisitorImpl.java @@ -16,6 +16,8 @@ */ package org.apache.calcite.rex; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -24,7 +26,7 @@ * * @param Return type from each {@code visitXxx} method. */ -public class RexVisitorImpl implements RexVisitor { +public class RexVisitorImpl<@Nullable R> implements RexVisitor { //~ Instance fields -------------------------------------------------------- protected final boolean deep; diff --git a/core/src/main/java/org/apache/calcite/runtime/CalciteContextException.java b/core/src/main/java/org/apache/calcite/runtime/CalciteContextException.java index 0b269d19328b..7b134de29afc 100644 --- a/core/src/main/java/org/apache/calcite/runtime/CalciteContextException.java +++ b/core/src/main/java/org/apache/calcite/runtime/CalciteContextException.java @@ -20,6 +20,9 @@ // resource generation can use reflection. That means it must have no // dependencies on other Calcite code. +import org.checkerframework.checker.initialization.qual.UnderInitialization; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * Exception which contains information about the textual context of the causing * exception. @@ -44,7 +47,7 @@ public class CalciteContextException extends CalciteException { private int endPosColumn; - private String originalStatement; + private @Nullable String originalStatement; //~ Constructors ----------------------------------------------------------- @@ -121,6 +124,7 @@ public void setPosition(int posLine, int posColumn) { * @param endPosColumn 1-based end column number */ public void setPosition( + @UnderInitialization CalciteContextException this, int posLine, int posColumn, int endPosLine, @@ -164,20 +168,25 @@ public int getEndPosColumn() { /** * Returns the input string that is associated with the context. */ - public String getOriginalStatement() { + public @Nullable String getOriginalStatement() { return originalStatement; } /** * Sets the input string to associate with the current context. */ - public void setOriginalStatement(String originalStatement) { + public void setOriginalStatement(@Nullable String originalStatement) { this.originalStatement = originalStatement; } - @Override public String getMessage() { + @Override public @Nullable String getMessage() { // The superclass' message is the textual context information // for this exception, so we add in the underlying cause to the message - return super.getMessage() + ": " + getCause().getMessage(); + Throwable cause = getCause(); + if (cause == null) { + // It would be sad to get NPE from getMessage + return super.getMessage(); + } + return super.getMessage() + ": " + cause.getMessage(); } } diff --git a/core/src/main/java/org/apache/calcite/runtime/CalciteException.java b/core/src/main/java/org/apache/calcite/runtime/CalciteException.java index 440bca1182c8..73a55c5de6ab 100644 --- a/core/src/main/java/org/apache/calcite/runtime/CalciteException.java +++ b/core/src/main/java/org/apache/calcite/runtime/CalciteException.java @@ -52,6 +52,7 @@ public class CalciteException extends RuntimeException { * @param message error message * @param cause underlying cause */ + @SuppressWarnings({"argument.type.incompatible", "method.invocation.invalid"}) public CalciteException( String message, Throwable cause) { diff --git a/core/src/main/java/org/apache/calcite/runtime/FlatLists.java b/core/src/main/java/org/apache/calcite/runtime/FlatLists.java index b2d161a7fe6d..9c77a5f1298e 100644 --- a/core/src/main/java/org/apache/calcite/runtime/FlatLists.java +++ b/core/src/main/java/org/apache/calcite/runtime/FlatLists.java @@ -22,6 +22,7 @@ import com.google.common.collect.ImmutableMap; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.checker.nullness.qual.PolyNull; import java.util.AbstractList; import java.util.ArrayList; @@ -380,7 +381,7 @@ public int lastIndexOf(Object o) { } @SuppressWarnings({"unchecked" }) - public T2[] toArray(T2[] a) { + public T2 @PolyNull [] toArray(T2 @PolyNull [] a) { if (a.length < 1) { // Make a new array of a's runtime type, but my contents: return (T2[]) Arrays.copyOf(toArray(), 1, a.getClass()); @@ -512,7 +513,7 @@ public int lastIndexOf(Object o) { } @SuppressWarnings({"unchecked" }) - public T2[] toArray(T2[] a) { + public T2 @PolyNull [] toArray(T2 @PolyNull [] a) { if (a.length < 2) { // Make a new array of a's runtime type, but my contents: return (T2[]) Arrays.copyOf(toArray(), 2, a.getClass()); @@ -661,7 +662,7 @@ public int lastIndexOf(Object o) { } @SuppressWarnings({"unchecked" }) - public T2[] toArray(T2[] a) { + public T2 @PolyNull [] toArray(T2 @PolyNull [] a) { if (a.length < 3) { // Make a new array of a's runtime type, but my contents: return (T2[]) Arrays.copyOf(toArray(), 3, a.getClass()); @@ -829,7 +830,7 @@ public int lastIndexOf(Object o) { } @SuppressWarnings({"unchecked" }) - public T2[] toArray(T2[] a) { + public T2 @PolyNull [] toArray(T2 @PolyNull [] a) { if (a.length < 4) { // Make a new array of a's runtime type, but my contents: return (T2[]) Arrays.copyOf(toArray(), 4, a.getClass()); @@ -1016,7 +1017,7 @@ public int lastIndexOf(Object o) { } @SuppressWarnings({"unchecked" }) - public T2[] toArray(T2[] a) { + public T2 @PolyNull [] toArray(T2 @PolyNull [] a) { if (a.length < 5) { // Make a new array of a's runtime type, but my contents: return (T2[]) Arrays.copyOf(toArray(), 5, a.getClass()); @@ -1223,7 +1224,7 @@ public int lastIndexOf(Object o) { } @SuppressWarnings({"unchecked" }) - public T2[] toArray(T2[] a) { + public T2 @PolyNull [] toArray(T2 @PolyNull [] a) { if (a.length < 6) { // Make a new array of a's runtime type, but my contents: return (T2[]) Arrays.copyOf(toArray(), 6, a.getClass()); diff --git a/core/src/main/java/org/apache/calcite/runtime/Resources.java b/core/src/main/java/org/apache/calcite/runtime/Resources.java index 27060c898ad8..f309f481eab4 100644 --- a/core/src/main/java/org/apache/calcite/runtime/Resources.java +++ b/core/src/main/java/org/apache/calcite/runtime/Resources.java @@ -17,6 +17,7 @@ package org.apache.calcite.runtime; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.checker.nullness.qual.PolyNull; import java.io.IOException; import java.io.InputStream; @@ -67,7 +68,7 @@ public static void setThreadLocale(Locale locale) { * thread has not called {@link #setThreadLocale}. * * @return Locale */ - public static Locale getThreadLocale() { + public static @Nullable Locale getThreadLocale() { return MAP_THREAD_TO_LOCALE.get(); } @@ -139,7 +140,7 @@ private static T create(final String base, new InvocationHandler() { final Map cache = new ConcurrentHashMap<>(); - public Object invoke(Object proxy, Method method, Object[] args) + public Object invoke(Object proxy, Method method, @Nullable Object @Nullable [] args) throws Throwable { if (args == null || args.length == 0) { Object o = cache.get(method.getName()); @@ -152,7 +153,7 @@ public Object invoke(Object proxy, Method method, Object[] args) return create(method, args); } - private Object create(Method method, Object[] args) + private Object create(Method method, @Nullable Object @Nullable [] args) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { if (method.equals(BuiltinMethod.OBJECT_TO_STRING.method)) { @@ -229,7 +230,7 @@ public static void validate(Object o, EnumSet validations) { } } - private static Object zero(Class clazz) { + private static @Nullable Object zero(Class clazz) { return clazz == String.class ? "" : clazz == byte.class ? (byte) 0 : clazz == char.class ? (char) 0 @@ -243,7 +244,7 @@ private static Object zero(Class clazz) { } /** Returns whether two objects are equal or are both null. */ - private static boolean equal(Object o0, Object o1) { + private static boolean equal(@Nullable Object o0, @Nullable Object o1) { return o0 == o1 || o0 != null && o0.equals(o1); } @@ -276,7 +277,7 @@ public static class Inst extends Element { protected final String base; protected final Object[] args; - public Inst(String base, Locale locale, Method method, Object... args) { + public Inst(String base, Locale locale, Method method, @Nullable Object... args) { super(method); this.base = base; this.locale = locale; @@ -700,7 +701,7 @@ public double defaultValue() { /** String property instance. */ public static class StringProp extends Prop { - private final String defaultValue; + private final @Nullable String defaultValue; public StringProp(PropertyAccessor accessor, Method method) { super(accessor, method); @@ -743,8 +744,8 @@ public interface PropertyAccessor { boolean isSet(Prop p); int intValue(IntProp p); int intValue(IntProp p, int defaultValue); - String stringValue(StringProp p); - String stringValue(StringProp p, String defaultValue); + @Nullable String stringValue(StringProp p); + @PolyNull String stringValue(StringProp p, @PolyNull String defaultValue); boolean booleanValue(BooleanProp p); boolean booleanValue(BooleanProp p, boolean defaultValue); double doubleValue(DoubleProp p); @@ -766,11 +767,11 @@ public int intValue(IntProp p, int defaultValue) { return defaultValue; } - public String stringValue(StringProp p) { + public @Nullable String stringValue(StringProp p) { return p.defaultValue(); } - public String stringValue(StringProp p, String defaultValue) { + public @PolyNull String stringValue(StringProp p, @PolyNull String defaultValue) { return defaultValue; } @@ -926,11 +927,11 @@ protected ShadowResourceBundle() throws IOException { * Opens the properties file corresponding to a given class. The code is * copied from {@link ResourceBundle}. */ - private static InputStream openPropertiesFile(Class clazz) { + private static @Nullable InputStream openPropertiesFile(Class clazz) { final ClassLoader loader = clazz.getClassLoader(); final String resName = clazz.getName().replace('.', '/') + ".properties"; return java.security.AccessController.doPrivileged( - (PrivilegedAction) () -> { + (PrivilegedAction<@Nullable InputStream>) () -> { if (loader != null) { return loader.getResourceAsStream(resName); } else { @@ -1060,7 +1061,7 @@ public int intValue(IntProp p, int defaultValue) { return s == null ? defaultValue : Integer.parseInt(s, 10); } - public String stringValue(StringProp p) { + public @Nullable String stringValue(StringProp p) { final String s = properties.getProperty(p.key); if (s != null) { return s; @@ -1069,7 +1070,7 @@ public String stringValue(StringProp p) { return p.defaultValue; } - public String stringValue(StringProp p, String defaultValue) { + public @PolyNull String stringValue(StringProp p, @PolyNull String defaultValue) { final String s = properties.getProperty(p.key); return s == null ? defaultValue : s; } diff --git a/core/src/main/java/org/apache/calcite/runtime/Utilities.java b/core/src/main/java/org/apache/calcite/runtime/Utilities.java index b09c91a5c6cd..458a07c8987c 100644 --- a/core/src/main/java/org/apache/calcite/runtime/Utilities.java +++ b/core/src/main/java/org/apache/calcite/runtime/Utilities.java @@ -16,6 +16,8 @@ */ package org.apache.calcite.runtime; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.text.Collator; import java.util.Comparator; import java.util.Iterator; @@ -36,13 +38,13 @@ protected Utilities() { // CHECKSTYLE: IGNORE 1 /** @deprecated Use {@link java.util.Objects#equals}. */ @Deprecated // to be removed before 2.0 - public static boolean equal(Object o0, Object o1) { + public static boolean equal(@Nullable Object o0, @Nullable Object o1) { // Same as java.lang.Objects.equals (JDK 1.7 and later) // and com.google.common.base.Objects.equal return Objects.equals(o0, o1); } - public static int hash(Object v) { + public static int hash(@Nullable Object v) { return v == null ? 0 : v.hashCode(); } @@ -130,7 +132,7 @@ public static int hash(int h, double v) { return hash(h, Double.hashCode(v)); } - public static int hash(int h, Object v) { + public static int hash(int h, @Nullable Object v) { return h * 31 + (v == null ? 1 : v.hashCode()); } @@ -200,7 +202,7 @@ public static int compare(Comparable v0, Comparable v1) { return v0.compareTo(v1); } - public static int compareNullsFirst(Comparable v0, Comparable v1) { + public static int compareNullsFirst(@Nullable Comparable v0, @Nullable Comparable v1) { //noinspection unchecked return v0 == v1 ? 0 : v0 == null ? -1 @@ -208,7 +210,7 @@ public static int compareNullsFirst(Comparable v0, Comparable v1) { : v0.compareTo(v1); } - public static int compareNullsLast(Comparable v0, Comparable v1) { + public static int compareNullsLast(@Nullable Comparable v0, @Nullable Comparable v1) { //noinspection unchecked return v0 == v1 ? 0 : v0 == null ? 1 @@ -216,12 +218,14 @@ public static int compareNullsLast(Comparable v0, Comparable v1) { : v0.compareTo(v1); } - public static int compare(Comparable v0, Comparable v1, Comparator comparator) { + public static int compare(@Nullable Comparable v0, @Nullable Comparable v1, + Comparator comparator) { //noinspection unchecked return comparator.compare(v0, v1); } - public static int compareNullsFirst(Comparable v0, Comparable v1, Comparator comparator) { + public static int compareNullsFirst(@Nullable Comparable v0, @Nullable Comparable v1, + Comparator comparator) { //noinspection unchecked return v0 == v1 ? 0 : v0 == null ? -1 @@ -229,7 +233,8 @@ public static int compareNullsFirst(Comparable v0, Comparable v1, Comparator com : comparator.compare(v0, v1); } - public static int compareNullsLast(Comparable v0, Comparable v1, Comparator comparator) { + public static int compareNullsLast(@Nullable Comparable v0, @Nullable Comparable v1, + Comparator comparator) { //noinspection unchecked return v0 == v1 ? 0 : v0 == null ? 1 diff --git a/core/src/main/java/org/apache/calcite/schema/Schema.java b/core/src/main/java/org/apache/calcite/schema/Schema.java index 7dee0c3b89d8..8f310dd58c6a 100644 --- a/core/src/main/java/org/apache/calcite/schema/Schema.java +++ b/core/src/main/java/org/apache/calcite/schema/Schema.java @@ -19,6 +19,8 @@ import org.apache.calcite.linq4j.tree.Expression; import org.apache.calcite.rel.type.RelProtoDataType; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.Collection; import java.util.Set; @@ -75,7 +77,7 @@ public interface Schema { * @param name Table name * @return Table, or null */ - RelProtoDataType getType(String name); + @Nullable RelProtoDataType getType(String name); /** * Returns the names of the types in this schema. @@ -106,7 +108,7 @@ public interface Schema { * @param name Sub-schema name * @return Sub-schema with a given name, or null */ - Schema getSubSchema(String name); + @Nullable Schema getSubSchema(String name); /** * Returns the names of this schema's child schemas. diff --git a/core/src/main/java/org/apache/calcite/schema/SchemaPlus.java b/core/src/main/java/org/apache/calcite/schema/SchemaPlus.java index 8043560394f7..e388e892b9d1 100644 --- a/core/src/main/java/org/apache/calcite/schema/SchemaPlus.java +++ b/core/src/main/java/org/apache/calcite/schema/SchemaPlus.java @@ -21,6 +21,8 @@ import com.google.common.collect.ImmutableList; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * Extension to the {@link Schema} interface. * @@ -57,7 +59,7 @@ public interface SchemaPlus extends Schema { String getName(); // override with stricter return - SchemaPlus getSubSchema(String name); + @Nullable SchemaPlus getSubSchema(String name); /** Adds a schema as a sub-schema of this schema, and returns the wrapped * object. */ diff --git a/core/src/main/java/org/apache/calcite/schema/Wrapper.java b/core/src/main/java/org/apache/calcite/schema/Wrapper.java index e68f61fc2b9b..6a575ede0861 100644 --- a/core/src/main/java/org/apache/calcite/schema/Wrapper.java +++ b/core/src/main/java/org/apache/calcite/schema/Wrapper.java @@ -16,11 +16,13 @@ */ package org.apache.calcite.schema; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * Mix-in interface that allows you to find sub-objects. */ public interface Wrapper { /** Finds an instance of an interface implemented by this object, * or returns null if this object does not support that interface. */ - C unwrap(Class aClass); + @Nullable C unwrap(Class aClass); } diff --git a/core/src/main/java/org/apache/calcite/schema/impl/AbstractSchema.java b/core/src/main/java/org/apache/calcite/schema/impl/AbstractSchema.java index 2c01b1958eba..d67144a72722 100644 --- a/core/src/main/java/org/apache/calcite/schema/impl/AbstractSchema.java +++ b/core/src/main/java/org/apache/calcite/schema/impl/AbstractSchema.java @@ -30,6 +30,8 @@ import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Multimap; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.Collection; import java.util.Map; import java.util.Set; @@ -103,7 +105,7 @@ protected Map getTypeMap() { return ImmutableMap.of(); } - public RelProtoDataType getType(String name) { + public @Nullable RelProtoDataType getType(String name) { return getTypeMap().get(name); } @@ -154,7 +156,7 @@ public final Set getSubSchemaNames() { return getSubSchemaMap().keySet(); } - public final Schema getSubSchema(String name) { + public final @Nullable Schema getSubSchema(String name) { return getSubSchemaMap().get(name); } diff --git a/core/src/main/java/org/apache/calcite/schema/impl/AbstractTable.java b/core/src/main/java/org/apache/calcite/schema/impl/AbstractTable.java index 3f93c7ee3809..a50c21058725 100644 --- a/core/src/main/java/org/apache/calcite/schema/impl/AbstractTable.java +++ b/core/src/main/java/org/apache/calcite/schema/impl/AbstractTable.java @@ -25,6 +25,8 @@ import org.apache.calcite.sql.SqlCall; import org.apache.calcite.sql.SqlNode; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * Abstract base class for implementing {@link Table}. * @@ -46,7 +48,7 @@ public Schema.TableType getJdbcTableType() { return Schema.TableType.TABLE; } - public C unwrap(Class aClass) { + public @Nullable C unwrap(Class aClass) { if (aClass.isInstance(this)) { return aClass.cast(this); } diff --git a/core/src/main/java/org/apache/calcite/schema/impl/DelegatingSchema.java b/core/src/main/java/org/apache/calcite/schema/impl/DelegatingSchema.java index 4cd1af3d4c97..8eafecdbf4fc 100644 --- a/core/src/main/java/org/apache/calcite/schema/impl/DelegatingSchema.java +++ b/core/src/main/java/org/apache/calcite/schema/impl/DelegatingSchema.java @@ -24,6 +24,8 @@ import org.apache.calcite.schema.SchemaVersion; import org.apache.calcite.schema.Table; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.Collection; import java.util.Set; @@ -67,7 +69,7 @@ public Set getTableNames() { return schema.getTableNames(); } - public RelProtoDataType getType(String name) { + public @Nullable RelProtoDataType getType(String name) { return schema.getType(name); } @@ -83,7 +85,7 @@ public Set getFunctionNames() { return schema.getFunctionNames(); } - public Schema getSubSchema(String name) { + public @Nullable Schema getSubSchema(String name) { return schema.getSubSchema(name); } diff --git a/core/src/main/java/org/apache/calcite/schema/impl/ModifiableViewTable.java b/core/src/main/java/org/apache/calcite/schema/impl/ModifiableViewTable.java index 2caa91d123d3..f9811b0b1211 100644 --- a/core/src/main/java/org/apache/calcite/schema/impl/ModifiableViewTable.java +++ b/core/src/main/java/org/apache/calcite/schema/impl/ModifiableViewTable.java @@ -40,6 +40,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.lang.reflect.Type; import java.util.ArrayList; import java.util.HashMap; @@ -87,7 +89,7 @@ public Path getTablePath() { return tablePath; } - @Override public C unwrap(Class aClass) { + @Override public @Nullable C unwrap(Class aClass) { if (aClass.isInstance(initializerExpressionFactory)) { return aClass.cast(initializerExpressionFactory); } else if (aClass.isInstance(table)) { diff --git a/core/src/main/java/org/apache/calcite/sql/SqlAbstractDateTimeLiteral.java b/core/src/main/java/org/apache/calcite/sql/SqlAbstractDateTimeLiteral.java index 65fa6bee212c..b24e7db13d2d 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlAbstractDateTimeLiteral.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlAbstractDateTimeLiteral.java @@ -22,6 +22,8 @@ import org.apache.calcite.sql.type.SqlTypeName; import org.apache.calcite.util.TimestampString; +import static org.apache.calcite.linq4j.Nullness.assertNonNull; + /** * A SQL literal representing a DATE, TIME or TIMESTAMP value. * @@ -55,7 +57,7 @@ protected SqlAbstractDateTimeLiteral(Object d, boolean tz, /** Converts this literal to a {@link TimestampString}. */ protected TimestampString getTimestamp() { - return (TimestampString) value; + return (TimestampString) assertNonNull(value); } public int getPrec() { diff --git a/core/src/main/java/org/apache/calcite/sql/SqlAggFunction.java b/core/src/main/java/org/apache/calcite/sql/SqlAggFunction.java index 9555a0b4e150..ae249e125d2c 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlAggFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlAggFunction.java @@ -26,6 +26,8 @@ import org.apache.calcite.sql.validate.SqlValidatorScope; import org.apache.calcite.util.Optionality; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; import java.util.Objects; import javax.annotation.Nonnull; @@ -111,7 +113,7 @@ protected SqlAggFunction( //~ Methods ---------------------------------------------------------------- - public T unwrap(Class clazz) { + public @Nullable T unwrap(Class clazz) { return clazz.isInstance(this) ? clazz.cast(this) : null; } diff --git a/core/src/main/java/org/apache/calcite/sql/SqlBasicCall.java b/core/src/main/java/org/apache/calcite/sql/SqlBasicCall.java index 0a141f70e40e..9a4542ecc81c 100755 --- a/core/src/main/java/org/apache/calcite/sql/SqlBasicCall.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlBasicCall.java @@ -19,6 +19,8 @@ import org.apache.calcite.sql.parser.SqlParserPos; import org.apache.calcite.util.UnmodifiableArrayList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; import java.util.Objects; @@ -28,7 +30,7 @@ public class SqlBasicCall extends SqlCall { private SqlOperator operator; public final SqlNode[] operands; - private final SqlLiteral functionQuantifier; + private final @Nullable SqlLiteral functionQuantifier; private final boolean expanded; public SqlBasicCall( @@ -43,7 +45,7 @@ public SqlBasicCall( SqlNode[] operands, SqlParserPos pos, boolean expanded, - SqlLiteral functionQualifier) { + @Nullable SqlLiteral functionQualifier) { super(pos); this.operator = Objects.requireNonNull(operator); this.operands = operands; @@ -88,7 +90,7 @@ public List getOperandList() { return operands.length; } - @Override public SqlLiteral getFunctionQuantifier() { + @Override public @Nullable SqlLiteral getFunctionQuantifier() { return functionQuantifier; } diff --git a/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java b/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java index d28d3e9711cd..6f85c6059384 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java @@ -28,9 +28,12 @@ import org.apache.calcite.util.Litmus; import org.apache.calcite.util.Util; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.math.BigDecimal; import java.nio.charset.Charset; +import static org.apache.calcite.linq4j.Nullness.assertNonNull; import static org.apache.calcite.util.Static.RESOURCE; /** @@ -55,9 +58,9 @@ public SqlBinaryOperator( SqlKind kind, int prec, boolean leftAssoc, - SqlReturnTypeInference returnTypeInference, - SqlOperandTypeInference operandTypeInference, - SqlOperandTypeChecker operandTypeChecker) { + @Nullable SqlReturnTypeInference returnTypeInference, + @Nullable SqlOperandTypeInference operandTypeInference, + @Nullable SqlOperandTypeChecker operandTypeChecker) { super( name, kind, @@ -74,7 +77,7 @@ public SqlSyntax getSyntax() { return SqlSyntax.BINARY; } - public String getSignatureTemplate(final int operandsCount) { + public @Nullable String getSignatureTemplate(final int operandsCount) { Util.discard(operandsCount); // op0 opname op1 @@ -135,7 +138,7 @@ private RelDataType convertType(SqlValidator validator, SqlCall call, RelDataTyp .createTypeWithCharsetAndCollation( type, type.getCharset(), - resultCol); + assertNonNull(resultCol)); } } return type; diff --git a/core/src/main/java/org/apache/calcite/sql/SqlCall.java b/core/src/main/java/org/apache/calcite/sql/SqlCall.java index 8678c7e4e446..6123f30942bd 100755 --- a/core/src/main/java/org/apache/calcite/sql/SqlCall.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlCall.java @@ -26,6 +26,8 @@ import org.apache.calcite.sql.validate.SqlValidatorScope; import org.apache.calcite.util.Litmus; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -203,7 +205,7 @@ && operandCount() == 1) { return false; } - public SqlLiteral getFunctionQuantifier() { + public @Nullable SqlLiteral getFunctionQuantifier() { return null; } } diff --git a/core/src/main/java/org/apache/calcite/sql/SqlCollation.java b/core/src/main/java/org/apache/calcite/sql/SqlCollation.java index 3f31d65c9545..993ab1ceb46e 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlCollation.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlCollation.java @@ -22,6 +22,7 @@ import org.apache.calcite.util.SerializableCharset; import org.apache.calcite.util.Util; +import org.checkerframework.checker.initialization.qual.UnderInitialization; import org.checkerframework.checker.nullness.qual.Nullable; import java.io.Serializable; @@ -134,7 +135,9 @@ public SqlCollation( return collationName.hashCode(); } - protected String generateCollationName(Charset charset) { + protected String generateCollationName( + @UnderInitialization SqlCollation this, + Charset charset) { return charset.name().toUpperCase(Locale.ROOT) + "$" + locale.toString() + "$" + strength; } @@ -149,7 +152,7 @@ protected String generateCollationName(Charset charset) { * * @see Glossary#SQL99 SQL:1999 Part 2 Section 4.2.3 Table 2 */ - public static SqlCollation getCoercibilityDyadicOperator( + public static @Nullable SqlCollation getCoercibilityDyadicOperator( SqlCollation col1, SqlCollation col2) { return getCoercibilityDyadic(col1, col2); @@ -207,7 +210,7 @@ public static String getCoercibilityDyadicComparison( * Returns the result for {@link #getCoercibilityDyadicComparison} and * {@link #getCoercibilityDyadicOperator}. */ - protected static SqlCollation getCoercibilityDyadic( + protected static @Nullable SqlCollation getCoercibilityDyadic( SqlCollation col1, SqlCollation col2) { assert null != col1; @@ -307,7 +310,7 @@ public final Locale getLocale() { * collation, or {@code null} if no specific {@link Collator} is needed, in * which case {@link String#compareTo} will be used. */ - public Collator getCollator() { + public @Nullable Collator getCollator() { return null; } } diff --git a/core/src/main/java/org/apache/calcite/sql/SqlDescribeSchema.java b/core/src/main/java/org/apache/calcite/sql/SqlDescribeSchema.java index 440396d42779..27bcdcfb2332 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlDescribeSchema.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlDescribeSchema.java @@ -19,6 +19,8 @@ import org.apache.calcite.sql.parser.SqlParserPos; import org.apache.calcite.util.ImmutableNullableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -29,7 +31,7 @@ public class SqlDescribeSchema extends SqlCall { public static final SqlSpecialOperator OPERATOR = new SqlSpecialOperator("DESCRIBE_SCHEMA", SqlKind.DESCRIBE_SCHEMA) { - @Override public SqlCall createCall(SqlLiteral functionQualifier, + @Override public SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { return new SqlDescribeSchema(pos, (SqlIdentifier) operands[0]); } diff --git a/core/src/main/java/org/apache/calcite/sql/SqlDescribeTable.java b/core/src/main/java/org/apache/calcite/sql/SqlDescribeTable.java index d275a4a6c09b..44487da5b79f 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlDescribeTable.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlDescribeTable.java @@ -19,6 +19,8 @@ import org.apache.calcite.sql.parser.SqlParserPos; import org.apache.calcite.util.ImmutableNullableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -29,7 +31,7 @@ public class SqlDescribeTable extends SqlCall { public static final SqlSpecialOperator OPERATOR = new SqlSpecialOperator("DESCRIBE_TABLE", SqlKind.DESCRIBE_TABLE) { - @Override public SqlCall createCall(SqlLiteral functionQualifier, + @Override public SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { return new SqlDescribeTable(pos, (SqlIdentifier) operands[0], (SqlIdentifier) operands[1]); diff --git a/core/src/main/java/org/apache/calcite/sql/SqlDialect.java b/core/src/main/java/org/apache/calcite/sql/SqlDialect.java index 6a7459196926..7b35a27773c1 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlDialect.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlDialect.java @@ -136,9 +136,9 @@ public class SqlDialect { //~ Instance fields -------------------------------------------------------- - protected final String identifierQuoteString; - protected final String identifierEndQuoteString; - protected final String identifierEscapedQuote; + protected final @Nullable String identifierQuoteString; + protected final @Nullable String identifierEndQuoteString; + protected final @Nullable String identifierEscapedQuote; protected final String literalQuoteString; protected final String literalEndQuoteString; protected final String literalEscapedQuote; @@ -359,6 +359,8 @@ public StringBuilder quoteIdentifier( StringBuilder buf, String val) { if (identifierQuoteString == null // quoting is not supported + || identifierEndQuoteString == null + || identifierEscapedQuote == null || !identifierNeedsQuote(val)) { buf.append(val); } else { @@ -412,7 +414,7 @@ public final String quoteStringLiteral(String val) { * @param charsetName Character set name, e.g. "utf16", or null * @param val String value */ - public void quoteStringLiteral(StringBuilder buf, String charsetName, + public void quoteStringLiteral(StringBuilder buf, @Nullable String charsetName, String val) { if (containsNonAscii(val) && charsetName == null) { quoteStringLiteralUnicode(buf, val); @@ -531,7 +533,7 @@ public void unparseSqlIntervalLiteral(SqlWriter writer, if (interval.getSign() == -1) { writer.print("-"); } - writer.literal("'" + literal.getValue().toString() + "'"); + writer.literal("'" + String.valueOf(literal.getValue()) + "'"); unparseSqlIntervalQualifier(writer, interval.getIntervalQualifier(), RelDataTypeSystem.DEFAULT); } @@ -768,7 +770,7 @@ public boolean supportsDataType(RelDataType type) { *

If this method returns null, the cast will be omitted. In the default * implementation, this is the case for the NULL type, and therefore * {@code CAST(NULL AS )} is rendered as {@code NULL}. */ - public SqlNode getCastSpec(RelDataType type) { + public @Nullable SqlNode getCastSpec(RelDataType type) { if (type instanceof BasicSqlType) { int maxPrecision = -1; switch (type.getSqlTypeName()) { @@ -801,11 +803,11 @@ public SqlNode rewriteSingleValueExpr(SqlNode aggCall) { * @param node The SqlNode representing the expression * @param nullsFirst Whether nulls should come first * @param desc Whether the sort direction is - * {@link org.apache.calcite.rel.RelFieldCollation.Direction#DESCENDING} or - * {@link org.apache.calcite.rel.RelFieldCollation.Direction#STRICTLY_DESCENDING} + * {@link RelFieldCollation.Direction#DESCENDING} or + * {@link RelFieldCollation.Direction#STRICTLY_DESCENDING} * @return A SqlNode for null direction emulation or null if not required */ - public SqlNode emulateNullDirection(SqlNode node, boolean nullsFirst, + public @Nullable SqlNode emulateNullDirection(SqlNode node, boolean nullsFirst, boolean desc) { return null; } @@ -814,7 +816,7 @@ public JoinType emulateJoinTypeForCrossJoin() { return JoinType.COMMA; } - protected SqlNode emulateNullDirectionWithIsNull(SqlNode node, + protected @Nullable SqlNode emulateNullDirectionWithIsNull(SqlNode node, boolean nullsFirst, boolean desc) { // No need for emulation if the nulls will anyways come out the way we want // them based on "nullsFirst" and "desc". @@ -1126,7 +1128,7 @@ public boolean supportsImplicitTypeCoercion(RexCall call) { /** Returns the quoting scheme, or null if the combination of * {@link #identifierQuoteString} and {@link #identifierEndQuoteString} * does not correspond to any known quoting scheme. */ - protected Quoting getQuoting() { + protected @Nullable Quoting getQuoting() { if ("\"".equals(identifierQuoteString) && "\"".equals(identifierEndQuoteString)) { return Quoting.DOUBLE_QUOTE; @@ -1274,7 +1276,7 @@ public enum DatabaseProduct { private final Supplier dialect; - DatabaseProduct(String databaseProductName, String quoteString, + DatabaseProduct(String databaseProductName, @Nullable String quoteString, NullCollation nullCollation) { Objects.requireNonNull(databaseProductName); Objects.requireNonNull(nullCollation); @@ -1315,9 +1317,9 @@ public SqlDialect getDialect() { public interface Context { @Nonnull DatabaseProduct databaseProduct(); Context withDatabaseProduct(@Nonnull DatabaseProduct databaseProduct); - String databaseProductName(); + @Nullable String databaseProductName(); Context withDatabaseProductName(String databaseProductName); - String databaseVersion(); + @Nullable String databaseVersion(); Context withDatabaseVersion(String databaseVersion); int databaseMajorVersion(); Context withDatabaseMajorVersion(int databaseMajorVersion); @@ -1328,8 +1330,8 @@ public interface Context { @Nonnull String literalEscapedQuoteString(); @Nonnull Context withLiteralEscapedQuoteString( String literalEscapedQuoteString); - String identifierQuoteString(); - @Nonnull Context withIdentifierQuoteString(String identifierQuoteString); + @Nullable String identifierQuoteString(); + @Nonnull Context withIdentifierQuoteString(@Nullable String identifierQuoteString); @Nonnull Casing unquotedCasing(); @Nonnull Context withUnquotedCasing(Casing unquotedCasing); @Nonnull Casing quotedCasing(); @@ -1349,13 +1351,13 @@ public interface Context { /** Implementation of Context. */ private static class ContextImpl implements Context { private final DatabaseProduct databaseProduct; - private final String databaseProductName; - private final String databaseVersion; + private final @Nullable String databaseProductName; + private final @Nullable String databaseVersion; private final int databaseMajorVersion; private final int databaseMinorVersion; private final String literalQuoteString; private final String literalEscapedQuoteString; - private final String identifierQuoteString; + private final @Nullable String identifierQuoteString; private final Casing unquotedCasing; private final Casing quotedCasing; private final boolean caseSensitive; @@ -1365,10 +1367,10 @@ private static class ContextImpl implements Context { private final JethroDataSqlDialect.JethroInfo jethroInfo; private ContextImpl(DatabaseProduct databaseProduct, - String databaseProductName, String databaseVersion, + @Nullable String databaseProductName, @Nullable String databaseVersion, int databaseMajorVersion, int databaseMinorVersion, String literalQuoteString, String literalEscapedQuoteString, - String identifierQuoteString, Casing quotedCasing, + @Nullable String identifierQuoteString, Casing quotedCasing, Casing unquotedCasing, boolean caseSensitive, SqlConformance conformance, NullCollation nullCollation, RelDataTypeSystem dataTypeSystem, @@ -1403,7 +1405,7 @@ public Context withDatabaseProduct( conformance, nullCollation, dataTypeSystem, jethroInfo); } - public String databaseProductName() { + public @Nullable String databaseProductName() { return databaseProductName; } @@ -1415,7 +1417,7 @@ public Context withDatabaseProductName(String databaseProductName) { conformance, nullCollation, dataTypeSystem, jethroInfo); } - public String databaseVersion() { + public @Nullable String databaseVersion() { return databaseVersion; } @@ -1476,12 +1478,12 @@ public Context withLiteralEscapedQuoteString( conformance, nullCollation, dataTypeSystem, jethroInfo); } - public String identifierQuoteString() { + public @Nullable String identifierQuoteString() { return identifierQuoteString; } @Nonnull public Context withIdentifierQuoteString( - String identifierQuoteString) { + @Nullable String identifierQuoteString) { return new ContextImpl(databaseProduct, databaseProductName, databaseVersion, databaseMajorVersion, databaseMinorVersion, literalQuoteString, literalEscapedQuoteString, diff --git a/core/src/main/java/org/apache/calcite/sql/SqlExplain.java b/core/src/main/java/org/apache/calcite/sql/SqlExplain.java index 79ccc5fbf17f..1f447d8eb77f 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlExplain.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlExplain.java @@ -19,6 +19,8 @@ import org.apache.calcite.sql.parser.SqlParserPos; import org.apache.calcite.util.ImmutableNullableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -28,7 +30,7 @@ public class SqlExplain extends SqlCall { public static final SqlSpecialOperator OPERATOR = new SqlSpecialOperator("EXPLAIN", SqlKind.EXPLAIN) { - @Override public SqlCall createCall(SqlLiteral functionQualifier, + @Override public SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { return new SqlExplain(pos, operands[0], (SqlLiteral) operands[1], (SqlLiteral) operands[2], (SqlLiteral) operands[3], 0); diff --git a/core/src/main/java/org/apache/calcite/sql/SqlFunction.java b/core/src/main/java/org/apache/calcite/sql/SqlFunction.java index e2128e669ef5..ccbfb33fb347 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlFunction.java @@ -30,6 +30,8 @@ import org.apache.calcite.sql.validate.implicit.TypeCoercion; import org.apache.calcite.util.Util; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; import java.util.Objects; import javax.annotation.Nonnull; @@ -90,10 +92,10 @@ public SqlFunction( */ public SqlFunction( SqlIdentifier sqlIdentifier, - SqlReturnTypeInference returnTypeInference, - SqlOperandTypeInference operandTypeInference, - SqlOperandTypeChecker operandTypeChecker, - List paramTypes, + @Nullable SqlReturnTypeInference returnTypeInference, + @Nullable SqlOperandTypeInference operandTypeInference, + @Nullable SqlOperandTypeChecker operandTypeChecker, + @Nullable List paramTypes, SqlFunctionCategory funcType) { this(Util.last(sqlIdentifier.names), sqlIdentifier, SqlKind.OTHER_FUNCTION, returnTypeInference, operandTypeInference, operandTypeChecker, @@ -105,10 +107,10 @@ protected SqlFunction( String name, SqlIdentifier sqlIdentifier, SqlKind kind, - SqlReturnTypeInference returnTypeInference, - SqlOperandTypeInference operandTypeInference, - SqlOperandTypeChecker operandTypeChecker, - List paramTypes, + @Nullable SqlReturnTypeInference returnTypeInference, + @Nullable SqlOperandTypeInference operandTypeInference, + @Nullable SqlOperandTypeChecker operandTypeChecker, + @Nullable List paramTypes, SqlFunctionCategory category) { this(name, sqlIdentifier, kind, returnTypeInference, operandTypeInference, operandTypeChecker, category); @@ -121,9 +123,9 @@ protected SqlFunction( String name, SqlIdentifier sqlIdentifier, SqlKind kind, - SqlReturnTypeInference returnTypeInference, - SqlOperandTypeInference operandTypeInference, - SqlOperandTypeChecker operandTypeChecker, + @Nullable SqlReturnTypeInference returnTypeInference, + @Nullable SqlOperandTypeInference operandTypeInference, + @Nullable SqlOperandTypeChecker operandTypeChecker, SqlFunctionCategory category) { super(name, kind, 100, 100, returnTypeInference, operandTypeInference, operandTypeChecker); diff --git a/core/src/main/java/org/apache/calcite/sql/SqlInsert.java b/core/src/main/java/org/apache/calcite/sql/SqlInsert.java index b3dccd7008ba..548bb3b4bdd3 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlInsert.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlInsert.java @@ -21,6 +21,8 @@ import org.apache.calcite.sql.validate.SqlValidatorScope; import org.apache.calcite.util.ImmutableNullableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -30,7 +32,8 @@ public class SqlInsert extends SqlCall { public static final SqlSpecialOperator OPERATOR = new SqlSpecialOperator("INSERT", SqlKind.INSERT) { - @Override public SqlCall createCall(SqlLiteral functionQualifier, SqlParserPos pos, + @Override public SqlCall createCall(@Nullable SqlLiteral functionQualifier, + SqlParserPos pos, SqlNode... operands) { return new SqlInsert( pos, diff --git a/core/src/main/java/org/apache/calcite/sql/SqlIntervalQualifier.java b/core/src/main/java/org/apache/calcite/sql/SqlIntervalQualifier.java index e0d0cd9f7e45..10360faec43a 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlIntervalQualifier.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlIntervalQualifier.java @@ -29,6 +29,8 @@ import org.apache.calcite.util.Litmus; import org.apache.calcite.util.Util; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.math.BigDecimal; import java.util.Objects; import java.util.regex.Matcher; @@ -37,6 +39,8 @@ import static org.apache.calcite.util.Static.RESOURCE; +import static org.checkerframework.checker.nullness.NullnessUtil.castNonNull; + /** * Represents an INTERVAL qualifier. * @@ -101,7 +105,7 @@ public class SqlIntervalQualifier extends SqlNode { public SqlIntervalQualifier( TimeUnit startUnit, int startPrecision, - TimeUnit endUnit, + @Nullable TimeUnit endUnit, int fractionalSecondPrecision, SqlParserPos pos) { super(pos); @@ -739,7 +743,7 @@ private int[] evaluateIntervalLiteralAsDayToSecond( } if (hasFractionalSecond) { - secondFrac = normalizeSecondFraction(m.group(5)); + secondFrac = normalizeSecondFraction(castNonNull(m.group(5))); } else { secondFrac = ZERO; } @@ -890,7 +894,7 @@ private int[] evaluateIntervalLiteralAsHourToSecond( } if (hasFractionalSecond) { - secondFrac = normalizeSecondFraction(m.group(4)); + secondFrac = normalizeSecondFraction(castNonNull(m.group(4))); } else { secondFrac = ZERO; } @@ -996,7 +1000,7 @@ private int[] evaluateIntervalLiteralAsMinuteToSecond( } if (hasFractionalSecond) { - secondFrac = normalizeSecondFraction(m.group(3)); + secondFrac = normalizeSecondFraction(castNonNull(m.group(3))); } else { secondFrac = ZERO; } @@ -1064,7 +1068,7 @@ private int[] evaluateIntervalLiteralAsSecond( } if (hasFractionalSecond) { - secondFrac = normalizeSecondFraction(m.group(2)); + secondFrac = normalizeSecondFraction(castNonNull(m.group(2))); } else { secondFrac = ZERO; } @@ -1162,7 +1166,7 @@ public int[] evaluateIntervalLiteral(String value, SqlParserPos pos, } private BigDecimal parseField(Matcher m, int i) { - return new BigDecimal(m.group(i)); + return new BigDecimal(castNonNull(m.group(i))); } private CalciteContextException invalidValueException(SqlParserPos pos, diff --git a/core/src/main/java/org/apache/calcite/sql/SqlJdbcFunctionCall.java b/core/src/main/java/org/apache/calcite/sql/SqlJdbcFunctionCall.java index c04babcd4e7c..7e9fe0f131ef 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlJdbcFunctionCall.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlJdbcFunctionCall.java @@ -28,6 +28,8 @@ import com.google.common.collect.ImmutableMap; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.Map; import java.util.Objects; @@ -436,7 +438,7 @@ private static String constructFuncList(String... functionNames) { } public SqlCall createCall( - SqlLiteral functionQualifier, + @Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { thisOperands = operands; diff --git a/core/src/main/java/org/apache/calcite/sql/SqlJoin.java b/core/src/main/java/org/apache/calcite/sql/SqlJoin.java index 21663e83e37d..478f8a165c96 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlJoin.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlJoin.java @@ -23,6 +23,8 @@ import com.google.common.base.Preconditions; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; import java.util.Objects; @@ -180,7 +182,7 @@ public SqlSyntax getSyntax() { } public SqlCall createCall( - SqlLiteral functionQualifier, + @Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { assert functionQualifier == null; diff --git a/core/src/main/java/org/apache/calcite/sql/SqlLiteral.java b/core/src/main/java/org/apache/calcite/sql/SqlLiteral.java index 2bb68d11ed0e..720d104906d0 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlLiteral.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlLiteral.java @@ -48,6 +48,7 @@ import java.util.Objects; import javax.annotation.Nonnull; +import static org.apache.calcite.linq4j.Nullness.assertNonNull; import static org.apache.calcite.util.Static.RESOURCE; /** @@ -159,7 +160,7 @@ public class SqlLiteral extends SqlNode { * The value of this literal. The type of the value must be appropriate for * the typeName, as defined by the {@link #valueMatchesType} method. */ - protected final Object value; + protected final @Nullable Object value; //~ Constructors ----------------------------------------------------------- @@ -167,7 +168,7 @@ public class SqlLiteral extends SqlNode { * Creates a SqlLiteral. */ protected SqlLiteral( - Object value, + @Nullable Object value, SqlTypeName typeName, SqlParserPos pos) { super(pos); @@ -187,7 +188,7 @@ public SqlTypeName getTypeName() { /** Returns whether value is appropriate for its type. (We have rules about * these things!) */ public static boolean valueMatchesType( - Object value, + @Nullable Object value, SqlTypeName typeName) { switch (typeName) { case BOOLEAN: @@ -252,7 +253,7 @@ public SqlLiteral clone(SqlParserPos pos) { * @see #booleanValue() * @see #symbolValue(Class) */ - public Object getValue() { + public @Nullable Object getValue() { return value; } @@ -278,12 +279,15 @@ public Object getValue() { * @throws AssertionError if the value type is not supported */ @Nonnull public T getValueAs(Class clazz) { + Object value = this.value; if (clazz.isInstance(value)) { return clazz.cast(value); } - switch (typeName) { - case NULL: + if (typeName == SqlTypeName.NULL) { return clazz.cast(NullSentinel.INSTANCE); + } + value = assertNonNull(value); + switch (typeName) { case CHAR: if (clazz == String.class) { return clazz.cast(((NlsString) value).getValue()); @@ -392,7 +396,7 @@ public > E symbolValue(Class class_) { /** Returns the value as a boolean. */ public boolean booleanValue() { - return (Boolean) value; + return (Boolean) assertNonNull(value); } /** @@ -402,7 +406,7 @@ public boolean booleanValue() { * @see #createSymbol(Enum, SqlParserPos) */ public static SqlSampleSpec sampleValue(SqlNode node) { - return (SqlSampleSpec) ((SqlLiteral) node).value; + return (SqlSampleSpec) assertNonNull(((SqlLiteral) node).value); } /** @@ -434,20 +438,21 @@ public static Comparable value(SqlNode node) if (node instanceof SqlLiteral) { final SqlLiteral literal = (SqlLiteral) node; if (literal.getTypeName() == SqlTypeName.SYMBOL) { - return (Enum) literal.value; + return (Enum) literal.value; } - switch (literal.getTypeName().getFamily()) { + // Literals always have non-null family + switch (assertNonNull(literal.getTypeName().getFamily())) { case CHARACTER: return (NlsString) literal.value; case NUMERIC: return (BigDecimal) literal.value; case INTERVAL_YEAR_MONTH: final SqlIntervalLiteral.IntervalValue valMonth = - (SqlIntervalLiteral.IntervalValue) literal.value; + (SqlIntervalLiteral.IntervalValue) assertNonNull(literal.value); return valMonth.getSign() * SqlParserUtil.intervalToMonths(valMonth); case INTERVAL_DAY_TIME: final SqlIntervalLiteral.IntervalValue valTime = - (SqlIntervalLiteral.IntervalValue) literal.value; + (SqlIntervalLiteral.IntervalValue) assertNonNull(literal.value); return valTime.getSign() * SqlParserUtil.intervalToMillis(valTime); } } @@ -467,7 +472,7 @@ public static Comparable value(SqlNode node) return value(((SqlCall) node).operand(0)); case MINUS_PREFIX: assert node instanceof SqlCall; - Comparable o = value(((SqlCall) node).operand(0)); + Comparable o = value(((SqlCall) node).operand(0)); if (o instanceof BigDecimal) { BigDecimal bigDecimal = (BigDecimal) o; return bigDecimal.negate(); @@ -489,12 +494,12 @@ public static String stringValue(SqlNode node) { if (node instanceof SqlLiteral) { SqlLiteral literal = (SqlLiteral) node; assert SqlTypeUtil.inCharFamily(literal.getTypeName()); - return literal.value.toString(); + return assertNonNull(literal.value).toString(); } else if (SqlUtil.isLiteralChain(node)) { final SqlLiteral literal = SqlLiteralChainOperator.concatenateOperands((SqlCall) node); assert SqlTypeUtil.inCharFamily(literal.getTypeName()); - return literal.value.toString(); + return assertNonNull(literal.value).toString(); } else if (node instanceof SqlCall && ((SqlCall) node).getOperator() == SqlStdOperatorTable.CAST) { return stringValue(((SqlCall) node).operand(0)); @@ -538,7 +543,7 @@ public static SqlLiteral unchain(SqlNode node) { * * @return string representation of the value */ - public String toValue() { + public @Nullable String toValue() { if (value == null) { return null; } @@ -644,7 +649,7 @@ public int intValue(boolean exact) { switch (typeName) { case DECIMAL: case DOUBLE: - BigDecimal bd = (BigDecimal) value; + BigDecimal bd = (BigDecimal) assertNonNull(value); if (exact) { try { return bd.intValueExact(); @@ -672,7 +677,7 @@ public long longValue(boolean exact) { switch (typeName) { case DECIMAL: case DOUBLE: - BigDecimal bd = (BigDecimal) value; + BigDecimal bd = (BigDecimal) assertNonNull(value); if (exact) { try { return bd.longValueExact(); @@ -714,7 +719,7 @@ public BigDecimal bigDecimalValue() { @Deprecated // to be removed before 2.0 public String getStringValue() { - return ((NlsString) value).getValue(); + return ((NlsString) assertNonNull(value)).getValue(); } public void unparse( @@ -737,15 +742,10 @@ public void unparse( throw Util.unexpected(typeName); case SYMBOL: - if (value instanceof Enum) { - Enum enumVal = (Enum) value; - writer.keyword(enumVal.toString()); - } else { - writer.keyword(String.valueOf(value)); - } + writer.keyword(String.valueOf(value)); break; default: - writer.literal(value.toString()); + writer.literal(String.valueOf(value)); } } @@ -758,11 +758,11 @@ public RelDataType createSqlType(RelDataTypeFactory typeFactory) { ret = typeFactory.createTypeWithNullability(ret, null == value); return ret; case BINARY: - bitString = (BitString) value; + bitString = (BitString) assertNonNull(value); int bitCount = bitString.getBitCount(); return typeFactory.createSqlType(SqlTypeName.BINARY, bitCount / 8); case CHAR: - NlsString string = (NlsString) value; + NlsString string = (NlsString) assertNonNull(value); Charset charset = string.getCharset(); if (null == charset) { charset = typeFactory.getDefaultCharset(); @@ -796,7 +796,7 @@ public RelDataType createSqlType(RelDataTypeFactory typeFactory) { case INTERVAL_MINUTE_SECOND: case INTERVAL_SECOND: SqlIntervalLiteral.IntervalValue intervalValue = - (SqlIntervalLiteral.IntervalValue) value; + (SqlIntervalLiteral.IntervalValue) assertNonNull(value); return typeFactory.createSqlIntervalType( intervalValue.getIntervalQualifier()); @@ -877,7 +877,7 @@ public static SqlNumericLiteral createNegative( SqlNumericLiteral num, SqlParserPos pos) { return new SqlNumericLiteral( - ((BigDecimal) num.getValue()).negate(), + ((BigDecimal) assertNonNull(num.getValue())).negate(), num.getPrec(), num.getScale(), num.isExact(), @@ -1004,7 +1004,7 @@ public SqlLiteral unescapeUnicode(char unicodeEscapeChar) { return this; } assert SqlTypeUtil.inCharFamily(getTypeName()); - NlsString ns = (NlsString) value; + NlsString ns = (NlsString) assertNonNull(value); String s = ns.getValue(); StringBuilder sb = new StringBuilder(); int n = s.length(); diff --git a/core/src/main/java/org/apache/calcite/sql/SqlMatchRecognize.java b/core/src/main/java/org/apache/calcite/sql/SqlMatchRecognize.java index c3b132229f74..5ca216b13c12 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlMatchRecognize.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlMatchRecognize.java @@ -25,6 +25,8 @@ import com.google.common.base.Preconditions; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; import java.util.Objects; import javax.annotation.Nonnull; @@ -267,7 +269,7 @@ private SqlMatchRecognizeOperator() { } @Override public SqlCall createCall( - SqlLiteral functionQualifier, + @Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { assert functionQualifier == null; diff --git a/core/src/main/java/org/apache/calcite/sql/SqlNumericLiteral.java b/core/src/main/java/org/apache/calcite/sql/SqlNumericLiteral.java index 40584f9b6bc8..c7b41961905c 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlNumericLiteral.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlNumericLiteral.java @@ -22,6 +22,8 @@ import org.apache.calcite.sql.type.SqlTypeName; import org.apache.calcite.util.Util; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.math.BigDecimal; /** @@ -30,16 +32,16 @@ public class SqlNumericLiteral extends SqlLiteral { //~ Instance fields -------------------------------------------------------- - private Integer prec; - private Integer scale; + private @Nullable Integer prec; + private @Nullable Integer scale; private boolean isExact; //~ Constructors ----------------------------------------------------------- protected SqlNumericLiteral( BigDecimal value, - Integer prec, - Integer scale, + @Nullable Integer prec, + @Nullable Integer scale, boolean isExact, SqlParserPos pos) { super( @@ -53,11 +55,11 @@ protected SqlNumericLiteral( //~ Methods ---------------------------------------------------------------- - public Integer getPrec() { + public @Nullable Integer getPrec() { return prec; } - public Integer getScale() { + public @Nullable Integer getScale() { return scale; } @@ -77,7 +79,7 @@ public void unparse( writer.literal(toValue()); } - public String toValue() { + public @Nullable String toValue() { BigDecimal bd = (BigDecimal) value; if (isExact) { return value.toString(); 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 e4c5aee0e525..e9f3121d981e 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlOperator.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlOperator.java @@ -45,6 +45,7 @@ import java.util.Objects; import java.util.function.Supplier; +import static org.apache.calcite.linq4j.Nullness.assertNonNull; import static org.apache.calcite.util.Static.RESOURCE; /** @@ -108,13 +109,13 @@ public abstract class SqlOperator { private final int rightPrec; /** Used to infer the return type of a call to this operator. */ - private final SqlReturnTypeInference returnTypeInference; + private final @Nullable SqlReturnTypeInference returnTypeInference; /** Used to infer types of unknown operands. */ - private final SqlOperandTypeInference operandTypeInference; + private final @Nullable SqlOperandTypeInference operandTypeInference; /** Used to validate operand types. */ - private final SqlOperandTypeChecker operandTypeChecker; + private final @Nullable SqlOperandTypeChecker operandTypeChecker; //~ Constructors ----------------------------------------------------------- @@ -126,9 +127,9 @@ protected SqlOperator( SqlKind kind, int leftPrecedence, int rightPrecedence, - SqlReturnTypeInference returnTypeInference, - SqlOperandTypeInference operandTypeInference, - SqlOperandTypeChecker operandTypeChecker) { + @Nullable SqlReturnTypeInference returnTypeInference, + @Nullable SqlOperandTypeInference operandTypeInference, + @Nullable SqlOperandTypeChecker operandTypeChecker) { assert kind != null; this.name = name; this.kind = kind; @@ -178,7 +179,7 @@ protected static int rightPrec(int prec, boolean leftAssoc) { return prec; } - public SqlOperandTypeChecker getOperandTypeChecker() { + public @Nullable SqlOperandTypeChecker getOperandTypeChecker() { return operandTypeChecker; } @@ -237,13 +238,12 @@ public int getRightPrec() { * *

The position of the resulting call is the union of the * pos and the positions of all of the operands. - * * @param functionQualifier function qualifier (e.g. "DISTINCT"), may be * @param pos parser position of the identifier of the call * @param operands array of operands */ public SqlCall createCall( - SqlLiteral functionQualifier, + @Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { pos = pos.plusAll(Arrays.asList(operands)); @@ -539,7 +539,7 @@ argTypes, null, null, getSyntax(), getKind(), return type; } - protected List constructArgNameList(SqlCall call) { + protected @Nullable List constructArgNameList(SqlCall call) { // If any arguments are named, construct a map. final ImmutableList.Builder nameBuilder = ImmutableList.builder(); for (SqlNode operand : call.getOperandList()) { @@ -560,7 +560,7 @@ protected List constructArgNameList(SqlCall call) { protected List constructOperandList( SqlValidator validator, SqlCall call, - List argNames) { + @Nullable List argNames) { if (argNames == null) { return call.getOperandList(); } @@ -685,7 +685,7 @@ public boolean checkOperandTypes( protected void checkOperandCount( SqlValidator validator, - SqlOperandTypeChecker argType, + @Nullable SqlOperandTypeChecker argType, SqlCall call) { SqlOperandCountRange od = call.getOperator().getOperandCountRange(); if (od.isValidCount(call.operandCount())) { @@ -722,7 +722,7 @@ public boolean validRexOperands(int count, Litmus litmus) { * @return signature template, or null to indicate that a default template * will suffice */ - public String getSignatureTemplate(final int operandsCount) { + public @Nullable String getSignatureTemplate(final int operandsCount) { return null; } @@ -740,14 +740,14 @@ public final String getAllowedSignatures() { * example) can be replaced by a specified name. */ public String getAllowedSignatures(String opNameToUse) { - assert operandTypeChecker != null - : "If you see this, assign operandTypeChecker a value " - + "or override this function"; + assertNonNull(operandTypeChecker, + "If you see this, assign operandTypeChecker a value " + + "or override this function"); return operandTypeChecker.getAllowedSignatures(this, opNameToUse) .trim(); } - public SqlOperandTypeInference getOperandTypeInference() { + public @Nullable SqlOperandTypeInference getOperandTypeInference() { return operandTypeInference; } @@ -846,7 +846,7 @@ public boolean isGroupAuxiliary() { * @param visitor Visitor * @param call Call to visit */ - public R acceptCall(SqlVisitor visitor, SqlCall call) { + public @Nullable R acceptCall(SqlVisitor visitor, SqlCall call) { for (SqlNode operand : call.getOperandList()) { if (operand == null) { continue; @@ -884,7 +884,7 @@ public void acceptCall( /** Returns the return type inference strategy for this operator, or null if * return type inference is implemented by a subclass override. */ - public SqlReturnTypeInference getReturnTypeInference() { + public @Nullable SqlReturnTypeInference getReturnTypeInference() { return returnTypeInference; } @@ -895,7 +895,7 @@ public SqlReturnTypeInference getReturnTypeInference() { * * @see Strong */ - public Supplier getStrongPolicyInference() { + public @Nullable Supplier getStrongPolicyInference() { return null; } diff --git a/core/src/main/java/org/apache/calcite/sql/SqlOperatorTable.java b/core/src/main/java/org/apache/calcite/sql/SqlOperatorTable.java index 3ff6073fb3f1..9027bbfadc09 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlOperatorTable.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlOperatorTable.java @@ -18,6 +18,8 @@ import org.apache.calcite.sql.validate.SqlNameMatcher; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -40,7 +42,7 @@ public interface SqlOperatorTable { * @param nameMatcher Name matcher */ void lookupOperatorOverloads(SqlIdentifier opName, - SqlFunctionCategory category, + @Nullable SqlFunctionCategory category, SqlSyntax syntax, List operatorList, SqlNameMatcher nameMatcher); diff --git a/core/src/main/java/org/apache/calcite/sql/SqlOrderBy.java b/core/src/main/java/org/apache/calcite/sql/SqlOrderBy.java index e21fe4d4e5c7..11a42c6f15f3 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlOrderBy.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlOrderBy.java @@ -19,6 +19,8 @@ import org.apache.calcite.sql.parser.SqlParserPos; import org.apache.calcite.util.ImmutableNullableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -31,7 +33,7 @@ */ public class SqlOrderBy extends SqlCall { public static final SqlSpecialOperator OPERATOR = new Operator() { - @Override public SqlCall createCall(SqlLiteral functionQualifier, + @Override public SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { return new SqlOrderBy(pos, operands[0], (SqlNodeList) operands[1], operands[2], operands[3]); diff --git a/core/src/main/java/org/apache/calcite/sql/SqlPostfixOperator.java b/core/src/main/java/org/apache/calcite/sql/SqlPostfixOperator.java index a4e0b7ef4b95..ab746151e5c1 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlPostfixOperator.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlPostfixOperator.java @@ -25,6 +25,8 @@ import org.apache.calcite.util.Litmus; import org.apache.calcite.util.Util; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * A postfix unary operator. */ @@ -35,9 +37,9 @@ public SqlPostfixOperator( String name, SqlKind kind, int prec, - SqlReturnTypeInference returnTypeInference, - SqlOperandTypeInference operandTypeInference, - SqlOperandTypeChecker operandTypeChecker) { + @Nullable SqlReturnTypeInference returnTypeInference, + @Nullable SqlOperandTypeInference operandTypeInference, + @Nullable SqlOperandTypeChecker operandTypeChecker) { super( name, kind, @@ -54,7 +56,7 @@ public SqlSyntax getSyntax() { return SqlSyntax.POSTFIX; } - public String getSignatureTemplate(final int operandsCount) { + public @Nullable String getSignatureTemplate(final int operandsCount) { Util.discard(operandsCount); return "{1} {0}"; } diff --git a/core/src/main/java/org/apache/calcite/sql/SqlPrefixOperator.java b/core/src/main/java/org/apache/calcite/sql/SqlPrefixOperator.java index aa407e769dc7..e957ecaddcf3 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlPrefixOperator.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlPrefixOperator.java @@ -26,6 +26,8 @@ import org.apache.calcite.util.Litmus; import org.apache.calcite.util.Util; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * A unary operator. */ @@ -36,9 +38,9 @@ public SqlPrefixOperator( String name, SqlKind kind, int prec, - SqlReturnTypeInference returnTypeInference, - SqlOperandTypeInference operandTypeInference, - SqlOperandTypeChecker operandTypeChecker) { + @Nullable SqlReturnTypeInference returnTypeInference, + @Nullable SqlOperandTypeInference operandTypeInference, + @Nullable SqlOperandTypeChecker operandTypeChecker) { super( name, kind, @@ -55,7 +57,7 @@ public SqlSyntax getSyntax() { return SqlSyntax.PREFIX; } - public String getSignatureTemplate(final int operandsCount) { + public @Nullable String getSignatureTemplate(final int operandsCount) { Util.discard(operandsCount); return "{0}{1}"; } diff --git a/core/src/main/java/org/apache/calcite/sql/SqlSelect.java b/core/src/main/java/org/apache/calcite/sql/SqlSelect.java index b05600d8d559..63d2c64c2c69 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlSelect.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlSelect.java @@ -21,6 +21,8 @@ import org.apache.calcite.sql.validate.SqlValidatorScope; import org.apache.calcite.util.ImmutableNullableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; import java.util.Objects; import javax.annotation.Nonnull; @@ -39,30 +41,30 @@ public class SqlSelect extends SqlCall { public static final int HAVING_OPERAND = 5; SqlNodeList keywordList; - SqlNodeList selectList; + @Nullable SqlNodeList selectList; SqlNode from; - SqlNode where; - SqlNodeList groupBy; - SqlNode having; + @Nullable SqlNode where; + @Nullable SqlNodeList groupBy; + @Nullable SqlNode having; SqlNodeList windowDecls; - SqlNodeList orderBy; - SqlNode offset; - SqlNode fetch; + @Nullable SqlNodeList orderBy; + @Nullable SqlNode offset; + @Nullable SqlNode fetch; SqlNodeList hints; //~ Constructors ----------------------------------------------------------- public SqlSelect(SqlParserPos pos, - SqlNodeList keywordList, - SqlNodeList selectList, + @Nullable SqlNodeList keywordList, + @Nullable SqlNodeList selectList, SqlNode from, - SqlNode where, - SqlNodeList groupBy, - SqlNode having, - SqlNodeList windowDecls, - SqlNodeList orderBy, - SqlNode offset, - SqlNode fetch, + @Nullable SqlNode where, + @Nullable SqlNodeList groupBy, + @Nullable SqlNode having, + @Nullable SqlNodeList windowDecls, + @Nullable SqlNodeList orderBy, + @Nullable SqlNode offset, + @Nullable SqlNode fetch, SqlNodeList hints) { super(pos); this.keywordList = Objects.requireNonNull(keywordList != null @@ -136,7 +138,7 @@ public final boolean isDistinct() { return getModifierNode(SqlSelectKeyword.DISTINCT) != null; } - public final SqlNode getModifierNode(SqlSelectKeyword modifier) { + public final @Nullable SqlNode getModifierNode(SqlSelectKeyword modifier) { for (SqlNode keyword : keywordList) { SqlSelectKeyword keyword2 = ((SqlLiteral) keyword).symbolValue(SqlSelectKeyword.class); diff --git a/core/src/main/java/org/apache/calcite/sql/SqlSelectOperator.java b/core/src/main/java/org/apache/calcite/sql/SqlSelectOperator.java index 5d12b71ad48d..b07e54c25443 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlSelectOperator.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlSelectOperator.java @@ -22,6 +22,8 @@ import org.apache.calcite.sql.util.SqlBasicVisitor; import org.apache.calcite.sql.util.SqlVisitor; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.ArrayList; import java.util.List; @@ -58,7 +60,7 @@ public SqlSyntax getSyntax() { } public SqlCall createCall( - SqlLiteral functionQualifier, + @Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { assert functionQualifier == null; diff --git a/core/src/main/java/org/apache/calcite/sql/SqlSetOption.java b/core/src/main/java/org/apache/calcite/sql/SqlSetOption.java index b99f14a4ec4c..487c3d1a2427 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlSetOption.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlSetOption.java @@ -21,6 +21,8 @@ import org.apache.calcite.sql.validate.SqlValidatorScope; import org.apache.calcite.util.ImmutableNullableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.ArrayList; import java.util.List; @@ -60,7 +62,7 @@ public class SqlSetOption extends SqlAlter { public static final SqlSpecialOperator OPERATOR = new SqlSpecialOperator("SET_OPTION", SqlKind.SET_OPTION) { - @Override public SqlCall createCall(SqlLiteral functionQualifier, + @Override public SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { final SqlNode scopeNode = operands[0]; return new SqlSetOption(pos, diff --git a/core/src/main/java/org/apache/calcite/sql/SqlSnapshot.java b/core/src/main/java/org/apache/calcite/sql/SqlSnapshot.java index e81d8e49912d..2e84af7a2fa8 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlSnapshot.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlSnapshot.java @@ -21,6 +21,8 @@ import org.apache.calcite.sql.util.SqlVisitor; import org.apache.calcite.util.ImmutableNullableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; import java.util.Objects; @@ -94,7 +96,7 @@ private SqlSnapshotOperator() { } @Override public SqlCall createCall( - SqlLiteral functionQualifier, + @Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { assert functionQualifier == null; diff --git a/core/src/main/java/org/apache/calcite/sql/SqlUnresolvedFunction.java b/core/src/main/java/org/apache/calcite/sql/SqlUnresolvedFunction.java index 9f3a1e633760..9ea781f4027f 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlUnresolvedFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlUnresolvedFunction.java @@ -23,6 +23,8 @@ import org.apache.calcite.sql.type.SqlReturnTypeInference; import org.apache.calcite.sql.type.SqlTypeName; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -46,10 +48,10 @@ public class SqlUnresolvedFunction extends SqlFunction { */ public SqlUnresolvedFunction( SqlIdentifier sqlIdentifier, - SqlReturnTypeInference returnTypeInference, - SqlOperandTypeInference operandTypeInference, - SqlOperandTypeChecker operandTypeChecker, - List paramTypes, + @Nullable SqlReturnTypeInference returnTypeInference, + @Nullable SqlOperandTypeInference operandTypeInference, + @Nullable SqlOperandTypeChecker operandTypeChecker, + @Nullable List paramTypes, SqlFunctionCategory funcType) { super(sqlIdentifier, returnTypeInference, operandTypeInference, operandTypeChecker, paramTypes, funcType); diff --git a/core/src/main/java/org/apache/calcite/sql/SqlUtil.java b/core/src/main/java/org/apache/calcite/sql/SqlUtil.java index 13144d438700..325f711fa3e7 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlUtil.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlUtil.java @@ -51,6 +51,8 @@ import com.google.common.collect.Iterators; import com.google.common.collect.Lists; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.charset.UnsupportedCharsetException; @@ -439,7 +441,7 @@ public static SqlLiteral concatenateLiterals(List lits) { public static SqlOperator lookupRoutine(SqlOperatorTable opTab, RelDataTypeFactory typeFactory, SqlIdentifier funcName, List argTypes, - List argNames, SqlFunctionCategory category, + @Nullable List argNames, @Nullable SqlFunctionCategory category, SqlSyntax syntax, SqlKind sqlKind, SqlNameMatcher nameMatcher, boolean coerce) { Iterator list = @@ -486,9 +488,9 @@ private static Iterator filterOperatorRoutinesByKind( */ public static Iterator lookupSubjectRoutines( SqlOperatorTable opTab, RelDataTypeFactory typeFactory, - SqlIdentifier funcName, List argTypes, List argNames, + SqlIdentifier funcName, List argTypes, @Nullable List argNames, SqlSyntax sqlSyntax, SqlKind sqlKind, - SqlFunctionCategory category, SqlNameMatcher nameMatcher, + @Nullable SqlFunctionCategory category, SqlNameMatcher nameMatcher, boolean coerce) { // start with all routines matching by name Iterator routines = @@ -563,7 +565,7 @@ private static Iterator lookupSubjectRoutinesByName( SqlOperatorTable opTab, SqlIdentifier funcName, final SqlSyntax syntax, - SqlFunctionCategory category, + @Nullable SqlFunctionCategory category, SqlNameMatcher nameMatcher) { final List sqlOperators = new ArrayList<>(); opTab.lookupOperatorOverloads(funcName, category, syntax, sqlOperators, @@ -595,7 +597,7 @@ private static Iterator filterRoutinesByParameterCount( private static Iterator filterRoutinesByParameterTypeAndName( RelDataTypeFactory typeFactory, SqlSyntax syntax, final Iterator routines, final List argTypes, - final List argNames, final boolean coerce) { + final @Nullable List argNames, final boolean coerce) { if (syntax != SqlSyntax.FUNCTION) { return routines; } @@ -675,7 +677,7 @@ private static Iterator filterRoutinesByTypePrecedence( RelDataTypeFactory typeFactory, Iterator routines, List argTypes, - List argNames) { + @Nullable List argNames) { if (sqlSyntax != SqlSyntax.FUNCTION) { return routines; } @@ -714,7 +716,7 @@ private static Iterator filterRoutinesByTypePrecedence( private static RelDataType bestMatch(RelDataTypeFactory typeFactory, List sqlFunctions, int i, - List argNames, RelDataTypePrecedenceList precList) { + @Nullable List argNames, RelDataTypePrecedenceList precList) { RelDataType bestMatch = null; for (SqlFunction function : sqlFunctions) { if (!function.getOperandTypeChecker().isFixedParameters()) { diff --git a/core/src/main/java/org/apache/calcite/sql/SqlWindow.java b/core/src/main/java/org/apache/calcite/sql/SqlWindow.java index ceba7e0f461e..85daefb7f68e 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlWindow.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlWindow.java @@ -35,6 +35,8 @@ import com.google.common.collect.ImmutableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; import static org.apache.calcite.util.Static.RESOURCE; @@ -808,7 +810,7 @@ public SqlSyntax getSyntax() { } public SqlCall createCall( - SqlLiteral functionQualifier, + @Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { assert functionQualifier == null; diff --git a/core/src/main/java/org/apache/calcite/sql/SqlWindowTableFunction.java b/core/src/main/java/org/apache/calcite/sql/SqlWindowTableFunction.java index 8af4b7711dbb..0ff87d32fbd7 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlWindowTableFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlWindowTableFunction.java @@ -30,6 +30,8 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.Collections; import java.util.List; @@ -79,7 +81,7 @@ public SqlWindowTableFunction(String name, SqlOperandMetadata operandMetadata) { operandMetadata, SqlFunctionCategory.SYSTEM); } - @Override public SqlOperandMetadata getOperandTypeChecker() { + @Override public @Nullable SqlOperandMetadata getOperandTypeChecker() { return (SqlOperandMetadata) super.getOperandTypeChecker(); } diff --git a/core/src/main/java/org/apache/calcite/sql/SqlWith.java b/core/src/main/java/org/apache/calcite/sql/SqlWith.java index 9363e2291417..98032b648a54 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlWith.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlWith.java @@ -22,6 +22,8 @@ import com.google.common.collect.ImmutableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -107,7 +109,7 @@ public void unparse( } - @Override public SqlCall createCall(SqlLiteral functionQualifier, + @Override public SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { return new SqlWith(pos, (SqlNodeList) operands[0], operands[1]); } diff --git a/core/src/main/java/org/apache/calcite/sql/SqlWithItem.java b/core/src/main/java/org/apache/calcite/sql/SqlWithItem.java index 686f772286b7..ce0365435b99 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlWithItem.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlWithItem.java @@ -19,6 +19,8 @@ import org.apache.calcite.sql.parser.SqlParserPos; import org.apache.calcite.util.ImmutableNullableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -96,7 +98,7 @@ public void unparse( withItem.query.unparse(writer, 10, 10); } - @Override public SqlCall createCall(SqlLiteral functionQualifier, + @Override public SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { assert functionQualifier == null; assert operands.length == 3; diff --git a/core/src/main/java/org/apache/calcite/sql/dialect/BigQuerySqlDialect.java b/core/src/main/java/org/apache/calcite/sql/dialect/BigQuerySqlDialect.java index 19276b1b9541..c893973e5e11 100644 --- a/core/src/main/java/org/apache/calcite/sql/dialect/BigQuerySqlDialect.java +++ b/core/src/main/java/org/apache/calcite/sql/dialect/BigQuerySqlDialect.java @@ -48,6 +48,7 @@ import java.util.List; import java.util.Locale; import java.util.regex.Pattern; +import javax.annotation.Nullable; /** * A SqlDialect implementation for Google BigQuery's "Standard SQL" @@ -99,7 +100,7 @@ public BigQuerySqlDialect(SqlDialect.Context context) { || RESERVED_KEYWORDS.contains(val.toUpperCase(Locale.ROOT)); } - @Override public SqlNode emulateNullDirection(SqlNode node, + @Override public @Nullable SqlNode emulateNullDirection(SqlNode node, boolean nullsFirst, boolean desc) { return emulateNullDirectionWithIsNull(node, nullsFirst, desc); } @@ -252,7 +253,7 @@ private TimeUnit validate(TimeUnit timeUnit) { * * BigQuery Standard SQL Data Types. */ - @Override public SqlNode getCastSpec(final RelDataType type) { + @Override public @Nullable SqlNode getCastSpec(final RelDataType type) { if (type instanceof BasicSqlType) { final SqlTypeName typeName = type.getSqlTypeName(); switch (typeName) { diff --git a/core/src/main/java/org/apache/calcite/sql/dialect/ClickHouseSqlDialect.java b/core/src/main/java/org/apache/calcite/sql/dialect/ClickHouseSqlDialect.java index c78662cea6fe..4b296b5ee5b9 100644 --- a/core/src/main/java/org/apache/calcite/sql/dialect/ClickHouseSqlDialect.java +++ b/core/src/main/java/org/apache/calcite/sql/dialect/ClickHouseSqlDialect.java @@ -38,6 +38,8 @@ import com.google.common.base.Preconditions; +import javax.annotation.Nullable; + /** * A SqlDialect implementation for the ClickHouse database. */ @@ -70,7 +72,7 @@ public ClickHouseSqlDialect(Context context) { return CalendarPolicy.SHIFT; } - @Override public SqlNode getCastSpec(RelDataType type) { + @Override public @Nullable SqlNode getCastSpec(RelDataType type) { if (type instanceof BasicSqlType) { SqlTypeName typeName = type.getSqlTypeName(); switch (typeName) { diff --git a/core/src/main/java/org/apache/calcite/sql/dialect/HiveSqlDialect.java b/core/src/main/java/org/apache/calcite/sql/dialect/HiveSqlDialect.java index aab874899d81..ca50d9627eea 100644 --- a/core/src/main/java/org/apache/calcite/sql/dialect/HiveSqlDialect.java +++ b/core/src/main/java/org/apache/calcite/sql/dialect/HiveSqlDialect.java @@ -32,6 +32,8 @@ import org.apache.calcite.sql.type.BasicSqlType; import org.apache.calcite.util.RelToSqlConverterUtil; +import javax.annotation.Nullable; + /** * A SqlDialect implementation for the Apache Hive database. */ @@ -63,7 +65,7 @@ public HiveSqlDialect(Context context) { unparseFetchUsingLimit(writer, offset, fetch); } - @Override public SqlNode emulateNullDirection(SqlNode node, + @Override public @Nullable SqlNode emulateNullDirection(SqlNode node, boolean nullsFirst, boolean desc) { if (emulateNullDirection) { return emulateNullDirectionWithIsNull(node, nullsFirst, desc); @@ -129,7 +131,7 @@ public HiveSqlDialect(Context context) { return false; } - @Override public SqlNode getCastSpec(final RelDataType type) { + @Override public @Nullable SqlNode getCastSpec(final RelDataType type) { if (type instanceof BasicSqlType) { switch (type.getSqlTypeName()) { case INTEGER: diff --git a/core/src/main/java/org/apache/calcite/sql/dialect/JethroDataSqlDialect.java b/core/src/main/java/org/apache/calcite/sql/dialect/JethroDataSqlDialect.java index abd2c79bfae4..d9ada291e413 100644 --- a/core/src/main/java/org/apache/calcite/sql/dialect/JethroDataSqlDialect.java +++ b/core/src/main/java/org/apache/calcite/sql/dialect/JethroDataSqlDialect.java @@ -38,6 +38,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import javax.annotation.Nullable; /** * A SqlDialect implementation for the JethroData database. @@ -55,7 +56,7 @@ public JethroDataSqlDialect(Context context) { return false; } - @Override public SqlNode emulateNullDirection(SqlNode node, + @Override public @Nullable SqlNode emulateNullDirection(SqlNode node, boolean nullsFirst, boolean desc) { return node; } diff --git a/core/src/main/java/org/apache/calcite/sql/dialect/MssqlSqlDialect.java b/core/src/main/java/org/apache/calcite/sql/dialect/MssqlSqlDialect.java index f0051751f53c..2ec892cfec80 100644 --- a/core/src/main/java/org/apache/calcite/sql/dialect/MssqlSqlDialect.java +++ b/core/src/main/java/org/apache/calcite/sql/dialect/MssqlSqlDialect.java @@ -36,6 +36,8 @@ import org.apache.calcite.sql.parser.SqlParserPos; import org.apache.calcite.sql.type.ReturnTypes; +import javax.annotation.Nullable; + /** * A SqlDialect implementation for the Microsoft SQL Server * database. @@ -78,8 +80,9 @@ public MssqlSqlDialect(Context context) { *

* {@code ORDER BY CASE WHEN x IS NULL THEN 0 ELSE 1 END, x} *
+ * @return */ - @Override public SqlNode emulateNullDirection(SqlNode node, + @Override public @Nullable SqlNode emulateNullDirection(SqlNode node, boolean nullsFirst, boolean desc) { // Default ordering preserved if (nullCollation.isDefaultOrder(nullsFirst, desc)) { diff --git a/core/src/main/java/org/apache/calcite/sql/dialect/MysqlSqlDialect.java b/core/src/main/java/org/apache/calcite/sql/dialect/MysqlSqlDialect.java index 19ad82091df1..257337f294e0 100644 --- a/core/src/main/java/org/apache/calcite/sql/dialect/MysqlSqlDialect.java +++ b/core/src/main/java/org/apache/calcite/sql/dialect/MysqlSqlDialect.java @@ -46,7 +46,7 @@ import org.apache.calcite.sql.type.ReturnTypes; import org.apache.calcite.sql.type.SqlTypeName; -import static org.apache.calcite.sql.type.SqlTypeName.TIMESTAMP; +import javax.annotation.Nullable; /** * A SqlDialect implementation for the MySQL database. @@ -111,7 +111,7 @@ public boolean supportsAliasedValues() { unparseFetchUsingLimit(writer, offset, fetch); } - @Override public SqlNode emulateNullDirection(SqlNode node, + @Override public @Nullable SqlNode emulateNullDirection(SqlNode node, boolean nullsFirst, boolean desc) { return emulateNullDirectionWithIsNull(node, nullsFirst, desc); } @@ -145,7 +145,7 @@ public boolean supportsAliasedValues() { return CalendarPolicy.SHIFT; } - @Override public SqlNode getCastSpec(RelDataType type) { + @Override public @Nullable SqlNode getCastSpec(RelDataType type) { switch (type.getSqlTypeName()) { case VARCHAR: // MySQL doesn't have a VARCHAR type, only CHAR. diff --git a/core/src/main/java/org/apache/calcite/sql/dialect/OracleSqlDialect.java b/core/src/main/java/org/apache/calcite/sql/dialect/OracleSqlDialect.java index ea2562a09ac7..a8223b81df82 100644 --- a/core/src/main/java/org/apache/calcite/sql/dialect/OracleSqlDialect.java +++ b/core/src/main/java/org/apache/calcite/sql/dialect/OracleSqlDialect.java @@ -41,6 +41,7 @@ import com.google.common.collect.ImmutableList; import java.util.List; +import javax.annotation.Nullable; /** * A SqlDialect implementation for the Oracle database. @@ -85,7 +86,7 @@ public OracleSqlDialect(Context context) { } } - @Override public SqlNode getCastSpec(RelDataType type) { + @Override public @Nullable SqlNode getCastSpec(RelDataType type) { String castSpec; switch (type.getSqlTypeName()) { case SMALLINT: diff --git a/core/src/main/java/org/apache/calcite/sql/dialect/PostgresqlSqlDialect.java b/core/src/main/java/org/apache/calcite/sql/dialect/PostgresqlSqlDialect.java index fa18abd66ed6..d7a25f8bffa7 100644 --- a/core/src/main/java/org/apache/calcite/sql/dialect/PostgresqlSqlDialect.java +++ b/core/src/main/java/org/apache/calcite/sql/dialect/PostgresqlSqlDialect.java @@ -32,6 +32,8 @@ import org.apache.calcite.sql.parser.SqlParserPos; import org.apache.calcite.sql.type.SqlTypeName; +import javax.annotation.Nullable; + /** * A SqlDialect implementation for the PostgreSQL database. */ @@ -72,7 +74,7 @@ public PostgresqlSqlDialect(Context context) { return false; } - @Override public SqlNode getCastSpec(RelDataType type) { + @Override public @Nullable SqlNode getCastSpec(RelDataType type) { String castSpec; switch (type.getSqlTypeName()) { case TINYINT: diff --git a/core/src/main/java/org/apache/calcite/sql/dialect/PrestoSqlDialect.java b/core/src/main/java/org/apache/calcite/sql/dialect/PrestoSqlDialect.java index 2e1b1d41ff65..bb76ccdae695 100644 --- a/core/src/main/java/org/apache/calcite/sql/dialect/PrestoSqlDialect.java +++ b/core/src/main/java/org/apache/calcite/sql/dialect/PrestoSqlDialect.java @@ -31,6 +31,8 @@ import com.google.common.base.Preconditions; +import javax.annotation.Nullable; + /** * A SqlDialect implementation for the Presto database. */ @@ -71,7 +73,7 @@ private void unparseUsingLimit(SqlWriter writer, SqlNode offset, unparseLimit(writer, fetch); } - @Override public SqlNode emulateNullDirection(SqlNode node, + @Override public @Nullable SqlNode emulateNullDirection(SqlNode node, boolean nullsFirst, boolean desc) { return emulateNullDirectionWithIsNull(node, nullsFirst, desc); } @@ -106,7 +108,7 @@ private void unparseUsingLimit(SqlWriter writer, SqlNode offset, return CalendarPolicy.SHIFT; } - @Override public SqlNode getCastSpec(RelDataType type) { + @Override public @Nullable SqlNode getCastSpec(RelDataType type) { return super.getCastSpec(type); } diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlBitOpAggFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlBitOpAggFunction.java index cc3db36abf5f..96abcca114cb 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlBitOpAggFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlBitOpAggFunction.java @@ -26,6 +26,8 @@ import com.google.common.base.Preconditions; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * Definition of the BIT_AND and BIT_OR aggregate functions, * returning the bitwise AND/OR of all non-null input values, or null if none. @@ -54,7 +56,7 @@ public SqlBitOpAggFunction(SqlKind kind) { || kind == SqlKind.BIT_XOR); } - @Override public T unwrap(Class clazz) { + @Override public @Nullable T unwrap(Class clazz) { if (clazz == SqlSplittableAggFunction.class) { return clazz.cast(SqlSplittableAggFunction.SelfSplitter.INSTANCE); } diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlCaseOperator.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlCaseOperator.java index 7d5c567300fe..a8635be3edd5 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlCaseOperator.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlCaseOperator.java @@ -47,6 +47,8 @@ import com.google.common.collect.Iterables; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.ArrayList; import java.util.List; @@ -329,7 +331,7 @@ public SqlSyntax getSyntax() { } public SqlCall createCall( - SqlLiteral functionQualifier, + @Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { assert functionQualifier == null; diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlCountAggFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlCountAggFunction.java index cd3c8a68d582..510e0604799a 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlCountAggFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlCountAggFunction.java @@ -35,6 +35,8 @@ import com.google.common.collect.ImmutableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -89,7 +91,7 @@ public RelDataType deriveType( return super.deriveType(validator, scope, call); } - @Override public T unwrap(Class clazz) { + @Override public @Nullable T unwrap(Class clazz) { if (clazz == SqlSplittableAggFunction.class) { return clazz.cast(SqlSplittableAggFunction.CountSplitter.INSTANCE); } diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonArrayAggAggFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonArrayAggAggFunction.java index cc83a4d829e0..962338773ea6 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonArrayAggAggFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonArrayAggAggFunction.java @@ -35,6 +35,8 @@ import org.apache.calcite.sql.validate.SqlValidatorScope; import org.apache.calcite.util.Optionality; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.Objects; /** @@ -70,7 +72,7 @@ public SqlJsonArrayAggAggFunction(SqlKind kind, return validateOperands(validator, scope, call); } - @Override public SqlCall createCall(SqlLiteral functionQualifier, + @Override public SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { assert operands.length == 1 || operands.length == 2; final SqlNode valueExpr = operands[0]; diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonArrayFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonArrayFunction.java index 50d696c17be3..415414cf4d47 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonArrayFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonArrayFunction.java @@ -33,6 +33,8 @@ import org.apache.calcite.sql.type.SqlOperandTypeChecker; import org.apache.calcite.sql.validate.SqlValidator; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.Locale; /** @@ -49,11 +51,11 @@ public SqlJsonArrayFunction() { } @Override protected void checkOperandCount(SqlValidator validator, - SqlOperandTypeChecker argType, SqlCall call) { + @Nullable SqlOperandTypeChecker argType, SqlCall call) { assert call.operandCount() >= 1; } - @Override public SqlCall createCall(SqlLiteral functionQualifier, + @Override public SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { if (operands[0] == null) { operands[0] = @@ -63,7 +65,7 @@ public SqlJsonArrayFunction() { return super.createCall(functionQualifier, pos, operands); } - @Override public String getSignatureTemplate(int operandsCount) { + @Override public @Nullable String getSignatureTemplate(int operandsCount) { assert operandsCount >= 1; final StringBuilder sb = new StringBuilder(); sb.append("{0}("); diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonDepthFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonDepthFunction.java index 94dbb7b5ad53..9335f94a2181 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonDepthFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonDepthFunction.java @@ -31,6 +31,8 @@ import org.apache.calcite.sql.type.SqlTypeTransforms; import org.apache.calcite.sql.validate.SqlValidator; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * The JSON_DEPTH function. */ @@ -49,11 +51,11 @@ public SqlJsonDepthFunction() { } @Override protected void checkOperandCount(SqlValidator validator, - SqlOperandTypeChecker argType, SqlCall call) { + @Nullable SqlOperandTypeChecker argType, SqlCall call) { assert call.operandCount() == 1; } - @Override public SqlCall createCall(SqlLiteral functionQualifier, + @Override public SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { return super.createCall(functionQualifier, pos, operands); } diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonObjectFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonObjectFunction.java index 160f166e255c..33d6c047db41 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonObjectFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonObjectFunction.java @@ -36,6 +36,8 @@ import org.apache.calcite.sql.type.SqlTypeUtil; import org.apache.calcite.sql.validate.SqlValidator; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.Locale; import static org.apache.calcite.util.Static.RESOURCE; @@ -64,7 +66,7 @@ public SqlJsonObjectFunction() { } @Override protected void checkOperandCount(SqlValidator validator, - SqlOperandTypeChecker argType, SqlCall call) { + @Nullable SqlOperandTypeChecker argType, SqlCall call) { assert call.operandCount() % 2 == 1; } @@ -91,7 +93,7 @@ public SqlJsonObjectFunction() { return true; } - @Override public SqlCall createCall(SqlLiteral functionQualifier, + @Override public SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { if (operands[0] == null) { operands[0] = SqlLiteral.createSymbol( @@ -100,7 +102,7 @@ public SqlJsonObjectFunction() { return super.createCall(functionQualifier, pos, operands); } - @Override public String getSignatureTemplate(int operandsCount) { + @Override public @Nullable String getSignatureTemplate(int operandsCount) { assert operandsCount % 2 == 1; StringBuilder sb = new StringBuilder(); sb.append("{0}("); diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonPrettyFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonPrettyFunction.java index 23d77b635194..fbb5293bfab5 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonPrettyFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonPrettyFunction.java @@ -31,6 +31,8 @@ import org.apache.calcite.sql.type.SqlTypeTransforms; import org.apache.calcite.sql.validate.SqlValidator; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * The JSON_TYPE function. */ @@ -47,11 +49,11 @@ public SqlJsonPrettyFunction() { } @Override protected void checkOperandCount(SqlValidator validator, - SqlOperandTypeChecker argType, SqlCall call) { + @Nullable SqlOperandTypeChecker argType, SqlCall call) { assert call.operandCount() == 1; } - @Override public SqlCall createCall(SqlLiteral functionQualifier, + @Override public SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { return super.createCall(functionQualifier, pos, operands); } diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonQueryFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonQueryFunction.java index 83a210e04691..6d5888b6bb01 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonQueryFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonQueryFunction.java @@ -31,6 +31,8 @@ import org.apache.calcite.sql.type.SqlTypeFamily; import org.apache.calcite.sql.type.SqlTypeTransforms; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * The JSON_QUERY function. */ @@ -44,7 +46,7 @@ public SqlJsonQueryFunction() { SqlFunctionCategory.SYSTEM); } - @Override public String getSignatureTemplate(int operandsCount) { + @Override public @Nullable String getSignatureTemplate(int operandsCount) { return "{0}({1} {2} {3} WRAPPER {4} ON EMPTY {5} ON ERROR)"; } @@ -77,7 +79,7 @@ public SqlJsonQueryFunction() { writer.endFunCall(frame); } - @Override public SqlCall createCall(SqlLiteral functionQualifier, + @Override public SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { if (operands[2] == null) { operands[2] = SqlLiteral.createSymbol(SqlJsonQueryWrapperBehavior.WITHOUT_ARRAY, pos); diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonTypeFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonTypeFunction.java index e477194a93f8..f8694c8a35e6 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonTypeFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlJsonTypeFunction.java @@ -32,6 +32,8 @@ import org.apache.calcite.sql.type.SqlTypeTransforms; import org.apache.calcite.sql.validate.SqlValidator; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * The JSON_TYPE function. */ @@ -48,11 +50,11 @@ public SqlJsonTypeFunction() { } @Override protected void checkOperandCount(SqlValidator validator, - SqlOperandTypeChecker argType, SqlCall call) { + @Nullable SqlOperandTypeChecker argType, SqlCall call) { assert call.operandCount() == 1; } - @Override public SqlCall createCall(SqlLiteral functionQualifier, + @Override public SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { return super.createCall(functionQualifier, pos, operands); } diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlMinMaxAggFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlMinMaxAggFunction.java index f6c3b2236d46..525ab499456c 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlMinMaxAggFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlMinMaxAggFunction.java @@ -30,6 +30,8 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -143,7 +145,7 @@ public RelDataType getReturnType(RelDataTypeFactory typeFactory) { } } - @Override public T unwrap(Class clazz) { + @Override public @Nullable T unwrap(Class clazz) { if (clazz == SqlSplittableAggFunction.class) { return clazz.cast(SqlSplittableAggFunction.SelfSplitter.INSTANCE); } diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlPosixRegexOperator.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlPosixRegexOperator.java index 232f94f01078..449faf8a605c 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlPosixRegexOperator.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlPosixRegexOperator.java @@ -33,6 +33,8 @@ import org.apache.calcite.sql.type.SqlOperandCountRanges; import org.apache.calcite.sql.type.SqlTypeUtil; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.Arrays; /** @@ -79,7 +81,7 @@ public SqlOperandCountRange getOperandCountRange() { } public SqlCall createCall( - SqlLiteral functionQualifier, + @Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { pos = pos.plusAll(Arrays.asList(operands)); diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlSumAggFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlSumAggFunction.java index b6a9df673379..ce49ea1b4c73 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlSumAggFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlSumAggFunction.java @@ -28,6 +28,8 @@ import com.google.common.collect.ImmutableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -77,7 +79,7 @@ public RelDataType getReturnType(RelDataTypeFactory typeFactory) { return type; } - @Override public T unwrap(Class clazz) { + @Override public @Nullable T unwrap(Class clazz) { if (clazz == SqlSplittableAggFunction.class) { return clazz.cast(SqlSplittableAggFunction.SumSplitter.INSTANCE); } diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlSumEmptyIsZeroAggFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlSumEmptyIsZeroAggFunction.java index 206303bc820c..dad27b475863 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlSumEmptyIsZeroAggFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlSumEmptyIsZeroAggFunction.java @@ -29,6 +29,8 @@ import com.google.common.collect.ImmutableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -68,7 +70,7 @@ public RelDataType getReturnType(RelDataTypeFactory typeFactory) { typeFactory.createSqlType(SqlTypeName.ANY), true); } - @Override public T unwrap(Class clazz) { + @Override public @Nullable T unwrap(Class clazz) { if (clazz == SqlSplittableAggFunction.class) { return clazz.cast(SqlSplittableAggFunction.Sum0Splitter.INSTANCE); } diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlTrimFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlTrimFunction.java index aff3235e09ed..1d71dff5e1b2 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlTrimFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlTrimFunction.java @@ -37,6 +37,8 @@ import com.google.common.collect.ImmutableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.Arrays; import java.util.List; @@ -119,7 +121,7 @@ public String getSignatureTemplate(final int operandsCount) { } public SqlCall createCall( - SqlLiteral functionQualifier, + @Nullable SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { assert functionQualifier == null; diff --git a/core/src/main/java/org/apache/calcite/sql/parser/SqlParserPos.java b/core/src/main/java/org/apache/calcite/sql/parser/SqlParserPos.java index ed505b569d5f..27e9c37fe0f5 100644 --- a/core/src/main/java/org/apache/calcite/sql/parser/SqlParserPos.java +++ b/core/src/main/java/org/apache/calcite/sql/parser/SqlParserPos.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Objects; +import static org.apache.calcite.linq4j.Nullness.assertNonNull; import static org.apache.calcite.util.Static.RESOURCE; /** @@ -199,7 +200,8 @@ public int size() { private static Iterable toPos(Iterable nodes) { return Iterables.transform(nodes, node -> { if (node == null) { - return null; + // Nulls are not expected + return assertNonNull(null); } else { return node.getParserPosition(); } diff --git a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeName.java b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeName.java index f1df3628b8a6..ce43a1bf11fd 100644 --- a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeName.java +++ b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeName.java @@ -29,6 +29,8 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Sets; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.math.BigDecimal; import java.sql.Types; import java.util.Arrays; @@ -260,10 +262,10 @@ public enum SqlTypeName { */ private final boolean special; private final int jdbcOrdinal; - private final SqlTypeFamily family; + private final @Nullable SqlTypeFamily family; SqlTypeName(int signatures, boolean special, int jdbcType, - SqlTypeFamily family) { + @Nullable SqlTypeFamily family) { this.signatures = signatures; this.special = special; this.jdbcOrdinal = jdbcType; @@ -275,7 +277,7 @@ public enum SqlTypeName { * * @return Type name, or null if not found */ - public static SqlTypeName get(String name) { + public static @Nullable SqlTypeName get(String name) { if (false) { // The following code works OK, but the spurious exceptions are // annoying. @@ -383,7 +385,7 @@ public int getDefaultScale() { * * @return containing family, or null for none */ - public SqlTypeFamily getFamily() { + public @Nullable SqlTypeFamily getFamily() { return family; } @@ -393,7 +395,7 @@ public SqlTypeFamily getFamily() { * @param jdbcType the JDBC type of interest * @return corresponding SqlTypeName, or null if the type is not known */ - public static SqlTypeName getNameForJdbcType(int jdbcType) { + public static @Nullable SqlTypeName getNameForJdbcType(int jdbcType) { return JDBC_TYPE_TO_NAME.get(jdbcType); } @@ -467,7 +469,7 @@ public static SqlTypeName getNameForJdbcType(int jdbcType) { * @param scale Scale, or -1 if not applicable * @return Limit value */ - public Object getLimit( + public @Nullable Object getLimit( boolean sign, Limit limit, boolean beyond, @@ -524,7 +526,7 @@ public Object getLimit( case OVERFLOW: final BigDecimal other = (BigDecimal) BIGINT.getLimit(sign, limit, beyond, -1, -1); - if (decimal.compareTo(other) == (sign ? 1 : -1)) { + if (other != null && decimal.compareTo(other) == (sign ? 1 : -1)) { decimal = other; } } @@ -865,7 +867,7 @@ public enum Limit { ZERO, UNDERFLOW, OVERFLOW } - private BigDecimal getNumericLimit( + private @Nullable BigDecimal getNumericLimit( int radix, int exponent, boolean sign, diff --git a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java index fce8b7bc6c1c..b116877aceba 100644 --- a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java +++ b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeUtil.java @@ -46,6 +46,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Sets; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.math.BigDecimal; import java.nio.charset.Charset; import java.util.AbstractList; @@ -986,7 +988,7 @@ private static boolean flattenFields( * @return corresponding parse representation */ public static SqlDataTypeSpec convertTypeToSpec(RelDataType type, - String charSetName, int maxPrecision) { + @Nullable String charSetName, int maxPrecision) { SqlTypeName typeName = type.getSqlTypeName(); // TODO jvs 28-Dec-2004: support row types, user-defined types, diff --git a/core/src/main/java/org/apache/calcite/sql/util/ChainedSqlOperatorTable.java b/core/src/main/java/org/apache/calcite/sql/util/ChainedSqlOperatorTable.java index a85d025d543b..fa0455156a3f 100644 --- a/core/src/main/java/org/apache/calcite/sql/util/ChainedSqlOperatorTable.java +++ b/core/src/main/java/org/apache/calcite/sql/util/ChainedSqlOperatorTable.java @@ -25,6 +25,8 @@ import com.google.common.collect.ImmutableList; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.ArrayList; import java.util.List; @@ -61,7 +63,7 @@ public void add(SqlOperatorTable table) { } public void lookupOperatorOverloads(SqlIdentifier opName, - SqlFunctionCategory category, SqlSyntax syntax, + @Nullable SqlFunctionCategory category, SqlSyntax syntax, List operatorList, SqlNameMatcher nameMatcher) { for (SqlOperatorTable table : tableList) { table.lookupOperatorOverloads(opName, category, syntax, operatorList, diff --git a/core/src/main/java/org/apache/calcite/sql/util/ListSqlOperatorTable.java b/core/src/main/java/org/apache/calcite/sql/util/ListSqlOperatorTable.java index f9a9c31a6fcd..6a6d3afbb9fd 100644 --- a/core/src/main/java/org/apache/calcite/sql/util/ListSqlOperatorTable.java +++ b/core/src/main/java/org/apache/calcite/sql/util/ListSqlOperatorTable.java @@ -24,6 +24,8 @@ import org.apache.calcite.sql.SqlSyntax; import org.apache.calcite.sql.validate.SqlNameMatcher; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.ArrayList; import java.util.List; @@ -53,7 +55,7 @@ public void add(SqlOperator op) { } public void lookupOperatorOverloads(SqlIdentifier opName, - SqlFunctionCategory category, + @Nullable SqlFunctionCategory category, SqlSyntax syntax, List operatorList, SqlNameMatcher nameMatcher) { diff --git a/core/src/main/java/org/apache/calcite/sql/util/ReflectiveSqlOperatorTable.java b/core/src/main/java/org/apache/calcite/sql/util/ReflectiveSqlOperatorTable.java index 069957df597d..9ba2a5d0b80d 100644 --- a/core/src/main/java/org/apache/calcite/sql/util/ReflectiveSqlOperatorTable.java +++ b/core/src/main/java/org/apache/calcite/sql/util/ReflectiveSqlOperatorTable.java @@ -31,6 +31,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Multimap; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.lang.reflect.Field; import java.util.Collection; import java.util.List; @@ -86,7 +88,7 @@ public final void init() { // implement SqlOperatorTable public void lookupOperatorOverloads(SqlIdentifier opName, - SqlFunctionCategory category, SqlSyntax syntax, + @Nullable SqlFunctionCategory category, SqlSyntax syntax, List operatorList, SqlNameMatcher nameMatcher) { // NOTE jvs 3-Mar-2005: ignore category until someone cares diff --git a/core/src/main/java/org/apache/calcite/sql/util/SqlBasicVisitor.java b/core/src/main/java/org/apache/calcite/sql/util/SqlBasicVisitor.java index eac3b7e07baa..03bb709759ad 100644 --- a/core/src/main/java/org/apache/calcite/sql/util/SqlBasicVisitor.java +++ b/core/src/main/java/org/apache/calcite/sql/util/SqlBasicVisitor.java @@ -25,6 +25,8 @@ import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.SqlNodeList; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * Basic implementation of {@link SqlVisitor} which does nothing at each node. * @@ -34,7 +36,7 @@ * * @param Return type */ -public class SqlBasicVisitor implements SqlVisitor { +public class SqlBasicVisitor<@Nullable R> implements SqlVisitor { //~ Methods ---------------------------------------------------------------- public R visit(SqlLiteral literal) { diff --git a/core/src/main/java/org/apache/calcite/sql/validate/DelegatingSqlValidatorCatalogReader.java b/core/src/main/java/org/apache/calcite/sql/validate/DelegatingSqlValidatorCatalogReader.java index 0aff0f064b3a..af74e955c61b 100644 --- a/core/src/main/java/org/apache/calcite/sql/validate/DelegatingSqlValidatorCatalogReader.java +++ b/core/src/main/java/org/apache/calcite/sql/validate/DelegatingSqlValidatorCatalogReader.java @@ -19,6 +19,8 @@ import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.sql.SqlIdentifier; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -56,7 +58,7 @@ public List> getSchemaPaths() { return catalogReader.getSchemaPaths(); } - @Override public C unwrap(Class aClass) { + @Override public @Nullable C unwrap(Class aClass) { return catalogReader.unwrap(aClass); } } diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedAggFunction.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedAggFunction.java index cf16d3d155e7..65f15b3671f6 100644 --- a/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedAggFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedAggFunction.java @@ -29,6 +29,8 @@ import org.apache.calcite.util.Optionality; import org.apache.calcite.util.Util; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * User-defined aggregate function. * @@ -67,7 +69,7 @@ public SqlUserDefinedAggFunction(SqlIdentifier opName, SqlKind kind, this.function = function; } - @Override public SqlOperandMetadata getOperandTypeChecker() { + @Override public @Nullable SqlOperandMetadata getOperandTypeChecker() { return (SqlOperandMetadata) super.getOperandTypeChecker(); } } diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedFunction.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedFunction.java index 813658b25a97..f5c268d69ce5 100644 --- a/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedFunction.java @@ -31,6 +31,8 @@ import com.google.common.collect.Lists; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -78,7 +80,7 @@ protected SqlUserDefinedFunction(SqlIdentifier opName, SqlKind kind, this.function = function; } - @Override public SqlOperandMetadata getOperandTypeChecker() { + @Override public @Nullable SqlOperandMetadata getOperandTypeChecker() { return (SqlOperandMetadata) super.getOperandTypeChecker(); } diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedTableMacro.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedTableMacro.java index 307bf75c049f..1e921e2703bd 100644 --- a/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedTableMacro.java +++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedTableMacro.java @@ -37,6 +37,8 @@ import com.google.common.collect.Lists; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.ArrayList; import java.util.List; @@ -75,7 +77,7 @@ public SqlUserDefinedTableMacro(SqlIdentifier opName, SqlKind kind, this.tableMacro = tableMacro; } - @Override public SqlOperandMetadata getOperandTypeChecker() { + @Override public @Nullable SqlOperandMetadata getOperandTypeChecker() { return (SqlOperandMetadata) super.getOperandTypeChecker(); } diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorCatalogReader.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorCatalogReader.java index 1dea5800550c..59174a6f3fda 100644 --- a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorCatalogReader.java +++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorCatalogReader.java @@ -23,6 +23,8 @@ import org.apache.calcite.schema.Wrapper; import org.apache.calcite.sql.SqlIdentifier; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.List; /** @@ -50,7 +52,7 @@ public interface SqlValidatorCatalogReader extends Wrapper { * * @return Table with the given name, or null */ - SqlValidatorTable getTable(List names); + @Nullable SqlValidatorTable getTable(List names); /** * Finds a user-defined type with the given name, possibly qualified. diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java index 2874a3cd4a20..59f4a32ec80a 100644 --- a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java +++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java @@ -64,6 +64,8 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; @@ -1003,7 +1005,7 @@ public static CalciteSchema.TypeEntry getTypeEntry( * * @return TableEntry with a table with the given name, or null */ - public static CalciteSchema.TableEntry getTableEntry( + public static CalciteSchema.@Nullable TableEntry getTableEntry( SqlValidatorCatalogReader catalogReader, List names) { // First look in the default schema, if any. // If not found, look in the root schema. diff --git a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java index 2cb4079d67c9..a3c68867f476 100644 --- a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java +++ b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java @@ -108,6 +108,8 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.math.BigDecimal; import java.util.AbstractList; import java.util.ArrayDeque; @@ -155,7 +157,7 @@ public class RelBuilder { private final RelOptTable.ViewExpander viewExpander; private RelFactories.Struct struct; - protected RelBuilder(Context context, RelOptCluster cluster, + protected RelBuilder(@Nullable Context context, RelOptCluster cluster, RelOptSchema relOptSchema) { this.cluster = cluster; this.relOptSchema = relOptSchema; @@ -309,7 +311,7 @@ public RelNode peek() { return peek_().rel; } - private Frame peek_() { + private @Nullable Frame peek_() { return stack.peek(); } @@ -350,7 +352,7 @@ private int inputOffset(int inputCount, int inputOrdinal) { // Methods that return scalar expressions /** Creates a literal (constant expression). */ - public RexNode literal(Object value) { + public RexNode literal(@Nullable Object value) { final RexBuilder rexBuilder = cluster.getRexBuilder(); if (value == null) { final RelDataType type = getTypeFactory().createSqlType(SqlTypeName.NULL); @@ -785,7 +787,7 @@ public GroupKey groupKey(ImmutableBitSet groupSet, * or {@link #groupKey(ImmutableBitSet, Iterable)}. */ @Deprecated // to be removed before 2.0 public GroupKey groupKey(ImmutableBitSet groupSet, - ImmutableList groupSets) { + @Nullable ImmutableList groupSets) { return groupKey_(groupSet, groupSets == null ? ImmutableList.of(groupSet) : ImmutableList.copyOf(groupSets)); } @@ -794,7 +796,7 @@ public GroupKey groupKey(ImmutableBitSet groupSet, /** @deprecated Use {@link #groupKey(ImmutableBitSet, Iterable)}. */ @Deprecated // to be removed before 2.0 public GroupKey groupKey(ImmutableBitSet groupSet, boolean indicator, - ImmutableList groupSets) { + @Nullable ImmutableList groupSets) { Aggregate.checkIndicator(indicator); return groupKey_(groupSet, groupSets == null ? ImmutableList.of(groupSet) : ImmutableList.copyOf(groupSets)); @@ -869,8 +871,9 @@ public AggCall aggregateCall(SqlAggFunction aggFunction, /** Creates a call to an aggregate function with all applicable operands. */ protected AggCall aggregateCall(SqlAggFunction aggFunction, boolean distinct, - boolean approximate, boolean ignoreNulls, RexNode filter, ImmutableList orderKeys, - String alias, ImmutableList operands) { + boolean approximate, boolean ignoreNulls, @Nullable RexNode filter, + ImmutableList orderKeys, + @Nullable String alias, ImmutableList operands) { return new AggCallImpl(aggFunction, distinct, approximate, ignoreNulls, filter, alias, operands, orderKeys); } @@ -887,7 +890,7 @@ public AggCall count(Iterable operands) { /** Creates a call to the {@code COUNT} aggregate function, * optionally distinct and with an alias. */ - public AggCall count(boolean distinct, String alias, RexNode... operands) { + public AggCall count(boolean distinct, @Nullable String alias, RexNode... operands) { return aggregateCall(SqlStdOperatorTable.COUNT, distinct, false, false, null, ImmutableList.of(), alias, ImmutableList.copyOf(operands)); } @@ -1499,7 +1502,7 @@ private RelBuilder project_( * projections are trivial */ public RelBuilder projectNamed(Iterable nodes, - Iterable fieldNames, boolean force) { + @Nullable Iterable fieldNames, boolean force) { @SuppressWarnings("unchecked") final List nodeList = nodes instanceof List ? (List) nodes : ImmutableList.copyOf(nodes); final List fieldNameList = @@ -1791,7 +1794,7 @@ public RelBuilder aggregate(GroupKey groupKey, Iterable aggCalls) { // There are duplicate aggregate calls. Rebuild the list to eliminate // duplicates, then add a Project. final Set callSet = new HashSet<>(); - final List> projects = new ArrayList<>(); + final List> projects = new ArrayList<>(); Util.range(groupSet.cardinality()) .forEach(i -> projects.add(Pair.of(i, null))); final List distinctAggregateCalls = new ArrayList<>(); @@ -2298,7 +2301,7 @@ public RelBuilder as(final String alias) { * @param fieldNames Field names * @param values Values */ - public RelBuilder values(String[] fieldNames, Object... values) { + public RelBuilder values(@Nullable String[] fieldNames, @Nullable Object... values) { if (fieldNames == null || fieldNames.length == 0 || values.length % fieldNames.length != 0 @@ -2353,7 +2356,7 @@ private ImmutableList> tupleList(int columnCount, } /** Returns whether all values for a given column are null. */ - private boolean allNull(Object[] values, int column, int columnCount) { + private boolean allNull(@Nullable Object[] values, int column, int columnCount) { for (int i = column; i < values.length; i += columnCount) { if (values[i] != null) { return false; @@ -2737,7 +2740,7 @@ public void clear() { public interface AggCall { /** Returns a copy of this AggCall that applies a filter before aggregating * values. */ - AggCall filter(RexNode condition); + AggCall filter(@Nullable RexNode condition); /** Returns a copy of this AggCall that sorts its input values by * {@code orderKeys} before aggregating, as in SQL's {@code WITHIN GROUP} @@ -2773,17 +2776,18 @@ public interface GroupKey { /** Assigns an alias to this group key. * *

Used to assign field names in the {@code group} operation. */ - GroupKey alias(String alias); + GroupKey alias(@Nullable String alias); } /** Implementation of {@link RelBuilder.GroupKey}. */ public static class GroupKeyImpl implements GroupKey { public final ImmutableList nodes; - public final ImmutableList> nodeLists; - public final String alias; + public final @Nullable ImmutableList> nodeLists; + public final @Nullable String alias; GroupKeyImpl(ImmutableList nodes, - ImmutableList> nodeLists, String alias) { + @Nullable ImmutableList> nodeLists, + @Nullable String alias) { this.nodes = Objects.requireNonNull(nodes); this.nodeLists = nodeLists; this.alias = alias; @@ -2806,14 +2810,14 @@ private class AggCallImpl implements AggCall { private final boolean distinct; private final boolean approximate; private final boolean ignoreNulls; - private final RexNode filter; // may be null - private final String alias; // may be null + private final @Nullable RexNode filter; // may be null + private final @Nullable String alias; // may be null private final ImmutableList operands; // may be empty, never null private final ImmutableList orderKeys; // may be empty, never null AggCallImpl(SqlAggFunction aggFunction, boolean distinct, - boolean approximate, boolean ignoreNulls, RexNode filter, - String alias, ImmutableList operands, + boolean approximate, boolean ignoreNulls, @Nullable RexNode filter, + @Nullable String alias, ImmutableList operands, ImmutableList orderKeys) { this.aggFunction = Objects.requireNonNull(aggFunction); // If the aggregate function ignores DISTINCT, @@ -2878,7 +2882,7 @@ public AggCall approximate(boolean approximate) { filter, alias, operands, orderKeys); } - public AggCall filter(RexNode condition) { + public AggCall filter(@Nullable RexNode condition) { return Objects.equals(condition, this.filter) ? this : new AggCallImpl(aggFunction, distinct, approximate, ignoreNulls, @@ -2936,7 +2940,7 @@ public AggCall approximate(boolean approximate) { throw new UnsupportedOperationException(); } - public AggCall filter(RexNode condition) { + public AggCall filter(@Nullable RexNode condition) { throw new UnsupportedOperationException(); } @@ -3053,7 +3057,7 @@ private Frame(RelNode rel) { return rel + ": " + fields; } - private static String deriveAlias(RelNode rel) { + private static @Nullable String deriveAlias(RelNode rel) { if (rel instanceof TableScan) { final List names = rel.getTable().getQualifiedName(); if (!names.isEmpty()) { diff --git a/core/src/main/java/org/apache/calcite/util/ImmutableBitSet.java b/core/src/main/java/org/apache/calcite/util/ImmutableBitSet.java index 10da5a491986..946ca8ab274e 100644 --- a/core/src/main/java/org/apache/calcite/util/ImmutableBitSet.java +++ b/core/src/main/java/org/apache/calcite/util/ImmutableBitSet.java @@ -24,7 +24,9 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Ordering; +import org.checkerframework.checker.initialization.qual.UnderInitialization; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.dataflow.qual.Pure; import java.io.Serializable; import java.nio.LongBuffer; @@ -43,6 +45,8 @@ import java.util.TreeMap; import javax.annotation.Nonnull; +import static org.apache.calcite.linq4j.Nullness.assertNonNull; + /** * An immutable list of bits. */ @@ -255,6 +259,7 @@ public static ImmutableBitSet range(int toIndex) { /** * Given a bit index, return word index containing it. */ + @Pure private static int wordIndex(int bitIndex) { return bitIndex >> ADDRESS_BITS_PER_WORD; } @@ -939,7 +944,10 @@ private static class Closure { } } - private ImmutableBitSet computeClosure(int pos) { + private ImmutableBitSet computeClosure( + @UnderInitialization Closure this, + int pos + ) { ImmutableBitSet o = closure.get(pos); if (o != null) { return o; @@ -961,7 +969,7 @@ private ImmutableBitSet computeClosure(int pos) { /** Builder. */ public static class Builder { - private long[] words; + private long @Nullable [] words; private Builder(long[] words) { this.words = words; @@ -1042,7 +1050,7 @@ public boolean get(int bitIndex) { } private void trim(int wordCount) { - while (wordCount > 0 && words[wordCount - 1] == 0L) { + while (wordCount > 0 && assertNonNull(words)[wordCount - 1] == 0L) { --wordCount; } if (wordCount == words.length) { diff --git a/core/src/main/java/org/apache/calcite/util/ImmutableIntList.java b/core/src/main/java/org/apache/calcite/util/ImmutableIntList.java index 61fb7f5402ee..05669d3edbe2 100644 --- a/core/src/main/java/org/apache/calcite/util/ImmutableIntList.java +++ b/core/src/main/java/org/apache/calcite/util/ImmutableIntList.java @@ -26,6 +26,7 @@ import com.google.common.collect.UnmodifiableListIterator; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.checker.nullness.qual.PolyNull; import java.lang.reflect.Array; import java.util.Arrays; @@ -36,6 +37,8 @@ import java.util.ListIterator; import java.util.NoSuchElementException; +import static org.apache.calcite.linq4j.Nullness.assertNonNull; + /** * An immutable list of {@link Integer} values backed by an array of * {@code int}s. @@ -141,14 +144,14 @@ public Object[] toArray() { return objects; } - public T[] toArray(T[] a) { + public T @PolyNull [] toArray(T @PolyNull [] a) { final int size = ints.length; if (a.length < size) { // Make a new array of a's runtime type, but my contents: a = a.getClass() == Object[].class ? (T[]) new Object[size] : (T[]) Array.newInstance( - a.getClass().getComponentType(), size); + assertNonNull(a.getClass().getComponentType()), size); } if ((Class) a.getClass() == Integer[].class) { final Integer[] integers = (Integer[]) a; @@ -285,7 +288,7 @@ private static class EmptyImmutableIntList extends ImmutableIntList { return EMPTY_ARRAY; } - @Override public T[] toArray(T[] a) { + @Override public T @PolyNull [] toArray(T @PolyNull [] a) { if (a.length > 0) { a[0] = null; } diff --git a/core/src/main/java/org/apache/calcite/util/Litmus.java b/core/src/main/java/org/apache/calcite/util/Litmus.java index 047738152460..ab5e29841985 100644 --- a/core/src/main/java/org/apache/calcite/util/Litmus.java +++ b/core/src/main/java/org/apache/calcite/util/Litmus.java @@ -16,6 +16,7 @@ */ package org.apache.calcite.util; +import org.checkerframework.checker.nullness.qual.Nullable; import org.slf4j.helpers.MessageFormatter; /** @@ -25,7 +26,7 @@ public interface Litmus { /** Implementation of {@link org.apache.calcite.util.Litmus} that throws * an {@link java.lang.AssertionError} on failure. */ Litmus THROW = new Litmus() { - public boolean fail(String message, Object... args) { + public boolean fail(@Nullable String message, Object... args) { final String s = message == null ? null : MessageFormatter.arrayFormat(message, args).getMessage(); throw new AssertionError(s); @@ -35,7 +36,7 @@ public boolean succeed() { return true; } - public boolean check(boolean condition, String message, Object... args) { + public boolean check(boolean condition, @Nullable String message, Object... args) { if (condition) { return succeed(); } else { @@ -47,7 +48,7 @@ public boolean check(boolean condition, String message, Object... args) { /** Implementation of {@link org.apache.calcite.util.Litmus} that returns * a status code but does not throw. */ Litmus IGNORE = new Litmus() { - public boolean fail(String message, Object... args) { + public boolean fail(@Nullable String message, Object... args) { return false; } @@ -55,7 +56,7 @@ public boolean succeed() { return true; } - public boolean check(boolean condition, String message, Object... args) { + public boolean check(boolean condition, @Nullable String message, Object... args) { return condition; } }; @@ -65,7 +66,7 @@ public boolean check(boolean condition, String message, Object... args) { * @param message Message * @param args Arguments */ - boolean fail(String message, Object... args); + boolean fail(@Nullable String message, Object... args); /** Called when test succeeds. Returns true. */ boolean succeed(); @@ -76,5 +77,5 @@ public boolean check(boolean condition, String message, Object... args) { * if the condition is false, calls {@link #fail}, * converting {@code info} into a string message. */ - boolean check(boolean condition, String message, Object... args); + boolean check(boolean condition, @Nullable String message, Object... args); } diff --git a/core/src/main/java/org/apache/calcite/util/NlsString.java b/core/src/main/java/org/apache/calcite/util/NlsString.java index 685f679c9340..e328bb61f578 100644 --- a/core/src/main/java/org/apache/calcite/util/NlsString.java +++ b/core/src/main/java/org/apache/calcite/util/NlsString.java @@ -71,11 +71,11 @@ public String load(@Nonnull Pair key) { } }); - private final String stringValue; - private final ByteString bytesValue; - private final String charsetName; - private final Charset charset; - private final SqlCollation collation; + private final @Nullable String stringValue; + private final @Nullable ByteString bytesValue; + private final @Nullable String charsetName; + private final @Nullable Charset charset; + private final @Nullable SqlCollation collation; //~ Constructors ----------------------------------------------------------- @@ -93,7 +93,7 @@ public String load(@Nonnull Pair key) { * given charset */ public NlsString(ByteString bytesValue, String charsetName, - SqlCollation collation) { + @Nullable SqlCollation collation) { this(null, Objects.requireNonNull(bytesValue), Objects.requireNonNull(charsetName), collation); } @@ -111,14 +111,14 @@ public NlsString(ByteString bytesValue, String charsetName, * @throws RuntimeException If the given value cannot be represented in the * given charset */ - public NlsString(String stringValue, String charsetName, - SqlCollation collation) { + public NlsString(String stringValue, @Nullable String charsetName, + @Nullable SqlCollation collation) { this(Objects.requireNonNull(stringValue), null, charsetName, collation); } /** Internal constructor; other constructors must call it. */ - private NlsString(String stringValue, ByteString bytesValue, - String charsetName, SqlCollation collation) { + private NlsString(@Nullable String stringValue, @Nullable ByteString bytesValue, + @Nullable String charsetName, @Nullable SqlCollation collation) { if (charsetName != null) { this.charsetName = charsetName.toUpperCase(Locale.ROOT); this.charset = SqlUtil.getCharset(charsetName); @@ -179,15 +179,15 @@ public int hashCode() { return getValue().compareTo(other.getValue()); } - public String getCharsetName() { + public @Nullable String getCharsetName() { return charsetName; } - public Charset getCharset() { + public @Nullable Charset getCharset() { return charset; } - public SqlCollation getCollation() { + public @Nullable SqlCollation getCollation() { return collation; } @@ -298,7 +298,7 @@ public NlsString copy(String value) { } /** Returns the value as a {@link ByteString}. */ - public ByteString getValueBytes() { + public @Nullable ByteString getValueBytes() { return bytesValue; } } diff --git a/core/src/main/java/org/apache/calcite/util/Util.java b/core/src/main/java/org/apache/calcite/util/Util.java index 7fbcb64c0689..8fd5370b3c4c 100644 --- a/core/src/main/java/org/apache/calcite/util/Util.java +++ b/core/src/main/java/org/apache/calcite/util/Util.java @@ -40,6 +40,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Sets; +import org.checkerframework.checker.nullness.qual.Nullable; import org.slf4j.Logger; import java.io.BufferedReader; @@ -250,7 +251,7 @@ public static void discard(double d) { */ public static void swallow( Throwable e, - Logger logger) { + @Nullable Logger logger) { if (logger != null) { logger.debug("Discarding exception", e); } @@ -299,7 +300,7 @@ public static int hash( @Deprecated // to be removed before 2.0 public static int hash( int h, - Object o) { + @Nullable Object o) { int k = (o == null) ? 0 : o.hashCode(); return ((h << 4) | h) ^ k; } @@ -370,7 +371,7 @@ public static void print( public static void print( PrintWriter pw, - Object o, + @Nullable Object o, int indent) { if (o == null) { pw.print("null"); @@ -488,7 +489,7 @@ public static void print( */ public static void printJavaString( Appendable appendable, - String s, + @Nullable String s, boolean nullMeansNull) { try { if (s == null) { @@ -764,7 +765,7 @@ public static List toList(Iterator iter) { /** * Returns whether s == null or if s.length() == 0. */ - public static boolean isNullOrEmpty(String s) { + public static boolean isNullOrEmpty(@Nullable String s) { return (null == s) || (s.length() == 0); } @@ -967,7 +968,7 @@ public static void permAssert(boolean b, String description) { * overridden and a subclass forgot to do so. * @return an {@link UnsupportedOperationException}. */ - public static RuntimeException needToImplement(Object o) { + public static RuntimeException needToImplement(@Nullable Object o) { String description = null; if (o != null) { description = o.getClass().toString() + ": " + o.toString(); @@ -1087,7 +1088,7 @@ public static String readAllAsString(Reader reader) throws IOException { * @param jar jar to close */ @Deprecated // to be removed before 2.0 - public static void squelchJar(JarFile jar) { + public static void squelchJar(@Nullable JarFile jar) { try { if (jar != null) { jar.close(); @@ -1105,7 +1106,7 @@ public static void squelchJar(JarFile jar) { * @param stream stream to close */ @Deprecated // to be removed before 2.0 - public static void squelchStream(InputStream stream) { + public static void squelchStream(@Nullable InputStream stream) { try { if (stream != null) { stream.close(); @@ -1125,7 +1126,7 @@ public static void squelchStream(InputStream stream) { * @param stream stream to close */ @Deprecated // to be removed before 2.0 - public static void squelchStream(OutputStream stream) { + public static void squelchStream(@Nullable OutputStream stream) { try { if (stream != null) { stream.close(); @@ -1143,7 +1144,7 @@ public static void squelchStream(OutputStream stream) { * @param reader reader to close */ @Deprecated // to be removed before 2.0 - public static void squelchReader(Reader reader) { + public static void squelchReader(@Nullable Reader reader) { try { if (reader != null) { reader.close(); @@ -1163,7 +1164,7 @@ public static void squelchReader(Reader reader) { * @param writer writer to close */ @Deprecated // to be removed before 2.0 - public static void squelchWriter(Writer writer) { + public static void squelchWriter(@Nullable Writer writer) { try { if (writer != null) { writer.close(); @@ -1181,7 +1182,7 @@ public static void squelchWriter(Writer writer) { * @param stmt stmt to close */ @Deprecated // to be removed before 2.0 - public static void squelchStmt(Statement stmt) { + public static void squelchStmt(@Nullable Statement stmt) { try { if (stmt != null) { stmt.close(); @@ -1199,7 +1200,7 @@ public static void squelchStmt(Statement stmt) { * @param connection connection to close */ @Deprecated // to be removed before 2.0 - public static void squelchConnection(Connection connection) { + public static void squelchConnection(@Nullable Connection connection) { try { if (connection != null) { connection.close(); @@ -1902,53 +1903,53 @@ public static T first(T v0, T v1) { /** Unboxes a {@link Double} value, * using a given default value if it is null. */ - public static double first(Double v0, double v1) { + public static double first(@Nullable Double v0, double v1) { return v0 != null ? v0 : v1; } /** Unboxes a {@link Float} value, * using a given default value if it is null. */ - public static float first(Float v0, float v1) { + public static float first(@Nullable Float v0, float v1) { return v0 != null ? v0 : v1; } /** Unboxes a {@link Integer} value, * using a given default value if it is null. */ - public static int first(Integer v0, int v1) { + public static int first(@Nullable Integer v0, int v1) { return v0 != null ? v0 : v1; } /** Unboxes a {@link Long} value, * using a given default value if it is null. */ - public static long first(Long v0, long v1) { + public static long first(@Nullable Long v0, long v1) { return v0 != null ? v0 : v1; } /** Unboxes a {@link Boolean} value, * using a given default value if it is null. */ - public static boolean first(Boolean v0, boolean v1) { + public static boolean first(@Nullable Boolean v0, boolean v1) { return v0 != null ? v0 : v1; } /** Unboxes a {@link Short} value, * using a given default value if it is null. */ - public static short first(Short v0, short v1) { + public static short first(@Nullable Short v0, short v1) { return v0 != null ? v0 : v1; } /** Unboxes a {@link Character} value, * using a given default value if it is null. */ - public static char first(Character v0, char v1) { + public static char first(@Nullable Character v0, char v1) { return v0 != null ? v0 : v1; } /** Unboxes a {@link Byte} value, * using a given default value if it is null. */ - public static byte first(Byte v0, byte v1) { + public static byte first(@Nullable Byte v0, byte v1) { return v0 != null ? v0 : v1; } - public static Iterable orEmpty(Iterable v0) { + public static Iterable orEmpty(@Nullable Iterable v0) { return v0 != null ? v0 : ImmutableList.of(); } diff --git a/core/src/main/java/org/apache/calcite/util/mapping/Mappings.java b/core/src/main/java/org/apache/calcite/util/mapping/Mappings.java index bd3273225aa5..a51b26a4ad9b 100644 --- a/core/src/main/java/org/apache/calcite/util/mapping/Mappings.java +++ b/core/src/main/java/org/apache/calcite/util/mapping/Mappings.java @@ -25,6 +25,7 @@ import com.google.common.collect.Iterables; import com.google.common.primitives.Ints; +import org.checkerframework.checker.initialization.qual.UnderInitialization; import org.checkerframework.checker.nullness.qual.Nullable; import java.util.AbstractList; @@ -344,7 +345,7 @@ public static TargetMapping target( } public static TargetMapping target( - IntFunction function, + IntFunction function, int sourceCount, int targetCount) { final PartialFunctionImpl mapping = @@ -624,7 +625,7 @@ public static TargetMapping offsetSource( throw new IllegalArgumentException("new source count too low"); } return target( - (IntFunction) source -> { + (IntFunction<@Nullable Integer>) source -> { int source2 = source - offset; return source2 < 0 || source2 >= mapping.getSourceCount() ? null @@ -668,7 +669,7 @@ public static TargetMapping offsetTarget( throw new IllegalArgumentException("new target count too low"); } return target( - (IntFunction) source -> { + (IntFunction<@Nullable Integer>) source -> { int target = mapping.getTargetOpt(source); return target < 0 ? null : target + offset; }, @@ -696,7 +697,7 @@ public static TargetMapping offset( throw new IllegalArgumentException("new source count too low"); } return target( - (IntFunction) source -> { + (IntFunction<@Nullable Integer>) source -> { final int source2 = source - offset; if (source2 < 0 || source2 >= mapping.getSourceCount()) { return null; @@ -1312,7 +1313,9 @@ public boolean hasNext() { return i < targets.length; } - private void advance() { + private void advance( + @UnderInitialization MappingItr this + ) { do { ++i; } while (i < targets.length && targets[i] == -1); @@ -1671,6 +1674,7 @@ public int size() { return size; } + @SuppressWarnings("method.invocation.invalid") public Iterator iterator() { return new Iterator() { int i = -1; diff --git a/src/main/config/checkerframework/GuavaFunction.astub b/src/main/config/checkerframework/GuavaFunction.astub new file mode 100644 index 000000000000..e6533029e699 --- /dev/null +++ b/src/main/config/checkerframework/GuavaFunction.astub @@ -0,0 +1,29 @@ +/* + * 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 com.google.common.base; + +import org.checkerframework.checker.nullness.qual.*; + +/** + * Guava has {@code Nullable} argument and return value by default. + * Checkerframework cna infer nullability from the actual generic types. + * @param argument type + * @param return type + */ +public interface Function { + T apply(F input); +}