Skip to content

Commit

Permalink
[CONJ-1103] support for nullDatabaseMeansCurrent (alias for nullCatal…
Browse files Browse the repository at this point in the history
…ogMeansCurrent)
  • Loading branch information
rusher committed Apr 2, 2024
1 parent 99442c1 commit fc791bc
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 3 deletions.
30 changes: 30 additions & 0 deletions src/main/java/org/mariadb/jdbc/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public class Configuration {
private String timezone = null;
private Boolean autocommit = null;
private boolean useMysqlMetadata = false;
private boolean nullDatabaseMeansCurrent = false;
private CatalogTerm useCatalogTerm = CatalogTerm.UseCatalog;
private boolean createDatabaseIfNotExist = false;
private boolean useLocalSessionState = false;
Expand Down Expand Up @@ -170,6 +171,7 @@ private Configuration(
String timezone,
Boolean autocommit,
boolean useMysqlMetadata,
boolean nullDatabaseMeansCurrent,
CatalogTerm useCatalogTerm,
boolean createDatabaseIfNotExist,
boolean useLocalSessionState,
Expand Down Expand Up @@ -252,6 +254,7 @@ private Configuration(
this.timezone = timezone;
this.autocommit = autocommit;
this.useMysqlMetadata = useMysqlMetadata;
this.nullDatabaseMeansCurrent = nullDatabaseMeansCurrent;
this.useCatalogTerm = useCatalogTerm;
this.createDatabaseIfNotExist = createDatabaseIfNotExist;
this.returnMultiValuesGeneratedIds = returnMultiValuesGeneratedIds;
Expand Down Expand Up @@ -372,6 +375,7 @@ private Configuration(
Boolean disablePipeline,
Boolean autocommit,
Boolean useMysqlMetadata,
Boolean nullDatabaseMeansCurrent,
String useCatalogTerm,
Boolean createDatabaseIfNotExist,
Boolean useLocalSessionState,
Expand Down Expand Up @@ -472,6 +476,7 @@ private Configuration(
if (disablePipeline != null) this.disablePipeline = disablePipeline;
if (autocommit != null) this.autocommit = autocommit;
if (useMysqlMetadata != null) this.useMysqlMetadata = useMysqlMetadata;
if (nullDatabaseMeansCurrent != null) this.nullDatabaseMeansCurrent = nullDatabaseMeansCurrent;
if (useCatalogTerm != null) {
if (!"CATALOG".equalsIgnoreCase(useCatalogTerm)
&& !"SCHEMA".equalsIgnoreCase(useCatalogTerm)) {
Expand Down Expand Up @@ -575,6 +580,7 @@ public Builder toBuilder() {
.timezone(this.timezone)
.autocommit(this.autocommit)
.useMysqlMetadata(this.useMysqlMetadata)
.nullDatabaseMeansCurrent(this.nullDatabaseMeansCurrent)
.useCatalogTerm(this.useCatalogTerm == CatalogTerm.UseCatalog ? "CATALOG" : "SCHEMA")
.createDatabaseIfNotExist(this.createDatabaseIfNotExist)
.useLocalSessionState(this.useLocalSessionState)
Expand Down Expand Up @@ -1633,6 +1639,16 @@ public boolean useMysqlMetadata() {
return useMysqlMetadata;
}

/**
* When enable, in DatabaseMetadata, will handle null database/schema (depending on
* UseCatalog=catalog/schema) as current
*
* @return must null value be considered as current catalog/schema
*/
public boolean nullDatabaseMeansCurrent() {
return nullDatabaseMeansCurrent;
}

/**
* Indicating using Catalog or Schema
*
Expand Down Expand Up @@ -1995,6 +2011,7 @@ public static final class Builder implements Cloneable {
private String timezone;
private Boolean autocommit;
private Boolean useMysqlMetadata;
private Boolean nullDatabaseMeansCurrent;
private String useCatalogTerm;
private Boolean createDatabaseIfNotExist;
private Boolean useLocalSessionState;
Expand Down Expand Up @@ -2709,6 +2726,18 @@ public Builder useMysqlMetadata(Boolean useMysqlMetadata) {
return this;
}

/**
* Permit indicating in DatabaseMetadata if null value must be considered current schema/catalog
*
* @param nullDatabaseMeansCurrent indicating in DatabaseMetadata if null value must be
* considered current schema/catalog
* @return this {@link Builder}
*/
public Builder nullDatabaseMeansCurrent(Boolean nullDatabaseMeansCurrent) {
this.nullDatabaseMeansCurrent = nullDatabaseMeansCurrent;
return this;
}

/**
* "schema" and "database" are server synonymous. Connector historically get/set database using
* Connection.setCatalog()/getCatalog(), setSchema()/getSchema() being no-op This parameter
Expand Down Expand Up @@ -3102,6 +3131,7 @@ public Configuration build() throws SQLException {
this.disablePipeline,
this.autocommit,
this.useMysqlMetadata,
this.nullDatabaseMeansCurrent,
this.useCatalogTerm,
this.createDatabaseIfNotExist,
this.useLocalSessionState,
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/org/mariadb/jdbc/DatabaseMetaData.java
Original file line number Diff line number Diff line change
Expand Up @@ -597,10 +597,11 @@ private boolean databaseCond(
String database,
boolean usePattern) {
// null database => searching without any database restriction
if (database == null || ("%".equals(database) && usePattern)) return firstCondition;
if ((database == null && !conf.nullDatabaseMeansCurrent())
|| ("%".equals(database) && usePattern)) return firstCondition;

// empty database => search restricting to current database
if (database.isEmpty()) {
if ((database == null && conf.nullDatabaseMeansCurrent()) || database.isEmpty()) {
sb.append(firstCondition ? " WHERE " : " AND ").append(columnName).append(" = database()");
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ public final class OptionAliases {
OPTIONS_ALIASES.put("clientcertificatekeystoreurl", "keyStore");
OPTIONS_ALIASES.put("clientcertificatekeystorepassword", "keyStorePassword");
OPTIONS_ALIASES.put("clientcertificatekeystoretype", "keyStoreType");
OPTIONS_ALIASES.put("nullcatalogmeanscurrent", "nullDatabaseMeansCurrent");
}
}
1 change: 1 addition & 0 deletions src/main/resources/driver.properties
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,4 @@ jdbcCompliantTruncation=If set, the connector ensures STRICT_TRANS_TABLES is alw
permitRedirect=permit server redirection. Default is true
fallbackToSystemKeyStore=Indicate if keystore default implementation can be used. Connector use keystore option if set or if not, use javax.net.ssl.keyStore* system properties to load keystore if this option is enable
fallbackToSystemTrustStore=Indicate if truststore default implementation can be used. Connector use serverSslCert option if set or if not, use java default truststore if this option is enable
nullDatabaseMeansCurrent=When enable, in DatabaseMetadata, will handle null database/schema (depending on UseCatalog=catalog/schema) as current. (Alias nullCatalogMeansCurrent)
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,44 @@ public void metaUnsigned() throws SQLException {
public void primaryKeysTest() throws SQLException {
DatabaseMetaData meta = sharedConn.getMetaData();
ResultSet rs = meta.getPrimaryKeys(sharedConn.getCatalog(), null, "dbpk_test");
primaryKeysTest(rs);

rs = meta.getPrimaryKeys(null, null, "dbpk_test");
primaryKeysTest(rs);

try (Connection con = createCon("&nullDatabaseMeansCurrent=false")) {
meta = con.getMetaData();
rs = meta.getPrimaryKeys(null, null, "dbpk_test");
primaryKeysTest(rs);

con.setCatalog("information_schema");
rs = meta.getPrimaryKeys(null, null, "dbpk_test");
primaryKeysTest(rs);
}

try (Connection con = createCon("&nullDatabaseMeansCurrent=true")) {
meta = con.getMetaData();
rs = meta.getPrimaryKeys(null, null, "dbpk_test");
primaryKeysTest(rs);

con.setCatalog("information_schema");
rs = meta.getPrimaryKeys(null, null, "dbpk_test");
assertFalse(rs.next());
}

try (Connection con = createCon("&nullCatalogMeansCurrent=true")) {
meta = con.getMetaData();
rs = meta.getPrimaryKeys(null, null, "dbpk_test");
primaryKeysTest(rs);

con.setCatalog("information_schema");
rs = meta.getPrimaryKeys(null, null, "dbpk_test");
assertFalse(rs.next());
}

}

private void primaryKeysTest(ResultSet rs) throws SQLException {
Assertions.assertEquals(ResultSet.TYPE_SCROLL_INSENSITIVE, rs.getType());
Assertions.assertEquals(ResultSet.CONCUR_READ_ONLY, rs.getConcurrency());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -862,13 +862,14 @@ public void builder() throws SQLException {
.createDatabaseIfNotExist(true)
.disablePipeline(true)
.maxAllowedPacket(8000)
.nullDatabaseMeansCurrent(true)
.fallbackToSystemKeyStore(false)
.fallbackToSystemTrustStore(false)
.initSql("SET @@a='10'")
.useCatalogTerm("schema")
.build();
String expected =
"jdbc:mariadb://host1:3305,address=(host=host2)(port=3307)(type=replica)/db?user=me&password=***&timezone=UTC&autocommit=false&useCatalogTerm=SCHEMA&createDatabaseIfNotExist=true&useLocalSessionState=true&returnMultiValuesGeneratedIds=true&permitRedirect=false&transactionIsolation=REPEATABLE_READ&defaultFetchSize=10&maxQuerySizeToLog=100&maxAllowedPacket=8000&geometryDefaultType=default&restrictedAuth=mysql_native_password,client_ed25519&initSql=SET"
"jdbc:mariadb://host1:3305,address=(host=host2)(port=3307)(type=replica)/db?user=me&password=***&timezone=UTC&autocommit=false&nullDatabaseMeansCurrent=true&useCatalogTerm=SCHEMA&createDatabaseIfNotExist=true&useLocalSessionState=true&returnMultiValuesGeneratedIds=true&permitRedirect=false&transactionIsolation=REPEATABLE_READ&defaultFetchSize=10&maxQuerySizeToLog=100&maxAllowedPacket=8000&geometryDefaultType=default&restrictedAuth=mysql_native_password,client_ed25519&initSql=SET"
+ " @@a='10'&socketFactory=someSocketFactory&connectTimeout=22&pipe=pipeName&localSocket=localSocket&uuidAsString=true&tcpKeepAlive=false&tcpKeepIdle=10&tcpKeepCount=50&tcpKeepInterval=50&tcpAbortiveClose=true&localSocketAddress=localSocketAddress&socketTimeout=1000&useReadAheadInput=true&tlsSocketType=TLStype&sslMode=TRUST&serverSslCert=mycertPath&keyStore=/tmp&keyStorePassword=MyPWD&keyStoreType=JKS&trustStoreType=JKS&enabledSslCipherSuites=myCipher,cipher2&enabledSslProtocolSuites=TLSv1.2&fallbackToSystemKeyStore=false&fallbackToSystemTrustStore=false&allowMultiQueries=true&allowLocalInfile=false&useCompression=true&useAffectedRows=true&useBulkStmts=true&disablePipeline=true&cachePrepStmts=false&prepStmtCacheSize=2&useServerPrepStmts=true&credentialType=ENV&sessionVariables=blabla&connectionAttributes=bla=bla&servicePrincipalName=SPN&blankTableNameMeta=true&tinyInt1isBit=false&yearIsDateType=false&dumpQueriesOnException=true&includeInnodbStatusInDeadlockExceptions=true&includeThreadDumpInDeadlockExceptions=true&retriesAllDown=10&galeraAllowedState=A,B&transactionReplay=true&pool=true&poolName=myPool&maxPoolSize=16&minPoolSize=12&maxIdleTime=25000&registerJmxPool=false&poolValidMinDelay=260&useResetConnection=true&serverRsaPublicKeyFile=RSAPath&allowPublicKeyRetrieval=true";
assertEquals(expected, conf.toString());
assertEquals(expected, conf.toBuilder().build().toString());
Expand Down

0 comments on commit fc791bc

Please sign in to comment.