use of com.mysql.cj.PreparedQuery in project aws-mysql-jdbc by awslabs.
the class ClientPreparedStatement method getMetaData.
@Override
public java.sql.ResultSetMetaData getMetaData() throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
if (!isResultSetProducingQuery()) {
return null;
}
JdbcPreparedStatement mdStmt = null;
java.sql.ResultSet mdRs = null;
if (this.pstmtResultMetaData == null) {
try {
mdStmt = new ClientPreparedStatement(this.connection, ((PreparedQuery<?>) this.query).getOriginalSql(), this.getCurrentDatabase(), getParseInfo());
mdStmt.setMaxRows(1);
int paramCount = ((PreparedQuery<?>) this.query).getParameterCount();
for (int i = 1; i <= paramCount; i++) {
mdStmt.setString(i, null);
}
boolean hadResults = mdStmt.execute();
if (hadResults) {
mdRs = mdStmt.getResultSet();
this.pstmtResultMetaData = mdRs.getMetaData();
} else {
this.pstmtResultMetaData = new ResultSetMetaData(this.session, new Field[0], this.session.getPropertySet().getBooleanProperty(PropertyKey.useOldAliasMetadataBehavior).getValue(), this.session.getPropertySet().getBooleanProperty(PropertyKey.yearIsDateType).getValue(), this.exceptionInterceptor);
}
} finally {
SQLException sqlExRethrow = null;
if (mdRs != null) {
try {
mdRs.close();
} catch (SQLException sqlEx) {
sqlExRethrow = sqlEx;
}
mdRs = null;
}
if (mdStmt != null) {
try {
mdStmt.close();
} catch (SQLException sqlEx) {
sqlExRethrow = sqlEx;
}
mdStmt = null;
}
if (sqlExRethrow != null) {
throw sqlExRethrow;
}
}
}
return this.pstmtResultMetaData;
}
}
use of com.mysql.cj.PreparedQuery in project aws-mysql-jdbc by awslabs.
the class ClientPreparedStatement method executeUpdateInternal.
/**
* Added to allow batch-updates
*
* @param bindings
* bindings object
* @param isReallyBatch
* is it a batched statement?
*
* @return the update count
*
* @throws SQLException
* if a database error occurs
*/
protected long executeUpdateInternal(QueryBindings<?> bindings, boolean isReallyBatch) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
JdbcConnection locallyScopedConn = this.connection;
if (locallyScopedConn.isReadOnly(false)) {
throw SQLError.createSQLException(Messages.getString("PreparedStatement.34") + Messages.getString("PreparedStatement.35"), MysqlErrorNumbers.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor);
}
if (!isNonResultSetProducingQuery()) {
throw SQLError.createSQLException(Messages.getString("PreparedStatement.37"), "01S03", this.exceptionInterceptor);
}
resetCancelledState();
implicitlyCloseAllOpenResults();
ResultSetInternalMethods rs = null;
Message sendPacket = ((PreparedQuery<?>) this.query).fillSendPacket(bindings);
String oldDb = null;
if (!locallyScopedConn.getDatabase().equals(this.getCurrentDatabase())) {
oldDb = locallyScopedConn.getDatabase();
locallyScopedConn.setDatabase(this.getCurrentDatabase());
}
//
// Only apply max_rows to selects
//
locallyScopedConn.setSessionMaxRows(-1);
rs = executeInternal(-1, sendPacket, false, false, null, isReallyBatch);
if (this.retrieveGeneratedKeys) {
rs.setFirstCharOfQuery(getParseInfo().getFirstStmtChar());
}
if (oldDb != null) {
locallyScopedConn.setDatabase(oldDb);
}
this.results = rs;
this.updateCount = rs.getUpdateCount();
if (containsOnDuplicateKeyUpdateInSQL() && this.compensateForOnDuplicateKeyUpdate) {
if (this.updateCount == 2 || this.updateCount == 0) {
this.updateCount = 1;
}
}
this.lastInsertId = rs.getUpdateID();
return this.updateCount;
}
}
use of com.mysql.cj.PreparedQuery in project aws-mysql-jdbc by awslabs.
the class ClientPreparedStatement method initializeFromParseInfo.
@SuppressWarnings("unchecked")
private void initializeFromParseInfo() throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
int parameterCount = getParseInfo().getStaticSql().length - 1;
((PreparedQuery<?>) this.query).setParameterCount(parameterCount);
((PreparedQuery<ClientPreparedQueryBindings>) this.query).setQueryBindings(new ClientPreparedQueryBindings(parameterCount, this.session));
((ClientPreparedQuery) this.query).getQueryBindings().setLoadDataQuery(getParseInfo().isLoadData());
clearParameters();
}
}
use of com.mysql.cj.PreparedQuery 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();
}
}
}
use of com.mysql.cj.PreparedQuery in project aws-mysql-jdbc by awslabs.
the class ServerPreparedStatement method asSql.
@Override
public String asSql(boolean quoteStreamsAndUnknowns) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
ClientPreparedStatement pStmtForSub = null;
try {
pStmtForSub = ClientPreparedStatement.getInstance(this.connection, ((PreparedQuery<?>) this.query).getOriginalSql(), this.getCurrentDatabase());
int numParameters = ((PreparedQuery<?>) pStmtForSub.query).getParameterCount();
int ourNumParameters = ((PreparedQuery<?>) this.query).getParameterCount();
ServerPreparedQueryBindValue[] parameterBindings = ((ServerPreparedQuery) this.query).getQueryBindings().getBindValues();
for (int i = 0; (i < numParameters) && (i < ourNumParameters); i++) {
if (parameterBindings[i] != null) {
if (parameterBindings[i].isNull()) {
pStmtForSub.setNull(i + 1, MysqlType.NULL);
} else {
ServerPreparedQueryBindValue bindValue = parameterBindings[i];
//
switch(bindValue.bufferType) {
case MysqlType.FIELD_TYPE_TINY:
pStmtForSub.setByte(i + 1, ((Long) bindValue.value).byteValue());
break;
case MysqlType.FIELD_TYPE_SHORT:
pStmtForSub.setShort(i + 1, ((Long) bindValue.value).shortValue());
break;
case MysqlType.FIELD_TYPE_LONG:
pStmtForSub.setInt(i + 1, ((Long) bindValue.value).intValue());
break;
case MysqlType.FIELD_TYPE_LONGLONG:
pStmtForSub.setLong(i + 1, ((Long) bindValue.value).longValue());
break;
case MysqlType.FIELD_TYPE_FLOAT:
pStmtForSub.setFloat(i + 1, ((Float) bindValue.value).floatValue());
break;
case MysqlType.FIELD_TYPE_DOUBLE:
pStmtForSub.setDouble(i + 1, ((Double) bindValue.value).doubleValue());
break;
default:
pStmtForSub.setObject(i + 1, parameterBindings[i].value);
break;
}
}
}
}
return pStmtForSub.asSql(quoteStreamsAndUnknowns);
} finally {
if (pStmtForSub != null) {
try {
pStmtForSub.close();
} catch (SQLException sqlEx) {
// ignore
}
}
}
}
}
Aggregations