Search in sources :

Example 1 with ServerVersion

use of com.mysql.cj.ServerVersion in project JavaSegundasQuintas by ecteruel.

the class ConnectionRegressionTest method testBug75592.

/**
 * Tests fix for BUG#75592 - "SHOW VARIABLES WHERE" is expensive.
 *
 * @throws Exception
 */
@Test
public void testBug75592() throws Exception {
    if (versionMeetsMinimum(5, 0, 3)) {
        Properties props = new Properties();
        props.setProperty(PropertyKey.sslMode.getKeyName(), "DISABLED");
        props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
        props.setProperty(PropertyKey.queryInterceptors.getKeyName(), Bug75592QueryInterceptor.class.getName());
        JdbcConnection con = (JdbcConnection) getConnectionWithProps(props);
        // reference values
        Map<String, String> serverVariables = new HashMap<>();
        this.rs = con.createStatement().executeQuery("SHOW VARIABLES");
        while (this.rs.next()) {
            String val = this.rs.getString(2);
            serverVariables.put(this.rs.getString(1), "utf8mb3".equals(val) ? "utf8" : val);
        }
        // fix the renaming of "tx_isolation" to "transaction_isolation" that is made in NativeSession.loadServerVariables().
        if (!serverVariables.containsKey("transaction_isolation") && serverVariables.containsKey("tx_isolation")) {
            serverVariables.put("transaction_isolation", serverVariables.remove("tx_isolation"));
        }
        Session session = con.getSession();
        // check values from "select @@var..."
        assertEquals(serverVariables.get("auto_increment_increment"), session.getServerSession().getServerVariable("auto_increment_increment"));
        assertEquals(serverVariables.get(CharsetSettings.CHARACTER_SET_CLIENT), session.getServerSession().getServerVariable(CharsetSettings.CHARACTER_SET_CLIENT));
        assertEquals(serverVariables.get(CharsetSettings.CHARACTER_SET_CONNECTION), session.getServerSession().getServerVariable(CharsetSettings.CHARACTER_SET_CONNECTION));
        // we override character_set_results sometimes when configuring client charsets, thus need to check against actual value
        if (session.getServerSession().getServerVariable(CharsetSettings.CHARACTER_SET_RESULTS) == null) {
            assertEquals("", serverVariables.get(CharsetSettings.CHARACTER_SET_RESULTS));
        } else {
            assertEquals(serverVariables.get(CharsetSettings.CHARACTER_SET_RESULTS), session.getServerSession().getServerVariable(CharsetSettings.CHARACTER_SET_RESULTS));
        }
        assertEquals(serverVariables.get("character_set_server"), session.getServerSession().getServerVariable("character_set_server"));
        assertEquals(serverVariables.get("init_connect"), session.getServerSession().getServerVariable("init_connect"));
        assertEquals(serverVariables.get("interactive_timeout"), session.getServerSession().getServerVariable("interactive_timeout"));
        assertEquals(serverVariables.get("license"), session.getServerSession().getServerVariable("license"));
        assertEquals(serverVariables.get("lower_case_table_names"), session.getServerSession().getServerVariable("lower_case_table_names"));
        assertEquals(serverVariables.get("max_allowed_packet"), session.getServerSession().getServerVariable("max_allowed_packet"));
        assertEquals(serverVariables.get("net_write_timeout"), session.getServerSession().getServerVariable("net_write_timeout"));
        if (!con.getServerVersion().meetsMinimum(new ServerVersion(8, 0, 3))) {
            assertEquals(serverVariables.get("query_cache_size"), session.getServerSession().getServerVariable("query_cache_size"));
            assertEquals(serverVariables.get("query_cache_type"), session.getServerSession().getServerVariable("query_cache_type"));
        }
        // not necessarily contains STRICT_TRANS_TABLES
        for (String sm : serverVariables.get("sql_mode").split(",")) {
            if (!sm.equals("STRICT_TRANS_TABLES")) {
                assertTrue(session.getServerSession().getServerVariable("sql_mode").contains(sm));
            }
        }
        assertEquals(serverVariables.get("system_time_zone"), session.getServerSession().getServerVariable("system_time_zone"));
        assertEquals(serverVariables.get("time_zone"), session.getServerSession().getServerVariable("time_zone"));
        assertEquals(serverVariables.get("transaction_isolation"), session.getServerSession().getServerVariable("transaction_isolation"));
        assertEquals(serverVariables.get("wait_timeout"), session.getServerSession().getServerVariable("wait_timeout"));
        if (!versionMeetsMinimum(5, 5, 0)) {
            assertEquals(serverVariables.get("language"), session.getServerSession().getServerVariable("language"));
        }
    }
}
Also used : ServerVersion(com.mysql.cj.ServerVersion) HashMap(java.util.HashMap) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) Properties(java.util.Properties) NativeServerSession(com.mysql.cj.protocol.a.NativeServerSession) NativeSession(com.mysql.cj.NativeSession) ServerSession(com.mysql.cj.protocol.ServerSession) Session(com.mysql.cj.Session) Test(org.junit.jupiter.api.Test)

