Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ enum SslVerificationMode
public static final ConnectionProperty<String, String> HOSTNAME_IN_CERTIFICATE = new HostnameInCertificate();
public static final ConnectionProperty<String, ZoneId> TIMEZONE = new TimeZone();
public static final ConnectionProperty<String, Boolean> EXPLICIT_PREPARE = new ExplicitPrepare();
public static final ConnectionProperty<String, Boolean> ASSUME_NULL_CATALOG_MEANS_CURRENT_CATALOG = new AssumeNullCatalogMeansCurrentCatalog();

private static final Set<ConnectionProperty<?, ?>> ALL_PROPERTIES = ImmutableSet.<ConnectionProperty<?, ?>>builder()
.add(USER)
Expand Down Expand Up @@ -146,6 +147,7 @@ enum SslVerificationMode
.add(HOSTNAME_IN_CERTIFICATE)
.add(TIMEZONE)
.add(EXPLICIT_PREPARE)
.add(ASSUME_NULL_CATALOG_MEANS_CURRENT_CATALOG)
.build();

private static final Map<String, ConnectionProperty<?, ?>> KEY_LOOKUP = unmodifiableMap(ALL_PROPERTIES.stream()
Expand Down Expand Up @@ -728,6 +730,15 @@ public ExplicitPrepare()
}
}

private static class AssumeNullCatalogMeansCurrentCatalog
extends AbstractConnectionProperty<String, Boolean>
{
public AssumeNullCatalogMeansCurrentCatalog()
{
super(PropertyName.ASSUME_NULL_CATALOG_MEANS_CURRENT_CATALOG, NOT_REQUIRED, ALLOWED, BOOLEAN_CONVERTER);
}
}

private static class MapPropertyParser
{
private static final CharMatcher PRINTABLE_ASCII = CharMatcher.inRange((char) 0x21, (char) 0x7E);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public enum PropertyName
SESSION_PROPERTIES("sessionProperties"),
SOURCE("source"),
EXPLICIT_PREPARE("explicitPrepare"),
ASSUME_NULL_CATALOG_MEANS_CURRENT_CATALOG("assumeNullCatalogMeansCurrentCatalog"),
DNS_RESOLVER("dnsResolver"),
DNS_RESOLVER_CONTEXT("dnsResolverContext"),
HOSTNAME_IN_CERTIFICATE("hostnameInCertificate"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
import static io.trino.client.uri.ConnectionProperties.APPLICATION_NAME_PREFIX;
import static io.trino.client.uri.ConnectionProperties.ASSUME_LITERAL_NAMES_IN_METADATA_CALLS_FOR_NON_CONFORMING_CLIENTS;
import static io.trino.client.uri.ConnectionProperties.ASSUME_LITERAL_UNDERSCORE_IN_METADATA_CALLS_FOR_NON_CONFORMING_CLIENTS;
import static io.trino.client.uri.ConnectionProperties.ASSUME_NULL_CATALOG_MEANS_CURRENT_CATALOG;
import static io.trino.client.uri.ConnectionProperties.CLIENT_INFO;
import static io.trino.client.uri.ConnectionProperties.CLIENT_TAGS;
import static io.trino.client.uri.ConnectionProperties.DISABLE_COMPRESSION;
Expand Down Expand Up @@ -170,6 +171,7 @@ public class TrinoUri
private Optional<Map<String, String>> sessionProperties;
private Optional<String> source;
private Optional<Boolean> explicitPrepare;
private Optional<Boolean> assumeNullCatalogMeansCurrentCatalog;

private Optional<String> catalog = Optional.empty();
private Optional<String> schema = Optional.empty();
Expand Down Expand Up @@ -223,7 +225,8 @@ private TrinoUri(
Optional<String> traceToken,
Optional<Map<String, String>> sessionProperties,
Optional<String> source,
Optional<Boolean> explicitPrepare)
Optional<Boolean> explicitPrepare,
Optional<Boolean> assumeNullCatalogMeansCurrentCatalog)
throws SQLException
{
this.uri = requireNonNull(uri, "uri is null");
Expand Down Expand Up @@ -277,6 +280,7 @@ private TrinoUri(
this.sessionProperties = SESSION_PROPERTIES.getValueOrDefault(urlProperties, sessionProperties);
this.source = SOURCE.getValueOrDefault(urlProperties, source);
this.explicitPrepare = EXPLICIT_PREPARE.getValueOrDefault(urlProperties, explicitPrepare);
this.assumeNullCatalogMeansCurrentCatalog = ASSUME_NULL_CATALOG_MEANS_CURRENT_CATALOG.getValueOrDefault(urlProperties, assumeNullCatalogMeansCurrentCatalog);

properties = buildProperties();

Expand Down Expand Up @@ -423,6 +427,7 @@ protected TrinoUri(URI uri, Properties driverProperties)
this.sessionProperties = SESSION_PROPERTIES.getValue(properties);
this.source = SOURCE.getValue(properties);
this.explicitPrepare = EXPLICIT_PREPARE.getValue(properties);
this.assumeNullCatalogMeansCurrentCatalog = ASSUME_NULL_CATALOG_MEANS_CURRENT_CATALOG.getValue(properties);

// enable SSL by default for the trino schema and the standard port
useSecureConnection = ssl.orElse(uri.getScheme().equals("https") || (uri.getScheme().equals("trino") && uri.getPort() == 443));
Expand Down Expand Up @@ -535,6 +540,11 @@ public Optional<Boolean> getExplicitPrepare()
return explicitPrepare;
}

public Optional<Boolean> getAssumeNullCatalogMeansCurrentCatalog()
{
return assumeNullCatalogMeansCurrentCatalog;
}

public boolean isCompressionDisabled()
{
return disableCompression.orElse(false);
Expand Down Expand Up @@ -941,6 +951,7 @@ public static final class Builder
private Map<String, String> sessionProperties;
private String source;
private Boolean explicitPrepare;
private Boolean assumeNullCatalogMeansCurrentCatalog;

private Builder() {}

Expand Down Expand Up @@ -1235,6 +1246,12 @@ public Builder setExplicitPrepare(Boolean explicitPrepare)
return this;
}

public Builder setAssumeNullCatalogMeansCurrentCatalog(Boolean assumeNullCatalogMeansCurrentCatalog)
{
this.assumeNullCatalogMeansCurrentCatalog = requireNonNull(assumeNullCatalogMeansCurrentCatalog, "assumeNullCatalogMeansCurrentCatalog is null");
return this;
}

public TrinoUri build()
throws SQLException
{
Expand Down Expand Up @@ -1284,7 +1301,8 @@ public TrinoUri build()
Optional.ofNullable(traceToken),
Optional.ofNullable(sessionProperties),
Optional.ofNullable(source),
Optional.ofNullable(explicitPrepare));
Optional.ofNullable(explicitPrepare),
Optional.ofNullable(assumeNullCatalogMeansCurrentCatalog));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ public class TrinoConnection
private final Call.Factory httpCallFactory;
private final Set<TrinoStatement> statements = newSetFromMap(new ConcurrentHashMap<>());
private boolean useExplicitPrepare = true;
private boolean assumeNullCatalogMeansCurrentCatalog;

TrinoConnection(TrinoDriverUri uri, Call.Factory httpCallFactory)
{
Expand Down Expand Up @@ -147,6 +148,7 @@ public class TrinoConnection
sessionProperties.putAll(uri.getSessionProperties());

uri.getExplicitPrepare().ifPresent(value -> this.useExplicitPrepare = value);
uri.getAssumeNullCatalogMeansCurrentCatalog().ifPresent(value -> this.assumeNullCatalogMeansCurrentCatalog = value);
}

@Override
Expand Down Expand Up @@ -919,4 +921,9 @@ public boolean useExplicitPrepare()
{
return this.useExplicitPrepare;
}

public boolean getAssumeNullCatalogMeansCurrentCatalog()
{
return this.assumeNullCatalogMeansCurrentCatalog;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,7 @@ public ResultSet getTables(String catalog, String schemaPattern, String tableNam
"FROM system.jdbc.tables");

List<String> filters = new ArrayList<>();
emptyStringEqualsFilter(filters, "TABLE_CAT", catalog);
emptyStringEqualsFilter(filters, "TABLE_CAT", effectiveCatalog(catalog));
emptyStringLikeFilter(filters, "TABLE_SCHEM", schemaPattern);
optionalStringLikeFilter(filters, "TABLE_NAME", tableNamePattern);
optionalStringInFilter(filters, "TABLE_TYPE", types);
Expand Down Expand Up @@ -1011,7 +1011,7 @@ public ResultSet getColumns(String catalog, String schemaPattern, String tableNa
"FROM system.jdbc.columns");

List<String> filters = new ArrayList<>();
emptyStringEqualsFilter(filters, "TABLE_CAT", catalog);
emptyStringEqualsFilter(filters, "TABLE_CAT", effectiveCatalog(catalog));
emptyStringLikeFilter(filters, "TABLE_SCHEM", schemaPattern);
optionalStringLikeFilter(filters, "TABLE_NAME", tableNamePattern);
optionalStringLikeFilter(filters, "COLUMN_NAME", columnNamePattern);
Expand Down Expand Up @@ -1393,7 +1393,7 @@ public ResultSet getSchemas(String catalog, String schemaPattern)
"FROM system.jdbc.schemas");

List<String> filters = new ArrayList<>();
emptyStringEqualsFilter(filters, "TABLE_CATALOG", catalog);
emptyStringEqualsFilter(filters, "TABLE_CATALOG", effectiveCatalog(catalog));
optionalStringLikeFilter(filters, "TABLE_SCHEM", schemaPattern);
buildFilters(query, filters);

Expand Down Expand Up @@ -1651,4 +1651,13 @@ private static void quoteStringLiteral(StringBuilder out, String value)
}
out.append('\'');
}

