Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
ab12fb1
[CALCITE-7736] Replace the Checker Framework with NullAway and JSpecify
vlsi Aug 23, 2026
78c92ab
[CALCITE-7736] Add the JSpecify Java 8 transformation workaround
vlsi Aug 30, 2026
4e59988
[CALCITE-7736] Move the Checker Framework annotations to JSpecify
vlsi Aug 30, 2026
0445ac7
[CALCITE-7736] Replace @PolyNull with @Contract
vlsi Aug 23, 2026
b30ab88
[CALCITE-7736] Give type parameters the nullable bounds the Checker F…
vlsi Aug 23, 2026
6830779
[CALCITE-7736] Let the linq4j tree visitor return null
vlsi Aug 24, 2026
352ebdf
[CALCITE-7736] Admit that min and max return null for an empty sequence
vlsi Aug 24, 2026
8d0c680
[CALCITE-7736] Let a seeded aggregate start from null
vlsi Aug 24, 2026
27e777b
[CALCITE-7736] Drop castNonNull calls whose argument is already non-null
vlsi Aug 24, 2026
193cfbd
[CALCITE-7736] Handle the nulls the JDK actually hands out
vlsi Aug 24, 2026
40492e0
[CALCITE-7736] Remove two annotations the migration made untrue
vlsi Aug 24, 2026
98c896d
[CALCITE-7736] Let the memory window hold the nulls it is padded with
vlsi Aug 24, 2026
8d1506c
[CALCITE-7736] Let the join enumerators carry the null rows they emit
vlsi Aug 24, 2026
caae6f6
[CALCITE-7736] Suppress the three do-nothing visitors
vlsi Aug 24, 2026
9a30b37
[CALCITE-7736] Instantiate the result-ignoring visitors with @Nullabl…
vlsi Aug 24, 2026
2e438ff
[CALCITE-7736] Drop castNonNull calls whose argument is already non-null
vlsi Aug 24, 2026
b618b5d
[CALCITE-7736] Let the PairList implementations hold nullable pairs
vlsi Aug 24, 2026
ff73a5d
[CALCITE-7736] Let select and its siblings produce a nullable result
vlsi Aug 24, 2026
d3cbfc6
[CALCITE-7736] Let the SQL collection helpers carry null elements
vlsi Aug 24, 2026
2e53e54
[CALCITE-7736] Let the null-tolerant collection helpers take nullable…
vlsi Aug 24, 2026
7b53ff9
[CALCITE-7736] Let SqlFunctions carry the nulls that SQL values have
vlsi Aug 24, 2026
0e86764
[CALCITE-7736] Let the shared utilities take nullable arguments
vlsi Aug 24, 2026
978eae2
[CALCITE-7736] Let the utility collections and visitors carry nulls
vlsi Aug 24, 2026
62b878a
[CALCITE-7736] Drop the preconditions that only the Checker Framework…
vlsi Aug 24, 2026
8d4b426
[CALCITE-7736] Say what the guards already check, and drop two more d…
vlsi Aug 24, 2026
db69bff
[CALCITE-7736] Take the nullable bound on the acceptCall overrides, a…
vlsi Aug 24, 2026
fbf3614
[CALCITE-7736] Read the nulls the JDK hands out, and restore two narr…
vlsi Aug 24, 2026
6efaac3
[CALCITE-7736] Let the values that are genuinely absent say so
vlsi Aug 24, 2026
c3d48f2
[CALCITE-7736] Type the collections and results that hold absent values
vlsi Aug 24, 2026
9d5de4e
[CALCITE-7736] Let unwrap say it may find nothing, and split two cont…
vlsi Aug 24, 2026
0b4d95a
[CALCITE-7736] Ask for what is already established, and let the expre…
vlsi Aug 24, 2026
600f708
[CALCITE-7736] Say where a value is genuinely absent, and work around…
vlsi Aug 24, 2026
08625f3
[CALCITE-7736] Let the profiled rows and composed lists hold absent v…
vlsi Aug 24, 2026
b340e2c
[CALCITE-7736] Read each value once, and drop a castNonNull that outl…
vlsi Aug 24, 2026
28369b6
[CALCITE-7736] Close out the last of the core findings
vlsi Aug 24, 2026
ddd6813
[CALCITE-7736] Give the Void visitors the return type their visitor i…
vlsi Aug 25, 2026
77efb2a
[CALCITE-7736] Carry the nullable element types through the JSON and …
vlsi Aug 30, 2026
0b18448
[CALCITE-7736] Carry the nullable element types through the adapters …
vlsi Aug 30, 2026
d6e8a55
[CALCITE-7736] Carry the nullable element types through the planner a…
vlsi Aug 30, 2026
b6a4afd
[CALCITE-7736] Let NullAway itself require the explicit null-marking
vlsi Aug 25, 2026
bffba1c
[CALCITE-7736] Put :server back under nullness verification
vlsi Aug 25, 2026
0ab1e27
[CALCITE-7736] Put :druid under nullness verification
vlsi Aug 25, 2026
34a8e17
[CALCITE-7736] Put :file under nullness verification
vlsi Aug 25, 2026
c307931
[CALCITE-7736] Put :kafka under nullness verification
vlsi Aug 25, 2026
67d5292
[CALCITE-7736] Put :spark under nullness verification
vlsi Aug 25, 2026
a3a7f72
[CALCITE-7736] Put :babel under nullness verification
vlsi Aug 25, 2026
359fc31
[CALCITE-7736] Put :redis under nullness verification
vlsi Aug 25, 2026
b60bf84
[CALCITE-7736] Put :splunk under nullness verification
vlsi Aug 25, 2026
c6b74b9
[CALCITE-7736] Put :mongodb under nullness verification
vlsi Aug 25, 2026
b01f2ce
[CALCITE-7736] Put :cassandra under nullness verification
vlsi Aug 25, 2026
b657086
[CALCITE-7736] Put :pig under nullness verification
vlsi Aug 25, 2026
6b36f5b
[CALCITE-7736] Put :arrow under nullness verification
vlsi Aug 25, 2026
26862be
[CALCITE-7736] Put :innodb under nullness verification
vlsi Aug 25, 2026
8568d53
[CALCITE-7736] Put :piglet under nullness verification
vlsi Aug 25, 2026
4a33a25
[CALCITE-7736] Put :geode under nullness verification
vlsi Aug 25, 2026
9396d74
[CALCITE-7736] Put :elasticsearch under nullness verification
vlsi Aug 25, 2026
970698e
[CALCITE-7736] Put :plus under nullness verification
vlsi Aug 25, 2026
ba6a7cb
[CALCITE-7736] Put :example:csv and :example:function under nullness …
vlsi Aug 25, 2026
18e873d
[CALCITE-7736] Put :testkit under nullness verification
vlsi Aug 26, 2026
7dd0178
[CALCITE-7736] Put :ubenchmark under nullness verification
vlsi Aug 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 0 additions & 3 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ ij_java_use_single_class_imports = true
max_line_length = 100
ij_any_wrap_long_lines = true

[*.astub]
indent_size = 2

[*.java]
# Doc: https://youtrack.jetbrains.com/issue/IDEA-170643#focus=streamItem-27-3708697.0-0
# $ means "static"
Expand Down
49 changes: 7 additions & 42 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -343,62 +343,27 @@ jobs:

errorprone-guava-latest:
if: github.event.action != 'labeled'
name: 'ErrorProne (JDK 11, latest Guava)'
# This is the only job that verifies nullness, so a nullability problem fails here alone and
# the test jobs keep reporting test failures
name: 'ErrorProne and NullAway (JDK 21, latest Guava)'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 50
- name: 'Set up JDK 11'
# Error Prone 2.43 and later require JDK 21, and NullAway requires JDK 17
- name: 'Set up JDK 21'
uses: actions/setup-java@v5
with:
java-version: 11
java-version: 21
distribution: 'zulu'
- uses: burrunan/gradle-cache-action@v1
name: Test
with:
job-id: errprone
remote-build-cache-proxy-enabled: false
# ErrorProne checks for Beta APIs, so use the latest supported Guava version
arguments: --scan --no-parallel --no-daemon -Pguava.version=${{ env.GUAVA_MAX }} -PenableErrorprone classes

linux-checkerframework:
name: 'CheckerFramework (JDK 11)'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 50
- name: 'Set up JDK 11'
uses: actions/setup-java@v5
with:
java-version: 11
distribution: 'zulu'
- name: 'Run CheckerFramework'
uses: burrunan/gradle-cache-action@v1
with:
job-id: checkerframework-jdk11
remote-build-cache-proxy-enabled: false
arguments: --scan --no-parallel --no-daemon -PenableCheckerframework :linq4j:classes :core:classes :server:classes

linux-checkerframework-oldest-guava:
name: 'CheckerFramework (JDK 11, oldest Guava)'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 50
- name: 'Set up JDK 11'
uses: actions/setup-java@v5
with:
java-version: 11
distribution: 'zulu'
- name: 'Run CheckerFramework'
uses: burrunan/gradle-cache-action@v1
with:
job-id: checkerframework-jdk11
remote-build-cache-proxy-enabled: false
arguments: --scan --no-parallel --no-daemon -Pguava.version=${{ env.GUAVA_MIN }} -PenableCheckerframework :linq4j:classes :core:classes :server:classes
arguments: --scan --no-parallel --no-daemon -Pguava.version=${{ env.GUAVA_MAX }} -PenableErrorprone classes jmhClasses

linux-slow:
# Run slow tests when the commit is on main or it is requested explicitly by adding an
Expand Down
4 changes: 2 additions & 2 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,16 @@
import org.apache.arrow.vector.types.TimeUnit;
import org.apache.arrow.vector.types.pojo.ArrowType;

import org.jspecify.annotations.Nullable;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
* Enumerator that reads from a collection of Arrow value-vectors.
*/
abstract class AbstractArrowEnumerator implements Enumerator<Object> {
abstract class AbstractArrowEnumerator implements Enumerator<@Nullable Object> {
protected final ArrowFileReader arrowFileReader;
protected final List<Integer> fields;
protected final List<ValueVector> valueVectors;
Expand Down Expand Up @@ -82,11 +84,11 @@ protected boolean loadNextNonEmptyArrowBatch() {
}
}

@Override public Object current() {
@Override public @Nullable Object current() {
if (fields.size() == 1) {
return getValue(this.valueVectors.get(0), currRowIndex);
}
Object[] current = new Object[valueVectors.size()];
final @Nullable Object[] current = new Object[valueVectors.size()];
for (int i = 0; i < valueVectors.size(); i++) {
ValueVector vector = this.valueVectors.get(i);
current[i] = getValue(vector, currRowIndex);
Expand All @@ -99,7 +101,7 @@ protected boolean loadNextNonEmptyArrowBatch() {
* <p>For {@link TimeStampVector}, converts the raw value to
* milliseconds since epoch, which is the representation used by
* Calcite's Enumerable runtime for TIMESTAMP types. */
protected static Object getValue(ValueVector vector, int index) {
protected static @Nullable Object getValue(ValueVector vector, int index) {
if (vector instanceof TimeStampVector) {
if (vector.isNull(index)) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@
import org.apache.arrow.vector.ipc.ArrowFileReader;
import org.apache.arrow.vector.types.pojo.Schema;

import org.jspecify.annotations.Nullable;

import java.util.List;

/**
* Enumerable that reads from Arrow value-vectors.
*/
class ArrowEnumerable extends AbstractEnumerable<Object> {
class ArrowEnumerable extends AbstractEnumerable<@Nullable Object> {
private final ArrowFileReader arrowFileReader;
private final ImmutableIntList fields;
private final List<List<List<String>>> conditions;
Expand All @@ -45,7 +47,7 @@ class ArrowEnumerable extends AbstractEnumerable<Object> {
this.onClose = onClose;
}

@Override public Enumerator<Object> enumerator() {
@Override public Enumerator<@Nullable Object> enumerator() {
try {
if (!conditions.isEmpty()) {
return new ArrowFilterEnumerator(arrowFileReader, fields,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.util.ImmutableIntList;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -32,14 +32,14 @@
* Relational expression that uses the Arrow calling convention.
*/
public interface ArrowRel extends RelNode {
void implement(Implementor implementor);

Check warning on line 35 in arrow/src/main/java/org/apache/calcite/adapter/arrow/ArrowRel.java

View workflow job for this annotation

GitHub Actions / macOS (JDK 21)

no comment

/** Calling convention for relational operations that occur in Arrow. */
Convention CONVENTION = new Convention.Impl("ARROW", ArrowRel.class);

/** Callback for the implementation process that converts a tree of
* {@link ArrowRel} nodes into a SQL query. */
class Implementor {

Check warning on line 42 in arrow/src/main/java/org/apache/calcite/adapter/arrow/ArrowRel.java

View workflow job for this annotation

GitHub Actions / macOS (JDK 21)

use of default constructor, which does not provide a comment
@Nullable List<Integer> selectFields;
final List<List<ConditionToken>> whereClause = new ArrayList<>();
@Nullable RelOptTable table;
Expand Down Expand Up @@ -70,7 +70,7 @@
selectFields = ImmutableIntList.copyOf(fields);
}

public void visitInput(int ordinal, RelNode input) {

Check warning on line 73 in arrow/src/main/java/org/apache/calcite/adapter/arrow/ArrowRel.java

View workflow job for this annotation

GitHub Actions / macOS (JDK 21)

no comment
checkArgument(ordinal == 0);
((ArrowRel) input).implement(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@

import com.google.common.collect.ImmutableList;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.immutables.value.Value;
import org.jspecify.annotations.Nullable;

import java.util.List;

Expand All @@ -49,14 +49,14 @@
public static final ArrowProjectRule PROJECT_SCAN =
ArrowProjectRule.DEFAULT_CONFIG.toRule(ArrowProjectRule.class);

public static final ArrowFilterRule FILTER_SCAN =

Check warning on line 52 in arrow/src/main/java/org/apache/calcite/adapter/arrow/ArrowRules.java

View workflow job for this annotation

GitHub Actions / macOS (JDK 21)

no comment
ArrowFilterRule.Config.DEFAULT.toRule();

public static final ConverterRule TO_ENUMERABLE =
ArrowToEnumerableConverterRule.DEFAULT_CONFIG
.toRule(ArrowToEnumerableConverterRule.class);

public static final List<RelOptRule> RULES = ImmutableList.of(PROJECT_SCAN, FILTER_SCAN);

Check warning on line 59 in arrow/src/main/java/org/apache/calcite/adapter/arrow/ArrowRules.java

View workflow job for this annotation

GitHub Actions / macOS (JDK 21)

no comment

static List<String> arrowFieldNames(final RelDataType rowType) {
return SqlValidatorUtil.uniquify(rowType.getFieldNames(),
Expand Down Expand Up @@ -177,7 +177,7 @@
}

@Override public RelNode convert(RelNode rel) {
RelTraitSet newTraitSet = rel.getTraitSet().replace(getOutConvention());

Check warning on line 180 in arrow/src/main/java/org/apache/calcite/adapter/arrow/ArrowRules.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Annotate the parameter with @javax.annotation.Nullable in method 'replace' declaration, or make sure that null can not be passed as argument.

See more on https://sonarcloud.io/project/issues?id=apache_calcite&issues=AaAwJ17rmR300Cbm1PZl&open=AaAwJ17rmR300Cbm1PZl&pullRequest=5213
return new ArrowToEnumerableConverter(rel.getCluster(), newTraitSet, rel);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,14 @@
import org.apache.arrow.vector.types.pojo.Field;
import org.apache.arrow.vector.types.pojo.Schema;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.Nullable;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.List;

import static java.util.Objects.requireNonNull;

/**
* Table backed by an Apache Arrow file.
*
Expand Down Expand Up @@ -100,9 +98,8 @@ public class ArrowTable extends AbstractTable
/** Called via code generation; see uses of
* {@link org.apache.calcite.adapter.arrow.ArrowMethod#ARROW_QUERY}. */
@SuppressWarnings("unused")
public Enumerable<Object> query(DataContext root, ImmutableIntList fields,
List<List<List<String>>> conditions) {
requireNonNull(fields, "fields");
public Enumerable<@Nullable Object> query(@Nullable DataContext root,
ImmutableIntList fields, List<List<List<String>>> conditions) {

FileInputStream fis = null;
try {
Expand Down Expand Up @@ -188,7 +185,7 @@ private ArrowTable getTable() {
* @return result as enumerable
*/
@SuppressWarnings("UnusedDeclaration")
public Enumerable<Object> query(List<Integer> fields,
public Enumerable<@Nullable Object> query(List<Integer> fields,
List<List<List<String>>> conditions) {
final ImmutableIntList fieldList = ImmutableIntList.copyOf(fields);
return getTable().query(null, fieldList, conditions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.util.DateString;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.Nullable;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import com.google.common.collect.ImmutableList;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.Nullable;

import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,7 @@
/**
* Query provider that reads from Arrow files.
*/
@NullMarked
package org.apache.calcite.adapter.arrow;

import org.jspecify.annotations.NullMarked;
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.util.ImmutableNullableList;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.Nullable;

import java.util.List;

Expand All @@ -44,7 +44,9 @@ public class SqlBabelCreateTable extends SqlCreateTable {
(operator, functionQualifier, pos, operands) ->
new SqlBabelCreateTable(pos,
requireNonNull((SqlLiteral) operands[0]).booleanValue(),
requireNonNull((SqlLiteral) operands[1]).symbolValue(TableCollectionType.class),
requireNonNull(
requireNonNull((SqlLiteral) operands[1])
.symbolValue(TableCollectionType.class)),
requireNonNull((SqlLiteral) operands[2]).booleanValue(),
requireNonNull((SqlLiteral) operands[3]).booleanValue(),
(SqlIdentifier) requireNonNull(operands[4]),
Expand All @@ -65,7 +67,7 @@ public SqlBabelCreateTable(SqlParserPos pos, boolean replace,
this.volatile_ = volatile_;
}

@SuppressWarnings("nullness")
@SuppressWarnings("NullAway")
@Override public List<SqlNode> getOperandList() {
return ImmutableNullableList.of(SqlLiteral.createBoolean(getReplace(), pos),
SqlLiteral.createSymbol(tableCollectionType, pos),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,7 @@
/**
* Parse tree for SQL extensions used by the Babel parser.
*/
@NullMarked
package org.apache.calcite.sql.babel;

import org.jspecify.annotations.NullMarked;
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,7 @@
/**
* Parse tree for PostgreSQL extensions used by the Babel parser.
*/
@NullMarked
package org.apache.calcite.sql.babel.postgres;

import org.jspecify.annotations.NullMarked;
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

import com.google.common.base.Throwables;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import net.hydromatic.quidem.CommandHandler;
import net.hydromatic.quidem.Quidem;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;

import java.sql.Connection;
Expand Down
7 changes: 0 additions & 7 deletions babel/src/test/java/org/apache/calcite/test/package-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,4 @@
/**
* Tests for Calcite.
*/
@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.test;

import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;
import org.checkerframework.framework.qual.TypeUseLocation;
2 changes: 1 addition & 1 deletion bom/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ dependencies {
apiv("com.yahoo.datasketches:sketches-core")
apiv("commons-codec:commons-codec")
apiv("commons-io:commons-io")
apiv("org.checkerframework:checker-qual", "checkerframework")
apiv("org.locationtech.jts:jts-core")
apiv("org.locationtech.jts.io:jts-io-common")
apiv("org.locationtech.proj4j:proj4j")
Expand Down Expand Up @@ -148,6 +147,7 @@ dependencies {
apiv("org.incava:java-diff")
apiv("org.jboss:jandex")
apiv("org.jooq:joou-java-6", "joou")
apiv("org.jspecify:jspecify")
apiv("org.jsoup:jsoup")
apiv("org.junit:junit-bom", "junit5")
apiv("org.mockito:mockito-core", "mockito")
Expand Down
Loading
Loading