Example 2 with ServerVersion

use of com.mysql.cj.ServerVersion in project JavaSegundasQuintas by ecteruel.

the class PooledConnectionRegressionTest method testConnectionWrapperMethods.

@SuppressWarnings("deprecation")
@Test
public void testConnectionWrapperMethods() throws Exception {
    PooledConnection pc = null;
    pc = this.cpds.getPooledConnection();
    ConnectionWrapper cw = (ConnectionWrapper) pc.getConnection();
    assertEquals(PreparedStatementWrapper.class, cw.clientPrepare("SELECT 1").getClass());
    assertEquals(PreparedStatementWrapper.class, cw.clientPrepare("SELECT 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY).getClass());
    assertEquals(PreparedStatementWrapper.class, cw.clientPrepareStatement("SELECT 1").getClass());
    assertEquals(PreparedStatementWrapper.class, cw.clientPrepareStatement("SELECT 1", Statement.RETURN_GENERATED_KEYS).getClass());
    assertEquals(PreparedStatementWrapper.class, cw.clientPrepareStatement("SELECT 1", new int[] { 1 }).getClass());
    assertEquals(PreparedStatementWrapper.class, cw.clientPrepareStatement("SELECT 1", new String[] { "1" }).getClass());
    assertEquals(PreparedStatementWrapper.class, cw.clientPrepareStatement("SELECT 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY).getClass());
    assertEquals(PreparedStatementWrapper.class, cw.clientPrepareStatement("SELECT 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT).getClass());
    assertEquals(PreparedStatementWrapper.class, cw.serverPrepareStatement("SELECT 1").getClass());
    assertEquals(PreparedStatementWrapper.class, cw.serverPrepareStatement("SELECT 1", Statement.RETURN_GENERATED_KEYS).getClass());
    assertEquals(PreparedStatementWrapper.class, cw.serverPrepareStatement("SELECT 1", new int[] { 1 }).getClass());
    assertEquals(PreparedStatementWrapper.class, cw.serverPrepareStatement("SELECT 1", new String[] { "1" }).getClass());
    assertEquals(PreparedStatementWrapper.class, cw.serverPrepareStatement("SELECT 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY).getClass());
    assertEquals(PreparedStatementWrapper.class, cw.serverPrepareStatement("SELECT 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT).getClass());
    assertEquals(PreparedStatementWrapper.class, cw.prepareStatement("SELECT 1").getClass());
    assertEquals(PreparedStatementWrapper.class, cw.prepareStatement("SELECT 1", Statement.RETURN_GENERATED_KEYS).getClass());
    assertEquals(PreparedStatementWrapper.class, cw.prepareStatement("SELECT 1", new int[] { 1 }).getClass());
    assertEquals(PreparedStatementWrapper.class, cw.prepareStatement("SELECT 1", new String[] { "1" }).getClass());
    assertEquals(PreparedStatementWrapper.class, cw.prepareStatement("SELECT 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY).getClass());
    assertEquals(PreparedStatementWrapper.class, cw.prepareStatement("SELECT 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT).getClass());
    assertEquals(CallableStatementWrapper.class, cw.prepareCall("SELECT 1").getClass());
    assertEquals(CallableStatementWrapper.class, cw.prepareCall("SELECT 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY).getClass());
    assertEquals(CallableStatementWrapper.class, cw.prepareCall("SELECT 1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT).getClass());
    assertEquals(StatementWrapper.class, cw.createStatement().getClass());
    assertEquals(StatementWrapper.class, cw.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY).getClass());
    assertEquals(StatementWrapper.class, cw.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT).getClass());
    assertEquals(26, cw.getActiveStatementCount());
    assertThrows(SQLFeatureNotSupportedException.class, new Callable<Void>() {

        public Void call() throws Exception {
            cw.createArrayOf(String.class.getName(), new Object[] {}).getClass();
            return null;
        }
    });
    assertThrows(SQLFeatureNotSupportedException.class, new Callable<Void>() {

        public Void call() throws Exception {
            cw.createStruct(String.class.getName(), new Object[] {}).getClass();
            return null;
        }
    });
    assertEquals(Blob.class, cw.createBlob().getClass());
    assertEquals(Clob.class, cw.createClob().getClass());
    assertEquals(NClob.class, cw.createNClob().getClass());
    assertEquals(MysqlSQLXML.class, cw.createSQLXML().getClass());
    assertEquals(ConnectionImpl.class, cw.getActiveMySQLConnection().getClass());
    assertEquals(this.conn.getAutoCommit(), cw.getAutoCommit());
    assertEquals(((JdbcConnection) this.conn).getAutoIncrementIncrement(), cw.getAutoIncrementIncrement());
    assertEquals(((JdbcConnection) this.conn).getCatalog(), cw.getCatalog());
    assertEquals(((JdbcConnection) this.conn).getCharacterSetMetadata(), cw.getCharacterSetMetadata());
    assertEquals(((JdbcConnection) this.conn).getHoldability(), cw.getHoldability());
    assertEquals(((JdbcConnection) this.conn).getHost(), cw.getHost());
    assertEquals(((JdbcConnection) this.conn).getHostPortPair(), cw.getHostPortPair());
    assertEquals(Properties.class, cw.getProperties().getClass());
    assertEquals(JdbcPropertySetImpl.class, cw.getPropertySet().getClass());
    assertEquals(((JdbcConnection) this.conn).getSchema(), cw.getSchema());
    assertEquals(((JdbcConnection) this.conn).getServerVersion().toString(), cw.getServerVersion().toString());
    assertEquals(NativeSession.class, cw.getSession().getClass());
    assertEquals(((JdbcConnection) this.conn).getSessionMaxRows(), cw.getSessionMaxRows());
    assertEquals(((JdbcConnection) this.conn).getURL(), cw.getURL());
    assertEquals(((JdbcConnection) this.conn).getUser(), cw.getUser());
    assertFalse(cw.hasTriedMaster());
    assertFalse(cw.isClosed());
    assertFalse(cw.isInGlobalTx());
    assertFalse(cw.isSourceConnection());
    assertFalse(cw.isProxySet());
    assertFalse(cw.isReadOnly());
    assertFalse(cw.isReadOnly(false));
    assertFalse(cw.isReadOnly(true));
    assertEquals(isMysqlRunningLocally(), cw.isServerLocal());
    assertTrue(cw.isValid(10));
    assertTrue(cw.isWrapperFor(Connection.class));
    assertEquals(((JdbcConnection) this.conn).lowerCaseTableNames(), cw.lowerCaseTableNames());
    assertEquals(CommentClientInfoProvider.class, cw.getClientInfoProviderImpl().getClass());
    Properties ci1 = new Properties();
    ci1.setProperty("k1", "v1");
    ci1.setProperty("k2", "v2");
    cw.setClientInfo(ci1);
    cw.setClientInfo("k3", "v3");
    Properties ci2 = cw.getClientInfo();
    assertFalse(ci1.equals(ci2));
    assertEquals("v1", cw.getClientInfo("k1"));
    assertEquals("v2", cw.getClientInfo("k2"));
    assertEquals("v3", cw.getClientInfo("k3"));
    String comment = cw.getStatementComment();
    assertEquals("k3=v3, k2=v2, k1=v1", comment);
    cw.setStatementComment("Test comment");
    assertNotEquals(((JdbcConnection) this.conn).getStatementComment(), cw.getStatementComment());
    assertEquals(ConnectionImpl.class, cw.getConnectionMutex().getClass());
    assertNull(cw.getExceptionInterceptor());
    assertEquals(((JdbcConnection) this.conn).getNetworkTimeout(), cw.getNetworkTimeout());
    assertEquals(((JdbcConnection) this.conn).getTypeMap(), cw.getTypeMap());
    assertNull(cw.getWarnings());
    // testsuite is built upon non-SSL default connection with additional useSSL=false&allowPublicKeyRetrieval=true properties
    assertFalse(cw.hasSameProperties((JdbcConnection) this.conn));
    assertTrue(cw.isSameResource((JdbcConnection) this.conn));
    assertEquals(((JdbcConnection) this.conn).nativeSQL("SELECT 1"), cw.nativeSQL("SELECT 1"));
    assertEquals(cw.getServerVersion().meetsMinimum(new ServerVersion(8, 0, 3)) ? DatabaseMetaDataUsingInfoSchema.class : DatabaseMetaData.class, cw.getMetaData().getClass());
    // TODO find a way to test following methods
    // cw.getId();
    // cw.getIdleFor();
    // cw.getMetadataSafeStatement();
    // cw.getMultiHostSafeProxy();
    // cw.resetServerState();
    cw.setCatalog(this.dbName);
    cw.setFailedOver(false);
    cw.setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT);
    cw.setInGlobalTx(false);
    // TODO find a way to test following methods
    // cw.setNetworkTimeout(executor, milliseconds);
    // cw.setProxy(this.conn);
    // cw.setReadOnly(readOnly);
    // cw.setReadOnlyInternal(readOnlyFlag);
    // cw.setSchema(schema);
    // cw.setSessionMaxRows(max);
    // cw.setTypeMap(map);
    assertEquals(((JdbcConnection) this.conn).storesLowerCaseTableName(), cw.storesLowerCaseTableName());
    // TODO find a way to test following methods
    // cw.getQueryInterceptorsInstances();
    // cw.initializeSafeQueryInterceptors();
    // cw.unSafeQueryInterceptors();
    // cw.unwrap(iface);
    // cw.initializeResultsMetadataFromCache(sql, cachedMetaData, resultSet);
    // cw.getCachedMetaData(sql);
    cw.setAutoCommit(false);
    cw.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
    assertEquals(Connection.TRANSACTION_READ_UNCOMMITTED, cw.getTransactionIsolation());
    cw.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
    assertEquals(Connection.TRANSACTION_READ_COMMITTED, cw.getTransactionIsolation());
    // TODO find a way to test following methods
    // cw.transactionBegun();
    // cw.transactionCompleted();
    // cw.commit();
    // cw.rollback();
    // cw.rollback(arg0);
    // cw.setSavepoint();
    // cw.setSavepoint(arg0);
    // cw.releaseSavepoint(arg0);
    cw.setAutoCommit(true);
    // TODO find a way to test following methods
    // cw.registerStatement(this.stmt);
    // cw.unregisterStatement(this.stmt);
    // cw.decachePreparedStatement(this.pstmt);
    // cw.recachePreparedStatement(this.pstmt);
    // TODO find a way to test following methods
    // cw.clearHasTriedMaster();
    // cw.clearWarnings();
    // cw.ping();
    // cw.pingInternal(checkForClosedConnection, timeoutMillis);
    // cw.createNewIO(isForReconnect);
    // cw.changeUser(userName, newPassword);
    // cw.checkClosed();
    cw.close();
    // TODO why are they still active? Active statements should be cleaned when connection is returned to pool.
    assertEquals(26, cw.getActiveStatementCount());
    checkConnectionReturnedToPool(cw);
    cw.normalClose();
    assertEquals(0, cw.getActiveStatementCount());
    checkReallyClosedConnection(cw);
// TODO find a way to test following methods
// cw.realClose(calledExplicitly, issueRollback, skipLocalTeardown, reason);
// cw.cleanup(whyCleanedUp);
// cw.abort(executor);
// cw.abortInternal();
}
Also used : PooledConnection(javax.sql.PooledConnection) ServerVersion(com.mysql.cj.ServerVersion) DatabaseMetaDataUsingInfoSchema(com.mysql.cj.jdbc.DatabaseMetaDataUsingInfoSchema) ConnectionWrapper(com.mysql.cj.jdbc.ConnectionWrapper) Connection(java.sql.Connection) PooledConnection(javax.sql.PooledConnection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) Properties(java.util.Properties) DatabaseMetaData(com.mysql.cj.jdbc.DatabaseMetaData) SQLFeatureNotSupportedException(java.sql.SQLFeatureNotSupportedException) SQLException(java.sql.SQLException) CommunicationsException(com.mysql.cj.jdbc.exceptions.CommunicationsException) PacketTooBigException(com.mysql.cj.jdbc.exceptions.PacketTooBigException) SQLNonTransientConnectionException(java.sql.SQLNonTransientConnectionException) Test(org.junit.jupiter.api.Test)

Example 3 with ServerVersion

use of com.mysql.cj.ServerVersion in project ABC by RuiPinto96274.

the class CharsetRegressionTest method testBug91317.

/**
 * Tests fix for Bug#91317 (28207422), Wrong defaults on collation mappings.
 *
 * @throws Exception
 */
@Test
public void testBug91317() throws Exception {
    Map<String, String> defaultCollations = new HashMap<>();
    Properties p = new Properties();
    p.setProperty(PropertyKey.sslMode.getKeyName(), "DISABLED");
    p.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
    p.setProperty(PropertyKey.detectCustomCollations.getKeyName(), "true");
    p.setProperty(PropertyKey.customCharsetMapping.getKeyName(), "custom:Cp1252");
    Connection c = getConnectionWithProps(p);
    // Compare server-side and client-side collation defaults.
    this.rs = this.stmt.executeQuery("SELECT COLLATION_NAME, CHARACTER_SET_NAME, ID FROM INFORMATION_SCHEMA.COLLATIONS WHERE IS_DEFAULT = 'Yes'");
    while (this.rs.next()) {
        String collationName = this.rs.getString(1);
        String charsetName = this.rs.getString(2);
        int collationId = this.rs.getInt(3);
        int mappedCollationId = ((MysqlConnection) c).getSession().getServerSession().getCharsetSettings().getCollationIndexForMysqlCharsetName(charsetName);
        defaultCollations.put(charsetName, collationName);
        // Default collation for 'utf8mb4' is 'utf8mb4_0900_ai_ci' in MySQL 8.0.1 and above, 'utf8mb4_general_ci' in the others.
        if ("utf8mb4".equalsIgnoreCase(charsetName) && !versionMeetsMinimum(8, 0, 1)) {
            mappedCollationId = 45;
        }
        assertEquals(collationId, mappedCollationId);
        assertEquals(collationName, ((MysqlConnection) c).getSession().getServerSession().getCharsetSettings().getCollationNameForCollationIndex(mappedCollationId));
    }
    ServerVersion sv = ((JdbcConnection) this.conn).getServerVersion();
    // Check `collation_connection` for each one of the known character sets.
    this.rs = this.stmt.executeQuery("SELECT character_set_name FROM information_schema.character_sets");
    int csCount = 0;
    while (this.rs.next()) {
        csCount++;
        String cs = this.rs.getString(1);
        // (https://dev.mysql.com/doc/refman/8.0/en/charset-connection.html#charset-connection-impermissible-client-charset)
        if (cs.equalsIgnoreCase("ucs2") || cs.equalsIgnoreCase("utf16") || cs.equalsIgnoreCase("utf16le") || cs.equalsIgnoreCase("utf32")) {
            continue;
        }
        String javaEnc = ((MysqlConnection) c).getSession().getServerSession().getCharsetSettings().getJavaEncodingForMysqlCharset(cs);
        System.out.println(cs + "->" + javaEnc);
        String charsetForJavaEnc = ((MysqlConnection) c).getSession().getServerSession().getCharsetSettings().getMysqlCharsetForJavaEncoding(javaEnc, sv);
        String expectedCollation = defaultCollations.get(charsetForJavaEnc);
        if ("UTF-8".equalsIgnoreCase(javaEnc)) {
            // UTF-8 is the exception. This encoding is converted to MySQL charset 'utf8mb4' instead of 'utf8', and its corresponding collation.
            expectedCollation = versionMeetsMinimum(8, 0, 1) ? "utf8mb4_0900_ai_ci" : "utf8mb4_general_ci";
        }
        Properties p2 = new Properties();
        p2.setProperty(PropertyKey.sslMode.getKeyName(), "DISABLED");
        p2.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
        p2.setProperty(PropertyKey.detectCustomCollations.getKeyName(), "true");
        p2.setProperty(PropertyKey.customCharsetMapping.getKeyName(), "custom:Cp1252");
        p2.setProperty(PropertyKey.characterEncoding.getKeyName(), javaEnc);
        Connection testConn = getConnectionWithProps(p2);
        ResultSet testRs = testConn.createStatement().executeQuery("SHOW VARIABLES LIKE 'collation_connection'");
        assertTrue(testRs.next());
        assertEquals(expectedCollation, testRs.getString(2));
        testConn.close();
    }
    // Assert that some charsets were tested.
    // There are 39 charsets in MySQL 5.5.61, 40 in MySQL 5.6.41 and 41 in MySQL 5.7.23 and above, but these numbers can vary.
    assertTrue(csCount > 35);
}
Also used : ServerVersion(com.mysql.cj.ServerVersion) HashMap(java.util.HashMap) Connection(java.sql.Connection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) MysqlConnection(com.mysql.cj.MysqlConnection) ResultSet(java.sql.ResultSet) MysqlConnection(com.mysql.cj.MysqlConnection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) Properties(java.util.Properties) Test(org.junit.jupiter.api.Test)

Example 4 with ServerVersion

use of com.mysql.cj.ServerVersion in project aws-mysql-jdbc by awslabs.

the class CharsetRegressionTest method testBug91317.

/**
 * Tests fix for Bug#91317 (28207422), Wrong defaults on collation mappings.
 *
 * @throws Exception
 */
@Test
public void testBug91317() throws Exception {
    Map<String, String> defaultCollations = new HashMap<>();
    Properties p = new Properties();
    p.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
    p.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
    p.setProperty(PropertyKey.detectCustomCollations.getKeyName(), "true");
    p.setProperty(PropertyKey.customCharsetMapping.getKeyName(), "custom:Cp1252");
    Connection c = getConnectionWithProps(p);
    // Compare server-side and client-side collation defaults.
    this.rs = this.stmt.executeQuery("SELECT COLLATION_NAME, CHARACTER_SET_NAME, ID FROM INFORMATION_SCHEMA.COLLATIONS WHERE IS_DEFAULT = 'Yes'");
    while (this.rs.next()) {
        String collationName = this.rs.getString(1);
        String charsetName = this.rs.getString(2);
        int collationId = this.rs.getInt(3);
        int mappedCollationId = ((MysqlConnection) c).getSession().getServerSession().getCharsetSettings().getCollationIndexForMysqlCharsetName(charsetName);
        defaultCollations.put(charsetName, collationName);
        // Default collation for 'utf8mb4' is 'utf8mb4_0900_ai_ci' in MySQL 8.0.1 and above, 'utf8mb4_general_ci' in the others.
        if ("utf8mb4".equalsIgnoreCase(charsetName) && !versionMeetsMinimum(8, 0, 1)) {
            mappedCollationId = 45;
        }
        assertEquals(collationId, mappedCollationId);
        assertEquals(collationName, ((MysqlConnection) c).getSession().getServerSession().getCharsetSettings().getCollationNameForCollationIndex(mappedCollationId));
    }
    ServerVersion sv = ((JdbcConnection) this.conn).getServerVersion();
    // Check `collation_connection` for each one of the known character sets.
    this.rs = this.stmt.executeQuery("SELECT character_set_name FROM information_schema.character_sets");
    int csCount = 0;
    while (this.rs.next()) {
        csCount++;
        String cs = this.rs.getString(1);
        // (https://dev.mysql.com/doc/refman/8.0/en/charset-connection.html#charset-connection-impermissible-client-charset)
        if (cs.equalsIgnoreCase("ucs2") || cs.equalsIgnoreCase("utf16") || cs.equalsIgnoreCase("utf16le") || cs.equalsIgnoreCase("utf32")) {
            continue;
        }
        String javaEnc = ((MysqlConnection) c).getSession().getServerSession().getCharsetSettings().getJavaEncodingForMysqlCharset(cs);
        System.out.println(cs + "->" + javaEnc);
        String charsetForJavaEnc = ((MysqlConnection) c).getSession().getServerSession().getCharsetSettings().getMysqlCharsetForJavaEncoding(javaEnc, sv);
        String expectedCollation = defaultCollations.get(charsetForJavaEnc);
        if ("UTF-8".equalsIgnoreCase(javaEnc)) {
            // UTF-8 is the exception. This encoding is converted to MySQL charset 'utf8mb4' instead of 'utf8', and its corresponding collation.
            expectedCollation = versionMeetsMinimum(8, 0, 1) ? "utf8mb4_0900_ai_ci" : "utf8mb4_general_ci";
        }
        Properties p2 = new Properties();
        p2.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
        p2.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
        p2.setProperty(PropertyKey.detectCustomCollations.getKeyName(), "true");
        p2.setProperty(PropertyKey.customCharsetMapping.getKeyName(), "custom:Cp1252");
        p2.setProperty(PropertyKey.characterEncoding.getKeyName(), javaEnc);
        Connection testConn = getConnectionWithProps(p2);
        ResultSet testRs = testConn.createStatement().executeQuery("SHOW VARIABLES LIKE 'collation_connection'");
        assertTrue(testRs.next());
        assertEquals(expectedCollation, testRs.getString(2));
        testConn.close();
    }
    // Assert that some charsets were tested.
    // There are 39 charsets in MySQL 5.5.61, 40 in MySQL 5.6.41 and 41 in MySQL 5.7.23 and above, but these numbers can vary.
    assertTrue(csCount > 35);
}
Also used : ServerVersion(com.mysql.cj.ServerVersion) HashMap(java.util.HashMap) Connection(java.sql.Connection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) MysqlConnection(com.mysql.cj.MysqlConnection) ResultSet(java.sql.ResultSet) MysqlConnection(com.mysql.cj.MysqlConnection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) Properties(java.util.Properties) Test(org.junit.jupiter.api.Test)

Example 5 with ServerVersion

use of com.mysql.cj.ServerVersion in project aws-mysql-jdbc by awslabs.

the class MetadataTest method testGetSqlKeywordsDynamic.

/**
 * Tests DatabaseMetaData.getSQLKeywords().
 * WL#10544, Update MySQL 8.0 keywords list.
 *
 * This test checks the dynamically maintained keywords lists.
 *
 * @throws Exception
 */
@Test
public void testGetSqlKeywordsDynamic() throws Exception {
    assumeTrue(versionMeetsMinimum(8, 0, 11), "MySQL 8.0.11+ is required to run this test.");
    /*
         * Setup test case.
         */
    // 1. Get list of SQL:2003 to exclude.
    Field dbmdSql2003Keywords = com.mysql.cj.jdbc.DatabaseMetaData.class.getDeclaredField("SQL2003_KEYWORDS");
    dbmdSql2003Keywords.setAccessible(true);
    @SuppressWarnings("unchecked") List<String> sql2003ReservedWords = Collections.unmodifiableList((List<String>) dbmdSql2003Keywords.get(null));
    assertTrue(sql2003ReservedWords != null && !sql2003ReservedWords.isEmpty(), "Failed to get field SQL2003_KEYWORDS from com.mysql.cj.jdbc.DatabaseMetaData");
    // 2. Retrieve list of reserved words from server.
    final String keywordsQuery = "SELECT WORD FROM INFORMATION_SCHEMA.KEYWORDS WHERE RESERVED=1 ORDER BY WORD";
    List<String> mysqlReservedWords = new ArrayList<>();
    this.rs = this.stmt.executeQuery(keywordsQuery);
    while (this.rs.next()) {
        mysqlReservedWords.add(this.rs.getString(1));
    }
    assertTrue(!mysqlReservedWords.isEmpty(), "Failed to retrieve reserved words from server.");
    // 3. Find the difference mysqlReservedWords - sql2003ReservedWords and prepare the expected result.
    mysqlReservedWords.removeAll(sql2003ReservedWords);
    String expectedSqlKeywords = String.join(",", mysqlReservedWords);
    // Make sure the keywords cache is empty in DatabaseMetaDataUsingInfoSchema.
    Field dbmduisKeywordsCacheField = DatabaseMetaDataUsingInfoSchema.class.getDeclaredField("keywordsCache");
    dbmduisKeywordsCacheField.setAccessible(true);
    @SuppressWarnings("unchecked") Map<ServerVersion, String> dbmduisKeywordsCache = (Map<ServerVersion, String>) dbmduisKeywordsCacheField.get(null);
    assertNotNull(dbmduisKeywordsCache, "Failed to retrieve the field keywordsCache from com.mysql.cj.jdbc.DatabaseMetaDataUsingInfoSchema.");
    dbmduisKeywordsCache.clear();
    assertTrue(dbmduisKeywordsCache.isEmpty(), "Failed to clear the DatabaseMetaDataUsingInfoSchema keywords cache.");
    /*
         * Check that keywords are retrieved from database and cached.
         */
    Properties props = new Properties();
    props.setProperty(PropertyKey.useInformationSchema.getKeyName(), "true");
    props.setProperty(PropertyKey.queryInterceptors.getKeyName(), TestGetSqlKeywordsDynamicQueryInterceptor.class.getName());
    // First call to DatabaseMetaData.getSQLKeywords() -> keywords are retrieved from database.
    Connection testConn = getConnectionWithProps(props);
    assertEquals(expectedSqlKeywords, testConn.getMetaData().getSQLKeywords(), "MySQL keywords don't match expected.");
    assertTrue(TestGetSqlKeywordsDynamicQueryInterceptor.interceptedQueries.contains(keywordsQuery), "MySQL keywords weren't obtained from database.");
    assertTrue(dbmduisKeywordsCache.containsKey(((JdbcConnection) testConn).getServerVersion()), "Keywords for current server weren't properly cached.");
    TestGetSqlKeywordsDynamicQueryInterceptor.interceptedQueries.clear();
    // Second call to DatabaseMetaData.getSQLKeywords(), using same connection -> keywords are retrieved from internal cache.
    assertEquals(expectedSqlKeywords, testConn.getMetaData().getSQLKeywords(), "MySQL keywords don't match expected.");
    assertFalse(TestGetSqlKeywordsDynamicQueryInterceptor.interceptedQueries.contains(keywordsQuery), "MySQL keywords weren't obtained from cache.");
    assertTrue(dbmduisKeywordsCache.containsKey(((JdbcConnection) testConn).getServerVersion()), "Keywords for current server weren't properly cached.");
    testConn.close();
    TestGetSqlKeywordsDynamicQueryInterceptor.interceptedQueries.clear();
    // Third call to DatabaseMetaData.getSQLKeywords(), using different connection -> keywords are retrieved from internal cache.
    testConn = getConnectionWithProps(props);
    assertEquals(expectedSqlKeywords, testConn.getMetaData().getSQLKeywords(), "MySQL keywords don't match expected.");
    assertFalse(TestGetSqlKeywordsDynamicQueryInterceptor.interceptedQueries.contains(keywordsQuery), "MySQL keywords weren't obtained from cache.");
    assertTrue(dbmduisKeywordsCache.containsKey(((JdbcConnection) testConn).getServerVersion()), "Keywords for current server weren't properly cached.");
    testConn.close();
    TestGetSqlKeywordsDynamicQueryInterceptor.interceptedQueries.clear();
}
Also used : ServerVersion(com.mysql.cj.ServerVersion) ArrayList(java.util.ArrayList) Connection(java.sql.Connection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) Properties(java.util.Properties) Field(java.lang.reflect.Field) Map(java.util.Map) Test(org.junit.jupiter.api.Test)

Aggregations

ServerVersion (com.mysql.cj.ServerVersion)14 JdbcConnection (com.mysql.cj.jdbc.JdbcConnection)12 Properties (java.util.Properties)12 Test (org.junit.jupiter.api.Test)12 Connection (java.sql.Connection)9 HashMap (java.util.HashMap)6 ArrayList (java.util.ArrayList)5 MysqlConnection (com.mysql.cj.MysqlConnection)3 NativeSession (com.mysql.cj.NativeSession)3 Session (com.mysql.cj.Session)3 ConnectionWrapper (com.mysql.cj.jdbc.ConnectionWrapper)3 DatabaseMetaData (com.mysql.cj.jdbc.DatabaseMetaData)3 DatabaseMetaDataUsingInfoSchema (com.mysql.cj.jdbc.DatabaseMetaDataUsingInfoSchema)3 CommunicationsException (com.mysql.cj.jdbc.exceptions.CommunicationsException)3 PacketTooBigException (com.mysql.cj.jdbc.exceptions.PacketTooBigException)3 ServerSession (com.mysql.cj.protocol.ServerSession)3 NativeServerSession (com.mysql.cj.protocol.a.NativeServerSession)3 Field (java.lang.reflect.Field)3 ResultSet (java.sql.ResultSet)3 SQLException (java.sql.SQLException)3