Skip to content

Commit 512026e

Browse files
authored
Added support for enableMultipleCatalogSupport param (#1025)
## Description <!-- Provide a brief summary of the changes made and the issue they aim to address.--> Added support for the connection param of enableMultipleCatalogSupport. The default value is kept to 1. The behaviour remains the same when the param is enabled. When the param is disabled, the behaviour is as follows: - getCatalogs() returns only the current catalog - Metadata operations are done on the current catalog - setCatalog() method does nothing (doesn't execute USE CATALOG) - The SQL query of USE CATALOG can still be executed. To maintain the current catalog, we make the query to get the current catalog everytime when this param is disabled. ## Testing <!-- Describe how the changes have been tested--> ## Additional Notes to the Reviewer <!-- Share any additional context or insights that may help the reviewer understand the changes better. This could include challenges faced, limitations, or compromises made during the development process. Also, mention any areas of the code that you would like the reviewer to focus on specifically. --> [PECOBLR-938](https://databricks.atlassian.net/browse/PECOBLR-938) [PECOBLR-938]: https://databricks.atlassian.net/browse/PECOBLR-938?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
1 parent b2cd651 commit 512026e

34 files changed

Lines changed: 847 additions & 8 deletions

File tree

.github/workflows/runIntegrationTests.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,7 @@ jobs:
5353
DATABRICKS_JDBC_M2M_PRIVATE_KEY_AUTH_KID: ${{ secrets.DATABRICKS_JDBC_M2M_PRIVATE_KEY_AUTH_KID }}
5454
DATABRICKS_JDBC_M2M_PRIVATE_KEY_JWT_KEY_PASSPHRASE: ${{ secrets.DATABRICKS_JDBC_M2M_PRIVATE_KEY_JWT_KEY_PASSPHRASE }}
5555
DATABRICKS_JDBC_M2M_PRIVATE_KEY_CREDENTIALS_HTTP_PATH: ${{ secrets.DATABRICKS_JDBC_M2M_PRIVATE_KEY_CREDENTIALS_HTTP_PATH }}
56-
DATABRICKS_JDBC_M2M_PRIVATE_KEY_CREDENTIALS_HOST: ${{ secrets.DATABRICKS_JDBC_M2M_PRIVATE_KEY_CREDENTIALS_HOST }}
56+
DATABRICKS_JDBC_M2M_PRIVATE_KEY_CREDENTIALS_HOST: ${{ secrets.DATABRICKS_JDBC_M2M_PRIVATE_KEY_CREDENTIALS_HOST }}
57+
DATABRICKS_BENCHFOOD_TOKEN: ${{ secrets.DATABRICKS_BENCHFOOD_TOKEN }}
58+
DATABRICKS_BENCHFOOD_HTTP_PATH: ${{ secrets.DATABRICKS_BENCHFOOD_HTTP_PATH }}
59+
DATABRICKS_BENCHFOOD_HOST: ${{ secrets.DATABRICKS_BENCHFOOD_HOST }}

NEXT_CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
### Added
66

7+
- Added `enableMultipleCatalogSupport` connection parameter to control catalog metadata behavior.
8+
79
### Updated
810

911
### Fixed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,11 @@ public boolean isReadOnly() throws SQLException {
199199

200200
@Override
201201
public void setCatalog(String catalog) throws SQLException {
202+
// If enableMultipleCatalogSupport is disabled, setCatalog does nothing
203+
if (!connectionContext.getEnableMultipleCatalogSupport()) {
204+
LOGGER.debug("setCatalog ignored - enableMultipleCatalogSupport is disabled");
205+
return;
206+
}
202207
Statement statement = this.createStatement();
203208
statement.execute("SET CATALOG " + catalog);
204209
this.session.setCatalog(catalog);

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,10 @@ public boolean getEnableSQLValidationForIsValid() {
236236
.equals("1");
237237
}
238238

239+
public boolean getEnableMultipleCatalogSupport() {
240+
return getParameter(DatabricksJdbcUrlParams.ENABLE_MULTIPLE_CATALOG_SUPPORT, "1").equals("1");
241+
}
242+
239243
@Override
240244
public String getHostForOAuth() {
241245
return this.host;

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.databricks.jdbc.common.DatabricksClientType;
1010
import com.databricks.jdbc.common.DatabricksJdbcUrlParams;
1111
import com.databricks.jdbc.common.IDatabricksComputeResource;
12+
import com.databricks.jdbc.common.StatementType;
1213
import com.databricks.jdbc.dbclient.IDatabricksClient;
1314
import com.databricks.jdbc.dbclient.IDatabricksMetadataClient;
1415
import com.databricks.jdbc.dbclient.impl.sqlexec.DatabricksEmptyMetadataClient;
@@ -24,6 +25,7 @@
2425
import com.databricks.jdbc.telemetry.latency.DatabricksMetricsTimedProcessor;
2526
import com.databricks.sdk.support.ToStringer;
2627
import com.google.common.annotations.VisibleForTesting;
28+
import java.util.HashMap;
2729
import java.util.Map;
2830
import javax.annotation.Nullable;
2931

@@ -277,6 +279,30 @@ public IDatabricksConnectionContext getConnectionContext() {
277279
return this.connectionContext;
278280
}
279281

282+
@Override
283+
public String getCurrentCatalog() throws DatabricksSQLException {
284+
try {
285+
DatabricksResultSet resultSet =
286+
databricksClient.executeStatement(
287+
"SELECT CURRENT_CATALOG()",
288+
this.computeResource,
289+
new HashMap<>(),
290+
StatementType.METADATA,
291+
this,
292+
null);
293+
294+
if (resultSet.next()) {
295+
String currentCatalog = resultSet.getString(1);
296+
return currentCatalog;
297+
}
298+
} catch (Exception e) {
299+
LOGGER.warn(
300+
"Failed to get current catalog from database, falling back to session catalog: {}",
301+
e.getMessage());
302+
}
303+
return this.catalog;
304+
}
305+
280306
@Override
281307
public void setEmptyMetadataClient() {
282308
databricksMetadataClient = new DatabricksEmptyMetadataClient(connectionContext);

src/main/java/com/databricks/jdbc/api/internal/IDatabricksConnectionContext.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ public interface IDatabricksConnectionContext {
9999
/** Returns the value of the EnableSQLValidationForIsValid connection property. */
100100
boolean getEnableSQLValidationForIsValid();
101101

102+
/** Returns the value of the enableMultipleCatalogSupport connection property. */
103+
boolean getEnableMultipleCatalogSupport();
104+
102105
String getProxyHost();
103106

104107
int getProxyPort();

src/main/java/com/databricks/jdbc/api/internal/IDatabricksSession.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ public interface IDatabricksSession {
8484
/** Returns the associated connection context for the session */
8585
IDatabricksConnectionContext getConnectionContext();
8686

87+
/** Gets the current catalog from the database */
88+
String getCurrentCatalog() throws DatabricksSQLException;
89+
8790
void setEmptyMetadataClient();
8891

8992
void forceClose();

src/main/java/com/databricks/jdbc/common/DatabricksJdbcUrlParams.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,9 @@ public enum DatabricksJdbcUrlParams {
164164
"Enable SQL query execution for connection validation in isValid() method",
165165
"0"),
166166
IGNORE_TRANSACTIONS("IgnoreTransactions", "Ignore transaction-related method calls", "0"),
167-
ENABLE_METRIC_VIEW_METADATA("EnableMetricViewMetadata", "Enable metric view metadata", "0");
168-
167+
ENABLE_METRIC_VIEW_METADATA("EnableMetricViewMetadata", "Enable metric view metadata", "0"),
168+
ENABLE_MULTIPLE_CATALOG_SUPPORT(
169+
"enableMultipleCatalogSupport", "Enable multiple catalog support", "1");
169170
private final String paramName;
170171
private final String defaultValue;
171172
private final String description;

src/main/java/com/databricks/jdbc/dbclient/impl/sqlexec/DatabricksMetadataSdkClient.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,19 @@ public DatabricksMetadataSdkClient(IDatabricksClient sdkClient) {
4242
this.metadataResultSetBuilder = new MetadataResultSetBuilder(sdkClient.getConnectionContext());
4343
}
4444

45+
private boolean isMultipleCatalogSupportDisabled() {
46+
return sdkClient.getConnectionContext() != null
47+
&& !sdkClient.getConnectionContext().getEnableMultipleCatalogSupport();
48+
}
49+
50+
private String autoFillCatalog(String catalog, IDatabricksSession session) throws SQLException {
51+
if (isMultipleCatalogSupportDisabled()) {
52+
String currentCatalog = session.getCurrentCatalog();
53+
return (currentCatalog != null && !currentCatalog.isEmpty()) ? currentCatalog : "";
54+
}
55+
return catalog;
56+
}
57+
4558
@Override
4659
public DatabricksResultSet listTypeInfo(IDatabricksSession session) {
4760
LOGGER.debug("public ResultSet getTypeInfo()");
@@ -50,6 +63,19 @@ public DatabricksResultSet listTypeInfo(IDatabricksSession session) {
5063

5164
@Override
5265
public DatabricksResultSet listCatalogs(IDatabricksSession session) throws SQLException {
66+
// If multiple catalog support is disabled, return only the current catalog
67+
if (isMultipleCatalogSupportDisabled()) {
68+
String currentCatalog = session.getCurrentCatalog();
69+
if (currentCatalog == null || currentCatalog.isEmpty()) {
70+
currentCatalog = "";
71+
}
72+
List<List<Object>> singleCatalogRows = new ArrayList<>();
73+
List<Object> catalogRow = new ArrayList<>();
74+
catalogRow.add(currentCatalog);
75+
singleCatalogRows.add(catalogRow);
76+
return metadataResultSetBuilder.getCatalogsResult(singleCatalogRows);
77+
}
78+
5379
CommandBuilder commandBuilder = new CommandBuilder(session);
5480
String SQL = commandBuilder.getSQLString(CommandName.LIST_CATALOGS);
5581
LOGGER.debug("SQL command to fetch catalogs: {}", SQL);
@@ -59,6 +85,7 @@ public DatabricksResultSet listCatalogs(IDatabricksSession session) throws SQLEx
5985
@Override
6086
public DatabricksResultSet listSchemas(
6187
IDatabricksSession session, String catalog, String schemaNamePattern) throws SQLException {
88+
catalog = autoFillCatalog(catalog, session);
6289
CommandBuilder commandBuilder =
6390
new CommandBuilder(catalog, session).setSchemaPattern(schemaNamePattern);
6491
String SQL = commandBuilder.getSQLString(CommandName.LIST_SCHEMAS);
@@ -87,6 +114,7 @@ public DatabricksResultSet listTables(
87114
String tableNamePattern,
88115
String[] tableTypes)
89116
throws SQLException {
117+
catalog = autoFillCatalog(catalog, session);
90118
String[] validatedTableTypes =
91119
Optional.ofNullable(tableTypes)
92120
.filter(types -> types.length > 0)
@@ -132,6 +160,7 @@ public DatabricksResultSet listColumns(
132160
String tableNamePattern,
133161
String columnNamePattern)
134162
throws SQLException {
163+
catalog = autoFillCatalog(catalog, session);
135164
CommandBuilder commandBuilder =
136165
new CommandBuilder(catalog, session)
137166
.setSchemaPattern(schemaNamePattern)
@@ -149,6 +178,7 @@ public DatabricksResultSet listFunctions(
149178
String schemaNamePattern,
150179
String functionNamePattern)
151180
throws SQLException {
181+
catalog = autoFillCatalog(catalog, session);
152182
CommandBuilder commandBuilder =
153183
new CommandBuilder(catalog, session)
154184
.setSchemaPattern(schemaNamePattern)
@@ -161,6 +191,7 @@ public DatabricksResultSet listFunctions(
161191
@Override
162192
public DatabricksResultSet listPrimaryKeys(
163193
IDatabricksSession session, String catalog, String schema, String table) throws SQLException {
194+
catalog = autoFillCatalog(catalog, session);
164195
CommandBuilder commandBuilder =
165196
new CommandBuilder(catalog, session).setSchema(schema).setTable(table);
166197
String SQL = commandBuilder.getSQLString(CommandName.LIST_PRIMARY_KEYS);
@@ -172,6 +203,7 @@ public DatabricksResultSet listPrimaryKeys(
172203
public DatabricksResultSet listImportedKeys(
173204
IDatabricksSession session, String catalog, String schema, String table) throws SQLException {
174205
LOGGER.debug("public ResultSet listImportedKeys() using SDK");
206+
catalog = autoFillCatalog(catalog, session);
175207
CommandBuilder commandBuilder =
176208
new CommandBuilder(catalog, session).setSchema(schema).setTable(table);
177209
String SQL = commandBuilder.getSQLString(CommandName.LIST_FOREIGN_KEYS);
@@ -195,8 +227,9 @@ public DatabricksResultSet listImportedKeys(
195227

196228
@Override
197229
public DatabricksResultSet listExportedKeys(
198-
IDatabricksSession session, String catalog, String schema, String table) {
230+
IDatabricksSession session, String catalog, String schema, String table) throws SQLException {
199231
LOGGER.debug("public ResultSet listExportedKeys() using SDK");
232+
catalog = autoFillCatalog(catalog, session);
200233
// Exported keys not tracked in DBSQL. Returning empty result set
201234
return metadataResultSetBuilder.getResultSetWithGivenRowsAndColumns(
202235
MetadataResultConstants.EXPORTED_KEYS_COLUMNS,

src/main/java/com/databricks/jdbc/dbclient/impl/thrift/DatabricksThriftServiceClient.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ void setServerProtocolVersion(TProtocolVersion serverProtocolVersion) {
6666
this.serverProtocolVersion = serverProtocolVersion;
6767
}
6868

69+
private boolean isMultipleCatalogSupportEnabled() {
70+
return connectionContext == null || connectionContext.getEnableMultipleCatalogSupport();
71+
}
72+
6973
@Override
7074
public IDatabricksConnectionContext getConnectionContext() {
7175
return connectionContext;
@@ -91,7 +95,7 @@ public ImmutableSessionInfo createSession(
9195
TOpenSessionReq openSessionReq =
9296
new TOpenSessionReq()
9397
.setConfiguration(sessionConf)
94-
.setCanUseMultipleCatalogs(true)
98+
.setCanUseMultipleCatalogs(isMultipleCatalogSupportEnabled())
9599
.setClient_protocol_i64(JDBC_THRIFT_VERSION.getValue());
96100
if (catalog != null || schema != null) {
97101
openSessionReq.setInitialNamespace(getNamespace(catalog, schema));
@@ -331,6 +335,20 @@ public DatabricksResultSet listCatalogs(IDatabricksSession session) throws SQLEx
331335
String.format("Fetching catalogs using Thrift client. Session {%s}", session.toString());
332336
LOGGER.debug(context);
333337
DatabricksThreadContextHolder.setSessionId(session.getSessionId());
338+
339+
// If multiple catalog support is disabled, return only the current catalog
340+
if (!isMultipleCatalogSupportEnabled()) {
341+
String currentCatalog = session.getCurrentCatalog();
342+
if (currentCatalog == null || currentCatalog.isEmpty()) {
343+
currentCatalog = "";
344+
}
345+
List<List<Object>> singleCatalogRows = new ArrayList<>();
346+
List<Object> catalogRow = new ArrayList<>();
347+
catalogRow.add(currentCatalog);
348+
singleCatalogRows.add(catalogRow);
349+
return metadataResultSetBuilder.getCatalogsResult(singleCatalogRows);
350+
}
351+
334352
TGetCatalogsReq request =
335353
new TGetCatalogsReq()
336354
.setSessionHandle(Objects.requireNonNull(session.getSessionInfo()).sessionHandle());

0 commit comments

Comments
 (0)