diff --git a/fdb-relational-api/fdb-relational-api.gradle b/fdb-relational-api/fdb-relational-api.gradle index 43760536c88..6ed0972ef84 100644 --- a/fdb-relational-api/fdb-relational-api.gradle +++ b/fdb-relational-api/fdb-relational-api.gradle @@ -22,6 +22,7 @@ import java.time.Instant plugins { alias(libs.plugins.gitversion) + alias(libs.plugins.errorprone) id 'java-test-fixtures' } @@ -64,16 +65,36 @@ dependencies { exclude(group: "com.squareup", module: "javapoet") } api(libs.protobuf) + // jsr305 is still needed for javax.annotation.concurrent.Immutable/NotThreadSafe usages + // in this module; jspecify only covers null-checking (see @NullMarked package-info.java + // files in com.apple.foundationdb.relational.api / .util). compileOnly(libs.jsr305) + compileOnly(libs.jspecify) implementation(libs.guava) + errorprone(libs.errorprone.core) + errorprone(libs.nullaway) + testImplementation(libs.bundles.test.impl) testImplementation(libs.bundles.test.runtime) - testCompileOnly(libs.jsr305) testFixturesImplementation(libs.assertj) } +// jspecify + NullAway null-checking, scoped to this module only. See @NullMarked +// package-info.java files in com.apple.foundationdb.relational.api (and sub-packages) and +// com.apple.foundationdb.relational.util. Companion change to the fdb-relational-grpc and +// fdb-relational-jdbc null-checking adoptions. +tasks.withType(JavaCompile).configureEach { + options.errorprone { + disableAllChecks = true + error("NullAway") + option("NullAway:AnnotatedPackages", "com.apple.foundationdb.relational.api,com.apple.foundationdb.relational.util") + option("NullAway:JSpecifyMode", "true") + option("NullAway:AcknowledgeRestrictiveAnnotations", "true") + } +} + sourceSets { main { java.srcDir ".out/generated/sources/annotationProcessor/java/main/" diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/ArrayMetaData.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/ArrayMetaData.java index cb898711d24..79197fc25f0 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/ArrayMetaData.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/ArrayMetaData.java @@ -23,7 +23,6 @@ import com.apple.foundationdb.relational.api.exceptions.ErrorCode; import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; import java.sql.SQLException; import java.sql.Wrapper; @@ -68,6 +67,5 @@ default StructMetaData getElementStructMetaData() throws SQLException { * @return the datatype object. * @throws SQLException if something goes wrong. */ - @Nonnull DataType.ArrayType asRelationalType() throws SQLException; } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/Continuation.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/Continuation.java index c5fbbd0cfc9..fa9f0bc908e 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/Continuation.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/Continuation.java @@ -20,7 +20,7 @@ package com.apple.foundationdb.relational.api; -import javax.annotation.Nullable; +import org.jspecify.annotations.Nullable; public interface Continuation { @@ -67,6 +67,7 @@ default boolean atBeginning() { return getExecutionState() == null; } + @SuppressWarnings("NullAway") // NullAway/JSpecify does not currently track @Nullable on array (byte[]) return types reliably across this local assignment; getExecutionState() genuinely returns null when there is no cursor state. default boolean atEnd() { byte[] bytes = getExecutionState(); return bytes != null && bytes.length == 0; @@ -76,5 +77,6 @@ default boolean atEnd() { * Returns the reason why the continuation was generated in the first place. * @return the reason */ + @Nullable Reason getReason(); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/DynamicMessageBuilder.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/DynamicMessageBuilder.java index 1d1578e4894..5a8012fd4fc 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/DynamicMessageBuilder.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/DynamicMessageBuilder.java @@ -25,7 +25,6 @@ import com.google.protobuf.Descriptors; import com.google.protobuf.Message; -import javax.annotation.Nonnull; import javax.annotation.concurrent.NotThreadSafe; import java.sql.SQLException; import java.util.Set; @@ -80,6 +79,5 @@ public interface DynamicMessageBuilder { Descriptors.Descriptor getDescriptor(); - @Nonnull DynamicMessageBuilder newBuilder(); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/KeySet.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/KeySet.java index aeffb764875..fde23c351c1 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/KeySet.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/KeySet.java @@ -24,6 +24,8 @@ import com.apple.foundationdb.relational.api.exceptions.ErrorCode; +import org.jspecify.annotations.Nullable; + import java.sql.SQLException; import java.util.Collections; import java.util.HashMap; @@ -38,13 +40,14 @@ public Map toMap() { } @Override - public KeySet setKeyColumn(String columnName, Object value) throws SQLException { + public KeySet setKeyColumn(String columnName, @Nullable Object value) throws SQLException { throw new SQLException("The Empty Keyset cannot be modified", ErrorCode.UNSUPPORTED_OPERATION.getErrorCode()); } }; @SuppressWarnings("PMD.AvoidFieldNameMatchingTypeName") + @Nullable private Map keySet; public Map toMap() { @@ -61,7 +64,7 @@ public Map toMap() { * @return the constructed key set that was inserted in the map * @throws SQLException Unsupported operation if the KeySet is immutable */ - public KeySet setKeyColumn(String columnName, Object value) throws SQLException { + public KeySet setKeyColumn(String columnName, @Nullable Object value) throws SQLException { if (keySet == null) { keySet = new HashMap<>(); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/Options.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/Options.java index 6463ad36efd..2fd3e749cd2 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/Options.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/Options.java @@ -34,8 +34,8 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Maps; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import org.jspecify.annotations.Nullable; + import java.sql.SQLException; import java.util.Collection; import java.util.Collections; @@ -298,7 +298,6 @@ public enum VectorIndexEnginePreference { @SuppressWarnings("PMD.AvoidFieldNameMatchingTypeName") private static final Map> OPTIONS = makeContracts(); - @Nonnull private static final Map OPTIONS_DEFAULT_VALUES; private static final Object NULL_STANDIN = new Object(); @@ -336,27 +335,24 @@ public enum VectorIndexEnginePreference { @Nullable private final Options parentOptions; - @Nonnull private final Map optionsMap; - @Nonnull public static Options none() { return NONE; } - @Nonnull public static Map defaultOptions() { return OPTIONS_DEFAULT_VALUES; } - private Options(@Nonnull Map optionsMap, @Nullable Options parentOptions) { + private Options(Map optionsMap, @Nullable Options parentOptions) { this.optionsMap = optionsMap; this.parentOptions = parentOptions; } - @SuppressWarnings("unchecked") - public T getOption(@Nonnull Name name) { - T option = getOptionInternal(name); + @SuppressWarnings({"unchecked", "NullAway"}) // Whether this can return null depends on whether `name` has a registered default in OPTIONS_DEFAULT_VALUES (a runtime fact, not visible to the type system); genuinely returns null for options such as INDEX_HINT that have neither a set value nor a default. + public T getOption(Name name) { + @Nullable T option = getOptionInternal(name); if (option == null) { return (T) OPTIONS_DEFAULT_VALUES.get(name); } else { @@ -364,17 +360,16 @@ public T getOption(@Nonnull Name name) { } } - public Options withOption(@Nonnull Name name, @Nullable Object value) throws SQLException { + public Options withOption(Name name, @Nullable Object value) throws SQLException { return builder().fromOptions(this).withOption(name, value).build(); } - public Options withChild(@Nonnull Options childOptions) throws SQLException { + public Options withChild(Options childOptions) throws SQLException { return Options.combine(this, childOptions); } - @Nonnull @SuppressWarnings({"PMD.CompareObjectsWithEquals"}) - private static Options combine(@Nonnull Options parentOptions, @Nonnull Options childOptions) throws SQLException { + private static Options combine(Options parentOptions, Options childOptions) throws SQLException { if (childOptions.parentOptions != null) { throw new SQLException("Cannot override parent options", ErrorCode.INTERNAL_ERROR.getErrorCode()); } @@ -386,14 +381,12 @@ private static Options combine(@Nonnull Options parentOptions, @Nonnull Options return new Options(childOptions.optionsMap, parentOptions); } - @Nonnull public static Builder builder() { return new Builder(); } public static final class Builder { - @Nonnull private final Map optionsMap; @Nullable @@ -403,14 +396,12 @@ private Builder() { optionsMap = Maps.newHashMap(); } - @Nonnull public Builder withOptionFromString(Name name, String valueAsString) throws SQLException { final Object value = parseStringOption(name, valueAsString); return withOption(name, value); } - @Nonnull - public Builder withOption(@Nonnull Name name, @Nullable Object value) throws SQLException { + public Builder withOption(Name name, @Nullable Object value) throws SQLException { if (value == NULL_STANDIN) { optionsMap.put(name, NULL_STANDIN); } else { @@ -424,7 +415,6 @@ public Builder withOption(@Nonnull Name name, @Nullable Object value) throws SQL return this; } - @Nonnull public Builder fromOptions(Options options) throws SQLException { optionsMap.putAll(options.optionsMap); if (parentOptions != null) { @@ -441,15 +431,15 @@ public void setParentOption(@Nullable final Options parentOptions) { this.parentOptions = parentOptions; } - @Nonnull public Options build() { return new Options(ImmutableMap.copyOf(optionsMap), parentOptions); } } @Nullable - private static Object parseStringOption(@Nonnull final Name name, String valueAsString) throws SQLException { - for (OptionContract contract : Objects.requireNonNull(OPTIONS).get(name)) { + private static Object parseStringOption(final Name name, String valueAsString) throws SQLException { + // makeContracts() registers a contract list for every Name constant, so this lookup is never null. + for (OptionContract contract : Objects.requireNonNull(OPTIONS.get(name))) { if (contract instanceof OptionContractWithConversion) { return ((OptionContractWithConversion)contract).fromString(valueAsString); } @@ -457,8 +447,9 @@ private static Object parseStringOption(@Nonnull final Name name, String valueAs throw new SQLException("option must have at least one type contract", ErrorCode.INTERNAL_ERROR.getErrorCode()); } - private static void validateOption(@Nonnull final Name name, Object value) throws SQLException { - for (OptionContract contract : Objects.requireNonNull(OPTIONS).get(name)) { + private static void validateOption(final Name name, @Nullable Object value) throws SQLException { + // makeContracts() registers a contract list for every Name constant, so this lookup is never null. + for (OptionContract contract : Objects.requireNonNull(OPTIONS.get(name))) { contract.validate(name, value); } } @@ -476,7 +467,6 @@ private T getOptionInternal(Name name) { } } - @Nonnull public Iterable> entries() { if (parentOptions != null) { return Iterables.concat(parentOptions.entries(), optionsMap.entrySet()); @@ -490,7 +480,7 @@ public static boolean isNull(@Nullable Object object) { } @Override - public boolean equals(final Object o) { + public boolean equals(@Nullable final Object o) { if (!(o instanceof Options)) { return false; } @@ -521,7 +511,6 @@ public static Options fromProperties(@Nullable Properties properties) throws SQL return builder.build(); } - @Nonnull @SuppressWarnings("unchecked") public static Properties toProperties(final Options options) { final Properties result = new Properties(); @@ -545,7 +534,7 @@ public static Properties toProperties(final Options options) { } // TODO: This is just to avoid dependencies; use HexFormat when upgraded to JDK 17. - private static String bytesToHex(@Nonnull byte[] bytes) { + private static String bytesToHex(byte[] bytes) { char[] hex = new char[bytes.length * 2]; for (int i = 0; i < bytes.length; i++ ) { int b = bytes[i] & 0xFF; diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/ParseTreeInfo.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/ParseTreeInfo.java index af3d69bc0d6..0a32e0e92be 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/ParseTreeInfo.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/ParseTreeInfo.java @@ -20,8 +20,6 @@ package com.apple.foundationdb.relational.api; -import javax.annotation.Nonnull; - /** * This represents query parsing information. * @@ -43,6 +41,5 @@ enum QueryType { OTHER } - @Nonnull QueryType getQueryType(); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalArray.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalArray.java index dfc523f2616..1e6e8b7f00c 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalArray.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalArray.java @@ -22,7 +22,6 @@ import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; import java.sql.Array; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; @@ -101,7 +100,6 @@ default boolean isWrapperFor(Class iface) throws SQLException { return iface.isInstance(this); } - @Nonnull @Override default DataType getRelationalMetaData() throws SQLException { return getMetaData().asRelationalType(); diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalArrayBuilder.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalArrayBuilder.java index 2abd49a50e1..c75d182272b 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalArrayBuilder.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalArrayBuilder.java @@ -20,7 +20,6 @@ package com.apple.foundationdb.relational.api; -import javax.annotation.Nonnull; import java.sql.SQLException; import java.util.UUID; @@ -37,17 +36,17 @@ public interface RelationalArrayBuilder { */ RelationalArray build() throws SQLException; - RelationalArrayBuilder addAll(@Nonnull Object... value) throws SQLException; + RelationalArrayBuilder addAll(Object... value) throws SQLException; - RelationalArrayBuilder addBytes(@Nonnull byte[] value) throws SQLException; + RelationalArrayBuilder addBytes(byte[] value) throws SQLException; - RelationalArrayBuilder addString(@Nonnull String value) throws SQLException; + RelationalArrayBuilder addString(String value) throws SQLException; RelationalArrayBuilder addLong(long value) throws SQLException; - RelationalArrayBuilder addUuid(@Nonnull UUID value) throws SQLException; + RelationalArrayBuilder addUuid(UUID value) throws SQLException; - RelationalArrayBuilder addObject(@Nonnull Object value) throws SQLException; + RelationalArrayBuilder addObject(Object value) throws SQLException; RelationalArrayBuilder addStruct(RelationalStruct struct) throws SQLException; } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalArrayMetaData.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalArrayMetaData.java index d16fb644413..b48ec8fe7f3 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalArrayMetaData.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalArrayMetaData.java @@ -26,7 +26,6 @@ import com.apple.foundationdb.relational.api.metadata.DataType; import com.google.common.base.Suppliers; -import javax.annotation.Nonnull; import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.util.Objects; @@ -42,13 +41,12 @@ public final class RelationalArrayMetaData implements ArrayMetaData { private final Supplier hashCodeSupplier; - private RelationalArrayMetaData(@Nonnull DataType.ArrayType type) { + private RelationalArrayMetaData(DataType.ArrayType type) { this.type = type; this.hashCodeSupplier = Suppliers.memoize(this::calculateHashCode); } - @Nonnull - public static RelationalArrayMetaData of(@Nonnull DataType.ArrayType type) { + public static RelationalArrayMetaData of(DataType.ArrayType type) { return new RelationalArrayMetaData(type); } @@ -108,13 +106,11 @@ public ArrayMetaData getElementArrayMetaData() throws SQLException { return RelationalArrayMetaData.of((DataType.ArrayType) type.getElementType()); } - @Nonnull @Override public DataType.ArrayType asRelationalType() throws SQLException { return type; } - @Nonnull public DataType getElementDataType() { return type.getElementType(); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalConnection.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalConnection.java index 6f4b5c7a833..805cc5e6d5e 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalConnection.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalConnection.java @@ -25,7 +25,8 @@ import com.apple.foundationdb.relational.api.fluentsql.statement.StatementBuilderFactory; import com.apple.foundationdb.relational.util.ExcludeFromJacocoGeneratedReport; -import javax.annotation.Nonnull; +import org.jspecify.annotations.Nullable; + import java.net.URI; import java.sql.Blob; import java.sql.CallableStatement; @@ -89,11 +90,11 @@ public interface RelationalConnection extends java.sql.Connection { @Override RelationalPreparedStatement prepareStatement(String sql) throws SQLException; - @Nonnull Options getOptions(); void setOption(Options.Name name, Object value) throws SQLException; + @Nullable URI getPath(); /* Unsupported SQL features*/ @@ -208,6 +209,7 @@ default String getCatalog() throws SQLException { @Override @ExcludeFromJacocoGeneratedReport + @Nullable default SQLWarning getWarnings() throws SQLException { throw new SQLFeatureNotSupportedException("Not implemented in the relational layer", ErrorCode.UNSUPPORTED_OPERATION.getErrorCode()); } @@ -337,12 +339,10 @@ default boolean isWrapperFor(Class iface) throws SQLException { throw new SQLFeatureNotSupportedException("Not implemented in the relational layer", ErrorCode.UNSUPPORTED_OPERATION.getErrorCode()); } - @Nonnull default StatementBuilderFactory createStatementBuilderFactory() throws SQLException { throw new SQLFeatureNotSupportedException("Not implemented in the relational layer", ErrorCode.UNSUPPORTED_OPERATION.getErrorCode()); } - @Nonnull default ExpressionFactory createExpressionBuilderFactory() throws SQLException { throw new SQLFeatureNotSupportedException("Not implemented in the relational layer", ErrorCode.UNSUPPORTED_OPERATION.getErrorCode()); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalDatabaseMetaData.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalDatabaseMetaData.java index b9676670596..281dd3f90f4 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalDatabaseMetaData.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalDatabaseMetaData.java @@ -25,7 +25,6 @@ import com.apple.foundationdb.relational.util.BuildVersion; import com.apple.foundationdb.relational.util.ExcludeFromJacocoGeneratedReport; -import javax.annotation.Nonnull; import java.sql.Connection; import java.sql.ResultSet; import java.sql.RowIdLifetime; @@ -55,7 +54,6 @@ public interface RelationalDatabaseMetaData extends java.sql.DatabaseMetaData { * @return a list of schemas contained in the currently connected database. * @throws SQLException if something goes wrong. */ - @Nonnull @Override RelationalResultSet getSchemas() throws SQLException; @@ -101,7 +99,6 @@ public interface RelationalDatabaseMetaData extends java.sql.DatabaseMetaData { * @throws SQLException with ErrorCode {@link ErrorCode#UNDEFINED_SCHEMA} if the schema * does not exist within this database; a different error code if something systemic goes wrong. */ - @Nonnull @Override RelationalResultSet getTables( String catalog, @@ -132,7 +129,6 @@ RelationalResultSet getTables( * @return a ResultSet with a column listing for the table. * @throws SQLException if something goes wrong. */ - @Nonnull @Override RelationalResultSet getColumns( String catalog, diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalDirectAccessStatement.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalDirectAccessStatement.java index 30441aebea9..9d368bf4cfe 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalDirectAccessStatement.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalDirectAccessStatement.java @@ -20,7 +20,6 @@ package com.apple.foundationdb.relational.api; -import javax.annotation.Nonnull; import java.sql.SQLException; import java.util.Collections; import java.util.Iterator; @@ -74,8 +73,7 @@ public interface RelationalDirectAccessStatement extends AutoCloseable { * @return a ResultSet containing the entire record in the underlying scan. * @throws SQLException if something goes wrong. Use the Error code to determine exactly what. */ - @Nonnull - RelationalResultSet executeScan(@Nonnull String tableName, @Nonnull KeySet keyPrefix, @Nonnull Options options) throws SQLException; + RelationalResultSet executeScan(String tableName, KeySet keyPrefix, Options options) throws SQLException; /** * Get a single record from the system by key. @@ -91,8 +89,7 @@ public interface RelationalDirectAccessStatement extends AutoCloseable { * not exist the ResultSet will be empty * @throws SQLException If something geos wrong. Use the error code to determine exactly what. */ - @Nonnull - RelationalResultSet executeGet(@Nonnull String tableName, @Nonnull KeySet key, @Nonnull Options options) throws SQLException; + RelationalResultSet executeGet(String tableName, KeySet key, Options options) throws SQLException; /** * Insert a record into the specified table, updating any indexes as necessary to maintain consistency. @@ -102,7 +99,7 @@ public interface RelationalDirectAccessStatement extends AutoCloseable { * @return the number of records inserted. * @throws SQLException If something goes wrong. Use the error code to determine exactly what. */ - default int executeInsert(@Nonnull String tableName, @Nonnull RelationalStruct data) throws SQLException { + default int executeInsert(String tableName, RelationalStruct data) throws SQLException { return executeInsert(tableName, Collections.singletonList(data), Options.NONE); } @@ -114,7 +111,7 @@ default int executeInsert(@Nonnull String tableName, @Nonnull RelationalStruct d * @return the number of records inserted. * @throws SQLException If something goes wrong. Use the error code to determine exactly what. */ - default int executeInsert(@Nonnull String tableName, @Nonnull RelationalStruct data, @Nonnull Options options) throws SQLException { + default int executeInsert(String tableName, RelationalStruct data, Options options) throws SQLException { return executeInsert(tableName, Collections.singletonList(data), options); } @@ -126,7 +123,7 @@ default int executeInsert(@Nonnull String tableName, @Nonnull RelationalStruct d * @return the number of records inserted. * @throws SQLException If something goes wrong. Use the error code to determine exactly what. */ - default int executeInsert(@Nonnull String tableName, @Nonnull List data) throws SQLException { + default int executeInsert(String tableName, List data) throws SQLException { return executeInsert(tableName, data, Options.NONE); } @@ -139,7 +136,7 @@ default int executeInsert(@Nonnull String tableName, @Nonnull List data, @Nonnull Options options) + int executeInsert(String tableName, List data, Options options) throws SQLException; /** @@ -154,11 +151,11 @@ int executeInsert(@Nonnull String tableName, @Nonnull List dat * @return the number of records deleted * @throws SQLException if something goes wrong. Use the error code to determine exactly what. */ - default int executeDelete(@Nonnull String tableName, @Nonnull Iterable keys) throws SQLException { + default int executeDelete(String tableName, Iterable keys) throws SQLException { return executeDelete(tableName, keys.iterator(), Options.NONE); } - default int executeDelete(@Nonnull String tableName, @Nonnull Iterable keys, @Nonnull Options options) throws SQLException { + default int executeDelete(String tableName, Iterable keys, Options options) throws SQLException { return executeDelete(tableName, keys.iterator(), options); } @@ -170,11 +167,11 @@ default int executeDelete(@Nonnull String tableName, @Nonnull Iterable k * @return the number of records deleted * @throws SQLException if something goes wrong. Use the error code to determine exactly what. */ - default int executeDelete(@Nonnull String tableName, @Nonnull Iterator keys) throws SQLException { + default int executeDelete(String tableName, Iterator keys) throws SQLException { return executeDelete(tableName, keys, Options.NONE); } - int executeDelete(@Nonnull String tableName, @Nonnull Iterator keys, @Nonnull Options options) throws SQLException; + int executeDelete(String tableName, Iterator keys, Options options) throws SQLException; /** * This can be used to delete contiguous rows on a table based on a certain PK range. @@ -211,7 +208,7 @@ default int executeDelete(@Nonnull String tableName, @Nonnull Iterator k * @param options options that can be used to configure the delete * @throws SQLException if something goes wrong. Use the error code to determine exactly what. */ - void executeDeleteRange(@Nonnull String tableName, @Nonnull KeySet keyPrefix, @Nonnull Options options) throws SQLException; + void executeDeleteRange(String tableName, KeySet keyPrefix, Options options) throws SQLException; /** * Close method to free up resources managed by this statement. diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalDriver.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalDriver.java index f145456b253..793cd4cfda3 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalDriver.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalDriver.java @@ -23,7 +23,8 @@ import com.apple.foundationdb.relational.api.exceptions.RelationalException; import com.apple.foundationdb.relational.util.BuildVersion; -import javax.annotation.Nonnull; +import org.jspecify.annotations.Nullable; + import java.net.URI; import java.sql.Driver; import java.sql.DriverPropertyInfo; @@ -37,11 +38,13 @@ */ public interface RelationalDriver extends Driver { - default RelationalConnection connect(@Nonnull URI url) throws SQLException { + @Nullable + default RelationalConnection connect(URI url) throws SQLException { return connect(url, Options.NONE); } - RelationalConnection connect(@Nonnull URI url, @Nonnull Options connectionOptions) throws SQLException; + @Nullable + RelationalConnection connect(URI url, Options connectionOptions) throws SQLException; @Override default int getMajorVersion() { diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalPreparedStatement.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalPreparedStatement.java index f65ee353bc3..eae2563015f 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalPreparedStatement.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalPreparedStatement.java @@ -23,6 +23,8 @@ import com.apple.foundationdb.relational.api.exceptions.ErrorCode; import com.apple.foundationdb.relational.util.ExcludeFromJacocoGeneratedReport; +import org.jspecify.annotations.Nullable; + import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; @@ -505,6 +507,7 @@ default void cancel() throws SQLException { } @Override + @Nullable default SQLWarning getWarnings() throws SQLException { // For now, return null until warnings are implemented. // Throwing an exception stops all processing. See TODO (Implement JDBC Warnings in Relational embedded Driver) diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalResultSet.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalResultSet.java index 7fc6903f94c..5eff34984ea 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalResultSet.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalResultSet.java @@ -23,7 +23,8 @@ import com.apple.foundationdb.relational.api.exceptions.ErrorCode; import com.apple.foundationdb.relational.util.ExcludeFromJacocoGeneratedReport; -import javax.annotation.Nonnull; +import org.jspecify.annotations.Nullable; + import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; @@ -60,7 +61,6 @@ public interface RelationalResultSet extends java.sql.ResultSet, RelationalStruc * @return A {@code Continuation} that can be used for retrieving the rest of the rows. * @throws SQLException if the continuation cannot be retrieved. */ - @Nonnull Continuation getContinuation() throws SQLException; /*Unsupported Operations*/ @@ -226,6 +226,7 @@ default InputStream getBinaryStream(String columnLabel) throws SQLException { @ExcludeFromJacocoGeneratedReport @Override + @Nullable default SQLWarning getWarnings() throws SQLException { throw new SQLFeatureNotSupportedException("Not implemented in the relational layer", ErrorCode.UNSUPPORTED_OPERATION.getErrorCode()); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalStatement.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalStatement.java index f03d184c964..01877cff834 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalStatement.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalStatement.java @@ -23,6 +23,8 @@ import com.apple.foundationdb.relational.api.exceptions.ErrorCode; import com.apple.foundationdb.relational.util.ExcludeFromJacocoGeneratedReport; +import org.jspecify.annotations.Nullable; + import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLWarning; @@ -119,6 +121,7 @@ default void cancel() throws SQLException { } @Override + @Nullable default SQLWarning getWarnings() throws SQLException { // Return null warnings for now until implemented. // Throwing an exception stops all processing. diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalStruct.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalStruct.java index 20fc1ad7a21..92d3cf458c2 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalStruct.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalStruct.java @@ -24,7 +24,8 @@ import com.apple.foundationdb.relational.api.exceptions.InvalidColumnReferenceException; import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; +import org.jspecify.annotations.Nullable; + import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Struct; @@ -59,28 +60,40 @@ public interface RelationalStruct extends Struct, Wrapper, WithMetadata { double getDouble(String fieldName) throws SQLException; + @Nullable byte[] getBytes(int oneBasedPosition) throws SQLException; + @Nullable byte[] getBytes(String fieldName) throws SQLException; + @Nullable String getString(int oneBasedPosition) throws SQLException; + @Nullable String getString(String fieldName) throws SQLException; + @Nullable Object getObject(int oneBasedPosition) throws SQLException; + @Nullable Object getObject(String fieldName) throws SQLException; + @Nullable RelationalStruct getStruct(int oneBasedPosition) throws SQLException; + @Nullable RelationalStruct getStruct(String fieldName) throws SQLException; + @Nullable RelationalArray getArray(int oneBasedPosition) throws SQLException; + @Nullable RelationalArray getArray(String fieldName) throws SQLException; + @Nullable UUID getUUID(int oneBasedPosition) throws SQLException; + @Nullable UUID getUUID(String fieldName) throws SQLException; /** @@ -94,6 +107,7 @@ default String getSQLTypeName() throws SQLException { } @Override + @SuppressWarnings("NullAway") // NullAway/JSpecify does not currently support declaring this array's elements @Nullable to match its overridden java.sql.Struct#getAttributes() contract; a SQL NULL column genuinely surfaces as a null array element here, same as before this migration. default Object[] getAttributes() throws SQLException { StructMetaData metaData = getMetaData(); Object[] arr = new Object[metaData.getColumnCount()]; @@ -104,12 +118,12 @@ default Object[] getAttributes() throws SQLException { } @Override - @SuppressWarnings("PMD.PreserveStackTrace") + @SuppressWarnings({"PMD.PreserveStackTrace", "NullAway"}) // NullAway/JSpecify does not currently support declaring this array's elements @Nullable to match its overridden java.sql.Struct#getAttributes(Map) contract; a SQL NULL column genuinely surfaces as a null array element here, same as before this migration. default Object[] getAttributes(Map> map) throws SQLException { StructMetaData metaData = getMetaData(); Object[] arr = new Object[metaData.getColumnCount()]; for (int i = 1; i <= arr.length; i++) { - Object o = getObject(i); + @Nullable Object o = getObject(i); if (o == null) { //TODO(bfines) replace this with default value when necessary arr[i - 1] = null; @@ -140,7 +154,6 @@ default boolean isWrapperFor(Class iface) throws SQLException { return iface.isInstance(this); } - @Nonnull @Override default DataType getRelationalMetaData() throws SQLException { return getMetaData().getRelationalDataType(); diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalStructBuilder.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalStructBuilder.java index 573b2dca548..4bb38624e50 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalStructBuilder.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalStructBuilder.java @@ -20,8 +20,8 @@ package com.apple.foundationdb.relational.api; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import org.jspecify.annotations.Nullable; + import java.sql.SQLException; import java.util.UUID; @@ -55,9 +55,9 @@ public interface RelationalStructBuilder { RelationalStructBuilder addObject(String fieldName, @Nullable Object obj) throws SQLException; - RelationalStructBuilder addStruct(String fieldName, @Nonnull RelationalStruct struct) throws SQLException; + RelationalStructBuilder addStruct(String fieldName, RelationalStruct struct) throws SQLException; - RelationalStructBuilder addArray(String fieldName, @Nonnull RelationalArray array) throws SQLException; + RelationalStructBuilder addArray(String fieldName, RelationalArray array) throws SQLException; RelationalStructBuilder addInt(String fieldName, int i) throws SQLException; } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalStructMetaData.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalStructMetaData.java index 05283be4b77..feaacc802d5 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalStructMetaData.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalStructMetaData.java @@ -27,7 +27,6 @@ import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableList; -import javax.annotation.Nonnull; import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; @@ -42,20 +41,18 @@ public class RelationalStructMetaData implements StructMetaData { //TODO(bfines) eventually this should move into the Planner (or closer to there, anyway), but for now we will hold on to it here private static final Set KNOWN_PHANTOM_COLUMNS = Set.of("__TYPE_KEY"); - @Nonnull private final DataType.StructType type; //the number of phantom columns that are at the front of the metadata private final int leadingPhantomColumnOffset; private final Supplier hashCodeSupplier; - private RelationalStructMetaData(@Nonnull DataType.StructType type) { + private RelationalStructMetaData(DataType.StructType type) { this.type = type; this.leadingPhantomColumnOffset = countLeadingPhantomColumns(); this.hashCodeSupplier = Suppliers.memoize(this::calculateHashCode); } - @Nonnull - public static RelationalStructMetaData of(@Nonnull DataType.StructType type) { + public static RelationalStructMetaData of(DataType.StructType type) { return new RelationalStructMetaData(type); } @@ -139,7 +136,6 @@ public int getLeadingPhantomColumnCount() { return leadingPhantomColumnOffset; } - @Nonnull @Override public DataType.StructType getRelationalDataType() throws SQLException { return type; @@ -155,7 +151,6 @@ public boolean isWrapperFor(Class iface) { return iface.isAssignableFrom(this.getClass()); } - @Nonnull private List getFields() { return ImmutableList.copyOf(type.getFields()); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/SqlTypeNamesSupport.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/SqlTypeNamesSupport.java index f15a2a09f03..7c9f7816102 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/SqlTypeNamesSupport.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/SqlTypeNamesSupport.java @@ -23,8 +23,8 @@ import com.apple.foundationdb.annotation.API; import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import org.jspecify.annotations.Nullable; + import java.sql.Types; /** @@ -105,7 +105,7 @@ public static int getSqlTypeCode(String sqlTypeName) { * @return the equivalent {@link DataType} for the type name */ @Nullable - public static DataType getDataTypeFromSqlTypeName(@Nonnull String sqlTypeName) { + public static DataType getDataTypeFromSqlTypeName(String sqlTypeName) { switch (sqlTypeName) { case "INTEGER": return DataType.Primitives.INTEGER.type(); diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/StructMetaData.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/StructMetaData.java index 6bbaa515552..42070e8338c 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/StructMetaData.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/StructMetaData.java @@ -22,7 +22,6 @@ import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; import java.sql.SQLException; import java.sql.Wrapper; @@ -97,6 +96,5 @@ default int getLeadingPhantomColumnCount() { * @return the datatype object. * @throws SQLException if something goes wrong. */ - @Nonnull DataType.StructType getRelationalDataType() throws SQLException; } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/StructResultSetMetaData.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/StructResultSetMetaData.java index e9078a44920..324b4e2c8f6 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/StructResultSetMetaData.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/StructResultSetMetaData.java @@ -23,7 +23,6 @@ import com.apple.foundationdb.annotation.API; import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; import java.sql.SQLException; @API(API.Status.EXPERIMENTAL) @@ -71,7 +70,6 @@ public ArrayMetaData getArrayMetaData(int oneBasedColumn) throws SQLException { return metaData.getArrayMetaData(oneBasedColumn); } - @Nonnull @Override public DataType.StructType getRelationalDataType() throws SQLException { return metaData.getRelationalDataType(); diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/WithMetadata.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/WithMetadata.java index 13c955b302d..c0f6e1dec5c 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/WithMetadata.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/WithMetadata.java @@ -22,12 +22,10 @@ import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; import java.sql.SQLException; public interface WithMetadata { - @Nonnull DataType getRelationalMetaData() throws SQLException; } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/exceptions/ContextualSQLException.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/exceptions/ContextualSQLException.java index e178bcd349d..1610eb240b7 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/exceptions/ContextualSQLException.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/exceptions/ContextualSQLException.java @@ -22,8 +22,8 @@ import com.apple.foundationdb.annotation.API; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import org.jspecify.annotations.Nullable; + import java.sql.SQLException; import java.util.Collections; import java.util.HashMap; @@ -36,7 +36,6 @@ @API(API.Status.EXPERIMENTAL) public class ContextualSQLException extends SQLException { private static final long serialVersionUID = 2135244094396331484L; - @Nonnull private final transient Map context; public ContextualSQLException(String reason, String SQLState, int vendorCode) { diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/exceptions/RelationalException.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/exceptions/RelationalException.java index 662d080f677..b84e9c4340f 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/exceptions/RelationalException.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/exceptions/RelationalException.java @@ -22,11 +22,13 @@ import com.apple.foundationdb.annotation.API; -import javax.annotation.Nonnull; +import org.jspecify.annotations.Nullable; + import java.sql.SQLException; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Objects; @API(API.Status.EXPERIMENTAL) public class RelationalException extends Exception { @@ -40,6 +42,7 @@ public class RelationalException extends Exception { * of logging and tooling is built around these assumptions. Therefore, we maintain this same * mapping structure. */ + @Nullable private transient Map errorContext; public RelationalException(String message, ErrorCode errorCode) { @@ -71,7 +74,7 @@ public SQLException toSqlException() { if (getCause() instanceof SQLException) { return (SQLException) getCause(); } - return new ContextualSQLException(getMessage(), getErrorCode().getErrorCode(), this, errorContext); + return new ContextualSQLException(Objects.requireNonNullElse(getMessage(), ""), getErrorCode().getErrorCode(), this, errorContext); } /** @@ -112,7 +115,7 @@ public RelationalException addContext(String ctxName, Object ctxValue) { * @param context additional context as a map. * @return an exception holding the context. */ - public RelationalException withContext(@Nonnull Map context) { + public RelationalException withContext(Map context) { if (errorContext == null) { errorContext = new HashMap<>(); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/exceptions/UncheckedRelationalException.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/exceptions/UncheckedRelationalException.java index d3c96cc6d87..bf6c9cc7a41 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/exceptions/UncheckedRelationalException.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/exceptions/UncheckedRelationalException.java @@ -22,6 +22,8 @@ import com.apple.foundationdb.annotation.API; +import java.util.Objects; + @API(API.Status.EXPERIMENTAL) public class UncheckedRelationalException extends RuntimeException { private static final long serialVersionUID = 1L; @@ -31,6 +33,7 @@ public UncheckedRelationalException(RelationalException cause) { } public RelationalException unwrap() { - return (RelationalException) this.getCause(); + // The cause is always set (and always a RelationalException) by the sole constructor above. + return (RelationalException) Objects.requireNonNull(this.getCause()); } } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/exceptions/package-info.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/exceptions/package-info.java index fae233d2263..946f21a1734 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/exceptions/package-info.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/exceptions/package-info.java @@ -24,4 +24,7 @@ * * @see com.apple.foundationdb.relational.api.exceptions.ContextualSQLException */ +@NullMarked package com.apple.foundationdb.relational.api.exceptions; + +import org.jspecify.annotations.NullMarked; diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/FluentVisitor.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/FluentVisitor.java index 2243f6230ce..20b2a3c5081 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/FluentVisitor.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/FluentVisitor.java @@ -32,41 +32,40 @@ import com.apple.foundationdb.relational.api.fluentsql.expression.StringLiteral; import com.apple.foundationdb.relational.api.fluentsql.expression.UserDefinedField; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import org.jspecify.annotations.Nullable; public interface FluentVisitor { @Nullable - R visit(@Nonnull BooleanFunction booleanFunction, @Nonnull C context); + R visit(BooleanFunction booleanFunction, C context); @Nullable - R visit(@Nonnull NumericFunction numericFunction, @Nonnull C context); + R visit(NumericFunction numericFunction, C context); @Nullable - R visit(@Nonnull ComparableFunction comparableFunction, @Nonnull C context); + R visit(ComparableFunction comparableFunction, C context); @Nullable - R visit(@Nonnull FunctionLike function, @Nonnull C context); + R visit(FunctionLike function, C context); @Nullable - R visit(@Nonnull BooleanLiteral booleanLiteral, @Nonnull C context); + R visit(BooleanLiteral booleanLiteral, C context); @Nullable - R visit(@Nonnull NestedBooleanExpression nestedBooleanExpression, @Nonnull C context); + R visit(NestedBooleanExpression nestedBooleanExpression, C context); @Nullable - R visit(@Nonnull NumericLiteral numericLiteral, @Nonnull C context); + R visit(NumericLiteral numericLiteral, C context); @Nullable - R visit(@Nonnull StringLiteral stringLiteral, @Nonnull C context); + R visit(StringLiteral stringLiteral, C context); @Nullable - R visit(@Nonnull ExpressionFragment expression, @Nonnull C context); + R visit(ExpressionFragment expression, C context); @Nullable - R visit(@Nonnull Field field, @Nonnull C context); + R visit(Field field, C context); @Nullable - R visit(@Nonnull UserDefinedField userDefinedField, @Nonnull C context); + R visit(UserDefinedField userDefinedField, C context); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/SqlVisitor.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/SqlVisitor.java index 586372ba3cb..247c168009a 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/SqlVisitor.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/SqlVisitor.java @@ -38,8 +38,8 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import org.jspecify.annotations.Nullable; + import javax.annotation.concurrent.Immutable; import java.util.Map; import java.util.stream.Collectors; @@ -75,25 +75,25 @@ public class SqlVisitor implements FluentVisitor { @Nullable @Override - public Void visit(@Nonnull final BooleanFunction booleanFunction, @Nonnull final StringBuilder context) { + public Void visit(final BooleanFunction booleanFunction, final StringBuilder context) { return visit((FunctionLike) booleanFunction, context); } @Nullable @Override - public Void visit(@Nonnull final NumericFunction numericFunction, @Nonnull final StringBuilder context) { + public Void visit(final NumericFunction numericFunction, final StringBuilder context) { return visit((FunctionLike) numericFunction, context); } @Nullable @Override - public Void visit(@Nonnull final ComparableFunction comparableFunction, @Nonnull final StringBuilder context) { + public Void visit(final ComparableFunction comparableFunction, final StringBuilder context) { return visit((FunctionLike) comparableFunction, context); } @Nullable @Override - public Void visit(@Nonnull final FunctionLike function, @Nonnull final StringBuilder context) { + public Void visit(final FunctionLike function, final StringBuilder context) { switch (function.getName()) { case JAVA_CALL: // fallthrough case GREATEST: { @@ -149,14 +149,14 @@ public Void visit(@Nonnull final FunctionLike function, @Nonnull final String @Nullable @Override - public Void visit(@Nonnull final BooleanLiteral booleanLiteral, @Nonnull final StringBuilder context) { + public Void visit(final BooleanLiteral booleanLiteral, final StringBuilder context) { context.append(booleanLiteral.getValue()); return null; } @Nullable @Override - public Void visit(@Nonnull NestedBooleanExpression expression, @Nonnull StringBuilder context) { + public Void visit(NestedBooleanExpression expression, StringBuilder context) { context.append("( "); expression.getValue().accept(this, context); context.append(" )"); @@ -165,35 +165,35 @@ public Void visit(@Nonnull NestedBooleanExpression expression, @Nonnull StringBu @Nullable @Override - public Void visit(@Nonnull final NumericLiteral numericLiteral, @Nonnull final StringBuilder context) { + public Void visit(final NumericLiteral numericLiteral, final StringBuilder context) { context.append(numericLiteral.getValue()); return null; } @Nullable @Override - public Void visit(@Nonnull final StringLiteral stringLiteral, @Nonnull final StringBuilder context) { + public Void visit(final StringLiteral stringLiteral, final StringBuilder context) { context.append('\'').append(stringLiteral.getValue()).append('\''); return null; } @Nullable @Override - public Void visit(@Nonnull final ExpressionFragment expression, @Nonnull final StringBuilder context) { + public Void visit(final ExpressionFragment expression, final StringBuilder context) { context.append(expression.getFragment()); return null; } @Nullable @Override - public Void visit(@Nonnull final Field field, @Nonnull final StringBuilder context) { + public Void visit(final Field field, final StringBuilder context) { context.append(StreamSupport.stream(field.getParts().spliterator(), false).map(f -> "\"" + f + "\"").collect(Collectors.joining("."))); return null; } @Nullable @Override - public Void visit(@Nonnull final UserDefinedField userDefinedField, @Nonnull final StringBuilder context) { + public Void visit(final UserDefinedField userDefinedField, final StringBuilder context) { context.append(StreamSupport.stream(userDefinedField.getParts().spliterator(), false).collect(Collectors.joining("."))); return null; } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/BooleanExpressionTrait.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/BooleanExpressionTrait.java index 4be7d02d42d..e64b80122c4 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/BooleanExpressionTrait.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/BooleanExpressionTrait.java @@ -22,7 +22,6 @@ import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; import javax.annotation.concurrent.Immutable; import java.util.List; @@ -32,23 +31,19 @@ @Immutable public interface BooleanExpressionTrait extends Expression { - @Nonnull - default BooleanExpressionTrait and(@Nonnull final BooleanExpressionTrait right) { + default BooleanExpressionTrait and(final BooleanExpressionTrait right) { return new BooleanFunction(Operation.AND, List.of(this, right)); } - @Nonnull - default BooleanExpressionTrait or(@Nonnull final BooleanExpressionTrait right) { + default BooleanExpressionTrait or(final BooleanExpressionTrait right) { return new BooleanFunction(Operation.OR, List.of(this, right)); } // todo (yhatem) remove this (post wave3). - @Nonnull default NestedBooleanExpression nested() { return new NestedBooleanExpression(this); } - @Nonnull default BooleanExpressionTrait not() { return new BooleanFunction(Operation.NOT, List.of(this)); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/BooleanFunction.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/BooleanFunction.java index f777e614717..dc0ce87237e 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/BooleanFunction.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/BooleanFunction.java @@ -25,7 +25,8 @@ import com.apple.foundationdb.relational.api.metadata.DataType; import com.google.common.collect.ImmutableList; -import javax.annotation.Nonnull; +import org.jspecify.annotations.Nullable; + import javax.annotation.concurrent.Immutable; import java.util.List; import java.util.Objects; @@ -38,35 +39,31 @@ @API(API.Status.EXPERIMENTAL) public class BooleanFunction implements BooleanExpressionTrait, FunctionLike { - @Nonnull private final Operation operator; - @Nonnull private final List> args; - public BooleanFunction(@Nonnull final Operation operator, - @Nonnull final List> args) { + public BooleanFunction(final Operation operator, + final List> args) { this.operator = operator; this.args = ImmutableList.copyOf(args); } @Override - public R accept(@Nonnull final FluentVisitor visitor, @Nonnull final C context) { + @Nullable + public R accept(final FluentVisitor visitor, final C context) { return visitor.visit(this, context); } - @Nonnull @Override public Iterable> getArguments() { return args; } - @Nonnull @Override public Operation getName() { return operator; } - @Nonnull @Override public DataType getType() { return DataType.BooleanType.nullable(); diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/BooleanLiteral.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/BooleanLiteral.java index 7c7d50982ab..b36c3d2c0c5 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/BooleanLiteral.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/BooleanLiteral.java @@ -25,9 +25,9 @@ import com.apple.foundationdb.relational.api.fluentsql.FluentVisitor; import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; +import org.jspecify.annotations.Nullable; + import java.util.Objects; /** @@ -36,10 +36,8 @@ @Immutable @API(API.Status.EXPERIMENTAL) public final class BooleanLiteral implements Literal, BooleanExpressionTrait { - @Nonnull private static final BooleanLiteral TRUE = new BooleanLiteral(DataType.BooleanType.notNullable(), true); - @Nonnull private static final BooleanLiteral FALSE = new BooleanLiteral(DataType.BooleanType.notNullable(), false); private static final BooleanLiteral NULL = new BooleanLiteral(DataType.BooleanType.nullable(), null); @@ -47,17 +45,16 @@ public final class BooleanLiteral implements Literal R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return visitor.visit(this, context); } @@ -67,22 +64,18 @@ public Boolean getValue() { return literal; } - @Nonnull public static BooleanLiteral trueLiteral() { return TRUE; } - @Nonnull public static BooleanLiteral falseLiteral() { return FALSE; } - @Nonnull public static BooleanLiteral nullLiteral() { return NULL; } - @Nonnull @Override public DataType.BooleanType getType() { return type; diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ComparableExpressionTrait.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ComparableExpressionTrait.java index aa89fcf35fb..06ff1148c4d 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ComparableExpressionTrait.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ComparableExpressionTrait.java @@ -25,7 +25,6 @@ import com.google.common.collect.ImmutableList; -import javax.annotation.Nonnull; import javax.annotation.concurrent.Immutable; import java.util.List; @@ -37,38 +36,31 @@ */ @Immutable public interface ComparableExpressionTrait

