From 45d03e2c79bfc81d1046d549cec7fa40221a0b8e Mon Sep 17 00:00:00 2001 From: Thomas Powell Date: Fri, 27 Mar 2026 12:20:52 +0000 Subject: [PATCH 1/2] Surface truncated flag from SEA result manifest. --- .../api/impl/DatabricksResultSetMetaData.java | 18 +++++++++++++++- .../impl/DatabricksResultSetMetaDataTest.java | 21 +++++++++++++++++++ ...lExecApiHybridResultsIntegrationTests.java | 2 ++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/databricks/jdbc/api/impl/DatabricksResultSetMetaData.java b/src/main/java/com/databricks/jdbc/api/impl/DatabricksResultSetMetaData.java index 933d059fdf..ae7d956aaa 100644 --- a/src/main/java/com/databricks/jdbc/api/impl/DatabricksResultSetMetaData.java +++ b/src/main/java/com/databricks/jdbc/api/impl/DatabricksResultSetMetaData.java @@ -21,6 +21,7 @@ import com.databricks.jdbc.model.core.ColumnInfoTypeName; import com.databricks.jdbc.model.core.ColumnMetadata; import com.databricks.jdbc.model.core.ResultManifest; +import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import java.sql.ResultSetMetaData; import java.sql.SQLException; @@ -42,8 +43,9 @@ public class DatabricksResultSetMetaData implements ResultSetMetaData { private final ImmutableList columns; private final CaseInsensitiveImmutableMap columnNameIndex; private final long totalRows; - private Long chunkCount; + private final Long chunkCount; private final boolean isCloudFetchUsed; + private final boolean truncated; /** * Constructs a {@code DatabricksResultSetMetaData} object for a SEA result set. @@ -142,6 +144,7 @@ public DatabricksResultSetMetaData( this.totalRows = resultManifest.getTotalRowCount(); this.chunkCount = resultManifest.getTotalChunkCount(); this.isCloudFetchUsed = usesExternalLinks; + this.truncated = MoreObjects.firstNonNull(resultManifest.getTruncated(), false); } /** @@ -258,6 +261,7 @@ public DatabricksResultSetMetaData( this.totalRows = rows; this.chunkCount = chunkCount; this.isCloudFetchUsed = getIsCloudFetchFromManifest(resultManifest); + this.truncated = false; } /** @@ -306,7 +310,9 @@ public DatabricksResultSetMetaData( this.columns = columnsBuilder.build(); this.columnNameIndex = CaseInsensitiveImmutableMap.copyOf(columnNameToIndexMap); this.totalRows = totalRows; + this.chunkCount = -1L; this.isCloudFetchUsed = false; + this.truncated = false; } /** @@ -358,7 +364,9 @@ public DatabricksResultSetMetaData( this.columns = columnsBuilder.build(); this.columnNameIndex = CaseInsensitiveImmutableMap.copyOf(columnNameToIndexMap); this.totalRows = totalRows; + this.chunkCount = -1L; this.isCloudFetchUsed = false; + this.truncated = false; } /** @@ -416,7 +424,9 @@ public DatabricksResultSetMetaData( this.columns = columnsBuilder.build(); this.columnNameIndex = CaseInsensitiveImmutableMap.copyOf(columnNameToIndexMap); this.totalRows = totalRows; + this.chunkCount = -1L; this.isCloudFetchUsed = false; + this.truncated = false; } /** @@ -492,8 +502,10 @@ public DatabricksResultSetMetaData( this.statementId = statementId; this.isCloudFetchUsed = false; this.totalRows = -1; + this.chunkCount = -1L; this.columns = columnsBuilder.build(); this.columnNameIndex = CaseInsensitiveImmutableMap.copyOf(columnNameToIndexMap); + this.truncated = false; } @Override @@ -643,6 +655,10 @@ private boolean getIsCloudFetchFromManifest(TGetResultSetMetadataResp resultMani return resultManifest.getResultFormat() == TSparkRowSetType.URL_BASED_SET; } + public boolean getIsTruncated() { + return truncated; + } + public Long getChunkCount() { return chunkCount; } diff --git a/src/test/java/com/databricks/jdbc/api/impl/DatabricksResultSetMetaDataTest.java b/src/test/java/com/databricks/jdbc/api/impl/DatabricksResultSetMetaDataTest.java index 51474e21a5..a4b0c2e873 100644 --- a/src/test/java/com/databricks/jdbc/api/impl/DatabricksResultSetMetaDataTest.java +++ b/src/test/java/com/databricks/jdbc/api/impl/DatabricksResultSetMetaDataTest.java @@ -461,6 +461,7 @@ public void testGetDispositionThrift(TSparkRowSetType resultFormat) { } else { assertFalse(metaData.getIsCloudFetchUsed()); } + assertFalse(metaData.getIsTruncated()); } @Test @@ -476,6 +477,26 @@ public void testCloudFetchUsedSdk() { assertFalse(metaData.getIsCloudFetchUsed()); } + @Test + public void testSdkTruncated() { + ResultManifest resultManifest = getResultManifest(); + resultManifest.setTruncated(null); + + DatabricksResultSetMetaData metaData = + new DatabricksResultSetMetaData(STATEMENT_ID, resultManifest, true, connectionContext); + assertFalse(metaData.getIsTruncated()); + + resultManifest.setTruncated(true); + metaData = + new DatabricksResultSetMetaData(STATEMENT_ID, resultManifest, false, connectionContext); + assertTrue(metaData.getIsTruncated()); + + resultManifest.setTruncated(false); + metaData = + new DatabricksResultSetMetaData(STATEMENT_ID, resultManifest, false, connectionContext); + assertFalse(metaData.getIsTruncated()); + } + @Test public void testSEAInlineComplexType() throws SQLException { ResultManifest resultManifest = new ResultManifest(); diff --git a/src/test/java/com/databricks/jdbc/integration/fakeservice/tests/SqlExecApiHybridResultsIntegrationTests.java b/src/test/java/com/databricks/jdbc/integration/fakeservice/tests/SqlExecApiHybridResultsIntegrationTests.java index f5253eb7e0..eb49b5eef5 100644 --- a/src/test/java/com/databricks/jdbc/integration/fakeservice/tests/SqlExecApiHybridResultsIntegrationTests.java +++ b/src/test/java/com/databricks/jdbc/integration/fakeservice/tests/SqlExecApiHybridResultsIntegrationTests.java @@ -52,6 +52,7 @@ void testHybridSmallQuery() throws SQLException { assertEquals(maxRows, metaData.getTotalRows()); // For small query, arrow results are received inline in hybrid mode assertFalse(metaData.getIsCloudFetchUsed()); + assertFalse(metaData.getIsTruncated()); // For small query, arrow results are received inline in hybrid mode so no cloud fetch calls // are made @@ -93,6 +94,7 @@ void testHybridLargeQuery() throws SQLException { assertEquals(maxRows, metaData.getTotalRows()); // For large query, arrow results are fetched using cloud fetch assertTrue(metaData.getIsCloudFetchUsed()); + assertFalse(metaData.getIsTruncated()); // The number of cloud fetch calls should be equal to the number of chunks final int cloudFetchCalls = From b011fee110bd64d9cc56a0ab00933040bab70380 Mon Sep 17 00:00:00 2001 From: Thomas Powell Date: Fri, 27 Mar 2026 13:03:28 +0000 Subject: [PATCH 2/2] revert chunkcount changes --- .../jdbc/api/impl/DatabricksResultSetMetaData.java | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/databricks/jdbc/api/impl/DatabricksResultSetMetaData.java b/src/main/java/com/databricks/jdbc/api/impl/DatabricksResultSetMetaData.java index ae7d956aaa..25c09acdd3 100644 --- a/src/main/java/com/databricks/jdbc/api/impl/DatabricksResultSetMetaData.java +++ b/src/main/java/com/databricks/jdbc/api/impl/DatabricksResultSetMetaData.java @@ -21,15 +21,11 @@ import com.databricks.jdbc.model.core.ColumnInfoTypeName; import com.databricks.jdbc.model.core.ColumnMetadata; import com.databricks.jdbc.model.core.ResultManifest; -import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Types; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -43,7 +39,7 @@ public class DatabricksResultSetMetaData implements ResultSetMetaData { private final ImmutableList columns; private final CaseInsensitiveImmutableMap columnNameIndex; private final long totalRows; - private final Long chunkCount; + private Long chunkCount; private final boolean isCloudFetchUsed; private final boolean truncated; @@ -144,7 +140,7 @@ public DatabricksResultSetMetaData( this.totalRows = resultManifest.getTotalRowCount(); this.chunkCount = resultManifest.getTotalChunkCount(); this.isCloudFetchUsed = usesExternalLinks; - this.truncated = MoreObjects.firstNonNull(resultManifest.getTruncated(), false); + this.truncated = Objects.requireNonNullElse(resultManifest.getTruncated(), false); } /** @@ -310,7 +306,6 @@ public DatabricksResultSetMetaData( this.columns = columnsBuilder.build(); this.columnNameIndex = CaseInsensitiveImmutableMap.copyOf(columnNameToIndexMap); this.totalRows = totalRows; - this.chunkCount = -1L; this.isCloudFetchUsed = false; this.truncated = false; } @@ -364,7 +359,6 @@ public DatabricksResultSetMetaData( this.columns = columnsBuilder.build(); this.columnNameIndex = CaseInsensitiveImmutableMap.copyOf(columnNameToIndexMap); this.totalRows = totalRows; - this.chunkCount = -1L; this.isCloudFetchUsed = false; this.truncated = false; } @@ -424,7 +418,6 @@ public DatabricksResultSetMetaData( this.columns = columnsBuilder.build(); this.columnNameIndex = CaseInsensitiveImmutableMap.copyOf(columnNameToIndexMap); this.totalRows = totalRows; - this.chunkCount = -1L; this.isCloudFetchUsed = false; this.truncated = false; } @@ -502,7 +495,6 @@ public DatabricksResultSetMetaData( this.statementId = statementId; this.isCloudFetchUsed = false; this.totalRows = -1; - this.chunkCount = -1L; this.columns = columnsBuilder.build(); this.columnNameIndex = CaseInsensitiveImmutableMap.copyOf(columnNameToIndexMap); this.truncated = false;