use of org.apache.ignite.internal.processors.odbc.jdbc.JdbcResultWithIo in project ignite by apache.
the class JdbcThinStatement method execute0.
/**
* @param stmtType Expected statement type.
* @param sql Sql query.
* @param args Query parameters.
*
* @throws SQLException Onj error.
*/
protected void execute0(JdbcStatementType stmtType, String sql, List<Object> args) throws SQLException {
ensureNotClosed();
closeResults();
if (sql == null || sql.isEmpty())
throw new SQLException("SQL query is empty.");
checkStatementBatchEmpty();
SqlCommand nativeCmd = null;
if (stmtType != JdbcStatementType.SELECT_STATEMENT_TYPE && isEligibleForNativeParsing(sql))
nativeCmd = tryParseNative(sql);
if (nativeCmd != null) {
conn.executeNative(sql, nativeCmd, this);
resultSets = Collections.singletonList(resultSetForUpdate(0));
// as an ordinary batch citizen.
return;
}
if (conn.isStream()) {
if (stmtType == JdbcStatementType.SELECT_STATEMENT_TYPE)
throw new SQLException("executeQuery() method is not allowed in streaming mode.", SqlStateCode.INTERNAL_ERROR, IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
conn.addBatch(sql, args);
resultSets = Collections.singletonList(resultSetForUpdate(0));
return;
}
JdbcQueryExecuteRequest req = new JdbcQueryExecuteRequest(stmtType, schema, pageSize, maxRows, conn.getAutoCommit(), explicitTimeout, sql, args == null ? null : args.toArray(new Object[args.size()]));
JdbcResultWithIo resWithIo = conn.sendRequest(req, this, null);
JdbcResult res0 = resWithIo.response();
JdbcThinTcpIo stickyIo = resWithIo.cliIo();
assert res0 != null;
if (res0 instanceof JdbcBulkLoadAckResult)
res0 = sendFile((JdbcBulkLoadAckResult) res0, stickyIo);
if (res0 instanceof JdbcQueryExecuteResult) {
JdbcQueryExecuteResult res = (JdbcQueryExecuteResult) res0;
resultSets = Collections.singletonList(new JdbcThinResultSet(this, res.cursorId(), pageSize, res.last(), res.items(), res.isQuery(), conn.autoCloseServerCursor(), res.updateCount(), closeOnCompletion, stickyIo));
} else if (res0 instanceof JdbcQueryExecuteMultipleStatementsResult) {
JdbcQueryExecuteMultipleStatementsResult res = (JdbcQueryExecuteMultipleStatementsResult) res0;
List<JdbcResultInfo> resInfos = res.results();
resultSets = new ArrayList<>(resInfos.size());
boolean firstRes = true;
for (JdbcResultInfo rsInfo : resInfos) {
if (!rsInfo.isQuery())
resultSets.add(resultSetForUpdate(rsInfo.updateCount()));
else {
if (firstRes) {
firstRes = false;
resultSets.add(new JdbcThinResultSet(this, rsInfo.cursorId(), pageSize, res.isLast(), res.items(), true, conn.autoCloseServerCursor(), -1, closeOnCompletion, stickyIo));
} else {
resultSets.add(new JdbcThinResultSet(this, rsInfo.cursorId(), pageSize, false, null, true, conn.autoCloseServerCursor(), -1, closeOnCompletion, stickyIo));
}
}
}
} else
throw new SQLException("Unexpected result [res=" + res0 + ']');
assert !resultSets.isEmpty() : "At least one results set is expected";
}
use of org.apache.ignite.internal.processors.odbc.jdbc.JdbcResultWithIo in project ignite by apache.
the class JdbcThinConnection method sendRequest.
/**
* Send request for execution via corresponding singleIo from {@link #ios} or sticky singleIo.
*
* @param req Request.
* @param stmt Jdbc thin statement.
* @param stickyIo Sticky ignite endpoint.
* @return Server response.
* @throws SQLException On any error.
*/
JdbcResultWithIo sendRequest(JdbcRequest req, JdbcThinStatement stmt, @Nullable JdbcThinTcpIo stickyIo) throws SQLException {
RequestTimeoutTask reqTimeoutTask = null;
acquireMutex();
try {
int retryAttemptsLeft = 1;
Exception lastE = null;
while (retryAttemptsLeft > 0) {
JdbcThinTcpIo cliIo = null;
ensureConnected();
try {
cliIo = (stickyIo == null || !stickyIo.connected()) ? cliIo(calculateNodeIds(req)) : stickyIo;
if (stmt != null && stmt.requestTimeout() != NO_TIMEOUT) {
reqTimeoutTask = new RequestTimeoutTask(req instanceof JdbcBulkLoadBatchRequest ? stmt.currentRequestId() : req.requestId(), cliIo, stmt.requestTimeout());
qryTimeoutScheduledFut = maintenanceExecutor.scheduleAtFixedRate(reqTimeoutTask, 0, REQUEST_TIMEOUT_PERIOD, TimeUnit.MILLISECONDS);
}
JdbcQueryExecuteRequest qryReq = null;
if (req instanceof JdbcQueryExecuteRequest)
qryReq = (JdbcQueryExecuteRequest) req;
JdbcResponse res = cliIo.sendRequest(req, stmt);
txIo = res.activeTransaction() ? cliIo : null;
if (res.status() == IgniteQueryErrorCode.QUERY_CANCELED && stmt != null && stmt.requestTimeout() != NO_TIMEOUT && reqTimeoutTask != null && reqTimeoutTask.expired.get()) {
int qryTimeout = stmt.getQueryTimeout();
throw new SQLTimeoutException(getTimeoutDescription(qryTimeout, cliIo), SqlStateCode.QUERY_CANCELLED, IgniteQueryErrorCode.QUERY_CANCELED);
} else if (res.status() != ClientListenerResponse.STATUS_SUCCESS)
throw new SQLException(res.error(), IgniteQueryErrorCode.codeToSqlState(res.status()), res.status());
updateAffinityCache(qryReq, res);
return new JdbcResultWithIo(res.response(), cliIo);
} catch (SQLException e) {
if (LOG.isLoggable(Level.FINE))
LOG.log(Level.FINE, "Exception during sending an sql request.", e);
throw e;
} catch (Exception e) {
if (LOG.isLoggable(Level.FINE))
LOG.log(Level.FINE, "Exception during sending an sql request.", e);
// for the first time and should skip it during next processing
if (cliIo != null && cliIo.connected())
onDisconnect(cliIo);
if (e instanceof SocketTimeoutException)
throw new SQLException("Connection timed out.", CONNECTION_FAILURE, e);
else {
if (lastE == null) {
retryAttemptsLeft = calculateRetryAttemptsCount(stickyIo, req);
lastE = e;
} else
retryAttemptsLeft--;
}
}
}
throw new SQLException("Failed to communicate with Ignite cluster.", CONNECTION_FAILURE, lastE);
} finally {
if (stmt != null && stmt.requestTimeout() != NO_TIMEOUT && reqTimeoutTask != null)
qryTimeoutScheduledFut.cancel(false);
releaseMutex();
}
}
Aggregations