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
Describe the bug
Multiple DatabaseMetadata methods in the Arrow Flight SQL JDBC driver throw
NullPointerExceptionwhen the server doesn't provide certain SqlInfo values. TheArrowDatabaseMetadata.getSqlInfoAndCacheIfCacheIsEmpty()method returnsnull, 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
supportsConvert()Component(s)
To Reproduce
Error Output
Expected behavior
Option A: Return sensible defaults when SqlInfo is unavailable:
0(as per JDBC spec for "no limit" or "unknown")false(conservative/safe default)Option B: Throw
SQLExceptionwith a descriptive message indicating the server doesn't support the requested SqlInfoMethods should NOT throw unchecked
NullPointerException- this violates JDBC contracts and the principle of least surpriseEnvironment
Arrow Version:
Java Version:
OS:
JDBC Specification Reference
Per JDBC 4.3 specification: