merzbird opened a new issue, #994:
URL: https://github.com/apache/arrow-java/issues/994
### Describe the bug, including details regarding any error messages,
version, and platform.
## 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
- `supportsConvert()`
## Component(s)
- FlightSQL
- JDBC
## To Reproduce
```java
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
1. **Option A (Preferred):** 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
2. **Option B:** Throw `SQLException` with a descriptive message indicating
the server doesn't support the requested SqlInfo
3. Methods should NOT throw unchecked `NullPointerException` - this violates
JDBC contracts and the principle of least surprise
## Environment
**Arrow Version:**
- Latest version (observed in production use)
**Java Version:**
- Java 11+
**OS:**
- All platforms
### 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
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]