> extends ScalarExpression

{ - @Nonnull - default BooleanExpressionTrait isEqualTo(@Nonnull final T right) { + default BooleanExpressionTrait isEqualTo(final T right) { return new BooleanFunction(Operation.EQUAL, List.of(this, right)); } - @Nonnull - default BooleanExpressionTrait notEquals(@Nonnull final T right) { + default BooleanExpressionTrait notEquals(final T right) { return new BooleanFunction(Operation.NOT_EQUAL, List.of(this, right)); } - @Nonnull - default BooleanExpressionTrait greaterThan(@Nonnull final T right) { + default BooleanExpressionTrait greaterThan(final T right) { return new BooleanFunction(Operation.GREATER_THAN, List.of(this, right)); } - @Nonnull - default BooleanExpressionTrait greaterThanOrEquals(@Nonnull final T right) { + default BooleanExpressionTrait greaterThanOrEquals(final T right) { return new BooleanFunction(Operation.GREATER_THAN_EQUALS, List.of(this, right)); } - @Nonnull - default BooleanExpressionTrait lessThan(@Nonnull final T right) { + default BooleanExpressionTrait lessThan(final T right) { return new BooleanFunction(Operation.LESS_THAN, List.of(this, right)); } - @Nonnull - default BooleanExpressionTrait lessThanOrEqual(@Nonnull final T right) { + default BooleanExpressionTrait lessThanOrEqual(final T right) { return new BooleanFunction(Operation.LESS_THAN_EQUALS, List.of(this, right)); } - @Nonnull - default ComparableExpressionTrait greatest(@Nonnull final List> arguments) { + default ComparableExpressionTrait greatest(final List> arguments) { if (arguments.isEmpty()) { return this; } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ComparableFunction.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ComparableFunction.java index c3f14bb82db..8001a204d1d 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ComparableFunction.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ComparableFunction.java @@ -25,9 +25,9 @@ import com.apple.foundationdb.relational.api.metadata.DataType; import com.google.common.collect.ImmutableList; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; +import org.jspecify.annotations.Nullable; + import java.util.Objects; import java.util.stream.Collectors; @@ -41,16 +41,13 @@ @API(API.Status.EXPERIMENTAL) public class ComparableFunction

> implements ComparableExpressionTrait, FunctionLike

{ - @Nonnull private final Operation operator; - @Nonnull private final ImmutableList> args; - @Nonnull private final P type; - public ComparableFunction(@Nonnull P type, @Nonnull Operation operator, @Nonnull ImmutableList> args) { + public ComparableFunction(P type, Operation operator, ImmutableList> args) { this.type = type; this.operator = operator; this.args = ImmutableList.copyOf(args); @@ -58,23 +55,20 @@ public ComparableFunction(@Nonnull P type, @Nonnull Operation operator, @Nonnull @Nullable @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return visitor.visit((FunctionLike) this, context); } - @Nonnull @Override public P getType() { return type; } - @Nonnull @Override public Iterable> getArguments() { return ImmutableList.copyOf(args); } - @Nonnull @Override public Operation getName() { return operator; diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/Expression.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/Expression.java index cad03832f89..799c7850d47 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/Expression.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/Expression.java @@ -23,8 +23,8 @@ import com.apple.foundationdb.relational.api.fluentsql.FluentVisitor; import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import org.jspecify.annotations.Nullable; + import javax.annotation.concurrent.Immutable; /** @@ -36,7 +36,7 @@ public interface Expression { @Nullable - R accept(@Nonnull FluentVisitor visitor, @Nonnull C context); + R accept(FluentVisitor visitor, C context); DataType getType(); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ExpressionFactory.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ExpressionFactory.java index cbb6241f4b0..b031b483471 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ExpressionFactory.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ExpressionFactory.java @@ -23,8 +23,8 @@ import com.apple.foundationdb.relational.api.fluentsql.expression.details.Mixins; import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import org.jspecify.annotations.Nullable; + import javax.annotation.concurrent.Immutable; import java.util.List; @@ -34,143 +34,121 @@ @Immutable public interface ExpressionFactory { - @Nonnull - default BooleanLiteral literal(Boolean value) { + default BooleanLiteral literal(@Nullable Boolean value) { if (value == null) { return BooleanLiteral.nullLiteral(); } return value ? BooleanLiteral.trueLiteral() : BooleanLiteral.falseLiteral(); } - @Nonnull default BooleanLiteral literal(boolean value) { return value ? BooleanLiteral.trueLiteral() : BooleanLiteral.falseLiteral(); } - @Nonnull - default NumericLiteral literal(Integer value) { + default NumericLiteral literal(@Nullable Integer value) { final var type = value == null ? DataType.IntegerType.notNullable() : DataType.IntegerType.nullable(); return new NumericLiteral<>(type, value); } - @Nonnull default NumericLiteral literal(int value) { return new NumericLiteral<>(DataType.IntegerType.notNullable(), value); } - @Nonnull default NumericLiteral literal(@Nullable final Long value) { final var type = value == null ? DataType.LongType.notNullable() : DataType.LongType.nullable(); return new NumericLiteral<>(type, value); } - @Nonnull default NumericLiteral literal(long value) { return new NumericLiteral<>(DataType.LongType.notNullable(), value); } - @Nonnull default NumericLiteral literal(@Nullable final Double value) { final var type = value == null ? DataType.DoubleType.notNullable() : DataType.DoubleType.nullable(); return new NumericLiteral<>(type, value); } - @Nonnull default NumericLiteral literal(double value) { return new NumericLiteral<>(DataType.DoubleType.notNullable(), value); } - @Nonnull default NumericLiteral literal(@Nullable final Float value) { final var type = value == null ? DataType.FloatType.notNullable() : DataType.FloatType.nullable(); return new NumericLiteral<>(type, value); } - @Nonnull default NumericLiteral literal(float value) { return new NumericLiteral<>(DataType.FloatType.notNullable(), value); } - @Nonnull default StringLiteral literal(@Nullable final String value) { final var type = value == null ? DataType.StringType.notNullable() : DataType.StringType.nullable(); return new StringLiteral(type, value); } - default Mixins.BooleanField field(@Nonnull final DataType.BooleanType type, @Nonnull final String part) { + default Mixins.BooleanField field(final DataType.BooleanType type, final String part) { return field(type, List.of(part)).asBoolean(type.isNullable()); } - @Nonnull - default Mixins.BooleanField field(@Nonnull final DataType.BooleanType type, @Nonnull final Iterable parts) { + default Mixins.BooleanField field(final DataType.BooleanType type, final Iterable parts) { return field((DataType) type, parts).asBoolean(type.isNullable()); } - default Mixins.IntField field(@Nonnull final DataType.IntegerType type, @Nonnull final String part) { + default Mixins.IntField field(final DataType.IntegerType type, final String part) { return field(type, List.of(part)); } - @Nonnull - default Mixins.IntField field(@Nonnull final DataType.IntegerType type, @Nonnull final Iterable parts) { + default Mixins.IntField field(final DataType.IntegerType type, final Iterable parts) { return field((DataType) type, parts).asInt(type.isNullable()); } - default Mixins.LongField field(@Nonnull final DataType.LongType type, @Nonnull final String part) { + default Mixins.LongField field(final DataType.LongType type, final String part) { return field(type, List.of(part)).asLong(type.isNullable()); } - @Nonnull - default Mixins.LongField field(@Nonnull final DataType.LongType type, @Nonnull final Iterable parts) { + default Mixins.LongField field(final DataType.LongType type, final Iterable parts) { return field((DataType) type, parts).asLong(type.isNullable()); } - default Mixins.DoubleField field(@Nonnull final DataType.DoubleType type, @Nonnull final String part) { + default Mixins.DoubleField field(final DataType.DoubleType type, final String part) { return field(type, List.of(part)).asDouble(type.isNullable()); } - @Nonnull - default Mixins.DoubleField field(@Nonnull final DataType.DoubleType type, @Nonnull final Iterable parts) { + default Mixins.DoubleField field(final DataType.DoubleType type, final Iterable parts) { return field((DataType) type, parts).asDouble(type.isNullable()); } - default Mixins.FloatField field(@Nonnull final DataType.FloatType type, @Nonnull final String part) { + default Mixins.FloatField field(final DataType.FloatType type, final String part) { return field(type, List.of(part)).asFloat(type.isNullable()); } - @Nonnull - default Mixins.FloatField field(@Nonnull final DataType.FloatType type, @Nonnull final Iterable parts) { + default Mixins.FloatField field(final DataType.FloatType type, final Iterable parts) { return field((DataType) type, parts).asFloat(type.isNullable()); } - default Mixins.StringField field(@Nonnull final DataType.StringType type, @Nonnull final String part) { + default Mixins.StringField field(final DataType.StringType type, final String part) { return field(type, List.of(part)).asString(type.isNullable()); } - @Nonnull - default Mixins.StringField field(@Nonnull final DataType.StringType type, @Nonnull final Iterable parts) { + default Mixins.StringField field(final DataType.StringType type, final Iterable parts) { return field((DataType) type, parts).asString(type.isNullable()); } - @Nonnull - default Field field(@Nonnull final T type, @Nonnull final String part) { + default Field field(final T type, final String part) { return field(type, List.of(part)); } - @Nonnull - default Field field(@Nonnull final T type, @Nonnull final Iterable parts) { + default Field field(final T type, final Iterable parts) { return new UserDefinedField<>(type, parts); } - @Nonnull - default Field field(@Nonnull final String tableName, @Nonnull final String part) { + default Field field(final String tableName, final String part) { return field(tableName, List.of(part)); } - @Nonnull - Field field(@Nonnull String tableName, @Nonnull Iterable parts); + Field field(String tableName, Iterable parts); - @Nonnull - default ExpressionFragment parseFragment(@Nonnull final String fragment) { + default ExpressionFragment parseFragment(final String fragment) { return new ParsingFragment<>(DataType.UnknownType.instance(), fragment); } } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ExpressionFragment.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ExpressionFragment.java index 161934d4bb2..26975ed4a0b 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ExpressionFragment.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ExpressionFragment.java @@ -23,19 +23,14 @@ import com.apple.foundationdb.relational.api.fluentsql.expression.details.Mixins; import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; - public interface ExpressionFragment extends Expression { - @Nonnull String getFragment(); - @Nonnull default Mixins.BooleanExpressionFragment asBoolean() { return asBoolean(true); } - @Nonnull default Mixins.BooleanExpressionFragment asBoolean(boolean isNullable) { if (this instanceof Mixins.BooleanExpressionFragment) { return (Mixins.BooleanExpressionFragment) this; @@ -43,12 +38,10 @@ default Mixins.BooleanExpressionFragment asBoolean(boolean isNullable) { return Mixins.asBoolean(this, isNullable); } - @Nonnull default Mixins.IntExpressionFragment asInt() { return asInt(true); } - @Nonnull default Mixins.IntExpressionFragment asInt(boolean isNullable) { if (this instanceof Mixins.IntExpressionFragment) { return (Mixins.IntExpressionFragment) this; @@ -56,12 +49,10 @@ default Mixins.IntExpressionFragment asInt(boolean isNullable) { return Mixins.asInt(this, isNullable); } - @Nonnull default Mixins.LongExpressionFragment asLong() { return asLong(true); } - @Nonnull default Mixins.LongExpressionFragment asLong(boolean isNullable) { if (this instanceof Mixins.LongExpressionFragment) { return (Mixins.LongExpressionFragment) this; @@ -69,12 +60,10 @@ default Mixins.LongExpressionFragment asLong(boolean isNullable) { return Mixins.asLong(this, isNullable); } - @Nonnull default Mixins.FloatExpressionFragment asFloat() { return asFloat(true); } - @Nonnull default Mixins.FloatExpressionFragment asFloat(boolean isNullable) { if (this instanceof Mixins.FloatExpressionFragment) { return (Mixins.FloatExpressionFragment) this; @@ -82,12 +71,10 @@ default Mixins.FloatExpressionFragment asFloat(boolean isNullable) { return Mixins.asFloat(this, isNullable); } - @Nonnull default Mixins.DoubleExpressionFragment asDouble() { return asDouble(true); } - @Nonnull default Mixins.DoubleExpressionFragment asDouble(boolean isNullable) { if (this instanceof Mixins.DoubleExpressionFragment) { return (Mixins.DoubleExpressionFragment) this; @@ -95,12 +82,10 @@ default Mixins.DoubleExpressionFragment asDouble(boolean isNullable) { return Mixins.asDouble(this, isNullable); } - @Nonnull default Mixins.StringExpressionFragment asString() { return asString(true); } - @Nonnull default Mixins.StringExpressionFragment asString(boolean isNullable) { if (this instanceof Mixins.StringExpressionFragment) { return (Mixins.StringExpressionFragment) this; diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/Field.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/Field.java index c5446e3984d..cda4fe426bb 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/Field.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/Field.java @@ -23,7 +23,6 @@ import com.apple.foundationdb.relational.api.fluentsql.expression.details.Mixins; import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; import javax.annotation.concurrent.Immutable; /** @@ -34,16 +33,12 @@ @Immutable public interface Field extends ComparableExpressionTrait> { - @Nonnull Iterable getParts(); - @Nonnull - Field subField(@Nonnull String part); + Field subField(String part); - @Nonnull String getName(); - @Nonnull default Mixins.BooleanField asBoolean() { return asBoolean(true); } @@ -55,12 +50,10 @@ default Mixins.BooleanField asBoolean(boolean isNullable) { return Mixins.asBoolean(this, isNullable); } - @Nonnull default Mixins.IntField asInt() { return asInt(true); } - @Nonnull default Mixins.IntField asInt(boolean isNullable) { if (this instanceof Mixins.IntField) { return (Mixins.IntField) this; @@ -68,12 +61,10 @@ default Mixins.IntField asInt(boolean isNullable) { return Mixins.asInt(this, isNullable); } - @Nonnull default Mixins.LongField asLong() { return asLong(true); } - @Nonnull default Mixins.LongField asLong(boolean isNullable) { if (this instanceof Mixins.LongField) { return (Mixins.LongField) this; @@ -81,12 +72,10 @@ default Mixins.LongField asLong(boolean isNullable) { return Mixins.asLong(this, isNullable); } - @Nonnull default Mixins.FloatField asFloat() { return asFloat(true); } - @Nonnull default Mixins.FloatField asFloat(boolean isNullable) { if (this instanceof Mixins.FloatField) { return (Mixins.FloatField) this; @@ -94,12 +83,10 @@ default Mixins.FloatField asFloat(boolean isNullable) { return Mixins.asFloat(this, isNullable); } - @Nonnull default Mixins.DoubleField asDouble() { return asDouble(true); } - @Nonnull default Mixins.DoubleField asDouble(boolean isNullable) { if (this instanceof Mixins.DoubleField) { return (Mixins.DoubleField) this; @@ -107,12 +94,10 @@ default Mixins.DoubleField asDouble(boolean isNullable) { return Mixins.asDouble(this, isNullable); } - @Nonnull default Mixins.StringField asString() { return asString(true); } - @Nonnull default Mixins.StringField asString(boolean isNullable) { if (this instanceof Mixins.StringField) { return (Mixins.StringField) this; diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/FunctionLike.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/FunctionLike.java index ff002b9f6f2..eba6b8a460e 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/FunctionLike.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/FunctionLike.java @@ -22,7 +22,6 @@ import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; import javax.annotation.concurrent.Immutable; /** @@ -31,9 +30,7 @@ */ @Immutable public interface FunctionLike extends Expression { - @Nonnull Iterable> getArguments(); - @Nonnull Operation getName(); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/Literal.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/Literal.java index c1dde060d67..9f881ff033f 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/Literal.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/Literal.java @@ -22,7 +22,8 @@ import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nullable; +import org.jspecify.annotations.Nullable; + import javax.annotation.concurrent.Immutable; /** diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/NestedBooleanExpression.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/NestedBooleanExpression.java index 5c5414e245b..a7b8b47f17b 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/NestedBooleanExpression.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/NestedBooleanExpression.java @@ -25,7 +25,8 @@ import com.apple.foundationdb.relational.api.fluentsql.FluentVisitor; import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; +import org.jspecify.annotations.Nullable; + import javax.annotation.concurrent.Immutable; import java.util.Objects; @@ -37,20 +38,19 @@ @API(API.Status.EXPERIMENTAL) public class NestedBooleanExpression implements BooleanExpressionTrait { - @Nonnull private final BooleanExpressionTrait underlying; - public NestedBooleanExpression(@Nonnull final BooleanExpressionTrait value) { + public NestedBooleanExpression(final BooleanExpressionTrait value) { this.underlying = value; } - @Nonnull public BooleanExpressionTrait getValue() { return underlying; } @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + @Nullable + public R accept(FluentVisitor visitor, C context) { return visitor.visit(this, context); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/NumericExpressionTrait.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/NumericExpressionTrait.java index 9fa68cea7e0..b8cd0a4c08b 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/NumericExpressionTrait.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/NumericExpressionTrait.java @@ -22,7 +22,6 @@ import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; import javax.annotation.concurrent.Immutable; import java.util.List; @@ -33,28 +32,23 @@ */ @Immutable public interface NumericExpressionTrait extends ComparableExpressionTrait> { - @Nonnull - default NumericExpressionTrait add(@Nonnull final NumericExpressionTrait right) { + default NumericExpressionTrait add(final NumericExpressionTrait right) { return new NumericFunction<>(this.getType(), Operation.ADD, List.of(this, right)); } - @Nonnull - default NumericExpressionTrait sub(@Nonnull final NumericExpressionTrait right) { + default NumericExpressionTrait sub(final NumericExpressionTrait right) { return new NumericFunction<>(this.getType(), Operation.SUB, List.of(this, right)); } - @Nonnull - default NumericExpressionTrait div(@Nonnull final NumericExpressionTrait right) { + default NumericExpressionTrait div(final NumericExpressionTrait right) { return new NumericFunction<>(this.getType(), Operation.DIV, List.of(this, right)); } - @Nonnull - default NumericExpressionTrait mul(@Nonnull final NumericExpressionTrait right) { + default NumericExpressionTrait mul(final NumericExpressionTrait right) { return new NumericFunction<>(this.getType(), Operation.MUL, List.of(this, right)); } - @Nonnull - default NumericExpressionTrait mod(@Nonnull final NumericExpressionTrait right) { + default NumericExpressionTrait mod(final NumericExpressionTrait right) { return new NumericFunction<>(this.getType(), Operation.MOD, List.of(this, right)); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/NumericFunction.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/NumericFunction.java index 00027a0cf82..073356d0681 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/NumericFunction.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/NumericFunction.java @@ -25,9 +25,9 @@ import com.apple.foundationdb.relational.api.metadata.DataType; import com.google.common.collect.ImmutableList; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; +import org.jspecify.annotations.Nullable; + import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @@ -42,30 +42,25 @@ @API(API.Status.EXPERIMENTAL) public class NumericFunction implements NumericExpressionTrait, FunctionLike { - @Nonnull private final Operation operator; - @Nonnull private final ImmutableList> args; - @Nonnull private final N type; - public NumericFunction(@Nonnull final N type, - @Nonnull final Operation operator, - @Nonnull final List> args) { + public NumericFunction(final N type, + final Operation operator, + final List> args) { this.operator = operator; this.args = ImmutableList.copyOf(args); this.type = type; } - @Nonnull @Override public Iterable> getArguments() { return args; } - @Nonnull @Override public Operation getName() { return operator; @@ -73,11 +68,10 @@ public Operation getName() { @Nullable @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return visitor.visit((FunctionLike) this, context); } - @Nonnull @Override public N getType() { return type; diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/NumericLiteral.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/NumericLiteral.java index 41929221316..e2f19059eb1 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/NumericLiteral.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/NumericLiteral.java @@ -25,9 +25,9 @@ import com.apple.foundationdb.relational.api.fluentsql.FluentVisitor; import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; +import org.jspecify.annotations.Nullable; + import java.util.Objects; /** @@ -39,24 +39,22 @@ @API(API.Status.EXPERIMENTAL) public class NumericLiteral implements Literal, NumericExpressionTrait { - @Nonnull private final D type; @Nullable private final N literal; - public NumericLiteral(@Nonnull D type, @Nullable N literal) { + public NumericLiteral(D type, @Nullable N literal) { this.type = type; this.literal = literal; } @Nullable @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return visitor.visit(this, context); } - @Nonnull @Override public D getType() { return type; diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/Operation.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/Operation.java index 622b1489275..a1a887bf678 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/Operation.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/Operation.java @@ -20,8 +20,6 @@ package com.apple.foundationdb.relational.api.fluentsql.expression; -import javax.annotation.Nonnull; - /** * This is a placeholder of all supported operations. */ @@ -46,14 +44,12 @@ public enum Operation { GREATEST(Comparable.class), JAVA_CALL(Object.class); - @Nonnull private final Class type; - Operation(@Nonnull Class type) { + Operation(Class type) { this.type = type; } - @Nonnull public Class getType() { return type; } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ParsingFragment.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ParsingFragment.java index 837ca8e1df3..8681ebfc520 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ParsingFragment.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ParsingFragment.java @@ -25,8 +25,8 @@ import com.apple.foundationdb.relational.api.fluentsql.FluentVisitor; import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import org.jspecify.annotations.Nullable; + import java.util.Objects; /** @@ -47,21 +47,19 @@ */ @API(API.Status.EXPERIMENTAL) public class ParsingFragment implements ExpressionFragment { - @Nonnull private final String fragment; - @Nonnull private final T dataType; - public ParsingFragment(@Nonnull final T dataType, - @Nonnull final String fragment) { + public ParsingFragment(final T dataType, + final String fragment) { this.dataType = dataType; this.fragment = fragment; } @Nullable @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return visitor.visit(this, context); } @@ -70,7 +68,6 @@ public DataType getType() { return dataType; } - @Nonnull @Override public String getFragment() { return fragment; diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ScalarExpression.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ScalarExpression.java index 5b7f1fe2e92..2a0149a532c 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ScalarExpression.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/ScalarExpression.java @@ -22,7 +22,6 @@ import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; import java.util.List; /** @@ -31,12 +30,10 @@ * @param The type of the expression. */ public interface ScalarExpression extends Expression { - @Nonnull default BooleanExpressionTrait isNull() { return new BooleanFunction(Operation.IS_NULL, List.of(this)); } - @Nonnull default BooleanExpressionTrait isNotNull() { return new BooleanFunction(Operation.IS_NOT_NULL, List.of(this)); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/StringLiteral.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/StringLiteral.java index ee774022000..abe7143d526 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/StringLiteral.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/StringLiteral.java @@ -25,9 +25,9 @@ import com.apple.foundationdb.relational.api.fluentsql.FluentVisitor; import com.apple.foundationdb.relational.api.metadata.DataType; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; +import org.jspecify.annotations.Nullable; + import java.util.Objects; /** @@ -40,21 +40,19 @@ public class StringLiteral implements Literal { @Nullable private final String literal; - @Nonnull private final DataType.StringType type; - public StringLiteral(@Nonnull final DataType.StringType type, @Nullable String literal) { + public StringLiteral(final DataType.StringType type, @Nullable String literal) { this.type = type; this.literal = literal; } @Nullable @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return visitor.visit(this, context); } - @Nonnull @Override public DataType.StringType getType() { return type; diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/UserDefinedField.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/UserDefinedField.java index d50ad4ed65c..118fa17faf7 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/UserDefinedField.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/UserDefinedField.java @@ -31,8 +31,8 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Streams; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import org.jspecify.annotations.Nullable; + import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -48,19 +48,15 @@ @API(API.Status.EXPERIMENTAL) public final class UserDefinedField implements Field { - @Nonnull private final String name; - @Nonnull private final ImmutableList parts; - @Nonnull private final T type; - @Nonnull private final java.util.function.Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); - public UserDefinedField(@Nonnull T type, @Nonnull final Iterable parts) { + public UserDefinedField(T type, final Iterable parts) { this.name = Iterables.getLast(parts); this.parts = ImmutableList.copyOf(parts); this.type = type; @@ -68,84 +64,73 @@ public UserDefinedField(@Nonnull T type, @Nonnull final Iterable parts) @Nullable @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return visitor.visit(this, context); } - @Nonnull @Override public Iterable getParts() { return parts; } - @Nonnull @Override public T getType() { return type; } - @Nonnull @Override public String getName() { return name; } - @Nonnull @Override - public Field subField(@Nonnull final String part) { + public Field subField(final String part) { return subField(DataType.UnknownType.instance(), part); } - @Nonnull - public Field subField(@Nonnull final DataType type, - @Nonnull final String name) { + public Field subField(final DataType type, + final String name) { final var newFields = Streams.concat(parts.stream(), Stream.of(name)).collect(Collectors.toUnmodifiableList()); return new UserDefinedField<>(type, newFields); } - @Nonnull @Override public Mixins.BooleanField asBoolean() { expectingType(DataType.Code.BOOLEAN); return Field.super.asBoolean(); } - @Nonnull @Override public Mixins.IntField asInt() { expectingType(DataType.Code.INTEGER); return Field.super.asInt(); } - @Nonnull @Override public Mixins.LongField asLong() { expectingType(DataType.Code.LONG); return Field.super.asLong(); } - @Nonnull @Override public Mixins.FloatField asFloat() { expectingType(DataType.Code.FLOAT); return Field.super.asFloat(); } - @Nonnull @Override public Mixins.DoubleField asDouble() { expectingType(DataType.Code.DOUBLE); return Field.super.asDouble(); } - @Nonnull @Override public Mixins.StringField asString() { expectingType(DataType.Code.STRING); return Field.super.asString(); } - private void expectingType(@Nonnull final DataType.Code code) { + private void expectingType(final DataType.Code code) { if (type.getCode() != DataType.Code.UNKNOWN && !type.getCode().equals(code)) { throw new RelationalException("Type mismatch, expected type '" + code.name() + "', actual type '" + type.getCode().name() + "'", ErrorCode.DATATYPE_MISMATCH).toUncheckedWrappedException(); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/details/Mixins.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/details/Mixins.java index da1a359dae6..6bb77a82f41 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/details/Mixins.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/details/Mixins.java @@ -29,15 +29,15 @@ import com.google.common.base.Suppliers; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import org.jspecify.annotations.Nullable; + import java.util.function.Supplier; public interface Mixins { interface FieldEqualityTrait extends Field { @SuppressWarnings("PMD.CompareObjectsWithEquals") - default boolean equalsInternal(Object obj) { + default boolean equalsInternal(@Nullable Object obj) { if (obj == this) { return true; } @@ -88,26 +88,21 @@ default DataType.DoubleType getType() { } } - @Nonnull - static BooleanField asBoolean(@Nonnull final Field mixin, boolean isNullable) { + static BooleanField asBoolean(final Field mixin, boolean isNullable) { return new BooleanField() { - @Nonnull @SuppressWarnings("PMD.FieldNamingConventions") private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); - @Nonnull @Override public Iterable getParts() { return mixin.getParts(); } - @Nonnull @Override - public Field subField(@Nonnull String part) { + public Field subField(String part) { return mixin.subField(part); } - @Nonnull @Override public String getName() { return mixin.getName(); @@ -115,7 +110,7 @@ public String getName() { @Nullable @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return mixin.accept(visitor, context); } @@ -135,7 +130,7 @@ public int hashCode() { @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") @Override - public boolean equals(Object other) { + public boolean equals(@Nullable Object other) { return equalsInternal(other); } @@ -146,26 +141,21 @@ public String toString() { }; } - @Nonnull - static IntField asInt(@Nonnull final Field mixin, boolean isNullable) { + static IntField asInt(final Field mixin, boolean isNullable) { return new IntField() { - @Nonnull @SuppressWarnings("PMD.FieldNamingConventions") private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); - @Nonnull @Override public Iterable getParts() { return mixin.getParts(); } - @Nonnull @Override - public Field subField(@Nonnull String part) { + public Field subField(String part) { return mixin.subField(part); } - @Nonnull @Override public String getName() { return mixin.getName(); @@ -173,7 +163,7 @@ public String getName() { @Nullable @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return mixin.accept(visitor, context); } @@ -193,7 +183,7 @@ public int hashCode() { @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") @Override - public boolean equals(Object other) { + public boolean equals(@Nullable Object other) { return equalsInternal(other); } @@ -204,26 +194,21 @@ public String toString() { }; } - @Nonnull - static LongField asLong(@Nonnull final Field mixin, boolean isNullable) { + static LongField asLong(final Field mixin, boolean isNullable) { return new LongField() { - @Nonnull @SuppressWarnings("PMD.FieldNamingConventions") private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); - @Nonnull @Override public Iterable getParts() { return mixin.getParts(); } - @Nonnull @Override - public Field subField(@Nonnull String part) { + public Field subField(String part) { return mixin.subField(part); } - @Nonnull @Override public String getName() { return mixin.getName(); @@ -231,7 +216,7 @@ public String getName() { @Nullable @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return mixin.accept(visitor, context); } @@ -251,7 +236,7 @@ public int hashCode() { @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") @Override - public boolean equals(Object other) { + public boolean equals(@Nullable Object other) { return equalsInternal(other); } @@ -262,26 +247,21 @@ public String toString() { }; } - @Nonnull - static FloatField asFloat(@Nonnull final Field mixin, boolean isNullable) { + static FloatField asFloat(final Field mixin, boolean isNullable) { return new FloatField() { - @Nonnull @SuppressWarnings("PMD.FieldNamingConventions") private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); - @Nonnull @Override public Iterable getParts() { return mixin.getParts(); } - @Nonnull @Override - public Field subField(@Nonnull String part) { + public Field subField(String part) { return mixin.subField(part); } - @Nonnull @Override public String getName() { return mixin.getName(); @@ -289,7 +269,7 @@ public String getName() { @Nullable @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return mixin.accept(visitor, context); } @@ -309,7 +289,7 @@ public int hashCode() { @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") @Override - public boolean equals(Object other) { + public boolean equals(@Nullable Object other) { return equalsInternal(other); } @@ -320,26 +300,21 @@ public String toString() { }; } - @Nonnull - static DoubleField asDouble(@Nonnull final Field mixin, boolean isNullable) { + static DoubleField asDouble(final Field mixin, boolean isNullable) { return new DoubleField() { - @Nonnull @SuppressWarnings("PMD.FieldNamingConventions") private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); - @Nonnull @Override public Iterable getParts() { return mixin.getParts(); } - @Nonnull @Override - public Field subField(@Nonnull String part) { + public Field subField(String part) { return mixin.subField(part); } - @Nonnull @Override public String getName() { return mixin.getName(); @@ -347,7 +322,7 @@ public String getName() { @Nullable @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return mixin.accept(visitor, context); } @@ -367,7 +342,7 @@ public int hashCode() { @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") @Override - public boolean equals(Object other) { + public boolean equals(@Nullable Object other) { return equalsInternal(other); } @@ -378,26 +353,21 @@ public String toString() { }; } - @Nonnull - static StringField asString(@Nonnull final Field mixin, boolean isNullable) { + static StringField asString(final Field mixin, boolean isNullable) { return new StringField() { - @Nonnull @SuppressWarnings("PMD.FieldNamingConventions") private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); - @Nonnull @Override public Iterable getParts() { return mixin.getParts(); } - @Nonnull @Override - public Field subField(@Nonnull String part) { + public Field subField(String part) { return mixin.subField(part); } - @Nonnull @Override public String getName() { return mixin.getName(); @@ -405,7 +375,7 @@ public String getName() { @Nullable @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return mixin.accept(visitor, context); } @@ -425,7 +395,7 @@ public int hashCode() { @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") @Override - public boolean equals(Object other) { + public boolean equals(@Nullable Object other) { return equalsInternal(other); } @@ -438,7 +408,7 @@ public String toString() { interface ExpressionFragmentEqualityTrait extends ExpressionFragment { @SuppressWarnings("PMD.CompareObjectsWithEquals") - default boolean equalsInternal(Object obj) { + default boolean equalsInternal(@Nullable Object obj) { if (obj == this) { return true; } @@ -499,10 +469,8 @@ default DataType.DoubleType getType() { } } - @Nonnull static BooleanExpressionFragment asBoolean(ExpressionFragment mixin, boolean isNullable) { return new BooleanExpressionFragment() { - @Nonnull @Override public String getFragment() { return mixin.getFragment(); @@ -510,7 +478,7 @@ public String getFragment() { @Nullable @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return mixin.accept(visitor, context); } @@ -526,7 +494,7 @@ public String toString() { @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") @Override - public boolean equals(Object obj) { + public boolean equals(@Nullable Object obj) { return equalsInternal(obj); } @@ -537,10 +505,8 @@ public int hashCode() { }; } - @Nonnull static IntExpressionFragment asInt(ExpressionFragment mixin, boolean isNullable) { return new IntExpressionFragment() { - @Nonnull @Override public String getFragment() { return mixin.getFragment(); @@ -548,7 +514,7 @@ public String getFragment() { @Nullable @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return mixin.accept(visitor, context); } @@ -564,7 +530,7 @@ public String toString() { @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") @Override - public boolean equals(Object obj) { + public boolean equals(@Nullable Object obj) { return equalsInternal(obj); } @@ -575,10 +541,8 @@ public int hashCode() { }; } - @Nonnull static LongExpressionFragment asLong(ExpressionFragment mixin, boolean isNullable) { return new LongExpressionFragment() { - @Nonnull @Override public String getFragment() { return mixin.getFragment(); @@ -586,7 +550,7 @@ public String getFragment() { @Nullable @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return mixin.accept(visitor, context); } @@ -602,7 +566,7 @@ public String toString() { @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") @Override - public boolean equals(Object obj) { + public boolean equals(@Nullable Object obj) { return equalsInternal(obj); } @@ -613,10 +577,8 @@ public int hashCode() { }; } - @Nonnull static FloatExpressionFragment asFloat(ExpressionFragment mixin, boolean isNullable) { return new FloatExpressionFragment() { - @Nonnull @Override public String getFragment() { return mixin.getFragment(); @@ -624,7 +586,7 @@ public String getFragment() { @Nullable @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return mixin.accept(visitor, context); } @@ -640,7 +602,7 @@ public String toString() { @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") @Override - public boolean equals(Object obj) { + public boolean equals(@Nullable Object obj) { return equalsInternal(obj); } @@ -651,10 +613,8 @@ public int hashCode() { }; } - @Nonnull static DoubleExpressionFragment asDouble(ExpressionFragment mixin, boolean isNullable) { return new DoubleExpressionFragment() { - @Nonnull @Override public String getFragment() { return mixin.getFragment(); @@ -662,7 +622,7 @@ public String getFragment() { @Nullable @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return mixin.accept(visitor, context); } @@ -678,7 +638,7 @@ public String toString() { @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") @Override - public boolean equals(Object obj) { + public boolean equals(@Nullable Object obj) { return equalsInternal(obj); } @@ -689,10 +649,8 @@ public int hashCode() { }; } - @Nonnull static StringExpressionFragment asString(ExpressionFragment mixin, boolean isNullable) { return new StringExpressionFragment() { - @Nonnull @Override public String getFragment() { return mixin.getFragment(); @@ -700,7 +658,7 @@ public String getFragment() { @Nullable @Override - public R accept(@Nonnull FluentVisitor visitor, @Nonnull C context) { + public R accept(FluentVisitor visitor, C context) { return mixin.accept(visitor, context); } @@ -716,7 +674,7 @@ public String toString() { @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") @Override - public boolean equals(Object obj) { + public boolean equals(@Nullable Object obj) { return equalsInternal(obj); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/details/package-info.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/details/package-info.java index 016d06a06dd..d63474d1c0a 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/details/package-info.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/details/package-info.java @@ -22,4 +22,7 @@ * Details involving static-typing of structured queries' expressions. */ +@NullMarked package com.apple.foundationdb.relational.api.fluentsql.expression.details; + +import org.jspecify.annotations.NullMarked; diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/package-info.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/package-info.java index 7bed9f13ff6..f1ddfb21cb5 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/package-info.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/expression/package-info.java @@ -22,4 +22,7 @@ * Toolbox of expressions used for constructing structured queries. */ +@NullMarked package com.apple.foundationdb.relational.api.fluentsql.expression; + +import org.jspecify.annotations.NullMarked; diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/package-info.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/package-info.java index 17193ba2ab9..2456abead9e 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/package-info.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/package-info.java @@ -22,4 +22,7 @@ * API for constructing statically-typed SQL statements. */ +@NullMarked package com.apple.foundationdb.relational.api.fluentsql; + +import org.jspecify.annotations.NullMarked; diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/statement/StatementBuilderFactory.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/statement/StatementBuilderFactory.java index 0ff0ec1fa19..a8ce4cb1796 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/statement/StatementBuilderFactory.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/statement/StatementBuilderFactory.java @@ -22,7 +22,6 @@ import com.apple.foundationdb.relational.api.ParseTreeInfo; -import javax.annotation.Nonnull; import javax.annotation.concurrent.NotThreadSafe; import java.util.List; import java.util.Map; @@ -30,11 +29,9 @@ @NotThreadSafe public interface StatementBuilderFactory { - @Nonnull UpdateStatement.Builder updateStatementBuilder(); - @Nonnull - UpdateStatement.Builder updateStatementBuilder(@Nonnull String updateQuery); + UpdateStatement.Builder updateStatementBuilder(String updateQuery); /** * Generates an {@link UpdateStatement.Builder} from a given SQL statement using the provided map of column synonyms. @@ -46,11 +43,9 @@ public interface StatementBuilderFactory { * @apiNote this method should not exist, instead the metadata itself should hold the synonym information. * TODO: remove once (TODO ([POST] Synonym support in Relational Metadata) is implemented. */ - @Nonnull - UpdateStatement.Builder updateStatementBuilder(@Nonnull String updateQuery, @Nonnull Map> columnSynonyms); + UpdateStatement.Builder updateStatementBuilder(String updateQuery, Map> columnSynonyms); - @Nonnull - UpdateStatement.Builder updateStatementBuilder(@Nonnull ParseTreeInfo parseTree); + UpdateStatement.Builder updateStatementBuilder(ParseTreeInfo parseTree); /** * Generates an {@link UpdateStatement.Builder} from a given update parse tree using the provided map of column synonyms. @@ -62,6 +57,5 @@ public interface StatementBuilderFactory { * @apiNote this method should not exist, instead the metadata itself should hold the synonym information. * TODO: remove once (TODO ([POST] Synonym support in Relational Metadata) is implemented. */ - @Nonnull - UpdateStatement.Builder updateStatementBuilder(@Nonnull ParseTreeInfo parseTree, @Nonnull Map> columnSynonyms); + UpdateStatement.Builder updateStatementBuilder(ParseTreeInfo parseTree, Map> columnSynonyms); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/statement/StructuredQuery.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/statement/StructuredQuery.java index c8df162f433..641239d8fcc 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/statement/StructuredQuery.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/statement/StructuredQuery.java @@ -20,7 +20,6 @@ package com.apple.foundationdb.relational.api.fluentsql.statement; -import javax.annotation.Nonnull; import javax.annotation.concurrent.Immutable; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -34,22 +33,18 @@ enum QueryOptions { DRY_RUN("DRY RUN"), PLAN_RIGHT_DEEP("PLAN RIGHT DEEP"); - @Nonnull private final String name; - QueryOptions(@Nonnull final String name) { + QueryOptions(final String name) { this.name = name; } - @Nonnull public String getName() { return name; } } - @Nonnull PreparedStatement getPreparedStatement() throws SQLException; - @Nonnull String getSqlQuery(); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/statement/UpdateStatement.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/statement/UpdateStatement.java index 5267334e1fa..a1a3516cd90 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/statement/UpdateStatement.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/statement/UpdateStatement.java @@ -26,8 +26,8 @@ import com.apple.foundationdb.relational.api.fluentsql.expression.ExpressionFactory; import com.apple.foundationdb.relational.api.fluentsql.expression.Field; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import org.jspecify.annotations.Nullable; + import javax.annotation.concurrent.Immutable; import java.util.List; import java.util.Map; @@ -35,68 +35,49 @@ @Immutable public interface UpdateStatement extends StructuredQuery { - @Nonnull Map, Expression> getSetClauses(); - @Nonnull List> getReturning(); @Nullable BooleanExpressionTrait getWhereClause(); - @Nonnull Set getOptions(); - @Nonnull String getTable(); interface Builder { - @Nonnull Map, Expression> getSetClauses(); - @Nonnull - Builder addSetClause(@Nonnull Field field, @Nonnull Expression newValue); + Builder addSetClause(Field field, Expression newValue); - @Nonnull Builder clearSetClauses(); - @Nonnull - Builder removeSetClause(@Nonnull Field field); + Builder removeSetClause(Field field); - @Nonnull List> getReturning(); - @Nonnull - Builder addReturning(@Nonnull Expression expression); + Builder addReturning(Expression expression); - @Nonnull Builder clearReturning(); @Nullable BooleanExpressionTrait getWhereClause(); - @Nonnull - Builder addWhereClause(@Nonnull BooleanExpressionTrait expression); + Builder addWhereClause(BooleanExpressionTrait expression); - @Nonnull Builder clearWhereClause(); - @Nonnull - Builder withOption(@Nonnull QueryOptions... options); + Builder withOption(QueryOptions... options); - @Nonnull Set getOptions(); - @Nonnull String getTable(); - @Nonnull - Builder setTable(@Nonnull String table); + Builder setTable(String table); - @Nonnull - Builder resolveSetFields(@Nonnull ExpressionFactory expressionFactory); + Builder resolveSetFields(ExpressionFactory expressionFactory); - @Nonnull UpdateStatement build() throws RelationalException; } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/statement/package-info.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/statement/package-info.java index 62784913fed..57179544562 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/statement/package-info.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/fluentsql/statement/package-info.java @@ -22,4 +22,7 @@ * Structured query statement construction API. */ +@NullMarked package com.apple.foundationdb.relational.api.fluentsql.statement; + +import org.jspecify.annotations.NullMarked; diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Column.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Column.java index cff6ea4f9d5..60fcd1e6617 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Column.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Column.java @@ -20,8 +20,6 @@ package com.apple.foundationdb.relational.api.metadata; -import javax.annotation.Nonnull; - /** * Represents a Relational {@code Column} metadata being part of a {@link Table}. */ @@ -35,7 +33,7 @@ public interface Column extends Metadata { DataType getDataType(); @Override - default void accept(@Nonnull final Visitor visitor) { + default void accept(final Visitor visitor) { visitor.visit(this); } } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/DataType.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/DataType.java index cd744fc0f9b..5afe9aaf70f 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/DataType.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/DataType.java @@ -32,8 +32,8 @@ import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableList; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import org.jspecify.annotations.Nullable; + import java.sql.SQLException; import java.sql.Types; import java.util.HashMap; @@ -59,7 +59,6 @@ * using a type-resolution map, one example of doing this can be found in build() method in RecordLayerSchemaTemplate.Builder. */ public abstract class DataType { - @Nonnull private static final Map typeCodeJdbcTypeMap; static { @@ -85,10 +84,9 @@ public abstract class DataType { private final boolean isPrimitive; - @Nonnull private final Code code; - private DataType(boolean isNullable, boolean isPrimitive, @Nonnull Code code) { + private DataType(boolean isNullable, boolean isPrimitive, Code code) { this.isNullable = isNullable; this.isPrimitive = isPrimitive; this.code = code; @@ -99,7 +97,6 @@ private DataType(boolean isNullable, boolean isPrimitive, @Nonnull Code code) { * * @return The {@link Code} of the type. */ - @Nonnull public Code getCode() { return code; } @@ -110,7 +107,11 @@ public Code getCode() { * @return a corresponding JDBC SQL type. */ public int getJdbcSqlCode() { - return typeCodeJdbcTypeMap.get(Objects.requireNonNull(getCode())); + final Integer sqlCode = typeCodeJdbcTypeMap.get(getCode()); + if (sqlCode == null) { + throw new IllegalStateException("No JDBC SQL type mapping for code " + getCode()); + } + return sqlCode; } /** @@ -144,7 +145,6 @@ public boolean isNullable() { * @param isNullable the nullable flag of the newly created {@link DataType} instance. * @return a new instance of {@code this} type with {@code nullable} field set accordingly. */ - @Nonnull public abstract DataType withNullable(boolean isNullable); /** @@ -153,8 +153,7 @@ public boolean isNullable() { * @param resolutionMap A list of all resolved types used for resolving this type. * @return a new {@link DataType} which is resolved. */ - @Nonnull - public abstract DataType resolve(@Nonnull Map resolutionMap); + public abstract DataType resolve(Map resolutionMap); /** * Trait representing a type that has a name. @@ -166,7 +165,6 @@ public interface Named { * * @return the name of the {@link DataType}. */ - @Nonnull String getName(); } @@ -185,7 +183,6 @@ default boolean hasIdenticalStructure(Object object) { } } - @Nonnull public static DataType getDataTypeFromObject(@Nullable Object obj) { try { if (obj == null) { @@ -231,26 +228,22 @@ public static DataType getDataTypeFromObject(@Nullable Object obj) { // todo: this is ugly, DataType should be an interface. public abstract static class NumericType extends DataType { - private NumericType(boolean isNullable, boolean isPrimitive, @Nonnull Code code) { + private NumericType(boolean isNullable, boolean isPrimitive, Code code) { super(isNullable, isPrimitive, code); } } public static final class BooleanType extends DataType { - @Nonnull private static final BooleanType NOT_NULLABLE_INSTANCE = new BooleanType(false); - @Nonnull private static final BooleanType NULLABLE_INSTANCE = new BooleanType(true); - @Nonnull private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); private BooleanType(boolean isNullable) { super(isNullable, true, Code.BOOLEAN); } - @Nonnull @Override public DataType withNullable(boolean isNullable) { if (isNullable) { @@ -265,18 +258,15 @@ public boolean isResolved() { return true; } - @Nonnull @Override - public DataType resolve(@Nonnull final Map resolutionMap) { + public DataType resolve(final Map resolutionMap) { return this; } - @Nonnull public static BooleanType nullable() { return NULLABLE_INSTANCE; } - @Nonnull public static BooleanType notNullable() { return NOT_NULLABLE_INSTANCE; } @@ -310,13 +300,10 @@ public String toString() { } public static final class IntegerType extends NumericType { - @Nonnull private static final IntegerType NOT_NULLABLE_INSTANCE = new IntegerType(false); - @Nonnull private static final IntegerType NULLABLE_INSTANCE = new IntegerType(true); - @Nonnull private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); private IntegerType(boolean isNullable) { @@ -324,7 +311,6 @@ private IntegerType(boolean isNullable) { } @Override - @Nonnull public DataType withNullable(boolean isNullable) { if (isNullable) { return Primitives.NULLABLE_INTEGER.type(); @@ -338,18 +324,15 @@ public boolean isResolved() { return true; } - @Nonnull @Override - public DataType resolve(@Nonnull final Map resolutionMap) { + public DataType resolve(final Map resolutionMap) { return this; } - @Nonnull public static IntegerType nullable() { return NULLABLE_INSTANCE; } - @Nonnull public static IntegerType notNullable() { return NOT_NULLABLE_INSTANCE; } @@ -383,13 +366,10 @@ public String toString() { } public static final class LongType extends NumericType { - @Nonnull private static final LongType NOT_NULLABLE_INSTANCE = new LongType(false); - @Nonnull private static final LongType NULLABLE_INSTANCE = new LongType(true); - @Nonnull private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); private LongType(boolean isNullable) { @@ -397,7 +377,6 @@ private LongType(boolean isNullable) { } @Override - @Nonnull public DataType withNullable(boolean isNullable) { if (isNullable) { return Primitives.NULLABLE_LONG.type(); @@ -411,9 +390,8 @@ public boolean isResolved() { return true; } - @Nonnull @Override - public DataType resolve(@Nonnull final Map resolutionMap) { + public DataType resolve(final Map resolutionMap) { return this; } @@ -444,25 +422,20 @@ public String toString() { return "long" + (isNullable() ? " ∪ āˆ…" : ""); } - @Nonnull public static LongType nullable() { return NULLABLE_INSTANCE; } - @Nonnull public static LongType notNullable() { return NOT_NULLABLE_INSTANCE; } } public static final class FloatType extends NumericType { - @Nonnull private static final FloatType NOT_NULLABLE_INSTANCE = new FloatType(false); - @Nonnull private static final FloatType NULLABLE_INSTANCE = new FloatType(true); - @Nonnull private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); private FloatType(boolean isNullable) { @@ -470,7 +443,6 @@ private FloatType(boolean isNullable) { } @Override - @Nonnull public DataType withNullable(boolean isNullable) { if (isNullable) { return Primitives.NULLABLE_FLOAT.type(); @@ -484,9 +456,8 @@ public boolean isResolved() { return true; } - @Nonnull @Override - public DataType resolve(@Nonnull final Map resolutionMap) { + public DataType resolve(final Map resolutionMap) { return this; } @@ -517,24 +488,19 @@ public String toString() { return "float" + (isNullable() ? " ∪ āˆ…" : ""); } - @Nonnull public static FloatType nullable() { return NULLABLE_INSTANCE; } - @Nonnull public static FloatType notNullable() { return NOT_NULLABLE_INSTANCE; } } public static final class DoubleType extends NumericType { - @Nonnull private static final DoubleType NOT_NULLABLE_INSTANCE = new DoubleType(false); - @Nonnull private static final DoubleType NULLABLE_INSTANCE = new DoubleType(true); - @Nonnull private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); private DoubleType(boolean isNullable) { @@ -542,7 +508,6 @@ private DoubleType(boolean isNullable) { } @Override - @Nonnull public DataType withNullable(boolean isNullable) { if (isNullable) { return Primitives.NULLABLE_DOUBLE.type(); @@ -556,18 +521,15 @@ public boolean isResolved() { return true; } - @Nonnull @Override - public DataType resolve(@Nonnull final Map resolutionMap) { + public DataType resolve(final Map resolutionMap) { return this; } - @Nonnull public static DoubleType nullable() { return NULLABLE_INSTANCE; } - @Nonnull public static DoubleType notNullable() { return NOT_NULLABLE_INSTANCE; } @@ -601,13 +563,10 @@ public String toString() { } public static final class StringType extends DataType { - @Nonnull private static final StringType NOT_NULLABLE_INSTANCE = new StringType(false); - @Nonnull private static final StringType NULLABLE_INSTANCE = new StringType(true); - @Nonnull private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); private StringType(boolean isNullable) { @@ -615,7 +574,6 @@ private StringType(boolean isNullable) { } @Override - @Nonnull public DataType withNullable(boolean isNullable) { if (isNullable) { return Primitives.NULLABLE_STRING.type(); @@ -629,9 +587,8 @@ public boolean isResolved() { return true; } - @Nonnull @Override - public DataType resolve(@Nonnull final Map resolutionMap) { + public DataType resolve(final Map resolutionMap) { return this; } @@ -662,25 +619,20 @@ public String toString() { return "string" + (isNullable() ? " ∪ āˆ…" : ""); } - @Nonnull public static StringType nullable() { return NULLABLE_INSTANCE; } - @Nonnull public static StringType notNullable() { return NOT_NULLABLE_INSTANCE; } } public static final class BytesType extends DataType { - @Nonnull private static final BytesType NOT_NULLABLE_INSTANCE = new BytesType(false); - @Nonnull private static final BytesType NULLABLE_INSTANCE = new BytesType(true); - @Nonnull private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); private BytesType(boolean isNullable) { @@ -688,7 +640,6 @@ private BytesType(boolean isNullable) { } @Override - @Nonnull public DataType withNullable(boolean isNullable) { if (isNullable) { return Primitives.NULLABLE_BYTES.type(); @@ -702,18 +653,15 @@ public boolean isResolved() { return true; } - @Nonnull @Override - public DataType resolve(@Nonnull Map resolutionMap) { + public DataType resolve(Map resolutionMap) { return this; } - @Nonnull public static BytesType nullable() { return NULLABLE_INSTANCE; } - @Nonnull public static BytesType notNullable() { return NOT_NULLABLE_INSTANCE; } @@ -751,7 +699,6 @@ public static final class VectorType extends DataType { private final int dimensions; - @Nonnull private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); private VectorType(final boolean isNullable, int precision, int dimensions) { @@ -765,7 +712,6 @@ public boolean isResolved() { return true; } - @Nonnull @Override public DataType withNullable(final boolean isNullable) { if (isNullable == this.isNullable()) { @@ -774,9 +720,8 @@ public DataType withNullable(final boolean isNullable) { return new VectorType(isNullable, precision, dimensions); } - @Nonnull @Override - public DataType resolve(@Nonnull final Map resolutionMap) { + public DataType resolve(final Map resolutionMap) { return this; } @@ -813,20 +758,16 @@ public String toString() { return "vector(p=" + precision + ", d=" + dimensions + ")" + (isNullable() ? " ∪ āˆ…" : ""); } - @Nonnull public static VectorType of(int precision, int dimensions, boolean isNullable) { return new VectorType(isNullable, precision, dimensions); } } public static final class VersionType extends DataType { - @Nonnull private static final VersionType NOT_NULLABLE_INSTANCE = new VersionType(false); - @Nonnull private static final VersionType NULLABLE_INSTANCE = new VersionType(true); - @Nonnull private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); private VersionType(boolean isNullable) { @@ -834,7 +775,6 @@ private VersionType(boolean isNullable) { } @Override - @Nonnull public DataType withNullable(boolean isNullable) { if (isNullable) { return Primitives.NULLABLE_VERSION.type(); @@ -848,18 +788,15 @@ public boolean isResolved() { return true; } - @Nonnull @Override - public DataType resolve(@Nonnull Map resolutionMap) { + public DataType resolve(Map resolutionMap) { return this; } - @Nonnull public static VersionType nullable() { return NULLABLE_INSTANCE; } - @Nonnull public static VersionType notNullable() { return NOT_NULLABLE_INSTANCE; } @@ -893,13 +830,10 @@ public String toString() { } public static final class UuidType extends DataType { - @Nonnull private static final UuidType NOT_NULLABLE_INSTANCE = new UuidType(false); - @Nonnull private static final UuidType NULLABLE_INSTANCE = new UuidType(true); - @Nonnull private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); private UuidType(boolean isNullable) { @@ -907,7 +841,6 @@ private UuidType(boolean isNullable) { } @Override - @Nonnull public DataType withNullable(boolean isNullable) { if (isNullable) { return Primitives.NULLABLE_UUID.type(); @@ -921,18 +854,15 @@ public boolean isResolved() { return true; } - @Nonnull @Override - public DataType resolve(@Nonnull Map resolutionMap) { + public DataType resolve(Map resolutionMap) { return this; } - @Nonnull public static UuidType nullable() { return NULLABLE_INSTANCE; } - @Nonnull public static UuidType notNullable() { return NOT_NULLABLE_INSTANCE; } @@ -967,10 +897,8 @@ public String toString() { public static final class NullType extends DataType { - @Nonnull private static final NullType INSTANCE = new NullType(); - @Nonnull private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); private NullType() { @@ -978,7 +906,6 @@ private NullType() { } @Override - @Nonnull public DataType withNullable(boolean isNullable) { if (isNullable) { return Primitives.NULL.type(); @@ -992,13 +919,11 @@ public boolean isResolved() { return true; } - @Nonnull @Override - public DataType resolve(@Nonnull Map resolutionMap) { + public DataType resolve(Map resolutionMap) { return this; } - @Nonnull public static NullType nullable() { return INSTANCE; } @@ -1032,32 +957,26 @@ public String toString() { } public static final class EnumType extends DataType implements Named { - @Nonnull private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); - @Nonnull private final String name; - @Nonnull private final List values; public static class EnumValue { - @Nonnull private final String name; private final int number; - private EnumValue(@Nonnull final String name, int number) { + private EnumValue(final String name, int number) { this.name = name; this.number = number; } - @Nonnull - public static EnumValue of(@Nonnull final String name, int number) { + public static EnumValue of(final String name, int number) { return new EnumValue(name, number); } - @Nonnull public String getName() { return name; } @@ -1094,26 +1013,23 @@ public String toString() { return "enum(" + name + "){" + values.stream().map(EnumValue::toString).collect(Collectors.joining(",")) + "}"; } - private EnumType(@Nonnull String name, @Nonnull final List values, boolean isNullable) { + private EnumType(String name, final List values, boolean isNullable) { super(isNullable, true, Code.ENUM); this.name = name; this.values = values; } - @Nonnull public List getValues() { return values; } - @Nonnull - public static EnumType from(@Nonnull final String name, @Nonnull final List values, boolean isNullable) { + public static EnumType from(final String name, final List values, boolean isNullable) { Assert.thatUnchecked(!values.isEmpty()); Assert.thatUnchecked(!name.isEmpty()); return new EnumType(name, values, isNullable); } @Override - @Nonnull public EnumType withNullable(boolean isNullable) { if (isNullable == isNullable()) { return this; @@ -1122,7 +1038,6 @@ public EnumType withNullable(boolean isNullable) { } @Override - @Nonnull public String getName() { return name; } @@ -1132,9 +1047,8 @@ public boolean isResolved() { return true; } - @Nonnull @Override - public DataType resolve(@Nonnull final Map resolutionMap) { + public DataType resolve(final Map resolutionMap) { return this; } @@ -1164,34 +1078,28 @@ public boolean equals(Object other) { } public static final class ArrayType extends DataType implements CompositeType { - @Nonnull private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); - @Nonnull private final DataType elementType; - private ArrayType(boolean isNullable, @Nonnull final DataType elementType) { + private ArrayType(boolean isNullable, final DataType elementType) { super(isNullable, false, Code.ARRAY); this.elementType = elementType; } - @Nonnull - public static ArrayType from(@Nonnull final DataType type) { + public static ArrayType from(final DataType type) { return from(type, false); } - @Nonnull - public static ArrayType from(@Nonnull final DataType type, boolean isNullable) { + public static ArrayType from(final DataType type, boolean isNullable) { return new ArrayType(isNullable, type); } - @Nonnull public DataType getElementType() { return elementType; } @Override - @Nonnull public ArrayType withNullable(boolean isNullable) { if (isNullable == isNullable()) { return this; @@ -1204,9 +1112,8 @@ public boolean isResolved() { return elementType.isResolved(); } - @Nonnull @Override - public DataType resolve(@Nonnull final Map resolutionMap) { + public DataType resolve(final Map resolutionMap) { if (isResolved()) { return this; } else { @@ -1264,65 +1171,53 @@ public boolean hasIdenticalStructure(final Object other) { } public static final class StructType extends DataType implements Named, CompositeType { - @Nonnull private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); - @Nonnull private final List fields; - @Nonnull private final String name; - @Nonnull private final Supplier resolvedSupplier = Suppliers.memoize(this::calculateResolved); - private StructType(@Nonnull final String name, boolean isNullable, @Nonnull final List fields) { + private StructType(final String name, boolean isNullable, final List fields) { super(isNullable, false, Code.STRUCT); this.name = name; this.fields = ImmutableList.copyOf(fields); } - @Nonnull public List getFields() { return fields; } @Override - @Nonnull public String getName() { return name; } public static class Field { - @Nonnull private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); - @Nonnull private final String name; - @Nonnull private final DataType type; private final int index; - private Field(@Nonnull final String name, @Nonnull final DataType type, int index) { + private Field(final String name, final DataType type, int index) { Assert.thatUnchecked(index >= 0); this.name = name; this.type = type; this.index = index; } - @Nonnull - public static Field from(@Nonnull final String name, @Nonnull final DataType type, int index) { + public static Field from(final String name, final DataType type, int index) { return new Field(name, type, index); } - @Nonnull public String getName() { return name; } - @Nonnull public DataType getType() { return type; } @@ -1361,13 +1256,11 @@ public String toString() { } } - @Nonnull - public static StructType from(@Nonnull final String name, @Nonnull final List fields, boolean isNullable) { + public static StructType from(final String name, final List fields, boolean isNullable) { return new StructType(name, isNullable, fields); } @Override - @Nonnull public StructType withNullable(boolean isNullable) { if (isNullable == isNullable()) { return this; @@ -1389,9 +1282,8 @@ public boolean isResolved() { return resolvedSupplier.get(); } - @Nonnull @Override - public DataType resolve(@Nonnull final Map resolutionMap) { + public DataType resolve(final Map resolutionMap) { if (isResolved()) { return this; } else { @@ -1475,24 +1367,20 @@ public String toString() { * To see how this type is used as resolved, check build() method in RecordLayerSchemaTemplate.Builder. */ public static final class UnresolvedType extends DataType implements Named { - @Nonnull private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); - @Nonnull private final String name; - private UnresolvedType(@Nonnull final String name, boolean isNullable) { + private UnresolvedType(final String name, boolean isNullable) { super(isNullable, false, Code.UNKNOWN); this.name = name; } - @Nonnull @Override public String getName() { return name; } - @Nonnull @Override public DataType withNullable(boolean isNullable) { if (isNullable == isNullable()) { @@ -1501,8 +1389,7 @@ public DataType withNullable(boolean isNullable) { return new UnresolvedType(name, isNullable); } - @Nonnull - public static UnresolvedType of(@Nonnull final String name, boolean isNullable) { + public static UnresolvedType of(final String name, boolean isNullable) { return new UnresolvedType(name, isNullable); } @@ -1511,11 +1398,13 @@ public boolean isResolved() { return false; } - @Nonnull @Override - public DataType resolve(@Nonnull final Map resolutionMap) { - Assert.thatUnchecked(resolutionMap.containsKey(name), ErrorCode.INTERNAL_ERROR, "Could not find type %s", name); - return ((DataType) resolutionMap.get(name)).withNullable(isNullable()); + public DataType resolve(final Map resolutionMap) { + final Named resolved = resolutionMap.get(name); + if (resolved == null) { + throw Assert.failUnchecked(ErrorCode.INTERNAL_ERROR, "Could not find type " + name); + } + return ((DataType) resolved).withNullable(isNullable()); } private int computeHashCode() { @@ -1543,17 +1432,14 @@ public boolean equals(Object other) { } public static final class UnknownType extends DataType { - @Nonnull private final Supplier hashCodeSupplier = Suppliers.memoize(this::computeHashCode); - @Nonnull private static final UnknownType INSTANCE = new UnknownType(); private UnknownType() { super(false, false, Code.UNKNOWN); } - @Nonnull @Override public DataType withNullable(boolean isNullable) { throw new RelationalException("Attempt to set nullability on unknown type", ErrorCode.INTERNAL_ERROR).toUncheckedWrappedException(); @@ -1564,9 +1450,8 @@ public boolean isResolved() { return false; } - @Nonnull @Override - public DataType resolve(@Nonnull Map resolutionMap) { + public DataType resolve(Map resolutionMap) { throw new RelationalException("Can not resolve unknown type", ErrorCode.INTERNAL_ERROR).toUncheckedWrappedException(); } @@ -1585,7 +1470,6 @@ public boolean equals(Object o) { return super.equals(o); } - @Nonnull public static UnknownType instance() { return INSTANCE; } @@ -1596,7 +1480,6 @@ public String toString() { } } - @Nonnull public enum Code { BOOLEAN, LONG, @@ -1616,7 +1499,6 @@ public enum Code { } @SuppressWarnings("PMD.AvoidFieldNameMatchingTypeName") - @Nonnull public enum Primitives { BOOLEAN(BooleanType.notNullable()), LONG(LongType.notNullable()), @@ -1639,14 +1521,12 @@ public enum Primitives { NULL(NullType.INSTANCE) ; - @Nonnull private final DataType datatype; - Primitives(@Nonnull DataType datatype) { + Primitives(DataType datatype) { this.datatype = datatype; } - @Nonnull public DataType type() { return datatype; } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Index.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Index.java index efa5789949c..c9e72f4154a 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Index.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Index.java @@ -20,8 +20,6 @@ package com.apple.foundationdb.relational.api.metadata; -import javax.annotation.Nonnull; - /** * An {@code Index} metadata that contains information an underlying index data structure of a {@link Table}. * @@ -37,7 +35,6 @@ public interface Index extends Metadata { * * @return The name of the {@link Table} that owns the {@code index}. */ - @Nonnull String getTableName(); /** @@ -50,7 +47,6 @@ public interface Index extends Metadata { * instead we should an {@code enum} structure. * TODO (yhatem) return {@code enum} instead. */ - @Nonnull String getIndexType(); /** @@ -68,7 +64,7 @@ public interface Index extends Metadata { boolean isSparse(); @Override - default void accept(@Nonnull final Visitor visitor) { + default void accept(final Visitor visitor) { visitor.visit(this); } } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/InvokedRoutine.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/InvokedRoutine.java index 1b3f2d13edb..746c9b7bcfa 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/InvokedRoutine.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/InvokedRoutine.java @@ -20,8 +20,6 @@ package com.apple.foundationdb.relational.api.metadata; -import javax.annotation.Nonnull; - /** * Base interface for all invoked routines, such as SQL functions. */ @@ -38,16 +36,14 @@ enum Language { * * @return The description of the routine. */ - @Nonnull String getDescription(); - @Nonnull String getNormalizedDescription(); boolean isTemporary(); @Override - default void accept(@Nonnull final Visitor visitor) { + default void accept(final Visitor visitor) { visitor.visit(this); } } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Metadata.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Metadata.java index 56457333e5e..bfef8057390 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Metadata.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Metadata.java @@ -20,8 +20,6 @@ package com.apple.foundationdb.relational.api.metadata; -import javax.annotation.Nonnull; - /** * Base interface for Relational metadata. A meta datum has a specific name, and is usually part of a metadata hierarchy * that can be visited using a general {@link Visitor}. @@ -33,8 +31,7 @@ public interface Metadata { * * @return the name of the metadata. */ - @Nonnull String getName(); - void accept(@Nonnull Visitor visitor); + void accept(Visitor visitor); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Schema.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Schema.java index 5841160d125..39f3f66c0b0 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Schema.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Schema.java @@ -24,7 +24,6 @@ import com.google.common.collect.Multimap; -import javax.annotation.Nonnull; import java.util.Set; /** @@ -37,7 +36,6 @@ public interface Schema extends Metadata { * * @return The {@link SchemaTemplate} from which {@code this} {@link Schema} is generated. */ - @Nonnull SchemaTemplate getSchemaTemplate(); /** @@ -45,7 +43,6 @@ public interface Schema extends Metadata { * * @return The ID of the database which {@code this} {@link Schema} belong to. */ - @Nonnull String getDatabaseName(); /** @@ -54,7 +51,6 @@ public interface Schema extends Metadata { * @return The tables inside the {@code Schema}. * @throws RelationalException if the schema template is NoOpSchemaTemplate */ - @Nonnull default Set getTables() throws RelationalException { return getSchemaTemplate().getTables(); } @@ -65,7 +61,6 @@ default Set getTables() throws RelationalException { * @return The views inside the {@code Schema}. * @throws RelationalException if the schema template is NoOpSchemaTemplate */ - @Nonnull default Set getViews() throws RelationalException { return getSchemaTemplate().getViews(); } @@ -76,7 +71,6 @@ default Set getViews() throws RelationalException { * @return a multi-map whose key is the {@link Table} name, and value(s) is the {@link Index}. * @throws RelationalException if something goes wrong. */ - @Nonnull default Multimap getIndexes() throws RelationalException { return getSchemaTemplate().getTableIndexMapping(); } @@ -87,13 +81,12 @@ default Multimap getIndexes() throws RelationalException { * @return A set of all {@link InvokedRoutine}s defined in this schema. * @throws RelationalException If there was an error retrieving the invoked routines from the catalog. */ - @Nonnull default Set getInvokedRoutines() throws RelationalException { return getSchemaTemplate().getInvokedRoutines(); } @Override - default void accept(@Nonnull final Visitor visitor) { + default void accept(final Visitor visitor) { visitor.visit(this); } } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/SchemaTemplate.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/SchemaTemplate.java index 7745b0a1ff7..ce59905dad3 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/SchemaTemplate.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/SchemaTemplate.java @@ -24,7 +24,6 @@ import com.google.common.collect.Multimap; -import javax.annotation.Nonnull; import java.util.BitSet; import java.util.Collection; import java.util.Map; @@ -64,7 +63,6 @@ public interface SchemaTemplate extends Metadata { * @return The {@link Table}s inside the schema template. * @throws RelationalException if it is a NoOpSchemaTemplate */ - @Nonnull Set getTables() throws RelationalException; /** @@ -73,7 +71,6 @@ public interface SchemaTemplate extends Metadata { * @return The {@link View}s inside the schema template. * @throws RelationalException if it is a NoOpSchemaTemplate */ - @Nonnull Set getViews() throws RelationalException; /** @@ -82,16 +79,12 @@ public interface SchemaTemplate extends Metadata { * @param tableName The name of the {@link Table}. * @return An {@link Optional} containing the {@link Table} if it is found, otherwise {@code Empty}. */ - @Nonnull - Optional findTableByName(@Nonnull String tableName) throws RelationalException; + Optional
findTableByName(String tableName) throws RelationalException; - @Nonnull - Optional findViewByName(@Nonnull String viewName) throws RelationalException; + Optional findViewByName(String viewName) throws RelationalException; - @Nonnull Multimap getTableIndexMapping() throws RelationalException; - @Nonnull Set getIndexes() throws RelationalException; /** @@ -107,8 +100,7 @@ public interface SchemaTemplate extends Metadata { * @throws RelationalException If a readable index is not found. */ @SuppressWarnings("OptionalUsedAsFieldOrParameterType") - @Nonnull - BitSet getIndexEntriesAsBitset(@Nonnull Optional> readableIndexNames) throws RelationalException; + BitSet getIndexEntriesAsBitset(Optional> readableIndexNames) throws RelationalException; /** * Returns all {@link InvokedRoutine}s defined in this schema template. @@ -116,7 +108,6 @@ public interface SchemaTemplate extends Metadata { * @return A set of all {@link InvokedRoutine}s defined in this schema template. * @throws RelationalException If there was an error retrieving the invoked routines from the catalog. */ - @Nonnull Set getInvokedRoutines() throws RelationalException; /** @@ -125,10 +116,8 @@ public interface SchemaTemplate extends Metadata { * @param routineName The name of the {@link InvokedRoutine}. * @return An {@link Optional} containing the {@link InvokedRoutine} if it is found, otherwise {@code Empty}. */ - @Nonnull - Optional findInvokedRoutineByName(@Nonnull String routineName) throws RelationalException; + Optional findInvokedRoutineByName(String routineName) throws RelationalException; - @Nonnull Collection getTemporaryInvokedRoutines() throws RelationalException; /** @@ -137,10 +126,8 @@ public interface SchemaTemplate extends Metadata { * @return A map of stored query names to their {@link StoredQuery} struct (SELECT text plus * the temp-function declarations that must precede it). */ - @Nonnull Map getStoredQueries() throws RelationalException; - @Nonnull String getTransactionBoundMetadataAsString() throws RelationalException; /** @@ -151,16 +138,14 @@ public interface SchemaTemplate extends Metadata { * @return A new {@link Schema} instance with the specified name, database Id, version containing the same set of * {@link Table}s in {@code this} {@link SchemaTemplate}. */ - @Nonnull - Schema generateSchema(@Nonnull String databaseId, @Nonnull String schemaName); + Schema generateSchema(String databaseId, String schemaName); @Override - default void accept(@Nonnull final Visitor visitor) { + default void accept(final Visitor visitor) { visitor.startVisit(this); visitor.visit(this); visitor.finishVisit(this); } - @Nonnull - T unwrap(@Nonnull Class iface) throws RelationalException; + T unwrap(Class iface) throws RelationalException; } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/StoredQuery.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/StoredQuery.java index 86994dbe71a..e87d9241023 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/StoredQuery.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/StoredQuery.java @@ -22,7 +22,6 @@ import com.google.common.collect.ImmutableList; -import javax.annotation.Nonnull; import java.util.List; /** @@ -33,22 +32,18 @@ *

The SELECT body and each temp-function declaration are kept as their original verbatim source.

*/ public final class StoredQuery { - @Nonnull private final String query; - @Nonnull private final List tempFunctions; - public StoredQuery(@Nonnull final String storedQuery, @Nonnull final List tempFunctions) { + public StoredQuery(final String storedQuery, final List tempFunctions) { this.query = storedQuery; this.tempFunctions = ImmutableList.copyOf(tempFunctions); } - @Nonnull public String getQuery() { return query; } - @Nonnull public List getTempFunctions() { return tempFunctions; } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Table.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Table.java index 516cc6f0222..76179fa5c44 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Table.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Table.java @@ -20,7 +20,6 @@ package com.apple.foundationdb.relational.api.metadata; -import javax.annotation.Nonnull; import java.util.Collection; import java.util.Set; @@ -29,7 +28,6 @@ */ public interface Table extends Metadata { - @Nonnull Set getIndexes(); // TODO (yhatem) implement this. @@ -41,11 +39,10 @@ public interface Table extends Metadata { * * @return A list of the table {@link Column}s. */ - @Nonnull Collection getColumns(); @Override - default void accept(@Nonnull final Visitor visitor) { + default void accept(final Visitor visitor) { visitor.visit(this); for (final var index : getIndexes()) { @@ -64,6 +61,5 @@ default void accept(@Nonnull final Visitor visitor) { * @apiNote Because of our nested {@link DataType} model, {@link Table}s have a compliant {@link DataType} which * is a {@link DataType.StructType}. */ - @Nonnull DataType.StructType getDatatype(); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/View.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/View.java index 6ffdbaafd75..c6bb8fceb13 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/View.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/View.java @@ -20,8 +20,6 @@ package com.apple.foundationdb.relational.api.metadata; -import javax.annotation.Nonnull; - /** * Metadata for a non-materialized view, which represents a virtual table defined by a SQL query. *

@@ -39,7 +37,6 @@ public interface View extends Metadata { * * @return The SQL query string that defines this view. */ - @Nonnull String getDescription(); /** @@ -52,7 +49,7 @@ public interface View extends Metadata { boolean isTemporary(); @Override - default void accept(@Nonnull final Visitor visitor) { + default void accept(final Visitor visitor) { visitor.visit(this); } } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Visitor.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Visitor.java index 78ce737571f..b693cde3f2c 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Visitor.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/Visitor.java @@ -20,8 +20,6 @@ package com.apple.foundationdb.relational.api.metadata; -import javax.annotation.Nonnull; - /** * A visitor interface for the {@link Metadata}. * This visitor allows us to design algorithms that work with metadata artifacts is isolation of metadata API. @@ -30,25 +28,25 @@ */ public interface Visitor { - default void visit(@Nonnull final Metadata metadata) { + default void visit(final Metadata metadata) { throw new RuntimeException("unexpected"); } - void visit(@Nonnull Table table); + void visit(Table table); - void visit(@Nonnull Column column); + void visit(Column column); - void startVisit(@Nonnull SchemaTemplate schemaTemplate); + void startVisit(SchemaTemplate schemaTemplate); - void visit(@Nonnull SchemaTemplate schemaTemplate); + void visit(SchemaTemplate schemaTemplate); - void finishVisit(@Nonnull SchemaTemplate schemaTemplate); + void finishVisit(SchemaTemplate schemaTemplate); - void visit(@Nonnull Schema schema); + void visit(Schema schema); - void visit(@Nonnull Index index); + void visit(Index index); - void visit(@Nonnull InvokedRoutine invokedRoutine); + void visit(InvokedRoutine invokedRoutine); - void visit(@Nonnull View view); + void visit(View view); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/package-info.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/package-info.java index cfa76df7916..0874df840f2 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/package-info.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/package-info.java @@ -22,4 +22,7 @@ * Metadata artefacts in Relational. */ +@NullMarked package com.apple.foundationdb.relational.api.metadata; + +import org.jspecify.annotations.NullMarked; diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/CollectionContract.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/CollectionContract.java index 13e483f2bc6..f5b0d3e305f 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/CollectionContract.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/CollectionContract.java @@ -23,8 +23,8 @@ import com.apple.foundationdb.relational.api.Options; import com.apple.foundationdb.relational.api.exceptions.ErrorCode; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import org.jspecify.annotations.Nullable; + import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; @@ -40,17 +40,16 @@ * @param the type parameter of the collection */ public class CollectionContract implements OptionContract, OptionContractWithConversion> { - @Nonnull private final TypeContract elementContract; - public CollectionContract(@Nonnull TypeContract elementContract) { + public CollectionContract(TypeContract elementContract) { this.elementContract = elementContract; } @Override - public void validate(final Options.Name name, final Object value) throws SQLException { + public void validate(final Options.Name name, @Nullable final Object value) throws SQLException { if (!(value instanceof Collection)) { - throw new SQLException("Option " + name + " should be of a collection type instead of " + value.getClass().getName(), ErrorCode.INVALID_PARAMETER.getErrorCode()); + throw new SQLException("Option " + name + " should be of a collection type instead of " + (value == null ? "null" : value.getClass().getName()), ErrorCode.INVALID_PARAMETER.getErrorCode()); } try { Collection collectionValue = (Collection)value; @@ -68,7 +67,11 @@ public Collection fromString(final String valueAsString) throws SQLException final List results = new ArrayList<>(); // not null-phobic for (final String split : valueAsString.split(",")) { final String trimmedElementString = split.trim(); - results.add(elementContract.fromString(trimmedElementString)); + final T element = elementContract.fromString(trimmedElementString); + if (element == null) { + throw new SQLException("Element '" + trimmedElementString + "' of collection option could not be converted", ErrorCode.INVALID_PARAMETER.getErrorCode()); + } + results.add(element); } return Collections.unmodifiableList(results); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/OptionContract.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/OptionContract.java index 96015ac7981..0f04a0c7e2c 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/OptionContract.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/OptionContract.java @@ -22,8 +22,10 @@ import com.apple.foundationdb.relational.api.Options; +import org.jspecify.annotations.Nullable; + import java.sql.SQLException; public interface OptionContract { - void validate(Options.Name name, Object value) throws SQLException; + void validate(Options.Name name, @Nullable Object value) throws SQLException; } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/OptionContractWithConversion.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/OptionContractWithConversion.java index d53aac66b27..8202e59334a 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/OptionContractWithConversion.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/OptionContractWithConversion.java @@ -20,7 +20,8 @@ package com.apple.foundationdb.relational.api.options; -import javax.annotation.Nullable; +import org.jspecify.annotations.Nullable; + import java.sql.SQLException; public interface OptionContractWithConversion extends OptionContract { diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/OrderedCollectionContract.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/OrderedCollectionContract.java index 9dad9ec32ad..ddf7faa9770 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/OrderedCollectionContract.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/OrderedCollectionContract.java @@ -23,7 +23,8 @@ import com.apple.foundationdb.relational.api.Options; import com.apple.foundationdb.relational.api.exceptions.ErrorCode; -import javax.annotation.Nonnull; +import org.jspecify.annotations.Nullable; + import java.sql.SQLException; import java.util.List; @@ -32,14 +33,14 @@ * @param the type parameter of the collection */ public class OrderedCollectionContract extends CollectionContract { - public OrderedCollectionContract(@Nonnull TypeContract elementContract) { + public OrderedCollectionContract(TypeContract elementContract) { super(elementContract); } @Override - public void validate(final Options.Name name, final Object value) throws SQLException { + public void validate(final Options.Name name, @Nullable final Object value) throws SQLException { if (!(value instanceof List)) { - throw new SQLException("Option " + name + " should be of a list type instead of " + value.getClass().getName(), ErrorCode.INVALID_PARAMETER.getErrorCode()); + throw new SQLException("Option " + name + " should be of a list type instead of " + (value == null ? "null" : value.getClass().getName()), ErrorCode.INVALID_PARAMETER.getErrorCode()); } super.validate(name, value); } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/RangeContract.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/RangeContract.java index 3f5d1952ec2..3b1dcdbb59f 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/RangeContract.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/RangeContract.java @@ -25,7 +25,8 @@ import com.apple.foundationdb.relational.api.Options; import com.apple.foundationdb.relational.api.exceptions.ErrorCode; -import javax.annotation.Nonnull; +import org.jspecify.annotations.Nullable; + import java.sql.SQLException; /** @@ -53,15 +54,17 @@ private RangeContract(T min, T max) { @Override @SuppressWarnings("unchecked") - public void validate(Options.Name name, Object value) throws SQLException { + public void validate(Options.Name name, @Nullable Object value) throws SQLException { + if (value == null) { + throw new SQLException("Option " + name + " should not be null", ErrorCode.INVALID_PARAMETER.getErrorCode()); + } T val = (T) value; if (min.compareTo(val) > 0 || max.compareTo(val) < 0) { throw new SQLException("Option " + name + " should be in range [" + min + ", " + max + "] but is " + value, ErrorCode.INVALID_PARAMETER.getErrorCode()); } } - @Nonnull - public static > RangeContract of(@Nonnull final T min, @Nonnull final T max) { + public static > RangeContract of(final T min, final T max) { return new RangeContract<>(min, max); } } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/TypeContract.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/TypeContract.java index cb6b2cbfb2f..aed46f4ad3f 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/TypeContract.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/TypeContract.java @@ -24,44 +24,37 @@ import com.apple.foundationdb.relational.api.Options; import com.apple.foundationdb.relational.api.exceptions.ErrorCode; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import org.jspecify.annotations.Nullable; + import java.sql.SQLException; import java.util.function.Function; @API(API.Status.EXPERIMENTAL) public class TypeContract implements OptionContract, OptionContractWithConversion { - @Nonnull private static final TypeContract BOOLEAN_TYPE = new TypeContract<>(Boolean.class, Boolean::parseBoolean, false); - @Nonnull private static final TypeContract INTEGER_TYPE = new TypeContract<>(Integer.class, Integer::parseInt, false); - @Nonnull private static final TypeContract LONG_TYPE = new TypeContract<>(Long.class, Long::parseLong, false); - @Nonnull private static final TypeContract STRING_TYPE = new TypeContract<>(String.class, Function.identity(), false); - @Nonnull private static final TypeContract NULLABLE_STRING_TYPE = new TypeContract<>(String.class, Function.identity(), true); - @Nonnull private final Class clazz; - @Nonnull private final Function fromStringFunction; private final boolean nullable; - private TypeContract(@Nonnull Class clazz, @Nonnull Function fromStringFunction, boolean nullable) { + private TypeContract(Class clazz, Function fromStringFunction, boolean nullable) { this.clazz = clazz; this.fromStringFunction = fromStringFunction; this.nullable = nullable; } @Override - public void validate(Options.Name name, Object value) throws SQLException { + public void validate(Options.Name name, @Nullable Object value) throws SQLException { if (value == null) { if (nullable) { return; @@ -79,32 +72,26 @@ public T fromString(String valueAsString) throws SQLException { return fromStringFunction.apply(valueAsString); } - @Nonnull - public static TypeContract of(@Nonnull final Class clazz, @Nonnull Function fromStringFunction) { + public static TypeContract of(final Class clazz, Function fromStringFunction) { return new TypeContract<>(clazz, fromStringFunction, false); } - @Nonnull public static TypeContract booleanType() { return BOOLEAN_TYPE; } - @Nonnull public static TypeContract stringType() { return STRING_TYPE; } - @Nonnull public static TypeContract nullableStringType() { return NULLABLE_STRING_TYPE; } - @Nonnull public static TypeContract intType() { return INTEGER_TYPE; } - @Nonnull public static TypeContract longType() { return LONG_TYPE; } diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/package-info.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/package-info.java index ea23b920268..4572f49a50e 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/package-info.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/options/package-info.java @@ -21,4 +21,7 @@ /** * Interfaces and core API functions around implementing a Catalog instance. */ +@NullMarked package com.apple.foundationdb.relational.api.options; + +import org.jspecify.annotations.NullMarked; diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/package-info.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/package-info.java index e99249f2498..e8f852e9a3c 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/package-info.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/package-info.java @@ -22,4 +22,7 @@ * Interfaces differently implemented upstream by relational-core and * fdb-relational-jdbc. */ +@NullMarked package com.apple.foundationdb.relational.api; + +import org.jspecify.annotations.NullMarked; diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/util/Assert.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/util/Assert.java index 11946972207..4fe1975e33b 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/util/Assert.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/util/Assert.java @@ -25,7 +25,8 @@ import com.apple.foundationdb.relational.api.exceptions.RelationalException; import com.apple.foundationdb.relational.api.exceptions.UncheckedRelationalException; -import javax.annotation.Nonnull; +import org.jspecify.annotations.Nullable; + import java.util.Locale; import java.util.Optional; import java.util.function.Supplier; @@ -40,43 +41,43 @@ public static void that(boolean mustBeTrue) throws RelationalException { that(mustBeTrue, "condition is not met!"); } - public static void that(boolean mustBeTrue, @Nonnull final String messageIfNotTrue) throws RelationalException { + public static void that(boolean mustBeTrue, final String messageIfNotTrue) throws RelationalException { that(mustBeTrue, ErrorCode.INTERNAL_ERROR, messageIfNotTrue); } - public static void that(boolean mustBeTrue, @Nonnull final ErrorCode errorCodeIfNotTrue, @Nonnull final Supplier messageSupplier) throws RelationalException { + public static void that(boolean mustBeTrue, final ErrorCode errorCodeIfNotTrue, final Supplier messageSupplier) throws RelationalException { if (!mustBeTrue) { throw new RelationalException(messageSupplier.get(), errorCodeIfNotTrue); } } - public static void that(boolean mustBeTrue, @Nonnull final ErrorCode errorCodeIfNotTrue, @Nonnull final String messageIfNotTrue) throws RelationalException { + public static void that(boolean mustBeTrue, final ErrorCode errorCodeIfNotTrue, final String messageIfNotTrue) throws RelationalException { if (!mustBeTrue) { throw new RelationalException(messageIfNotTrue, errorCodeIfNotTrue); } } - public static void that(boolean mustBeTrue, @Nonnull final ErrorCode errorCodeIfNotTrue, @Nonnull final String messageFormat, @Nonnull Object messageValue) throws RelationalException { + public static void that(boolean mustBeTrue, final ErrorCode errorCodeIfNotTrue, final String messageFormat, Object messageValue) throws RelationalException { if (!mustBeTrue) { throw new RelationalException(String.format(Locale.ROOT, messageFormat, messageValue), errorCodeIfNotTrue); } } - public static void that(boolean mustBeTrue, @Nonnull final ErrorCode errorCodeIfNotTrue, @Nonnull final String messageFormat, @Nonnull Object messageValue1, @Nonnull Object messageValue2) throws RelationalException { + public static void that(boolean mustBeTrue, final ErrorCode errorCodeIfNotTrue, final String messageFormat, Object messageValue1, Object messageValue2) throws RelationalException { if (!mustBeTrue) { throw new RelationalException(String.format(Locale.ROOT, messageFormat, messageValue1, messageValue2), errorCodeIfNotTrue); } } - public static T notNull(T object) throws RelationalException { + public static T notNull(@Nullable T object) throws RelationalException { return notNull(object, "unexpected null object"); } - public static T notNull(T object, @Nonnull final String messageIfNull) throws RelationalException { + public static T notNull(@Nullable T object, final String messageIfNull) throws RelationalException { return notNull(object, ErrorCode.INTERNAL_ERROR, messageIfNull); } - public static T notNull(T object, @Nonnull final ErrorCode errorCodeIfNotTrue, @Nonnull final String messageIfNull) throws RelationalException { + public static T notNull(@Nullable T object, final ErrorCode errorCodeIfNotTrue, final String messageIfNull) throws RelationalException { if (object == null) { throw new RelationalException(messageIfNull, errorCodeIfNotTrue); } else { @@ -84,15 +85,15 @@ public static T notNull(T object, @Nonnull final ErrorCode errorCodeIfNotTru } } - public static void isNull(Object object) throws RelationalException { + public static void isNull(@Nullable Object object) throws RelationalException { isNull(object, "expected object to be null"); } - public static void isNull(Object object, @Nonnull final String messageIfNull) throws RelationalException { + public static void isNull(@Nullable Object object, final String messageIfNull) throws RelationalException { isNull(object, ErrorCode.INTERNAL_ERROR, messageIfNull); } - public static void isNull(Object object, @Nonnull final ErrorCode errorCodeIfNotTrue, @Nonnull final String messageIfNull) throws RelationalException { + public static void isNull(@Nullable Object object, final ErrorCode errorCodeIfNotTrue, final String messageIfNull) throws RelationalException { if (object != null) { throw new RelationalException(messageIfNull, errorCodeIfNotTrue); } @@ -102,11 +103,11 @@ public static RelationalException fail() throws RelationalException { throw fail("unexpected error"); } - public static RelationalException fail(@Nonnull final String failMessage) throws RelationalException { + public static RelationalException fail(final String failMessage) throws RelationalException { throw fail(ErrorCode.INTERNAL_ERROR, failMessage); } - public static RelationalException fail(@Nonnull final ErrorCode failErrorCode, @Nonnull final String failMessage) throws RelationalException { + public static RelationalException fail(final ErrorCode failErrorCode, final String failMessage) throws RelationalException { throw new RelationalException(failMessage, failErrorCode); } @@ -114,43 +115,43 @@ public static void thatUnchecked(boolean mustBeTrue) { thatUnchecked(mustBeTrue, "condition is not met!"); } - public static void thatUnchecked(boolean mustBeTrue, @Nonnull final String messageIfNotTrue) { + public static void thatUnchecked(boolean mustBeTrue, final String messageIfNotTrue) { thatUnchecked(mustBeTrue, ErrorCode.INTERNAL_ERROR, messageIfNotTrue); } - public static void thatUnchecked(boolean mustBeTrue, @Nonnull final ErrorCode errorCodeIfNotTrue, @Nonnull final Supplier messageSupplier) { + public static void thatUnchecked(boolean mustBeTrue, final ErrorCode errorCodeIfNotTrue, final Supplier messageSupplier) { if (!mustBeTrue) { throw new RelationalException(messageSupplier.get(), errorCodeIfNotTrue).toUncheckedWrappedException(); } } - public static void thatUnchecked(boolean mustBeTrue, @Nonnull final ErrorCode errorCodeIfNotTrue, @Nonnull final String messageIfNotTrue) { + public static void thatUnchecked(boolean mustBeTrue, final ErrorCode errorCodeIfNotTrue, final String messageIfNotTrue) { if (!mustBeTrue) { throw new RelationalException(messageIfNotTrue, errorCodeIfNotTrue).toUncheckedWrappedException(); } } - public static void thatUnchecked(boolean mustBeTrue, @Nonnull final ErrorCode errorCodeIfNotTrue, @Nonnull final String messageTemplate, @Nonnull final Object messageValue) { + public static void thatUnchecked(boolean mustBeTrue, final ErrorCode errorCodeIfNotTrue, final String messageTemplate, final Object messageValue) { if (!mustBeTrue) { throw new RelationalException(String.format(Locale.ROOT, messageTemplate, messageValue), errorCodeIfNotTrue).toUncheckedWrappedException(); } } - public static void thatUnchecked(boolean mustBeTrue, @Nonnull final ErrorCode errorCodeIfNotTrue, @Nonnull final String messageTemplate, @Nonnull final Object messageValue1, @Nonnull final Object messageValue2) { + public static void thatUnchecked(boolean mustBeTrue, final ErrorCode errorCodeIfNotTrue, final String messageTemplate, final Object messageValue1, final Object messageValue2) { if (!mustBeTrue) { throw new RelationalException(String.format(Locale.ROOT, messageTemplate, messageValue1, messageValue2), errorCodeIfNotTrue).toUncheckedWrappedException(); } } - public static T notNullUnchecked(T object) { + public static T notNullUnchecked(@Nullable T object) { return notNullUnchecked(object, "unexpected null object"); } - public static T notNullUnchecked(T object, @Nonnull final String messageIfNull) { + public static T notNullUnchecked(@Nullable T object, final String messageIfNull) { return notNullUnchecked(object, ErrorCode.INTERNAL_ERROR, messageIfNull); } - public static T notNullUnchecked(T object, @Nonnull final ErrorCode errorCodeIfNull, @Nonnull Supplier messageSupplier) { + public static T notNullUnchecked(@Nullable T object, final ErrorCode errorCodeIfNull, Supplier messageSupplier) { if (object == null) { throw new RelationalException(messageSupplier.get(), errorCodeIfNull).toUncheckedWrappedException(); } else { @@ -158,7 +159,7 @@ public static T notNullUnchecked(T object, @Nonnull final ErrorCode errorCod } } - public static T notNullUnchecked(T object, @Nonnull final ErrorCode errorCodeIfNull, @Nonnull final String messageIfNull) { + public static T notNullUnchecked(@Nullable T object, final ErrorCode errorCodeIfNull, final String messageIfNull) { if (object == null) { throw new RelationalException(messageIfNull, errorCodeIfNull).toUncheckedWrappedException(); } else { @@ -166,7 +167,7 @@ public static T notNullUnchecked(T object, @Nonnull final ErrorCode errorCod } } - public static T notNullUnchecked(T object, @Nonnull final ErrorCode errorCodeIfNull, @Nonnull final String messageTemplate, @Nonnull final Object messageValue) { + public static T notNullUnchecked(@Nullable T object, final ErrorCode errorCodeIfNull, final String messageTemplate, final Object messageValue) { if (object == null) { throw new RelationalException(String.format(Locale.ROOT, messageTemplate, messageValue), errorCodeIfNull).toUncheckedWrappedException(); } else { @@ -174,21 +175,21 @@ public static T notNullUnchecked(T object, @Nonnull final ErrorCode errorCod } } - public static void isNullUnchecked(Object object) { + public static void isNullUnchecked(@Nullable Object object) { isNullUnchecked(object, "expected object to be null"); } - public static void isNullUnchecked(Object object, @Nonnull final String messageIfNotNull) { + public static void isNullUnchecked(@Nullable Object object, final String messageIfNotNull) { isNullUnchecked(object, ErrorCode.INTERNAL_ERROR, messageIfNotNull); } - public static void isNullUnchecked(Object object, @Nonnull final ErrorCode errorCodeIfNotNull, @Nonnull final Supplier messageSupplier) { + public static void isNullUnchecked(@Nullable Object object, final ErrorCode errorCodeIfNotNull, final Supplier messageSupplier) { if (object != null) { throw new RelationalException(messageSupplier.get(), errorCodeIfNotNull).toUncheckedWrappedException(); } } - public static void isNullUnchecked(Object object, @Nonnull final ErrorCode errorCodeIfNotNull, @Nonnull final String messageIfNotNull) { + public static void isNullUnchecked(@Nullable Object object, final ErrorCode errorCodeIfNotNull, final String messageIfNotNull) { if (object != null) { throw new RelationalException(messageIfNotNull, errorCodeIfNotNull).toUncheckedWrappedException(); } @@ -198,52 +199,45 @@ public static UncheckedRelationalException failUnchecked() { throw failUnchecked("unexpected error"); } - public static UncheckedRelationalException failUnchecked(@Nonnull final String failMessage) { + public static UncheckedRelationalException failUnchecked(final String failMessage) { throw failUnchecked(ErrorCode.INTERNAL_ERROR, failMessage); } - public static UncheckedRelationalException failUnchecked(@Nonnull final ErrorCode failErrorCode, @Nonnull final String failMessage) { + public static UncheckedRelationalException failUnchecked(final ErrorCode failErrorCode, final String failMessage) { throw new RelationalException(failMessage, failErrorCode).toUncheckedWrappedException(); } - @Nonnull - public static UncheckedRelationalException failUnchecked(@Nonnull final ErrorCode failErrorCode, @Nonnull final String failMessage, - @Nonnull final Throwable cause) { + public static UncheckedRelationalException failUnchecked(final ErrorCode failErrorCode, final String failMessage, + final Throwable cause) { throw new RelationalException(failMessage, failErrorCode, cause).toUncheckedWrappedException(); } - @Nonnull - public static S castUnchecked(T object, Class clazz) { + public static S castUnchecked(@Nullable T object, Class clazz) { return castUnchecked(object, clazz, ErrorCode.INTERNAL_ERROR, () -> "expected " + clazz.getSimpleName() + " but got " + (object == null ? "null" : object.getClass().getSimpleName())); } - @Nonnull - public static S castUnchecked(T object, Class clazz, @Nonnull final ErrorCode errorCodeIfCastFailed, - @Nonnull final Supplier messageSupplier) { + public static S castUnchecked(@Nullable T object, Class clazz, final ErrorCode errorCodeIfCastFailed, + final Supplier messageSupplier) { final var notNullObject = notNullUnchecked(object, errorCodeIfCastFailed, messageSupplier); if (clazz.isInstance(notNullObject)) { - return clazz.cast(object); + return clazz.cast(notNullObject); } - failUnchecked(errorCodeIfCastFailed, messageSupplier.get()); - return null; + throw failUnchecked(errorCodeIfCastFailed, messageSupplier.get()); } @SuppressWarnings("OptionalUsedAsFieldOrParameterType") - @Nonnull - public static V optionalUnchecked(@Nonnull final Optional optional) { + public static V optionalUnchecked(final Optional optional) { return optionalUnchecked(optional, ErrorCode.INTERNAL_ERROR, () -> "expected non-empty Optional"); } @SuppressWarnings("OptionalUsedAsFieldOrParameterType") - @Nonnull - public static T optionalUnchecked(@Nonnull final Optional optional, @Nonnull final ErrorCode errorCodeIfOptionalEmpty, - @Nonnull final Supplier messageSupplier) { + public static T optionalUnchecked(final Optional optional, final ErrorCode errorCodeIfOptionalEmpty, + final Supplier messageSupplier) { if (optional.isPresent()) { return optional.get(); } - failUnchecked(errorCodeIfOptionalEmpty, messageSupplier.get()); - return null; + throw failUnchecked(errorCodeIfOptionalEmpty, messageSupplier.get()); } private Assert() { diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/util/BuildVersion.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/util/BuildVersion.java index 2b1a046f7d7..306eddad89a 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/util/BuildVersion.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/util/BuildVersion.java @@ -25,6 +25,8 @@ import com.apple.foundationdb.relational.api.exceptions.ErrorCode; import com.apple.foundationdb.relational.api.exceptions.RelationalException; +import org.jspecify.annotations.Nullable; + import java.io.IOException; import java.io.InputStream; import java.util.Properties; @@ -47,6 +49,7 @@ */ @API(API.Status.EXPERIMENTAL) public final class BuildVersion { + @Nullable private static BuildVersion instance; private static final String VERSIONS_PROPERTIES_FILENAME = "version.properties"; private final Properties versionProperties = new Properties(); diff --git a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/util/package-info.java b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/util/package-info.java index 4d391cc8376..2d843dc5362 100644 --- a/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/util/package-info.java +++ b/fdb-relational-api/src/main/java/com/apple/foundationdb/relational/util/package-info.java @@ -21,4 +21,7 @@ /** * Utility classes for the Relational API. */ +@NullMarked package com.apple.foundationdb.relational.util; + +import org.jspecify.annotations.NullMarked; diff --git a/fdb-relational-api/src/test/java/com/apple/foundationdb/relational/api/DataTypeSmokeTest.java b/fdb-relational-api/src/test/java/com/apple/foundationdb/relational/api/DataTypeSmokeTest.java index 1c964587aca..c3093704e29 100644 --- a/fdb-relational-api/src/test/java/com/apple/foundationdb/relational/api/DataTypeSmokeTest.java +++ b/fdb-relational-api/src/test/java/com/apple/foundationdb/relational/api/DataTypeSmokeTest.java @@ -30,7 +30,6 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import javax.annotation.Nonnull; import java.util.List; import java.util.stream.Stream; @@ -41,10 +40,8 @@ * Basic tests for validating features of the {@link DataType} class. */ class DataTypeSmokeTest { - @Nonnull private static final String OR_NULL = " ∪ āˆ…"; - @Nonnull private static final DataType.StructType baseStructType = DataType.StructType.from("sample_type", List.of( DataType.StructType.Field.from("a", DataType.LongType.nullable(), 1), @@ -52,7 +49,6 @@ class DataTypeSmokeTest { ), false); - @Nonnull private static final DataType.StructType structWithNested = DataType.StructType.from("par", List.of( DataType.StructType.Field.from("x", baseStructType.withNullable(false), 1), @@ -60,7 +56,6 @@ class DataTypeSmokeTest { ), false); - @Nonnull private static final DataType.EnumType suitsEnum = DataType.EnumType.from("suits", List.of( DataType.EnumType.EnumValue.of("SPADES", 0), @@ -69,7 +64,6 @@ class DataTypeSmokeTest { DataType.EnumType.EnumValue.of("DIAMONDS", 3) ), false); - @Nonnull static Stream assertStringMatches() { return Stream.of( // Primitive types @@ -116,7 +110,7 @@ static Stream assertStringMatches() { @ParameterizedTest(name = "assertStringMatches[dataType={0}]") @MethodSource - void assertStringMatches(@Nonnull DataType dataType, @Nonnull String string) { + void assertStringMatches(DataType dataType, String string) { assertThat(dataType) .hasToString(string); } diff --git a/fdb-relational-api/src/test/java/com/apple/foundationdb/relational/api/RelationalExceptionTest.java b/fdb-relational-api/src/test/java/com/apple/foundationdb/relational/api/RelationalExceptionTest.java index bedbc18f4ad..0f11147b765 100644 --- a/fdb-relational-api/src/test/java/com/apple/foundationdb/relational/api/RelationalExceptionTest.java +++ b/fdb-relational-api/src/test/java/com/apple/foundationdb/relational/api/RelationalExceptionTest.java @@ -24,6 +24,7 @@ import org.junit.jupiter.api.Test; import java.sql.SQLException; +import java.util.Objects; class RelationalExceptionTest { RelationalException relationalException = new RelationalException("message", ErrorCode.INTERNAL_ERROR); @@ -84,7 +85,7 @@ private static RelationalException toRelationalException(Throwable re) { if (re instanceof RelationalException) { return (RelationalException) re; } else if (re instanceof SQLException) { - return new RelationalException(re.getMessage(), ErrorCode.get(((SQLException) re).getSQLState()), re); + return new RelationalException(Objects.requireNonNullElse(re.getMessage(), ""), ErrorCode.get(((SQLException) re).getSQLState()), re); } return new RelationalException(ErrorCode.UNKNOWN, re); } diff --git a/fdb-relational-core/src/main/java/com/apple/foundationdb/relational/api/EmbeddedRelationalStruct.java b/fdb-relational-core/src/main/java/com/apple/foundationdb/relational/api/EmbeddedRelationalStruct.java index 4e82c35b034..b6f6ad2ad17 100644 --- a/fdb-relational-core/src/main/java/com/apple/foundationdb/relational/api/EmbeddedRelationalStruct.java +++ b/fdb-relational-core/src/main/java/com/apple/foundationdb/relational/api/EmbeddedRelationalStruct.java @@ -22,6 +22,7 @@ import com.apple.foundationdb.relational.api.metadata.DataType; import com.apple.foundationdb.relational.recordlayer.ArrayRow; +import com.apple.foundationdb.relational.util.SpotBugsSuppressWarnings; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -36,6 +37,7 @@ static RelationalStructBuilder newBuilder() { return new Builder(); } + @SpotBugsSuppressWarnings(value = "NP_METHOD_PARAMETER_TIGHTENS_ANNOTATION", justification = "False positive: RelationalStructBuilder's parameters are jspecify @Nullable (fdb-relational-api), while this class still uses javax.annotation.Nullable (fdb-relational-core not yet migrated); SpotBugs does not recognize the two annotations as equivalent across the module boundary, including on the covariant-return bridge methods synthesized for addString/addUuid/addObject, which it can't otherwise be annotated.") class Builder implements RelationalStructBuilder { final List fields = new ArrayList<>(); diff --git a/fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/EmbeddedRelationalConnection.java b/fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/EmbeddedRelationalConnection.java index bb9c0671f53..be2e7ff0070 100644 --- a/fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/EmbeddedRelationalConnection.java +++ b/fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/EmbeddedRelationalConnection.java @@ -420,6 +420,7 @@ public void setOption(Options.Name name, Object value) throws SQLException { } @Override + @Nonnull public URI getPath() { return getRecordLayerDatabase().getURI(); } diff --git a/fdb-relational-core/src/testFixtures/java/com/apple/foundationdb/relational/utils/RelationalStructAssert.java b/fdb-relational-core/src/testFixtures/java/com/apple/foundationdb/relational/utils/RelationalStructAssert.java index 98208de5a08..a4e27bd0bfa 100644 --- a/fdb-relational-core/src/testFixtures/java/com/apple/foundationdb/relational/utils/RelationalStructAssert.java +++ b/fdb-relational-core/src/testFixtures/java/com/apple/foundationdb/relational/utils/RelationalStructAssert.java @@ -38,6 +38,7 @@ import java.sql.Types; import java.util.Iterator; import java.util.Map; +import java.util.Objects; @API(API.Status.EXPERIMENTAL) public class RelationalStructAssert extends AbstractAssert { @@ -165,7 +166,7 @@ private static boolean checkEquals(RelationalStruct actual, RelationalStruct exp case Types.VARCHAR: case Types.NCHAR: case Types.NVARCHAR: - fieldEquals = actual.getString(i).equals(expected.getString(i)); + fieldEquals = Objects.equals(actual.getString(i), expected.getString(i)); break; case Types.STRUCT: fieldEquals = RelationalStructAssert.checkEquals(actual.getStruct(i), expected.getStruct(i)); @@ -181,7 +182,7 @@ private static boolean checkEquals(RelationalStruct actual, RelationalStruct exp } break; default: - fieldEquals = actual.getObject(i).equals(expected.getObject(i)); + fieldEquals = Objects.equals(actual.getObject(i), expected.getObject(i)); } if (!fieldEquals) { return false; @@ -252,7 +253,7 @@ private static boolean checkPartlyEquals(RelationalStruct actual, RelationalStru case Types.VARCHAR: case Types.NCHAR: case Types.NVARCHAR: - fieldEquals = actual.getString(actualIdx).equals(expected.getString(expectedIdx)); + fieldEquals = Objects.equals(actual.getString(actualIdx), expected.getString(expectedIdx)); break; case Types.STRUCT: fieldEquals = RelationalStructAssert.checkPartlyEquals(actual.getStruct(actualIdx), expected.getStruct(expectedIdx)); @@ -268,7 +269,7 @@ private static boolean checkPartlyEquals(RelationalStruct actual, RelationalStru } break; default: - fieldEquals = actual.getObject(actualIdx).equals(expected.getObject(expectedIdx)); + fieldEquals = Objects.equals(actual.getObject(actualIdx), expected.getObject(expectedIdx)); } if (!fieldEquals) { return false; @@ -417,7 +418,7 @@ public RelationalStructAssert isEqualTo(RelationalStruct expected) { final var actualValue = actual.getObject(i); if (actualSqlType == Types.OTHER) { // maybe an ENUM value or a UUID - assertions.assertThat(actualValue.toString()).isEqualTo(expected.getObject(i).toString()); + assertions.assertThat(String.valueOf(actualValue)).isEqualTo(String.valueOf(expected.getObject(i))); } else { assertions.assertThat(actual.getObject(i)).isEqualTo(expected.getObject(i)); } diff --git a/fdb-relational-grpc/src/main/java/com/apple/foundationdb/relational/jdbc/TypeConversion.java b/fdb-relational-grpc/src/main/java/com/apple/foundationdb/relational/jdbc/TypeConversion.java index 6706696ee01..b1a404ed446 100644 --- a/fdb-relational-grpc/src/main/java/com/apple/foundationdb/relational/jdbc/TypeConversion.java +++ b/fdb-relational-grpc/src/main/java/com/apple/foundationdb/relational/jdbc/TypeConversion.java @@ -64,6 +64,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.UUID; import java.util.function.BiFunction; @@ -459,15 +460,15 @@ public static Column toColumn(int columnType, Object obj) throws SQLException { return builder.build(); } - private static Column toColumn(DataType.StructType.Field field, Object value, boolean wasNull) throws SQLException { + private static Column toColumn(DataType.StructType.Field field, @Nullable Object value, boolean wasNull) throws SQLException { Column column; switch (field.getType().getCode()) { case STRUCT: - column = toColumn(wasNull ? null : toStruct((RelationalStruct) value), + column = toColumn(wasNull ? null : toStruct((RelationalStruct) Objects.requireNonNull(value)), (a, b) -> a == null ? b.clearStruct() : b.setStruct(a)); break; case ARRAY: - column = toColumn(wasNull ? null : toArray((RelationalArray) value), + column = toColumn(wasNull ? null : toArray((RelationalArray) Objects.requireNonNull(value)), (a, b) -> a == null ? b.clearArray() : b.setArray(a)); break; case LONG: diff --git a/fdb-relational-jdbc/src/main/java/com/apple/foundationdb/relational/jdbc/JDBCRelationalStatement.java b/fdb-relational-jdbc/src/main/java/com/apple/foundationdb/relational/jdbc/JDBCRelationalStatement.java index fe3ed4d7878..f1012b90b28 100644 --- a/fdb-relational-jdbc/src/main/java/com/apple/foundationdb/relational/jdbc/JDBCRelationalStatement.java +++ b/fdb-relational-jdbc/src/main/java/com/apple/foundationdb/relational/jdbc/JDBCRelationalStatement.java @@ -247,8 +247,7 @@ public boolean isClosed() throws SQLException { } @Override - @SuppressWarnings("NullAway") // returns null, violating the @Nonnull contract of RelationalDirectAccessStatement#executeGet. Temporary until implemented; see the SpotBugsSuppressWarnings below. - @SpotBugsSuppressWarnings(value = "NP_NONNULL_RETURN_VIOLATION", justification = "Temporary until implemented.") + @SuppressWarnings("NullAway") // returns null, violating the @Nonnull contract of RelationalDirectAccessStatement#executeGet. Temporary until implemented. public RelationalResultSet executeGet(String tableName, KeySet keySet, Options options) throws SQLException { checkOpen(); GetResponse getResponse; @@ -272,8 +271,7 @@ public RelationalResultSet executeGet(String tableName, KeySet keySet, Options o } @Override - @SuppressWarnings("NullAway") // returns null, violating the @Nonnull contract of RelationalDirectAccessStatement#executeScan. Temporary until implemented; see the SpotBugsSuppressWarnings below. - @SpotBugsSuppressWarnings(value = "NP_NONNULL_RETURN_VIOLATION", justification = "Temporary until implemented.") + @SuppressWarnings("NullAway") // returns null, violating the @Nonnull contract of RelationalDirectAccessStatement#executeScan. Temporary until implemented. public RelationalResultSet executeScan(String tableName, KeySet keySet, Options options) throws SQLException { checkOpen(); diff --git a/fdb-relational-jdbc/src/test/java/com/apple/foundationdb/relational/jdbc/JDBCParameterizedQueryComparisonTest.java b/fdb-relational-jdbc/src/test/java/com/apple/foundationdb/relational/jdbc/JDBCParameterizedQueryComparisonTest.java index c77c6c725e2..8f91b73050c 100644 --- a/fdb-relational-jdbc/src/test/java/com/apple/foundationdb/relational/jdbc/JDBCParameterizedQueryComparisonTest.java +++ b/fdb-relational-jdbc/src/test/java/com/apple/foundationdb/relational/jdbc/JDBCParameterizedQueryComparisonTest.java @@ -52,6 +52,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.Random; import java.util.UUID; import java.util.stream.Collectors; @@ -235,7 +236,7 @@ void setTyped(PreparedStatement statement, int parameterIndex, Object val) throw @Override Object getTyped(ResultSet resultSet, int columnIndex) throws SQLException { RelationalResultSet rrs = resultSet.unwrap(RelationalResultSet.class); - return rrs.getStruct(columnIndex); + return Objects.requireNonNull(rrs.getStruct(columnIndex)); } @Override diff --git a/fdb-relational-server/src/main/java/com/apple/foundationdb/relational/server/FRL.java b/fdb-relational-server/src/main/java/com/apple/foundationdb/relational/server/FRL.java index e986261e92f..6c7be4a3023 100644 --- a/fdb-relational-server/src/main/java/com/apple/foundationdb/relational/server/FRL.java +++ b/fdb-relational-server/src/main/java/com/apple/foundationdb/relational/server/FRL.java @@ -215,7 +215,7 @@ public Response execute(String database, String schema, String sql, List