Search in sources :

Example 36 with BatchUpdateException

use of java.sql.BatchUpdateException in project teiid by teiid.

the class JDBCUpdateExecution method executeTranslatedCommand.

/**
 * @param translatedComm
 * @throws TranslatorException
 * @since 4.3
 */
private void executeTranslatedCommand(TranslatedCommand translatedComm) throws TranslatorException {
    // create statement or PreparedStatement and execute
    String sql = translatedComm.getSql();
    boolean commitType = false;
    boolean succeeded = false;
    try {
        int updateCount = 0;
        Class<?>[] keyColumnDataTypes = null;
        String[] keyColumnNames = null;
        if (command instanceof Insert && context.getCommandContext().isReturnAutoGeneratedKeys() && executionFactory.supportsGeneratedKeys(context, command)) {
            Insert insert = (Insert) command;
            NamedTable nt = insert.getTable();
            if (nt.getMetadataObject() != null) {
                KeyRecord key = nt.getMetadataObject().getPrimaryKey();
                if (key != null) {
                    List<Column> cols = key.getColumns();
                    keyColumnDataTypes = new Class<?>[cols.size()];
                    keyColumnNames = new String[cols.size()];
                    for (int i = 0; i < cols.size(); i++) {
                        Column c = cols.get(i);
                        keyColumnDataTypes[i] = c.getJavaType();
                        // won't work in scenarios where the teiid name is changed or contains a .
                        keyColumnNames[i] = c.getName();
                    }
                }
            }
        }
        if (!translatedComm.isPrepared()) {
            statement = getStatement();
            // handle autoGeneratedKeys
            if (keyColumnDataTypes != null) {
                if (executionFactory.useColumnNamesForGeneratedKeys()) {
                    updateCount = statement.executeUpdate(sql, keyColumnNames);
                } else {
                    updateCount = statement.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
                }
            } else {
                updateCount = statement.executeUpdate(sql);
            }
            result = new int[] { updateCount };
            addStatementWarnings();
        } else {
            PreparedStatement pstatement = null;
            if (statement != null) {
                statement.close();
            }
            if (keyColumnDataTypes != null) {
                if (executionFactory.useColumnNamesForGeneratedKeys()) {
                    pstatement = connection.prepareStatement(sql, keyColumnNames);
                } else {
                    pstatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
                }
            } else {
                pstatement = getPreparedStatement(sql);
            }
            statement = pstatement;
            Iterator<? extends List<?>> vi = null;
            if (command instanceof BulkCommand) {
                BulkCommand batchCommand = (BulkCommand) command;
                vi = batchCommand.getParameterValues();
            }
            int k = 0;
            int batchStart = 0;
            if (vi != null) {
                try {
                    commitType = getAutoCommit(translatedComm);
                    if (commitType) {
                        connection.setAutoCommit(false);
                    }
                    int maxBatchSize = (command instanceof Insert) ? maxPreparedInsertBatchSize : Integer.MAX_VALUE;
                    boolean done = false;
                    outer: while (!done) {
                        for (int i = 0; i < maxBatchSize; i++) {
                            if (vi.hasNext()) {
                                List<?> values = vi.next();
                                bind(pstatement, translatedComm.getPreparedValues(), values);
                                k++;
                            } else {
                                if (i == 0) {
                                    break outer;
                                }
                                done = true;
                                break;
                            }
                        }
                        int[] results = pstatement.executeBatch();
                        batchStart = k;
                        if (result == null) {
                            result = results;
                        } else {
                            int len = result.length;
                            result = Arrays.copyOf(result, len + results.length);
                            System.arraycopy(results, 0, result, len, results.length);
                        }
                    }
                } catch (SQLException e) {
                    int size = k + 1;
                    if (result == null) {
                        result = new int[size];
                    } else {
                        result = Arrays.copyOf(result, size);
                    }
                    // if there is a BatchUpdateException, there are more update counts to accumulate
                    if (e instanceof BatchUpdateException) {
                        BatchUpdateException bue = (BatchUpdateException) e;
                        int[] batchResults = bue.getUpdateCounts();
                        for (int j = 0; j < batchResults.length; j++) {
                            result[batchStart + j] = batchResults[j];
                        }
                        size = batchStart + batchResults.length;
                    } else {
                        size = batchStart;
                    }
                    // resize the result and throw exception
                    throw new TranslatorBatchException(e, Arrays.copyOf(result, size));
                }
            } else {
                bind(pstatement, translatedComm.getPreparedValues(), null);
                updateCount = pstatement.executeUpdate();
                result = new int[] { updateCount };
            }
            addStatementWarnings();
            succeeded = true;
        }
        if (keyColumnDataTypes != null) {
            try {
                ResultSet keys = statement.getGeneratedKeys();
                GeneratedKeys generatedKeys = context.getCommandContext().returnGeneratedKeys(keyColumnNames, keyColumnDataTypes);
                // many databases only support returning a single generated value, but we'll still attempt to gather all
                outer: while (keys.next()) {
                    List<Object> vals = new ArrayList<Object>(keyColumnDataTypes.length);
                    for (int i = 0; i < keyColumnDataTypes.length; i++) {
                        Object value = this.executionFactory.retrieveValue(keys, i + 1, keyColumnDataTypes[i]);
                        if (value != null && TypeFacility.getRuntimeType(value.getClass()) != keyColumnDataTypes[i]) {
                            // TODO we may need to let the engine to the final conversion
                            LogManager.logDetail(LogConstants.CTX_CONNECTOR, JDBCPlugin.Util.gs(JDBCPlugin.Event.TEIID11023, keyColumnDataTypes[i], keyColumnNames[i], value.getClass()));
                            continue outer;
                        }
                        vals.add(value);
                    }
                    generatedKeys.addKey(vals);
                }
            } catch (SQLException e) {
                context.addWarning(e);
                // $NON-NLS-1$
                LogManager.logDetail(LogConstants.CTX_CONNECTOR, e, "Exception determining generated keys, no keys will be returned");
            }
        }
    } catch (SQLException err) {
        throw new JDBCExecutionException(JDBCPlugin.Event.TEIID11013, err, translatedComm);
    } finally {
        if (commitType) {
            restoreAutoCommit(!succeeded, translatedComm);
        }
    }
}
Also used : NamedTable(org.teiid.language.NamedTable) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) GeneratedKeys(org.teiid.GeneratedKeys) Insert(org.teiid.language.Insert) TranslatorBatchException(org.teiid.translator.TranslatorBatchException) KeyRecord(org.teiid.metadata.KeyRecord) Column(org.teiid.metadata.Column) BulkCommand(org.teiid.language.BulkCommand) ResultSet(java.sql.ResultSet) ArrayList(java.util.ArrayList) List(java.util.List) BatchUpdateException(java.sql.BatchUpdateException)

Example 37 with BatchUpdateException

use of java.sql.BatchUpdateException in project teiid by teiid.

the class StatementImpl method postReceiveResults.

private synchronized void postReceiveResults(RequestMessage reqMessage, ResultsMessage resultsMsg) throws TeiidSQLException, SQLException {
    commandStatus = State.DONE;
    // warnings thrown
    List resultsWarning = resultsMsg.getWarnings();
    // save warnings if have any
    if (resultsWarning != null) {
        accumulateWarnings(resultsWarning);
    }
    setAnalysisInfo(resultsMsg);
    // throw an exception unless this represents a batch update exception
    if (resultsMsg.getException() != null && (!resultsMsg.isUpdateResult() || resultsMsg.getResultsList() == null)) {
        throw TeiidSQLException.create(resultsMsg.getException());
    }
    resultsMsg.processResults();
    if (resultsMsg.isUpdateResult()) {
        List<? extends List<?>> results = resultsMsg.getResultsList();
        if (resultsMsg.getUpdateCount() == -1) {
            this.updateCounts = new int[results.size()];
            for (int i = 0; i < results.size(); i++) {
                updateCounts[i] = (Integer) results.get(i).get(0);
            }
        } else {
            this.updateCounts = new int[] { resultsMsg.getUpdateCount() };
            this.createResultSet(resultsMsg);
        }
        if (logger.isLoggable(Level.FINER)) {
            // $NON-NLS-1$
            logger.finer("Recieved update counts: " + Arrays.toString(updateCounts));
        }
        // In update scenarios close the statement implicitly - the server should have already done this
        try {
            getDQP().closeRequest(getCurrentRequestID());
        } catch (TeiidProcessingException e) {
            throw TeiidSQLException.create(e);
        } catch (TeiidComponentException e) {
            throw TeiidSQLException.create(e);
        }
        // handle a batch update exception
        if (resultsMsg.getException() != null) {
            TeiidSQLException exe = TeiidSQLException.create(resultsMsg.getException());
            BatchUpdateException batchUpdateException = new BatchUpdateException(exe.getMessage(), exe.getSQLState(), exe.getErrorCode(), updateCounts, exe);
            this.updateCounts = null;
            throw batchUpdateException;
        }
    } else {
        createResultSet(resultsMsg);
    }
    if (logger.isLoggable(Level.FINE)) {
        // $NON-NLS-1$
        logger.fine(JDBCPlugin.Util.getString("MMStatement.Success_query", reqMessage.getCommandString()));
    }
}
Also used : TeiidComponentException(org.teiid.core.TeiidComponentException) TeiidProcessingException(org.teiid.core.TeiidProcessingException) BatchUpdateException(java.sql.BatchUpdateException)

Example 38 with BatchUpdateException

use of java.sql.BatchUpdateException in project teiid by teiid.

the class TestJDBCUpdateExecution method testPreparedBatchedUpdateFailed.

@Test
public void testPreparedBatchedUpdateFailed() throws Exception {
    // $NON-NLS-1$
    Insert command = (Insert) TranslationHelper.helpTranslate(TranslationHelper.BQT_VDB, "insert into BQT1.SmallA (IntKey) values (1)");
    Parameter param = new Parameter();
    param.setType(DataTypeManager.DefaultDataClasses.INTEGER);
    param.setValueIndex(0);
    List<Expression> values = ((ExpressionValueSource) command.getValueSource()).getValues();
    values.set(0, param);
    command.setParameterValues(Arrays.asList(Arrays.asList(1), Arrays.asList(1)).iterator());
    Connection connection = Mockito.mock(Connection.class);
    PreparedStatement s = Mockito.mock(PreparedStatement.class);
    Mockito.stub(s.executeBatch()).toThrow(new BatchUpdateException(new int[] { 1, Statement.EXECUTE_FAILED }));
    Mockito.stub(connection.prepareStatement("INSERT INTO SmallA (IntKey) VALUES (?)")).toReturn(s);
    JDBCExecutionFactory config = new JDBCExecutionFactory();
    ResultSet r = Mockito.mock(ResultSet.class);
    ResultSetMetaData rs = Mockito.mock(ResultSetMetaData.class);
    Mockito.stub(r.getMetaData()).toReturn(rs);
    FakeExecutionContextImpl context = new FakeExecutionContextImpl();
    JDBCUpdateExecution updateExecution = new JDBCUpdateExecution(command, connection, context, config);
    try {
        updateExecution.execute();
        fail();
    } catch (TranslatorBatchException e) {
        int[] counts = e.getUpdateCounts();
        assertArrayEquals(new int[] { 1, -3 }, counts);
    }
    // test multiple batches
    connection = Mockito.mock(Connection.class);
    updateExecution = new JDBCUpdateExecution(command, connection, context, config);
    command.setParameterValues(Arrays.asList(Arrays.asList(1), Arrays.asList(1)).iterator());
    s = Mockito.mock(PreparedStatement.class);
    Mockito.stub(connection.prepareStatement("INSERT INTO SmallA (IntKey) VALUES (?)")).toReturn(s);
    Mockito.stub(s.executeBatch()).toReturn(new int[] { 1 }).toThrow(new BatchUpdateException(new int[] { Statement.EXECUTE_FAILED }));
    updateExecution.setMaxPreparedInsertBatchSize(1);
    try {
        updateExecution.execute();
        fail();
    } catch (TranslatorBatchException e) {
        int[] counts = e.getUpdateCounts();
        assertArrayEquals(new int[] { 1, -3 }, counts);
    }
    // test only a single update count
    connection = Mockito.mock(Connection.class);
    updateExecution = new JDBCUpdateExecution(command, connection, context, config);
    command.setParameterValues(Arrays.asList(Arrays.asList(1), Arrays.asList(1)).iterator());
    s = Mockito.mock(PreparedStatement.class);
    Mockito.stub(connection.prepareStatement("INSERT INTO SmallA (IntKey) VALUES (?)")).toReturn(s);
    Mockito.stub(s.executeBatch()).toThrow(new BatchUpdateException(new int[] { 1 }));
    try {
        updateExecution.execute();
        fail();
    } catch (TranslatorBatchException e) {
        int[] counts = e.getUpdateCounts();
        assertArrayEquals(new int[] { 1 }, counts);
    }
}
Also used : FakeExecutionContextImpl(org.teiid.dqp.internal.datamgr.FakeExecutionContextImpl) Connection(java.sql.Connection) PreparedStatement(java.sql.PreparedStatement) Insert(org.teiid.language.Insert) TranslatorBatchException(org.teiid.translator.TranslatorBatchException) ResultSetMetaData(java.sql.ResultSetMetaData) Expression(org.teiid.language.Expression) ResultSet(java.sql.ResultSet) Parameter(org.teiid.language.Parameter) ExpressionValueSource(org.teiid.language.ExpressionValueSource) BatchUpdateException(java.sql.BatchUpdateException) Test(org.junit.Test)

Example 39 with BatchUpdateException

use of java.sql.BatchUpdateException in project teiid by teiid.

the class TestJDBCUpdateExecution method testBatchedUpdateFailed.

@Test
public void testBatchedUpdateFailed() throws Exception {
    // $NON-NLS-1$
    Insert command = (Insert) TranslationHelper.helpTranslate(TranslationHelper.BQT_VDB, "insert into BQT1.SmallA (IntKey) values (1)");
    // $NON-NLS-1$
    Insert command1 = (Insert) TranslationHelper.helpTranslate(TranslationHelper.BQT_VDB, "insert into BQT1.SmallA (StringKey) values ('1')");
    Connection connection = Mockito.mock(Connection.class);
    Statement s = Mockito.mock(Statement.class);
    Mockito.stub(s.executeBatch()).toThrow(new BatchUpdateException(new int[] { Statement.EXECUTE_FAILED }));
    Mockito.stub(connection.createStatement()).toReturn(s);
    JDBCExecutionFactory config = new JDBCExecutionFactory();
    ResultSet r = Mockito.mock(ResultSet.class);
    ResultSetMetaData rs = Mockito.mock(ResultSetMetaData.class);
    Mockito.stub(r.getMetaData()).toReturn(rs);
    Mockito.stub(s.getGeneratedKeys()).toReturn(r);
    FakeExecutionContextImpl context = new FakeExecutionContextImpl();
    JDBCUpdateExecution updateExecution = new JDBCUpdateExecution(new BatchedUpdates(Arrays.asList((Command) command, command1)), connection, context, config);
    try {
        updateExecution.execute();
        fail();
    } catch (TranslatorBatchException e) {
        int[] counts = e.getUpdateCounts();
        assertArrayEquals(new int[] { -3 }, counts);
    }
}
Also used : ResultSetMetaData(java.sql.ResultSetMetaData) FakeExecutionContextImpl(org.teiid.dqp.internal.datamgr.FakeExecutionContextImpl) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) Connection(java.sql.Connection) ResultSet(java.sql.ResultSet) Insert(org.teiid.language.Insert) TranslatorBatchException(org.teiid.translator.TranslatorBatchException) BatchUpdateException(java.sql.BatchUpdateException) BatchedUpdates(org.teiid.language.BatchedUpdates) Test(org.junit.Test)

Example 40 with BatchUpdateException

use of java.sql.BatchUpdateException in project derby by apache.

the class BatchUpdateTest method testTransactionErrorPreparedStmtBatch.

// try transaction error, in this particular case
// time out while getting the lock
public void testTransactionErrorPreparedStmtBatch() throws SQLException {
    Connection conn = getConnection();
    Connection conn2 = openDefaultConnection();
    conn.setAutoCommit(false);
    conn2.setAutoCommit(false);
    Statement stmt = createStatement();
    Statement stmt2 = conn2.createStatement();
    int[] updateCount = null;
    println("Negative Prepared Statement: " + "testing transaction error, time out while getting the lock");
    stmt.execute("insert into t1 values(1)");
    stmt2.execute("insert into t1 values(2)");
    PreparedStatement pStmt1 = prepareStatement("update t1 set c1=3 where c1=?");
    pStmt1.setInt(1, 2);
    pStmt1.addBatch();
    PreparedStatement pStmt2 = conn.prepareStatement("update t1 set c1=4 where c1=?");
    pStmt2.setInt(1, 1);
    pStmt2.addBatch();
    try {
        pStmt1.executeBatch();
        updateCount = pStmt2.executeBatch();
        fail("Batch is expected to fail");
    } catch (BatchUpdateException bue) {
        /* Check that the exception is time out while 
             * getting the lock */
        if (usingEmbedded())
            assertSQLState("40XL1", bue);
        else if (usingDerbyNetClient())
            assertSQLState("XJ208", bue);
        updateCount = ((BatchUpdateException) bue).getUpdateCounts();
        if (updateCount != null) {
            if (usingEmbedded())
                assertEquals("first statement in the batch caused time out" + " while getting the lock, there should be no update count", 0, updateCount.length);
            else if (usingDerbyNetClient())
                /* first statement in the batch caused time out while getting
                     *  the lock, there should be 1 update count of -3 */
                assertBatchUpdateCounts(new int[] { -3 }, updateCount);
        }
    }
    pStmt1.close();
    pStmt2.close();
    stmt.close();
    stmt2.close();
    rollback();
    conn2.rollback();
    conn2.close();
}
Also used : PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) CallableStatement(java.sql.CallableStatement) Connection(java.sql.Connection) PreparedStatement(java.sql.PreparedStatement) BatchUpdateException(java.sql.BatchUpdateException)

Aggregations

BatchUpdateException (java.sql.BatchUpdateException)103 SQLException (java.sql.SQLException)39 PreparedStatement (java.sql.PreparedStatement)33 Statement (java.sql.Statement)22 ArrayList (java.util.ArrayList)19 Test (org.junit.Test)19 Connection (java.sql.Connection)17 Test (org.testng.annotations.Test)17 BaseTest (util.BaseTest)17 SerializedBatchUpdateException (util.SerializedBatchUpdateException)17 ResultSet (java.sql.ResultSet)13 List (java.util.List)12 CallableStatement (java.sql.CallableStatement)8 HashSet (java.util.HashSet)8 IgniteSQLException (org.apache.ignite.internal.processors.query.IgniteSQLException)7 HashMap (java.util.HashMap)6 Map (java.util.Map)5 CustomChangeException (liquibase.exception.CustomChangeException)5 DatabaseException (liquibase.exception.DatabaseException)5 SetupException (liquibase.exception.SetupException)5