Search in sources :

Example 6 with NativeSession

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

the class ConnectionRegressionTest method testBug25642021.

/**
 * Tests fix for BUG#25642021, CHANGEUSER() FAILS WHEN ENABLEPACKETDEBUG=TRUE.
 *
 * @throws Exception
 */
@Test
public void testBug25642021() throws Exception {
    Properties props = getPropertiesFromTestsuiteUrl();
    props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
    props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
    props.setProperty(PropertyKey.enablePacketDebug.getKeyName(), "true");
    props.setProperty(PropertyKey.maintainTimeStats.getKeyName(), "true");
    Connection newConn = getConnectionWithProps(props);
    ((JdbcConnection) newConn).changeUser(props.getProperty(PropertyKey.USER.getKeyName()), props.getProperty(PropertyKey.PASSWORD.getKeyName()));
    // check that decorators are still in place
    NativeProtocol p = ((NativeSession) ((JdbcConnection) newConn).getSession()).getProtocol();
    MessageSender<NativePacketPayload> sender = p.getPacketSender();
    MessageReader<NativePacketHeader, NativePacketPayload> reader = p.getPacketReader();
    assertEquals(DebugBufferingPacketSender.class, sender.getClass());
    assertEquals(TimeTrackingPacketSender.class, sender.undecorate().getClass());
    assertEquals(SimplePacketSender.class, sender.undecorate().undecorate().getClass());
    assertEquals(SimplePacketSender.class, sender.undecorate().undecorate().undecorate().getClass());
    assertEquals(MultiPacketReader.class, reader.getClass());
    assertEquals(DebugBufferingPacketReader.class, reader.undecorate().getClass());
    assertEquals(TimeTrackingPacketReader.class, reader.undecorate().undecorate().getClass());
    assertEquals(SimplePacketReader.class, reader.undecorate().undecorate().undecorate().getClass());
    assertEquals(SimplePacketReader.class, reader.undecorate().undecorate().undecorate().undecorate().getClass());
}
Also used : ReplicationConnection(com.mysql.cj.jdbc.ha.ReplicationConnection) MysqlPooledConnection(com.mysql.cj.jdbc.MysqlPooledConnection) SuspendableXAConnection(com.mysql.cj.jdbc.SuspendableXAConnection) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) PooledConnection(javax.sql.PooledConnection) MysqlXAConnection(com.mysql.cj.jdbc.MysqlXAConnection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) MysqlConnection(com.mysql.cj.MysqlConnection) NativeSession(com.mysql.cj.NativeSession) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) NativeProtocol(com.mysql.cj.protocol.a.NativeProtocol) Properties(java.util.Properties) NativePacketPayload(com.mysql.cj.protocol.a.NativePacketPayload) NativePacketHeader(com.mysql.cj.protocol.a.NativePacketHeader) Test(org.junit.jupiter.api.Test)

Example 7 with NativeSession

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

the class ConnectionTest method testDecoratorsChain.

@Test
public void testDecoratorsChain() throws Exception {
    Connection c = null;
    try {
        Properties props = new Properties();
        props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
        props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
        props.setProperty(PropertyKey.useCompression.getKeyName(), "false");
        props.setProperty(PropertyKey.maintainTimeStats.getKeyName(), "true");
        props.setProperty(PropertyKey.traceProtocol.getKeyName(), "true");
        props.setProperty(PropertyKey.enablePacketDebug.getKeyName(), "true");
        c = getConnectionWithProps(props);
        NativeProtocol p = ((NativeSession) ((JdbcConnection) c).getSession()).getProtocol();
        MessageSender<NativePacketPayload> sender = p.getPacketSender();
        MessageReader<NativePacketHeader, NativePacketPayload> reader = p.getPacketReader();
        assertEquals(DebugBufferingPacketSender.class, sender.getClass());
        assertEquals(TracingPacketSender.class, sender.undecorate().getClass());
        assertEquals(TimeTrackingPacketSender.class, sender.undecorate().undecorate().getClass());
        assertEquals(SimplePacketSender.class, sender.undecorate().undecorate().undecorate().getClass());
        assertEquals(MultiPacketReader.class, reader.getClass());
        assertEquals(DebugBufferingPacketReader.class, reader.undecorate().getClass());
        assertEquals(TracingPacketReader.class, reader.undecorate().undecorate().getClass());
        assertEquals(TimeTrackingPacketReader.class, reader.undecorate().undecorate().undecorate().getClass());
        assertEquals(SimplePacketReader.class, reader.undecorate().undecorate().undecorate().undecorate().getClass());
        // remove traceProtocol
        p.getPropertySet().getProperty(PropertyKey.traceProtocol).setValue(false);
        sender = p.getPacketSender();
        reader = p.getPacketReader();
        assertEquals(DebugBufferingPacketSender.class, sender.getClass());
        assertEquals(TimeTrackingPacketSender.class, sender.undecorate().getClass());
        assertEquals(SimplePacketSender.class, sender.undecorate().undecorate().getClass());
        assertEquals(MultiPacketReader.class, reader.getClass());
        assertEquals(DebugBufferingPacketReader.class, reader.undecorate().getClass());
        assertEquals(TimeTrackingPacketReader.class, reader.undecorate().undecorate().getClass());
        assertEquals(SimplePacketReader.class, reader.undecorate().undecorate().undecorate().getClass());
        // remove maintainTimeStats
        p.getPropertySet().getProperty(PropertyKey.maintainTimeStats).setValue(false);
        sender = p.getPacketSender();
        reader = p.getPacketReader();
        assertEquals(DebugBufferingPacketSender.class, sender.getClass());
        assertEquals(SimplePacketSender.class, sender.undecorate().getClass());
        assertEquals(MultiPacketReader.class, reader.getClass());
        assertEquals(DebugBufferingPacketReader.class, reader.undecorate().getClass());
        assertEquals(SimplePacketReader.class, reader.undecorate().undecorate().getClass());
        assertNotEquals(TimeTrackingPacketSender.class, p.getPacketSentTimeHolder().getClass());
        assertNotEquals(TimeTrackingPacketReader.class, p.getPacketReceivedTimeHolder().getClass());
        // remove enablePacketDebug
        p.getPropertySet().getProperty(PropertyKey.enablePacketDebug).setValue(false);
        sender = p.getPacketSender();
        reader = p.getPacketReader();
        assertEquals(SimplePacketSender.class, sender.getClass());
        assertEquals(MultiPacketReader.class, reader.getClass());
        assertEquals(SimplePacketReader.class, reader.undecorate().getClass());
        // add maintainTimeStats
        p.getPropertySet().getProperty(PropertyKey.maintainTimeStats).setValue(true);
        sender = p.getPacketSender();
        reader = p.getPacketReader();
        assertEquals(TimeTrackingPacketSender.class, sender.getClass());
        assertEquals(SimplePacketSender.class, sender.undecorate().getClass());
        assertEquals(MultiPacketReader.class, reader.getClass());
        assertEquals(TimeTrackingPacketReader.class, reader.undecorate().getClass());
        assertEquals(SimplePacketReader.class, reader.undecorate().undecorate().getClass());
        assertEquals(TimeTrackingPacketSender.class, p.getPacketSentTimeHolder().getClass());
        assertEquals(TimeTrackingPacketReader.class, p.getPacketReceivedTimeHolder().getClass());
        // remove listener and try to enable traceProtocol, it should be missed in this case
        p.getPropertySet().getBooleanProperty(PropertyKey.traceProtocol).removeListener(p);
        // please note that the property is changed anyways, see the next step
        p.getPropertySet().getProperty(PropertyKey.traceProtocol).setValue(true);
        sender = p.getPacketSender();
        reader = p.getPacketReader();
        assertEquals(TimeTrackingPacketSender.class, sender.getClass());
        assertEquals(SimplePacketSender.class, sender.undecorate().getClass());
        assertEquals(MultiPacketReader.class, reader.getClass());
        assertEquals(TimeTrackingPacketReader.class, reader.undecorate().getClass());
        assertEquals(SimplePacketReader.class, reader.undecorate().undecorate().getClass());
        // ensure that other listeners are still working
        p.getPropertySet().getProperty(PropertyKey.enablePacketDebug).setValue(true);
        sender = p.getPacketSender();
        reader = p.getPacketReader();
        assertEquals(DebugBufferingPacketSender.class, sender.getClass());
        // it's here because we changed the traceProtocol previously
        assertEquals(TracingPacketSender.class, sender.undecorate().getClass());
        assertEquals(TimeTrackingPacketSender.class, sender.undecorate().undecorate().getClass());
        assertEquals(SimplePacketSender.class, sender.undecorate().undecorate().undecorate().getClass());
        assertEquals(MultiPacketReader.class, reader.getClass());
        assertEquals(DebugBufferingPacketReader.class, reader.undecorate().getClass());
        assertEquals(TracingPacketReader.class, reader.undecorate().undecorate().getClass());
        assertEquals(TimeTrackingPacketReader.class, reader.undecorate().undecorate().undecorate().getClass());
        assertEquals(SimplePacketReader.class, reader.undecorate().undecorate().undecorate().undecorate().getClass());
    } finally {
        if (c != null) {
            c.close();
        }
    }
}
Also used : Connection(java.sql.Connection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) MysqlConnection(com.mysql.cj.MysqlConnection) NativeSession(com.mysql.cj.NativeSession) NativeProtocol(com.mysql.cj.protocol.a.NativeProtocol) Properties(java.util.Properties) NativePacketPayload(com.mysql.cj.protocol.a.NativePacketPayload) NativePacketHeader(com.mysql.cj.protocol.a.NativePacketHeader) Test(org.junit.jupiter.api.Test)

Example 8 with NativeSession

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

the class ClientPreparedStatement method executePreparedBatchAsMultiStatement.

/**
 * Rewrites the already prepared statement into a multi-statement
 * query of 'statementsPerBatch' values and executes the entire batch
 * using this new statement.
 *
 * @param batchTimeout
 *            timeout for the batch execution
 * @return update counts in the same fashion as executeBatch()
 *
 * @throws SQLException
 *             if a database access error occurs or this method is called on a closed PreparedStatement
 */
protected long[] executePreparedBatchAsMultiStatement(int batchTimeout) throws SQLException {
    synchronized (checkClosed().getConnectionMutex()) {
        // This is kind of an abuse, but it gets the job done
        if (this.batchedValuesClause == null) {
            this.batchedValuesClause = ((PreparedQuery<?>) this.query).getOriginalSql() + ";";
        }
        JdbcConnection locallyScopedConn = this.connection;
        boolean multiQueriesEnabled = locallyScopedConn.getPropertySet().getBooleanProperty(PropertyKey.allowMultiQueries).getValue();
        CancelQueryTask timeoutTask = null;
        try {
            clearWarnings();
            int numBatchedArgs = this.query.getBatchedArgs().size();
            if (this.retrieveGeneratedKeys) {
                this.batchedGeneratedKeys = new ArrayList<>(numBatchedArgs);
            }
            int numValuesPerBatch = ((PreparedQuery<?>) this.query).computeBatchSize(numBatchedArgs);
            if (numBatchedArgs < numValuesPerBatch) {
                numValuesPerBatch = numBatchedArgs;
            }
            java.sql.PreparedStatement batchedStatement = null;
            int batchedParamIndex = 1;
            int numberToExecuteAsMultiValue = 0;
            int batchCounter = 0;
            int updateCountCounter = 0;
            long[] updateCounts = new long[numBatchedArgs * getParseInfo().getNumberOfQueries()];
            SQLException sqlEx = null;
            try {
                if (!multiQueriesEnabled) {
                    ((NativeSession) locallyScopedConn.getSession()).enableMultiQueries();
                }
                batchedStatement = this.retrieveGeneratedKeys ? ((Wrapper) locallyScopedConn.prepareStatement(generateMultiStatementForBatch(numValuesPerBatch), RETURN_GENERATED_KEYS)).unwrap(java.sql.PreparedStatement.class) : ((Wrapper) locallyScopedConn.prepareStatement(generateMultiStatementForBatch(numValuesPerBatch))).unwrap(java.sql.PreparedStatement.class);
                timeoutTask = startQueryTimer((StatementImpl) batchedStatement, batchTimeout);
                numberToExecuteAsMultiValue = numBatchedArgs < numValuesPerBatch ? numBatchedArgs : numBatchedArgs / numValuesPerBatch;
                int numberArgsToExecute = numberToExecuteAsMultiValue * numValuesPerBatch;
                for (int i = 0; i < numberArgsToExecute; i++) {
                    if (i != 0 && i % numValuesPerBatch == 0) {
                        try {
                            batchedStatement.execute();
                        } catch (SQLException ex) {
                            sqlEx = handleExceptionForBatch(batchCounter, numValuesPerBatch, updateCounts, ex);
                        }
                        updateCountCounter = processMultiCountsAndKeys((StatementImpl) batchedStatement, updateCountCounter, updateCounts);
                        batchedStatement.clearParameters();
                        batchedParamIndex = 1;
                    }
                    batchedParamIndex = setOneBatchedParameterSet(batchedStatement, batchedParamIndex, this.query.getBatchedArgs().get(batchCounter++));
                }
                try {
                    batchedStatement.execute();
                } catch (SQLException ex) {
                    sqlEx = handleExceptionForBatch(batchCounter - 1, numValuesPerBatch, updateCounts, ex);
                }
                updateCountCounter = processMultiCountsAndKeys((StatementImpl) batchedStatement, updateCountCounter, updateCounts);
                batchedStatement.clearParameters();
                numValuesPerBatch = numBatchedArgs - batchCounter;
                if (timeoutTask != null) {
                    // we need to check the cancel state now because we loose if after the following batchedStatement.close()
                    ((JdbcPreparedStatement) batchedStatement).checkCancelTimeout();
                }
            } finally {
                if (batchedStatement != null) {
                    batchedStatement.close();
                    batchedStatement = null;
                }
            }
            try {
                if (numValuesPerBatch > 0) {
                    batchedStatement = this.retrieveGeneratedKeys ? locallyScopedConn.prepareStatement(generateMultiStatementForBatch(numValuesPerBatch), RETURN_GENERATED_KEYS) : locallyScopedConn.prepareStatement(generateMultiStatementForBatch(numValuesPerBatch));
                    if (timeoutTask != null) {
                        timeoutTask.setQueryToCancel((Query) batchedStatement);
                    }
                    batchedParamIndex = 1;
                    while (batchCounter < numBatchedArgs) {
                        batchedParamIndex = setOneBatchedParameterSet(batchedStatement, batchedParamIndex, this.query.getBatchedArgs().get(batchCounter++));
                    }
                    try {
                        batchedStatement.execute();
                    } catch (SQLException ex) {
                        sqlEx = handleExceptionForBatch(batchCounter - 1, numValuesPerBatch, updateCounts, ex);
                    }
                    updateCountCounter = processMultiCountsAndKeys((StatementImpl) batchedStatement, updateCountCounter, updateCounts);
                    batchedStatement.clearParameters();
                }
                if (timeoutTask != null) {
                    stopQueryTimer(timeoutTask, true, true);
                    timeoutTask = null;
                }
                if (sqlEx != null) {
                    throw SQLError.createBatchUpdateException(sqlEx, updateCounts, this.exceptionInterceptor);
                }
                return updateCounts;
            } finally {
                if (batchedStatement != null) {
                    batchedStatement.close();
                }
            }
        } finally {
            stopQueryTimer(timeoutTask, false, false);
            resetCancelledState();
            if (!multiQueriesEnabled) {
                ((NativeSession) locallyScopedConn.getSession()).disableMultiQueries();
            }
            clearBatch();
        }
    }
}
Also used : Wrapper(java.sql.Wrapper) SQLException(java.sql.SQLException) ClientPreparedQuery(com.mysql.cj.ClientPreparedQuery) PreparedQuery(com.mysql.cj.PreparedQuery) CancelQueryTask(com.mysql.cj.CancelQueryTask) NativeSession(com.mysql.cj.NativeSession)

Example 9 with NativeSession

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

the class ServerPreparedStatement method realClose.

@Override
public void realClose(boolean calledExplicitly, boolean closeOpenResults) throws SQLException {
    JdbcConnection locallyScopedConn = this.connection;
    if (locallyScopedConn == null) {
        // already closed
        return;
    }
    synchronized (locallyScopedConn.getConnectionMutex()) {
        if (this.connection != null) {
            // 
            // Don't communicate with the server if we're being called from the finalizer...
            // 
            // This will leak server resources, but if we don't do this, we'll deadlock (potentially, because there's no guarantee when, what order, and
            // what concurrency finalizers will be called with). Well-behaved programs won't rely on finalizers to clean up their statements.
            // 
            CJException exceptionDuringClose = null;
            if (this.isCached) {
                locallyScopedConn.decachePreparedStatement(this);
                this.isCached = false;
            }
            super.realClose(calledExplicitly, closeOpenResults);
            ((ServerPreparedQuery) this.query).clearParameters(false);
            // Finally deallocate the prepared statement.
            if (calledExplicitly && !locallyScopedConn.isClosed()) {
                synchronized (locallyScopedConn.getConnectionMutex()) {
                    try {
                        ((NativeSession) locallyScopedConn.getSession()).sendCommand(this.commandBuilder.buildComStmtClose(null, ((ServerPreparedQuery) this.query).getServerStatementId()), true, 0);
                    } catch (CJException sqlEx) {
                        exceptionDuringClose = sqlEx;
                    }
                }
            }
            if (exceptionDuringClose != null) {
                throw exceptionDuringClose;
            }
        }
    }
}
Also used : NativeSession(com.mysql.cj.NativeSession) ServerPreparedQuery(com.mysql.cj.ServerPreparedQuery) CJException(com.mysql.cj.exceptions.CJException)

Aggregations

NativeSession (com.mysql.cj.NativeSession)9 JdbcConnection (com.mysql.cj.jdbc.JdbcConnection)5 MysqlConnection (com.mysql.cj.MysqlConnection)4 Connection (java.sql.Connection)4 Properties (java.util.Properties)4 Test (org.junit.jupiter.api.Test)4 MysqlPooledConnection (com.mysql.cj.jdbc.MysqlPooledConnection)3 MysqlXAConnection (com.mysql.cj.jdbc.MysqlXAConnection)3 SuspendableXAConnection (com.mysql.cj.jdbc.SuspendableXAConnection)3 ReplicationConnection (com.mysql.cj.jdbc.ha.ReplicationConnection)3 IOException (java.io.IOException)3 SQLException (java.sql.SQLException)3 PooledConnection (javax.sql.PooledConnection)3 XAConnection (javax.sql.XAConnection)3 HostInfo (com.mysql.cj.conf.HostInfo)2 ClosedOnExpiredPasswordException (com.mysql.cj.exceptions.ClosedOnExpiredPasswordException)2 PasswordExpiredException (com.mysql.cj.exceptions.PasswordExpiredException)2 PropertyNotModifiableException (com.mysql.cj.exceptions.PropertyNotModifiableException)2 CommunicationsException (com.mysql.cj.jdbc.exceptions.CommunicationsException)2 NativePacketHeader (com.mysql.cj.protocol.a.NativePacketHeader)2