private String effectiveCatalog(String catalog)
throws SQLException
{
if (connection.getAssumeNullCatalogMeansCurrentCatalog() && catalog == null) {
return connection.getCatalog();
}
return catalog;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,71 @@ public void testGetSchemasMetadataCalls()
list(),
ImmutableMultiset.of());
}

try (Connection connection = createConnectionWithNullCatalogMeansCurrent()) {
// should list all schemas as the catalog is not set
assertMetadataCalls(
connection,
readMetaData(
databaseMetaData -> databaseMetaData.getSchemas(null, null),
list("TABLE_CATALOG", "TABLE_SCHEM")),
list(
list("blackhole", "information_schema"),
list("blackhole", "default"),
list("blackhole", "blackhole"),
list("hive", "information_schema"),
list("hive", "default"),
list(COUNTING_CATALOG, "information_schema"),
list(COUNTING_CATALOG, "test_schema1"),
list(COUNTING_CATALOG, "test_schema2"),
list(COUNTING_CATALOG, "test_schema3_empty"),
list(COUNTING_CATALOG, "test_schema4_empty"),
list("system", "information_schema"),
list("system", "jdbc"),
list("system", "metadata"),
list("system", "runtime"),
list(TEST_CATALOG, "information_schema"),
list(TEST_CATALOG, "sf1"),
list(TEST_CATALOG, "sf100"),
list(TEST_CATALOG, "sf1000"),
list(TEST_CATALOG, "sf10000"),
list(TEST_CATALOG, "sf100000"),
list(TEST_CATALOG, "sf300"),
list(TEST_CATALOG, "sf3000"),
list(TEST_CATALOG, "sf30000"),
list(TEST_CATALOG, "tiny")),
ImmutableMultiset.of("ConnectorMetadata.listSchemaNames"));

// set a different catalog to check if current catalog is used
connection.setCatalog(COUNTING_CATALOG);

assertMetadataCalls(
connection,
readMetaData(
databaseMetaData -> databaseMetaData.getSchemas(null, null),
list("TABLE_CATALOG", "TABLE_SCHEM")),
list(
list(COUNTING_CATALOG, "information_schema"),
list(COUNTING_CATALOG, "test_schema1"),
list(COUNTING_CATALOG, "test_schema2"),
list(COUNTING_CATALOG, "test_schema3_empty"),
list(COUNTING_CATALOG, "test_schema4_empty")),
ImmutableMultiset.of("ConnectorMetadata.listSchemaNames"));

// change the catalog back using a statement on the connection
connection.createStatement().execute(String.format("USE %s.%s", "blackhole", "blackhole"));

assertMetadataCalls(
connection,
readMetaData(
databaseMetaData -> databaseMetaData.getSchemas(null, null),
list("TABLE_CATALOG", "TABLE_SCHEM")),
list(
list("blackhole", "information_schema"),
list("blackhole", "default"),
list("blackhole", "blackhole")),
ImmutableMultiset.of());
}
}

@Test
Expand Down Expand Up @@ -1254,6 +1319,38 @@ public void testGetTablesMetadataCalls()
list(),
ImmutableMultiset.of());
}

try (Connection connection = createConnectionWithNullCatalogMeansCurrent()) {
assertMetadataCalls(
connection,
readMetaData(
databaseMetaData -> databaseMetaData.getTables(null, null, null, new String[0]),
list("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "TABLE_TYPE")),
list(),
ImmutableMultiset.of());

// set a different catalog to check if current catalog is used
connection.setCatalog(COUNTING_CATALOG);

assertMetadataCalls(
connection,
readMetaData(
databaseMetaData -> databaseMetaData.getTables(null, null, null, new String[0]),
list("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "TABLE_TYPE")),
list(),
ImmutableMultiset.of());

// change the catalog back using a statement on the connection
connection.createStatement().execute(String.format("USE %s.%s", "blackhole", "blackhole"));

assertMetadataCalls(
connection,
readMetaData(
databaseMetaData -> databaseMetaData.getTables(null, null, null, new String[0]),
list("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "TABLE_TYPE")),
list(),
ImmutableMultiset.of());
}
}

@Test
Expand Down Expand Up @@ -1495,6 +1592,38 @@ public void testGetColumnsMetadataCalls()
list(),
ImmutableMultiset.of("ConnectorMetadata.streamRelationColumns"));
}

try (Connection connection = createConnectionWithNullCatalogMeansCurrent()) {
assertMetadataCalls(
connection,
readMetaData(
databaseMetaData -> databaseMetaData.getColumns(null, null, null, ""),
list("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "TYPE_NAME")),
list(),
ImmutableMultiset.of("ConnectorMetadata.streamRelationColumns"));

// set a different catalog to check if current catalog is used
connection.setCatalog(COUNTING_CATALOG);

assertMetadataCalls(
connection,
readMetaData(
databaseMetaData -> databaseMetaData.getColumns(null, null, null, ""),
list("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "TYPE_NAME")),
list(),
ImmutableMultiset.of("ConnectorMetadata.streamRelationColumns"));

// change the catalog back using a statement on the connection
connection.createStatement().execute(String.format("USE %s.%s", "blackhole", "blackhole"));

assertMetadataCalls(
connection,
readMetaData(
databaseMetaData -> databaseMetaData.getColumns(null, null, null, ""),
list("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "TYPE_NAME")),
list(),
ImmutableMultiset.of());
}
}

@Test
Expand Down Expand Up @@ -1823,6 +1952,13 @@ private Connection createConnection(String catalog, String schema)
return DriverManager.getConnection(url, "admin", null);
}

private Connection createConnectionWithNullCatalogMeansCurrent()
throws SQLException
{
String url = format("jdbc:trino://%s?assumeNullCatalogMeansCurrentCatalog=true", server.getAddress());
return DriverManager.getConnection(url, "admin", null);
}

private interface MetaDataCallback<T>
{
T apply(DatabaseMetaData metaData)
Expand Down