Skip to content

Commit 1893a40

Browse files
sreekanth-dbclaude
andauthored
Fix IndexOutOfBoundsException in Arrow Metadata Access for DDL Statements (databricks#1186)
## Description Fixed `IndexOutOfBoundsException` that occurs when executing DDL statements (e.g., `CREATE DATABASE`) using the Thrift protocol. The bug manifests when there's a mismatch between the number of Thrift column descriptors and Arrow schema fields. ### Root Cause When executing DDL statements, the Databricks server behavior is: - **Thrift Protocol**: Returns column descriptors including a "Result" status column (1 column) - **Arrow Schema**: Returns an empty schema with 0 fields (no actual data) - **The Bug**: Code attempted to access `arrowMetadata[0]` without checking if the list was empty This mismatch caused `IndexOutOfBoundsException` when the driver tried to access arrow metadata at index 0 of an empty list. ### Debug Evidence **TColumnDesc (Thrift)**: ``` Column[0]: name: Result type: STRING_TYPE position: 1 Full TColumnDesc: TColumnDesc(columnName:Result, typeDesc:TTypeDesc(...), position:1, comment:) ``` **Arrow Schema**: ``` Arrow schema bytes length: 72 Deserialized Arrow schema, field count: 0 ← Empty! Arrow metadata list: size=0 ``` ### Changes Made Added bounds checking in two locations where arrow metadata is accessed: 1. **`ArrowUtil.java:247`** - Used by `StreamingInlineArrowResult` 2. **`DatabricksResultSetMetaData.java:195`** - Used for result set metadata construction **Before:** ```java String columnArrowMetadata = arrowMetadata != null ? arrowMetadata.get(columnIndex) : null; ``` **After:** ```java String columnArrowMetadata = arrowMetadata != null && columnIndex < arrowMetadata.size() ? arrowMetadata.get(columnIndex) : null; ``` ## Testing ### Manual Testing **Test Case**: Execute CREATE DATABASE statement ```java String sqlQuery = "CREATE DATABASE IF NOT EXISTS hive_metastore.test_db"; boolean hasResultSet = stmt.execute(sqlQuery); ``` **Before Fix**: `IndexOutOfBoundsException: Index 0 out of bounds for length 0` **After Fix**: Executes successfully, returns `hasResultSet=false` ## Additional Notes to the Reviewer NO_CHANGELOG=true Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 1a68271 commit 1893a40

File tree

2 files changed

+6
-2
lines changed

2 files changed

+6
-2
lines changed

src/main/java/com/databricks/jdbc/api/impl/DatabricksResultSetMetaData.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,9 @@ public DatabricksResultSetMetaData(
192192
TColumnDesc columnDesc = resultManifest.getSchema().getColumns().get(columnIndex);
193193

194194
String columnArrowMetadata =
195-
arrowMetadata != null ? arrowMetadata.get(columnIndex) : null;
195+
arrowMetadata != null && columnIndex < arrowMetadata.size()
196+
? arrowMetadata.get(columnIndex)
197+
: null;
196198
ColumnInfo columnInfo = getColumnInfoFromTColumnDesc(columnDesc, columnArrowMetadata);
197199
int[] precisionAndScale = getPrecisionAndScale(columnInfo);
198200
int precision = precisionAndScale[0];

src/main/java/com/databricks/jdbc/common/util/ArrowUtil.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,9 @@ public static List<ColumnInfo> getColumnInfoList(TGetResultSetMetadataResp resul
245245
for (int columnIndex = 0; columnIndex < columns.size(); columnIndex++) {
246246
TColumnDesc tColumnDesc = columns.get(columnIndex);
247247
String columnArrowMetadata =
248-
arrowMetadataList != null ? arrowMetadataList.get(columnIndex) : null;
248+
arrowMetadataList != null && columnIndex < arrowMetadataList.size()
249+
? arrowMetadataList.get(columnIndex)
250+
: null;
249251
columnInfos.add(getColumnInfoFromTColumnDesc(tColumnDesc, columnArrowMetadata));
250252
}
251253
return columnInfos;

0 commit comments

Comments
 (0)