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]

Reply via email to