use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.
the class DmlStatementsProcessor method updateSqlFieldsBatched.
/**
* Execute DML statement, possibly with few re-attempts in case of concurrent data modifications.
*
* @param schemaName Schema.
* @param conn Connection.
* @param prepared Prepared statement.
* @param fieldsQry Original query.
* @param loc Query locality flag.
* @param filters Cache name and key filter.
* @param cancel Cancel.
* @return Update result (modified items count and failed keys).
* @throws IgniteCheckedException if failed.
*/
private Collection<UpdateResult> updateSqlFieldsBatched(String schemaName, Connection conn, Prepared prepared, SqlFieldsQueryEx fieldsQry, boolean loc, IndexingQueryFilter filters, GridQueryCancel cancel) throws IgniteCheckedException {
List<Object[]> argss = fieldsQry.batchedArguments();
UpdatePlan plan = getPlanForStatement(schemaName, conn, prepared, fieldsQry, loc, null);
if (plan.hasRows() && plan.mode() == UpdateMode.INSERT) {
GridCacheContext<?, ?> cctx = plan.cacheContext();
CacheOperationContext opCtx = setKeepBinaryContext(cctx);
try {
List<List<List<?>>> cur = plan.createRows(argss);
List<UpdateResult> res = processDmlSelectResultBatched(plan, cur, fieldsQry.getPageSize());
return res;
} finally {
cctx.operationContextPerCall(opCtx);
}
} else {
// Fallback to previous mode.
Collection<UpdateResult> ress = new ArrayList<>(argss.size());
SQLException batchException = null;
int[] cntPerRow = new int[argss.size()];
int cntr = 0;
for (Object[] args : argss) {
SqlFieldsQueryEx qry0 = (SqlFieldsQueryEx) fieldsQry.copy();
qry0.clearBatchedArgs();
qry0.setArgs(args);
UpdateResult res;
try {
res = updateSqlFields(schemaName, conn, prepared, qry0, loc, filters, cancel);
cntPerRow[cntr++] = (int) res.counter();
ress.add(res);
} catch (Exception e) {
String sqlState;
int code;
if (e instanceof IgniteSQLException) {
sqlState = ((IgniteSQLException) e).sqlState();
code = ((IgniteSQLException) e).statusCode();
} else {
sqlState = SqlStateCode.INTERNAL_ERROR;
code = IgniteQueryErrorCode.UNKNOWN;
}
batchException = chainException(batchException, new SQLException(e.getMessage(), sqlState, code, e));
cntPerRow[cntr++] = Statement.EXECUTE_FAILED;
}
}
if (batchException != null) {
BatchUpdateException e = new BatchUpdateException(batchException.getMessage(), batchException.getSQLState(), batchException.getErrorCode(), cntPerRow, batchException);
throw new IgniteCheckedException(e);
}
return ress;
}
}
use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.
the class DmlStatementsProcessor method processBulkLoadCommand.
/**
* Process bulk load COPY command.
*
* @param cmd The command.
* @return The context (which is the result of the first request/response).
* @throws IgniteCheckedException If something failed.
*/
public FieldsQueryCursor<List<?>> processBulkLoadCommand(SqlBulkLoadCommand cmd) throws IgniteCheckedException {
if (cmd.packetSize() == null)
cmd.packetSize(BulkLoadAckClientParameters.DFLT_PACKET_SIZE);
GridH2Table tbl = idx.dataTable(cmd.schemaName(), cmd.tableName());
if (tbl == null) {
idx.kernalContext().cache().createMissingQueryCaches();
tbl = idx.dataTable(cmd.schemaName(), cmd.tableName());
}
if (tbl == null) {
throw new IgniteSQLException("Table does not exist: " + cmd.tableName(), IgniteQueryErrorCode.TABLE_NOT_FOUND);
}
UpdatePlan plan = UpdatePlanBuilder.planForBulkLoad(cmd, tbl);
IgniteClosureX<List<?>, IgniteBiTuple<?, ?>> dataConverter = new BulkLoadDataConverter(plan);
GridCacheContext cache = tbl.cache();
IgniteDataStreamer<Object, Object> streamer = cache.grid().dataStreamer(cache.name());
BulkLoadCacheWriter outputWriter = new BulkLoadStreamerWriter(streamer);
BulkLoadParser inputParser = BulkLoadParser.createParser(cmd.inputFormat());
BulkLoadProcessor processor = new BulkLoadProcessor(inputParser, dataConverter, outputWriter);
BulkLoadAckClientParameters params = new BulkLoadAckClientParameters(cmd.localFileName(), cmd.packetSize());
return new BulkLoadContextCursor(processor, params);
}
use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.
the class DmlStatementsProcessor method doInsert.
/**
* Execute INSERT statement plan.
* @param cursor Cursor to take inserted data from.
* @param pageSize Batch size for streaming, anything <= 0 for single page operations.
* @return Number of items affected.
* @throws IgniteCheckedException if failed, particularly in case of duplicate keys.
*/
@SuppressWarnings({ "unchecked", "ConstantConditions" })
private long doInsert(UpdatePlan plan, Iterable<List<?>> cursor, int pageSize) throws IgniteCheckedException {
GridCacheContext cctx = plan.cacheContext();
// If we have just one item to put, just do so
if (plan.rowCount() == 1) {
IgniteBiTuple t = plan.processRow(cursor.iterator().next());
if (cctx.cache().putIfAbsent(t.getKey(), t.getValue()))
return 1;
else
throw new IgniteSQLException("Duplicate key during INSERT [key=" + t.getKey() + ']', DUPLICATE_KEY);
} else {
// Keys that failed to INSERT due to duplication.
DmlBatchSender sender = new DmlBatchSender(cctx, pageSize, 1);
for (List<?> row : cursor) {
final IgniteBiTuple keyValPair = plan.processRow(row);
sender.add(keyValPair.getKey(), new InsertEntryProcessor(keyValPair.getValue()), 0);
}
sender.flush();
SQLException resEx = sender.error();
if (!F.isEmpty(sender.failedKeys())) {
String msg = "Failed to INSERT some keys because they are already in cache " + "[keys=" + sender.failedKeys() + ']';
SQLException dupEx = new SQLException(msg, SqlStateCode.CONSTRAINT_VIOLATION);
if (resEx == null)
resEx = dupEx;
else
resEx.setNextException(dupEx);
}
if (resEx != null)
throw new IgniteSQLException(resEx);
return sender.updateCount();
}
}
use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.
the class JdbcConnection method prepareStatement.
/**
* {@inheritDoc}
*/
@Override
public PreparedStatement prepareStatement(String sql, int resSetType, int resSetConcurrency, int resSetHoldability) throws SQLException {
ensureNotClosed();
if (resSetType != TYPE_FORWARD_ONLY)
throw new SQLFeatureNotSupportedException("Invalid result set type (only forward is supported.)");
if (resSetConcurrency != CONCUR_READ_ONLY)
throw new SQLFeatureNotSupportedException("Invalid concurrency (updates are not supported).");
if (!txAllowed && resSetHoldability != HOLD_CURSORS_OVER_COMMIT)
throw new SQLFeatureNotSupportedException("Invalid holdability (transactions are not supported).");
JdbcPreparedStatement stmt;
if (!stream)
stmt = new JdbcPreparedStatement(this, sql);
else {
GridQueryIndexing idx = ignite().context().query().getIndexing();
PreparedStatement nativeStmt = prepareNativeStatement(sql);
try {
idx.checkStatementStreamable(nativeStmt);
} catch (IgniteSQLException e) {
throw e.toJdbcException();
}
IgniteDataStreamer streamer = ignite().dataStreamer(cacheName);
streamer.autoFlushFrequency(streamFlushTimeout);
streamer.allowOverwrite(streamAllowOverwrite);
if (streamNodeBufSize > 0)
streamer.perNodeBufferSize(streamNodeBufSize);
if (streamNodeParOps > 0)
streamer.perNodeParallelOperations(streamNodeParOps);
stmt = new JdbcStreamedPreparedStatement(this, sql, streamer, nativeStmt);
}
statements.add(stmt);
return stmt;
}
use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.
the class OdbcRequestHandler method exceptionToBatchResult.
/**
* Create {@link OdbcResponse} bearing appropriate Ignite specific result code if possible
* from given {@link Exception}.
*
* @param e Exception to convert.
* @return resulting {@link OdbcResponse}.
*/
private OdbcResponse exceptionToBatchResult(Exception e) {
int code;
String msg;
List<Long> rowsAffected = new ArrayList<>();
if (e instanceof IgniteSQLException) {
BatchUpdateException batchCause = X.cause(e, BatchUpdateException.class);
if (batchCause != null) {
for (long cnt : batchCause.getLargeUpdateCounts()) rowsAffected.add(cnt);
msg = batchCause.getMessage();
code = batchCause.getErrorCode();
} else {
msg = OdbcUtils.tryRetrieveH2ErrorMessage(e);
code = ((IgniteSQLException) e).statusCode();
}
} else {
msg = e.getMessage();
code = IgniteQueryErrorCode.UNKNOWN;
}
OdbcQueryExecuteBatchResult res = new OdbcQueryExecuteBatchResult(rowsAffected, -1, code, msg);
return new OdbcResponse(res);
}
Aggregations