use of org.apache.ignite.internal.processors.query.h2.dml.DmlBatchSender in project ignite by apache.
the class DmlUtils method doInsertBatched.
/**
* Execute INSERT statement plan.
*
* @param plan Plan to execute.
* @param cursor Cursor to take inserted data from. I.e. list of batch arguments for each query.
* @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.
*/
private static List<UpdateResult> doInsertBatched(UpdatePlan plan, List<List<List<?>>> cursor, int pageSize) throws IgniteCheckedException {
GridCacheContext cctx = plan.cacheContext();
DmlBatchSender snd = new DmlBatchSender(cctx, pageSize, cursor.size());
int rowNum = 0;
SQLException resEx = null;
for (List<List<?>> qryRow : cursor) {
for (List<?> row : qryRow) {
try {
final IgniteBiTuple keyValPair = plan.processRow(row);
snd.add(keyValPair.getKey(), new DmlStatementsProcessor.InsertEntryProcessor(keyValPair.getValue()), rowNum);
} 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;
}
resEx = chainException(resEx, new SQLException(e.getMessage(), sqlState, code, e));
snd.setFailed(rowNum);
}
}
rowNum++;
}
try {
snd.flush();
} catch (Exception e) {
resEx = chainException(resEx, new SQLException(e.getMessage(), SqlStateCode.INTERNAL_ERROR, IgniteQueryErrorCode.UNKNOWN, e));
}
resEx = chainException(resEx, snd.error());
if (!F.isEmpty(snd.failedKeys())) {
SQLException e = new SQLException("Failed to INSERT some keys because they are already in cache [keys=" + snd.failedKeys() + ']', SqlStateCode.CONSTRAINT_VIOLATION, DUPLICATE_KEY);
resEx = chainException(resEx, e);
}
if (resEx != null) {
BatchUpdateException e = new BatchUpdateException(resEx.getMessage(), resEx.getSQLState(), resEx.getErrorCode(), snd.perRowCounterAsArray(), resEx);
throw new IgniteCheckedException(e);
}
int[] cntPerRow = snd.perRowCounterAsArray();
List<UpdateResult> res = new ArrayList<>(cntPerRow.length);
for (int i = 0; i < cntPerRow.length; i++) {
int cnt = cntPerRow[i];
res.add(new UpdateResult(cnt, X.EMPTY_OBJECT_ARRAY));
}
return res;
}
use of org.apache.ignite.internal.processors.query.h2.dml.DmlBatchSender in project ignite by apache.
the class DmlStatementsProcessor method doInsertBatched.
/**
* Execute INSERT statement plan.
*
* @param plan Plan to execute.
* @param cursor Cursor to take inserted data from. I.e. list of batch arguments for each query.
* @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.
*/
private List<UpdateResult> doInsertBatched(UpdatePlan plan, List<List<List<?>>> cursor, int pageSize) throws IgniteCheckedException {
GridCacheContext cctx = plan.cacheContext();
DmlBatchSender snd = new DmlBatchSender(cctx, pageSize, cursor.size());
int rowNum = 0;
SQLException resEx = null;
for (List<List<?>> qryRow : cursor) {
for (List<?> row : qryRow) {
try {
final IgniteBiTuple keyValPair = plan.processRow(row);
snd.add(keyValPair.getKey(), new InsertEntryProcessor(keyValPair.getValue()), rowNum);
} 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;
}
resEx = chainException(resEx, new SQLException(e.getMessage(), sqlState, code, e));
snd.setFailed(rowNum);
}
}
rowNum++;
}
try {
snd.flush();
} catch (Exception e) {
resEx = chainException(resEx, new SQLException(e.getMessage(), SqlStateCode.INTERNAL_ERROR, IgniteQueryErrorCode.UNKNOWN, e));
}
resEx = chainException(resEx, snd.error());
if (!F.isEmpty(snd.failedKeys())) {
SQLException e = new SQLException("Failed to INSERT some keys because they are already in cache [keys=" + snd.failedKeys() + ']', SqlStateCode.CONSTRAINT_VIOLATION, DUPLICATE_KEY);
resEx = chainException(resEx, e);
}
if (resEx != null) {
BatchUpdateException e = new BatchUpdateException(resEx.getMessage(), resEx.getSQLState(), resEx.getErrorCode(), snd.perRowCounterAsArray(), resEx);
throw new IgniteCheckedException(e);
}
int[] cntPerRow = snd.perRowCounterAsArray();
List<UpdateResult> res = new ArrayList<>(cntPerRow.length);
for (int i = 0; i < cntPerRow.length; i++) {
int cnt = cntPerRow[i];
res.add(new UpdateResult(cnt, X.EMPTY_OBJECT_ARRAY));
}
return res;
}
use of org.apache.ignite.internal.processors.query.h2.dml.DmlBatchSender in project ignite by apache.
the class DmlUtils method doDelete.
/**
* Perform DELETE operation on top of results of SELECT.
*
* @param cctx Cache context.
* @param cursor SELECT results.
* @param pageSize Batch size for streaming, anything <= 0 for single page operations.
* @return Results of DELETE (number of items affected AND keys that failed to be updated).
*/
private static UpdateResult doDelete(GridCacheContext cctx, Iterable<List<?>> cursor, int pageSize) throws IgniteCheckedException {
DmlBatchSender sender = new DmlBatchSender(cctx, pageSize, 1);
for (List<?> row : cursor) {
if (row.size() != 2)
continue;
Object key = row.get(0);
ClusterNode node = sender.primaryNodeByKey(key);
IgniteInClosure<MutableEntry<Object, Object>> rmvC = DmlStatementsProcessor.getRemoveClosure(node, key);
sender.add(key, new DmlStatementsProcessor.ModifyingEntryProcessor(row.get(1), rmvC), 0);
}
sender.flush();
SQLException resEx = sender.error();
if (resEx != null) {
if (!F.isEmpty(sender.failedKeys())) {
// Don't go for a re-run if processing of some keys yielded exceptions and report keys that
// had been modified concurrently right away.
String msg = "Failed to DELETE some keys because they had been modified concurrently " + "[keys=" + sender.failedKeys() + ']';
SQLException conEx = createJdbcSqlException(msg, IgniteQueryErrorCode.CONCURRENT_UPDATE);
conEx.setNextException(resEx);
resEx = conEx;
}
throw new IgniteSQLException(resEx);
}
return new UpdateResult(sender.updateCount(), sender.failedKeys().toArray(), cursor instanceof QueryCursorImpl ? ((QueryCursorImpl) cursor).partitionResult() : null);
}
Aggregations