From 4b3b45d06f0866dfc1d6ed30d0b6b25a20d3ca48 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/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/Convention.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/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 | 4 +- .../calcite/prepare/RelOptTableImpl.java | 4 +- .../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 +- .../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 ++- .../java/org/apache/calcite/rex/RexNode.java | 8 ++- .../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/Utilities.java | 21 ++++--- .../org/apache/calcite/schema/Schema.java | 6 +- .../org/apache/calcite/schema/SchemaPlus.java | 4 +- .../calcite/schema/impl/AbstractSchema.java | 6 +- .../calcite/schema/impl/DelegatingSchema.java | 6 +- .../sql/SqlAbstractDateTimeLiteral.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 +-- .../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/SqlCaseOperator.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 +- .../sql/fun/SqlPosixRegexOperator.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 +- .../validate/SqlUserDefinedAggFunction.java | 4 +- .../sql/validate/SqlUserDefinedFunction.java | 4 +- .../validate/SqlUserDefinedTableMacro.java | 4 +- .../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 ++++----- .../apache/calcite/util/mapping/Mappings.java | 14 +++-- .../checkerframework/GuavaFunction.astub | 29 +++++++++ 120 files changed, 628 insertions(+), 355 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/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/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/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/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..e10935d7dae9 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; @@ -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..c31a250d0925 100644 --- a/core/src/main/java/org/apache/calcite/prepare/RelOptTableImpl.java +++ b/core/src/main/java/org/apache/calcite/prepare/RelOptTableImpl.java @@ -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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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); +}