From b1da686606c869752cdff387257283eb4408ad14 Mon Sep 17 00:00:00 2001 From: Vu Anh Phung Date: Wed, 2 Sep 2026 17:40:03 +0000 Subject: [PATCH 1/3] Enable native SEA metadata defaults behind server flag Signed-off-by: Vu Anh Phung --- NEXT_CHANGELOG.md | 1 + .../api/impl/DatabricksConnectionContext.java | 9 ++- .../jdbc/common/DatabricksJdbcUrlParams.java | 4 +- .../impl/DatabricksConnectionContextTest.java | 79 +++++++++++++++++++ 4 files changed, 89 insertions(+), 4 deletions(-) diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index 6c27fbc1ac..8466832e3c 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -6,6 +6,7 @@ - Added `EnableThriftNativeMetadata` to request and consume supported Thrift-native SEA metadata results. ### Updated +- `UseBoundedSeaApi` and `EnableThriftNativeMetadata` now default to `1`; when unset, activation is controlled by the server-side `enableNativeMetadataViaSEA` rollout flag. - `DatabaseMetaData.getColumns(...)` with a `null` catalog now issues a single `SHOW COLUMNS IN ALL CATALOGS` statement (consistent with `getSchemas`/`getTables`) instead of enumerating every catalog and issuing a per-catalog `SHOW COLUMNS`. Older DBR versions that do not support the syntax transparently fall back to the previous enumerate-and-fan-out behavior. - Updated bundled Jackson, lz4-java, Netty, and Apache HttpComponents Client and Core dependencies to patched versions to address security findings. diff --git a/src/main/java/com/databricks/jdbc/api/impl/DatabricksConnectionContext.java b/src/main/java/com/databricks/jdbc/api/impl/DatabricksConnectionContext.java index 25f8d1bbe7..05f1c59ea1 100644 --- a/src/main/java/com/databricks/jdbc/api/impl/DatabricksConnectionContext.java +++ b/src/main/java/com/databricks/jdbc/api/impl/DatabricksConnectionContext.java @@ -49,6 +49,9 @@ public class DatabricksConnectionContext implements IDatabricksConnectionContext private static final String USE_QUERY_FOR_THRIFT_FLAG_NAME = "databricks.partnerplatform.clientConfigsFeatureFlags.enableUseQueryForThriftJdbc"; + private static final String NATIVE_METADATA_VIA_SEA_FLAG_NAME = + "databricks.partnerplatform.clientConfigsFeatureFlags.enableNativeMetadataViaSEA"; + private final String host; @VisibleForTesting final int port; private final String schema; @@ -1519,7 +1522,8 @@ public boolean isSeaSyncMetadataEnabled() { @Override public boolean isThriftNativeMetadataEnabled() { - return getParameter(DatabricksJdbcUrlParams.ENABLE_THRIFT_NATIVE_METADATA).equals("1"); + return resolveFeatureFlag( + DatabricksJdbcUrlParams.ENABLE_THRIFT_NATIVE_METADATA, NATIVE_METADATA_VIA_SEA_FLAG_NAME); } @Override @@ -1549,7 +1553,8 @@ public boolean isCloudFetchEnabled() { @Override public boolean isBoundedSeaApiEnabled() { - return getParameter(DatabricksJdbcUrlParams.USE_BOUNDED_SEA_API).equals("1"); + return resolveFeatureFlag( + DatabricksJdbcUrlParams.USE_BOUNDED_SEA_API, NATIVE_METADATA_VIA_SEA_FLAG_NAME); } @Override diff --git a/src/main/java/com/databricks/jdbc/common/DatabricksJdbcUrlParams.java b/src/main/java/com/databricks/jdbc/common/DatabricksJdbcUrlParams.java index 5c983a003f..7b575910b7 100644 --- a/src/main/java/com/databricks/jdbc/common/DatabricksJdbcUrlParams.java +++ b/src/main/java/com/databricks/jdbc/common/DatabricksJdbcUrlParams.java @@ -215,11 +215,11 @@ public enum DatabricksJdbcUrlParams { USE_BOUNDED_SEA_API( "UseBoundedSeaApi", "Use bounded SEA API for CloudFetch: send row_offset on GetResultData, force StreamingChunkProvider, stop relying on total_chunk_count. Requires server support.", - "0"), + "1"), ENABLE_THRIFT_NATIVE_METADATA( "EnableThriftNativeMetadata", "Request Thrift-native SEA results for catalogs, schemas, tables, columns, functions, primary keys, imported keys, and cross references", - "0"), + "1"), DISABLE_OAUTH_REFRESH_TOKEN( "DisableOauthRefreshToken", "Disable requesting OAuth refresh tokens (omit offline_access unless explicitly provided)", diff --git a/src/test/java/com/databricks/jdbc/api/impl/DatabricksConnectionContextTest.java b/src/test/java/com/databricks/jdbc/api/impl/DatabricksConnectionContextTest.java index 3fcf26aff6..fbfc316c3c 100644 --- a/src/test/java/com/databricks/jdbc/api/impl/DatabricksConnectionContextTest.java +++ b/src/test/java/com/databricks/jdbc/api/impl/DatabricksConnectionContextTest.java @@ -1677,6 +1677,85 @@ public void testUseQueryForMetadata_clientExplicit0_overridesServerFlagEnabled() assertFalse(ctx.useQueryForMetadata()); } + @Test + public void testNativeMetadataViaSea_serverFlagEnabled_warehouseReturnsTrue() + throws DatabricksSQLException { + DatabricksConnectionContext ctx = + (DatabricksConnectionContext) + DatabricksConnectionContext.parse(TestConstants.VALID_URL_1, properties); + + Map flags = new HashMap<>(); + flags.put( + "databricks.partnerplatform.clientConfigsFeatureFlags.enableNativeMetadataViaSEA", "true"); + DatabricksDriverFeatureFlagsContextFactory.setFeatureFlagsContext(ctx, flags); + + assertEquals("1", DatabricksJdbcUrlParams.USE_BOUNDED_SEA_API.getDefaultValue()); + assertEquals("1", DatabricksJdbcUrlParams.ENABLE_THRIFT_NATIVE_METADATA.getDefaultValue()); + assertTrue(ctx.isBoundedSeaApiEnabled()); + assertTrue(ctx.isThriftNativeMetadataEnabled()); + } + + @Test + public void testNativeMetadataViaSea_serverFlagDisabled_warehouseReturnsFalse() + throws DatabricksSQLException { + DatabricksConnectionContext ctx = + (DatabricksConnectionContext) + DatabricksConnectionContext.parse(TestConstants.VALID_URL_1, properties); + + Map flags = new HashMap<>(); + flags.put( + "databricks.partnerplatform.clientConfigsFeatureFlags.enableNativeMetadataViaSEA", "false"); + DatabricksDriverFeatureFlagsContextFactory.setFeatureFlagsContext(ctx, flags); + + assertFalse(ctx.isBoundedSeaApiEnabled()); + assertFalse(ctx.isThriftNativeMetadataEnabled()); + } + + @Test + public void testNativeMetadataViaSea_serverFlagEnabled_clusterIgnored() + throws DatabricksSQLException { + DatabricksConnectionContext ctx = + (DatabricksConnectionContext) + DatabricksConnectionContext.parse(TestConstants.VALID_CLUSTER_URL, properties); + + Map flags = new HashMap<>(); + flags.put( + "databricks.partnerplatform.clientConfigsFeatureFlags.enableNativeMetadataViaSEA", "true"); + DatabricksDriverFeatureFlagsContextFactory.setFeatureFlagsContext(ctx, flags); + + assertFalse(ctx.isBoundedSeaApiEnabled()); + assertFalse(ctx.isThriftNativeMetadataEnabled()); + } + + @Test + public void testNativeMetadataViaSea_explicitParamsOverrideServerFlag() + throws DatabricksSQLException { + DatabricksConnectionContext enabledCtx = + (DatabricksConnectionContext) + DatabricksConnectionContext.parse( + TestConstants.VALID_URL_1 + ";UseBoundedSeaApi=1;EnableThriftNativeMetadata=1", + properties); + DatabricksConnectionContext disabledCtx = + (DatabricksConnectionContext) + DatabricksConnectionContext.parse( + TestConstants.VALID_URL_1 + ";UseBoundedSeaApi=0;EnableThriftNativeMetadata=0", + properties); + + Map disabledFlag = new HashMap<>(); + disabledFlag.put( + "databricks.partnerplatform.clientConfigsFeatureFlags.enableNativeMetadataViaSEA", "false"); + DatabricksDriverFeatureFlagsContextFactory.setFeatureFlagsContext(enabledCtx, disabledFlag); + Map enabledFlag = new HashMap<>(); + enabledFlag.put( + "databricks.partnerplatform.clientConfigsFeatureFlags.enableNativeMetadataViaSEA", "true"); + DatabricksDriverFeatureFlagsContextFactory.setFeatureFlagsContext(disabledCtx, enabledFlag); + + assertTrue(enabledCtx.isBoundedSeaApiEnabled()); + assertTrue(enabledCtx.isThriftNativeMetadataEnabled()); + assertFalse(disabledCtx.isBoundedSeaApiEnabled()); + assertFalse(disabledCtx.isThriftNativeMetadataEnabled()); + } + // --------------------------------------------------------------------------- // Geospatial flag independence from complex datatype flag // --------------------------------------------------------------------------- From 2af3439e6cd26fac8d63494a5121f3df77fc63bf Mon Sep 17 00:00:00 2001 From: Vu Anh Phung Date: Wed, 2 Sep 2026 21:38:06 +0000 Subject: [PATCH 2/3] Reuse SQL Exec flag for native metadata rollout Signed-off-by: Vu Anh Phung --- NEXT_CHANGELOG.md | 2 +- .../jdbc/api/impl/DatabricksConnectionContext.java | 8 ++------ .../api/impl/DatabricksConnectionContextTest.java | 13 +++++-------- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index 8466832e3c..c9388cda73 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -6,7 +6,7 @@ - Added `EnableThriftNativeMetadata` to request and consume supported Thrift-native SEA metadata results. ### Updated -- `UseBoundedSeaApi` and `EnableThriftNativeMetadata` now default to `1`; when unset, activation is controlled by the server-side `enableNativeMetadataViaSEA` rollout flag. +- `UseBoundedSeaApi` and `EnableThriftNativeMetadata` now default to `1`; when unset, activation is controlled by the server-side `enableSqlExecForJdbc` rollout flag. - `DatabaseMetaData.getColumns(...)` with a `null` catalog now issues a single `SHOW COLUMNS IN ALL CATALOGS` statement (consistent with `getSchemas`/`getTables`) instead of enumerating every catalog and issuing a per-catalog `SHOW COLUMNS`. Older DBR versions that do not support the syntax transparently fall back to the previous enumerate-and-fan-out behavior. - Updated bundled Jackson, lz4-java, Netty, and Apache HttpComponents Client and Core dependencies to patched versions to address security findings. diff --git a/src/main/java/com/databricks/jdbc/api/impl/DatabricksConnectionContext.java b/src/main/java/com/databricks/jdbc/api/impl/DatabricksConnectionContext.java index 05f1c59ea1..de58419856 100644 --- a/src/main/java/com/databricks/jdbc/api/impl/DatabricksConnectionContext.java +++ b/src/main/java/com/databricks/jdbc/api/impl/DatabricksConnectionContext.java @@ -49,9 +49,6 @@ public class DatabricksConnectionContext implements IDatabricksConnectionContext private static final String USE_QUERY_FOR_THRIFT_FLAG_NAME = "databricks.partnerplatform.clientConfigsFeatureFlags.enableUseQueryForThriftJdbc"; - private static final String NATIVE_METADATA_VIA_SEA_FLAG_NAME = - "databricks.partnerplatform.clientConfigsFeatureFlags.enableNativeMetadataViaSEA"; - private final String host; @VisibleForTesting final int port; private final String schema; @@ -1523,7 +1520,7 @@ public boolean isSeaSyncMetadataEnabled() { @Override public boolean isThriftNativeMetadataEnabled() { return resolveFeatureFlag( - DatabricksJdbcUrlParams.ENABLE_THRIFT_NATIVE_METADATA, NATIVE_METADATA_VIA_SEA_FLAG_NAME); + DatabricksJdbcUrlParams.ENABLE_THRIFT_NATIVE_METADATA, SQL_EXEC_FLAG_NAME); } @Override @@ -1553,8 +1550,7 @@ public boolean isCloudFetchEnabled() { @Override public boolean isBoundedSeaApiEnabled() { - return resolveFeatureFlag( - DatabricksJdbcUrlParams.USE_BOUNDED_SEA_API, NATIVE_METADATA_VIA_SEA_FLAG_NAME); + return resolveFeatureFlag(DatabricksJdbcUrlParams.USE_BOUNDED_SEA_API, SQL_EXEC_FLAG_NAME); } @Override diff --git a/src/test/java/com/databricks/jdbc/api/impl/DatabricksConnectionContextTest.java b/src/test/java/com/databricks/jdbc/api/impl/DatabricksConnectionContextTest.java index fbfc316c3c..3dae8a2c20 100644 --- a/src/test/java/com/databricks/jdbc/api/impl/DatabricksConnectionContextTest.java +++ b/src/test/java/com/databricks/jdbc/api/impl/DatabricksConnectionContextTest.java @@ -1685,8 +1685,7 @@ public void testNativeMetadataViaSea_serverFlagEnabled_warehouseReturnsTrue() DatabricksConnectionContext.parse(TestConstants.VALID_URL_1, properties); Map flags = new HashMap<>(); - flags.put( - "databricks.partnerplatform.clientConfigsFeatureFlags.enableNativeMetadataViaSEA", "true"); + flags.put("databricks.partnerplatform.clientConfigsFeatureFlags.enableSqlExecForJdbc", "true"); DatabricksDriverFeatureFlagsContextFactory.setFeatureFlagsContext(ctx, flags); assertEquals("1", DatabricksJdbcUrlParams.USE_BOUNDED_SEA_API.getDefaultValue()); @@ -1703,8 +1702,7 @@ public void testNativeMetadataViaSea_serverFlagDisabled_warehouseReturnsFalse() DatabricksConnectionContext.parse(TestConstants.VALID_URL_1, properties); Map flags = new HashMap<>(); - flags.put( - "databricks.partnerplatform.clientConfigsFeatureFlags.enableNativeMetadataViaSEA", "false"); + flags.put("databricks.partnerplatform.clientConfigsFeatureFlags.enableSqlExecForJdbc", "false"); DatabricksDriverFeatureFlagsContextFactory.setFeatureFlagsContext(ctx, flags); assertFalse(ctx.isBoundedSeaApiEnabled()); @@ -1719,8 +1717,7 @@ public void testNativeMetadataViaSea_serverFlagEnabled_clusterIgnored() DatabricksConnectionContext.parse(TestConstants.VALID_CLUSTER_URL, properties); Map flags = new HashMap<>(); - flags.put( - "databricks.partnerplatform.clientConfigsFeatureFlags.enableNativeMetadataViaSEA", "true"); + flags.put("databricks.partnerplatform.clientConfigsFeatureFlags.enableSqlExecForJdbc", "true"); DatabricksDriverFeatureFlagsContextFactory.setFeatureFlagsContext(ctx, flags); assertFalse(ctx.isBoundedSeaApiEnabled()); @@ -1743,11 +1740,11 @@ public void testNativeMetadataViaSea_explicitParamsOverrideServerFlag() Map disabledFlag = new HashMap<>(); disabledFlag.put( - "databricks.partnerplatform.clientConfigsFeatureFlags.enableNativeMetadataViaSEA", "false"); + "databricks.partnerplatform.clientConfigsFeatureFlags.enableSqlExecForJdbc", "false"); DatabricksDriverFeatureFlagsContextFactory.setFeatureFlagsContext(enabledCtx, disabledFlag); Map enabledFlag = new HashMap<>(); enabledFlag.put( - "databricks.partnerplatform.clientConfigsFeatureFlags.enableNativeMetadataViaSEA", "true"); + "databricks.partnerplatform.clientConfigsFeatureFlags.enableSqlExecForJdbc", "true"); DatabricksDriverFeatureFlagsContextFactory.setFeatureFlagsContext(disabledCtx, enabledFlag); assertTrue(enabledCtx.isBoundedSeaApiEnabled()); From 1155b7af1d9cd4dad6085b3df44e0ea22141ad91 Mon Sep 17 00:00:00 2001 From: Vu Anh Phung Date: Wed, 2 Sep 2026 22:29:54 +0000 Subject: [PATCH 3/3] Clean up native metadata feature flag tests Signed-off-by: Vu Anh Phung --- .../impl/DatabricksConnectionContextTest.java | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/databricks/jdbc/api/impl/DatabricksConnectionContextTest.java b/src/test/java/com/databricks/jdbc/api/impl/DatabricksConnectionContextTest.java index 3dae8a2c20..ed9c6df824 100644 --- a/src/test/java/com/databricks/jdbc/api/impl/DatabricksConnectionContextTest.java +++ b/src/test/java/com/databricks/jdbc/api/impl/DatabricksConnectionContextTest.java @@ -20,6 +20,7 @@ import com.databricks.jdbc.exception.DatabricksVendorCode; import com.databricks.sdk.core.ProxyConfig; import com.google.common.collect.ImmutableMap; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -27,6 +28,7 @@ import java.util.Map; import java.util.Properties; import java.util.stream.Stream; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -39,6 +41,7 @@ class DatabricksConnectionContextTest { private static final Properties properties = new Properties(); private static final Properties properties_with_pwd = new Properties(); + private final List featureFlagContextsToCleanUp = new ArrayList<>(); @BeforeAll public static void setUp() { @@ -46,6 +49,18 @@ public static void setUp() { properties_with_pwd.setProperty("pwd", "passwd2"); } + @AfterEach + public void cleanUpFeatureFlagContexts() { + featureFlagContextsToCleanUp.forEach( + DatabricksDriverFeatureFlagsContextFactory::removeInstance); + } + + private void setFeatureFlagsContext( + IDatabricksConnectionContext context, Map flags) { + featureFlagContextsToCleanUp.add(context); + DatabricksDriverFeatureFlagsContextFactory.setFeatureFlagsContext(context, flags); + } + @Test public void testBuildPropertiesMap() { String connectionParamString = "param1=value1;param2=value2"; @@ -1686,7 +1701,7 @@ public void testNativeMetadataViaSea_serverFlagEnabled_warehouseReturnsTrue() Map flags = new HashMap<>(); flags.put("databricks.partnerplatform.clientConfigsFeatureFlags.enableSqlExecForJdbc", "true"); - DatabricksDriverFeatureFlagsContextFactory.setFeatureFlagsContext(ctx, flags); + setFeatureFlagsContext(ctx, flags); assertEquals("1", DatabricksJdbcUrlParams.USE_BOUNDED_SEA_API.getDefaultValue()); assertEquals("1", DatabricksJdbcUrlParams.ENABLE_THRIFT_NATIVE_METADATA.getDefaultValue()); @@ -1703,7 +1718,7 @@ public void testNativeMetadataViaSea_serverFlagDisabled_warehouseReturnsFalse() Map flags = new HashMap<>(); flags.put("databricks.partnerplatform.clientConfigsFeatureFlags.enableSqlExecForJdbc", "false"); - DatabricksDriverFeatureFlagsContextFactory.setFeatureFlagsContext(ctx, flags); + setFeatureFlagsContext(ctx, flags); assertFalse(ctx.isBoundedSeaApiEnabled()); assertFalse(ctx.isThriftNativeMetadataEnabled()); @@ -1718,7 +1733,7 @@ public void testNativeMetadataViaSea_serverFlagEnabled_clusterIgnored() Map flags = new HashMap<>(); flags.put("databricks.partnerplatform.clientConfigsFeatureFlags.enableSqlExecForJdbc", "true"); - DatabricksDriverFeatureFlagsContextFactory.setFeatureFlagsContext(ctx, flags); + setFeatureFlagsContext(ctx, flags); assertFalse(ctx.isBoundedSeaApiEnabled()); assertFalse(ctx.isThriftNativeMetadataEnabled()); @@ -1741,11 +1756,11 @@ public void testNativeMetadataViaSea_explicitParamsOverrideServerFlag() Map disabledFlag = new HashMap<>(); disabledFlag.put( "databricks.partnerplatform.clientConfigsFeatureFlags.enableSqlExecForJdbc", "false"); - DatabricksDriverFeatureFlagsContextFactory.setFeatureFlagsContext(enabledCtx, disabledFlag); + setFeatureFlagsContext(enabledCtx, disabledFlag); Map enabledFlag = new HashMap<>(); enabledFlag.put( "databricks.partnerplatform.clientConfigsFeatureFlags.enableSqlExecForJdbc", "true"); - DatabricksDriverFeatureFlagsContextFactory.setFeatureFlagsContext(disabledCtx, enabledFlag); + setFeatureFlagsContext(disabledCtx, enabledFlag); assertTrue(enabledCtx.isBoundedSeaApiEnabled()); assertTrue(enabledCtx.isThriftNativeMetadataEnabled());