Title: [FlightSQL][JDBC] NullPointerException in DatabaseMetadata methods when SqlInfo is unavailable · Issue #994 · apache/arrow-java · GitHub
Open Graph Title: [FlightSQL][JDBC] NullPointerException in DatabaseMetadata methods when SqlInfo is unavailable · Issue #994 · apache/arrow-java
X Title: [FlightSQL][JDBC] NullPointerException in DatabaseMetadata methods when SqlInfo is unavailable · Issue #994 · apache/arrow-java
Description: 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...
Open Graph Description: 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.g...
X Description: 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 ArrowDatabaseMetada...
Opengraph URL: https://github.com/apache/arrow-java/issues/994
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"[FlightSQL][JDBC] NullPointerException in DatabaseMetadata methods when SqlInfo is unavailable","articleBody":"## Describe the bug\n\nMultiple 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()`.\n\n## Affected Methods\n\nAll 68+ DatabaseMetadata methods that rely on `getSqlInfoAndCacheIfCacheIsEmpty()` are affected, including:\n\n### Integer-returning methods (20 methods)\n- `getMaxBinaryLiteralLength()`\n- `getMaxCharLiteralLength()`\n- `getMaxColumnNameLength()`\n- `getMaxColumnsInGroupBy()`\n- `getMaxColumnsInIndex()`\n- `getMaxColumnsInOrderBy()`\n- `getMaxColumnsInSelect()`\n- `getMaxColumnsInTable()`\n- `getMaxConnections()`\n- `getMaxCursorNameLength()`\n- `getMaxIndexLength()`\n- `getMaxSchemaNameLength()`\n- `getMaxProcedureNameLength()`\n- `getMaxCatalogNameLength()`\n- `getMaxRowSize()`\n- `getMaxStatementLength()`\n- `getMaxStatements()`\n- `getMaxTableNameLength()`\n- `getMaxTablesInSelect()`\n- `getMaxUserNameLength()`\n\n### Boolean-returning methods (30 methods)\n- `supportsColumnAliasing()`\n- `nullPlusNonNullIsNull()`\n- `supportsTableCorrelationNames()`\n- `supportsDifferentTableCorrelationNames()`\n- `supportsExpressionsInOrderBy()`\n- `supportsOrderByUnrelated()`\n- `supportsLikeEscapeClause()`\n- `supportsNonNullableColumns()`\n- `supportsIntegrityEnhancementFacility()`\n- `isCatalogAtStart()`\n- `supportsSelectForUpdate()`\n- `supportsStoredProcedures()`\n- `supportsCorrelatedSubqueries()`\n- `doesMaxRowSizeIncludeBlobs()`\n- `supportsTransactions()`\n- `dataDefinitionCausesTransactionCommit()`\n- `dataDefinitionIgnoredInTransactions()`\n- `supportsBatchUpdates()`\n- `supportsSavepoints()`\n- `supportsNamedParameters()`\n- `locatorsUpdateCopy()`\n- `supportsStoredFunctionsUsingCallSyntax()`\n\n### Support level methods (18 methods)\n- `getDefaultTransactionIsolation()`\n- `supportsGroupBy()`\n- `supportsGroupByUnrelated()`\n- `supportsMinimumSQLGrammar()`\n- `supportsCoreSQLGrammar()`\n- `supportsExtendedSQLGrammar()`\n- `supportsANSI92EntryLevelSQL()`\n- `supportsANSI92IntermediateSQL()`\n- `supportsANSI92FullSQL()`\n- `supportsOuterJoins()`\n- `supportsFullOuterJoins()`\n- `supportsLimitedOuterJoins()`\n- `supportsSchemasInProcedureCalls()`\n- `supportsSchemasInIndexDefinitions()`\n- `supportsSchemasInPrivilegeDefinitions()`\n- `supportsCatalogsInIndexDefinitions()`\n- `supportsCatalogsInPrivilegeDefinitions()`\n- `supportsPositionedDelete()`\n- `supportsPositionedUpdate()`\n- `supportsSubqueriesInComparisons()`\n- `supportsSubqueriesInExists()`\n- `supportsSubqueriesInIns()`\n- `supportsSubqueriesInQuantifieds()`\n- `supportsUnion()`\n- `supportsUnionAll()`\n\n### Map-returning methods\n- `supportsConvert()`\n\n## Component(s)\n\n- FlightSQL\n- JDBC\n\n## To Reproduce\n\n```java\nimport java.sql.*;\nimport java.util.Properties;\n\npublic class DatabaseMetadataTest {\n public static void main(String[] args) throws SQLException {\n String url = \"jdbc:arrow-flight-sql://...\";\n Properties props = new Properties();\n Driver driver = DriverManager.getDriver(url);\n try (Connection conn = driver.connect(url, props)) {\n DatabaseMetaData metaData = conn.getMetaData();\n\n // All of these throw NullPointerException\n System.out.println(metaData.getMaxBinaryLiteralLength());\n System.out.println(metaData.supportsTransactions());\n System.out.println(metaData.supportsGroupBy());\n }\n }\n}\n```\n\n### Error Output\n\n```\nException in thread \"main\" java.lang.NullPointerException: Cannot invoke \"java.lang.Long.intValue()\"\nbecause the return value of \"org.apache.arrow.driver.jdbc.ArrowDatabaseMetadata.getSqlInfoAndCacheIfCacheIsEmpty\n(org.apache.arrow.driver.jdbc.shaded.org.apache.arrow.flight.sql.impl.FlightSql$SqlInfo, java.lang.Class)\" is null\n\tat org.apache.arrow.driver.jdbc.ArrowDatabaseMetadata.getMaxBinaryLiteralLength(ArrowDatabaseMetadata.java:xxx)\n```\n\n## Expected behavior\n\n1. **Option A:** Return sensible defaults when SqlInfo is unavailable:\n - Integer methods: return `0` (as per JDBC spec for \"no limit\" or \"unknown\")\n - Boolean methods: return `false` (conservative/safe default)\n - Support level methods: return appropriate default enums\n - Map methods: return empty map\n\n2. **Option B:** Throw `SQLException` with a descriptive message indicating the server doesn't support the requested SqlInfo\n\n3. Methods should NOT throw unchecked `NullPointerException` - this violates JDBC contracts and the principle of least surprise\n\n## Environment\n\n**Arrow Version:**\n- 18.3.0\n\n**Java Version:**\n- Java 11+\n\n**OS:**\n- All platforms\n\n### JDBC Specification Reference\n\nPer JDBC 4.3 specification:\n- Methods returning int should return 0 when the limit is unknown or there is no limit\n- Methods returning boolean should return false for unsupported features\n- Methods should throw SQLException for errors, not unchecked exceptions","author":{"url":"https://github.com/merzbird","@type":"Person","name":"merzbird"},"datePublished":"2026-01-29T10:12:42.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":4},"url":"https://github.com/994/arrow-java/issues/994"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:4aeaf3e0-4988-4a6c-0c6c-e28733be390b |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | B6B4:1A1C5F:10B040:15D5C7:6990F033 |
| html-safe-nonce | 0de23972cf77e96437f101375caea8a39835d4ea9cbf067398098659889b065d |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCNkI0OjFBMUM1RjoxMEIwNDA6MTVENUM3OjY5OTBGMDMzIiwidmlzaXRvcl9pZCI6IjY0NTA3NDg4ODcwMTE0ODc3OTUiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 1ef145f146ea46077e3cb8480030e45505146ec1ae1bf5b975ab906f5bfad025 |
| hovercard-subject-tag | issue:3869862777 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/apache/arrow-java/994/issue_layout |
| twitter:image | https://opengraph.githubassets.com/222c58bee245bbd1c59f767ef7c587f7b9f9cfe1402db961fd5bac0d1fc12a94/apache/arrow-java/issues/994 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/222c58bee245bbd1c59f767ef7c587f7b9f9cfe1402db961fd5bac0d1fc12a94/apache/arrow-java/issues/994 |
| og:image:alt | 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.g... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | merzbird |
| hostname | github.com |
| expected-hostname | github.com |
| None | 42c603b9d642c4a9065a51770f75e5e27132fef0e858607f5c9cb7e422831a7b |
| turbo-cache-control | no-preview |
| go-import | github.com/apache/arrow-java git https://github.com/apache/arrow-java.git |
| octolytics-dimension-user_id | 47359 |
| octolytics-dimension-user_login | apache |
| octolytics-dimension-repository_id | 893682219 |
| octolytics-dimension-repository_nwo | apache/arrow-java |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 893682219 |
| octolytics-dimension-repository_network_root_nwo | apache/arrow-java |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 848bc6032dcc93a9a7301dcc3f379a72ba13b96e |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width