Describe the bug
Multiple DatabaseMetadata methods in the Arrow Flight SQL JDBC driver throw NullPointerException when the server doesn't provide certain SqlInfo values. The ArrowDatabaseMetadata.getSqlInfoAndCacheIfCacheIsEmpty() method returns null, but calling code doesn't handle null defensively before invoking methods like .intValue(), .booleanValue(), or .isEmpty().
Affected Methods
All 68+ DatabaseMetadata methods that rely on getSqlInfoAndCacheIfCacheIsEmpty() are affected, including:
Integer-returning methods (20 methods)
- getMaxBinaryLiteralLength()
- getMaxCharLiteralLength()
- getMaxColumnNameLength()
- getMaxColumnsInGroupBy()
- getMaxColumnsInIndex()
- getMaxColumnsInOrderBy()
- getMaxColumnsInSelect()
- getMaxColumnsInTable()
- getMaxConnections()
- getMaxCursorNameLength()
- getMaxIndexLength()
- getMaxSchemaNameLength()
- getMaxProcedureNameLength()
- getMaxCatalogNameLength()
- getMaxRowSize()
- getMaxStatementLength()
- getMaxStatements()
- getMaxTableNameLength()
- getMaxTablesInSelect()
- getMaxUserNameLength()
Boolean-returning methods (30 methods)
- supportsColumnAliasing()
- nullPlusNonNullIsNull()
- supportsTableCorrelationNames()
- supportsDifferentTableCorrelationNames()
- supportsExpressionsInOrderBy()
- supportsOrderByUnrelated()
- supportsLikeEscapeClause()
- supportsNonNullableColumns()
- supportsIntegrityEnhancementFacility()
- isCatalogAtStart()
- supportsSelectForUpdate()
- supportsStoredProcedures()
- supportsCorrelatedSubqueries()
- doesMaxRowSizeIncludeBlobs()
- supportsTransactions()
- dataDefinitionCausesTransactionCommit()
- dataDefinitionIgnoredInTransactions()
- supportsBatchUpdates()
- supportsSavepoints()
- supportsNamedParameters()
- locatorsUpdateCopy()
- supportsStoredFunctionsUsingCallSyntax()
Support level methods (18 methods)
- getDefaultTransactionIsolation()
- supportsGroupBy()
- supportsGroupByUnrelated()
- supportsMinimumSQLGrammar()
- supportsCoreSQLGrammar()
- supportsExtendedSQLGrammar()
- supportsANSI92EntryLevelSQL()
- supportsANSI92IntermediateSQL()
- supportsANSI92FullSQL()
- supportsOuterJoins()
- supportsFullOuterJoins()
- supportsLimitedOuterJoins()
- supportsSchemasInProcedureCalls()
- supportsSchemasInIndexDefinitions()
- supportsSchemasInPrivilegeDefinitions()
- supportsCatalogsInIndexDefinitions()
- supportsCatalogsInPrivilegeDefinitions()
- supportsPositionedDelete()
- supportsPositionedUpdate()
- supportsSubqueriesInComparisons()
- supportsSubqueriesInExists()
- supportsSubqueriesInIns()
- supportsSubqueriesInQuantifieds()
- supportsUnion()
- supportsUnionAll()
Map-returning methods
Component(s)
To Reproduce
import java.sql.*;
import java.util.Properties;
public class DatabaseMetadataTest {
public static void main(String[] args) throws SQLException {
String url = "jdbc:arrow-flight-sql://...";
Properties props = new Properties();
Driver driver = DriverManager.getDriver(url);
try (Connection conn = driver.connect(url, props)) {
DatabaseMetaData metaData = conn.getMetaData();
// All of these throw NullPointerException
System.out.println(metaData.getMaxBinaryLiteralLength());
System.out.println(metaData.supportsTransactions());
System.out.println(metaData.supportsGroupBy());
}
}
}
Error Output
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.Long.intValue()"
because the return value of "org.apache.arrow.driver.jdbc.ArrowDatabaseMetadata.getSqlInfoAndCacheIfCacheIsEmpty
(org.apache.arrow.driver.jdbc.shaded.org.apache.arrow.flight.sql.impl.FlightSql$SqlInfo, java.lang.Class)" is null
at org.apache.arrow.driver.jdbc.ArrowDatabaseMetadata.getMaxBinaryLiteralLength(ArrowDatabaseMetadata.java:xxx)
Expected behavior
-
Option A: Return sensible defaults when SqlInfo is unavailable:
- Integer methods: return 0 (as per JDBC spec for "no limit" or "unknown")
- Boolean methods: return false (conservative/safe default)
- Support level methods: return appropriate default enums
- Map methods: return empty map
-
Option B: Throw SQLException with a descriptive message indicating the server doesn't support the requested SqlInfo
-
Methods should NOT throw unchecked NullPointerException - this violates JDBC contracts and the principle of least surprise
Environment
Arrow Version:
Java Version:
OS:
JDBC Specification Reference
Per JDBC 4.3 specification:
- Methods returning int should return 0 when the limit is unknown or there is no limit
- Methods returning boolean should return false for unsupported features
- Methods should throw SQLException for errors, not unchecked exceptions
Reactions are currently unavailable
Describe the bug
Multiple DatabaseMetadata methods in the Arrow Flight SQL JDBC driver throw NullPointerException when the server doesn't provide certain SqlInfo values. The ArrowDatabaseMetadata.getSqlInfoAndCacheIfCacheIsEmpty() method returns null, but calling code doesn't handle null defensively before invoking methods like .intValue(), .booleanValue(), or .isEmpty().
Affected Methods
All 68+ DatabaseMetadata methods that rely on getSqlInfoAndCacheIfCacheIsEmpty() are affected, including:
Integer-returning methods (20 methods)
Boolean-returning methods (30 methods)
Support level methods (18 methods)
Map-returning methods
Component(s)
To Reproduce
Error Output
Expected behavior
Option A: Return sensible defaults when SqlInfo is unavailable:
Option B: Throw SQLException with a descriptive message indicating the server doesn't support the requested SqlInfo
Methods should NOT throw unchecked NullPointerException - this violates JDBC contracts and the principle of least surprise
Environment
Arrow Version:
Java Version:
OS:
JDBC Specification Reference
Per JDBC 4.3 specification: