use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.
the class IgniteH2Indexing method lockSelectedRows.
/**
* Locks rows from query cursor and returns the select result.
*
* @param cur Query cursor.
* @param cctx Cache context.
* @param pageSize Page size.
* @param timeout Timeout.
* @return Query results cursor.
*/
private Iterable<List<?>> lockSelectedRows(Iterable<List<?>> cur, GridCacheContext cctx, int pageSize, long timeout) {
assert cctx != null && cctx.mvccEnabled();
GridNearTxLocal tx = tx(ctx);
if (tx == null)
throw new IgniteSQLException("Failed to perform SELECT FOR UPDATE operation: transaction has already finished.");
Collection<List<?>> rowsCache = new ArrayList<>();
UpdateSourceIterator srcIt = new UpdateSourceIterator<KeyCacheObject>() {
private Iterator<List<?>> it = cur.iterator();
@Override
public EnlistOperation operation() {
return EnlistOperation.LOCK;
}
@Override
public boolean hasNextX() throws IgniteCheckedException {
return it.hasNext();
}
@Override
public KeyCacheObject nextX() throws IgniteCheckedException {
List<?> res = it.next();
// nextX() can be called from the different threads.
synchronized (rowsCache) {
rowsCache.add(res.subList(0, res.size() - 1));
if (rowsCache.size() > TX_SIZE_THRESHOLD) {
throw new IgniteCheckedException("Too many rows are locked by SELECT FOR UPDATE statement. " + "Consider locking fewer keys or increase the limit by setting a " + IGNITE_MVCC_TX_SIZE_CACHING_THRESHOLD + " system property. Current value is " + TX_SIZE_THRESHOLD + " rows.");
}
}
// The last column is expected to be a _key.
return cctx.toCacheKeyObject(res.get(res.size() - 1));
}
};
IgniteInternalFuture<Long> fut = tx.updateAsync(cctx, srcIt, pageSize, timeout, true);
try {
fut.get();
} catch (IgniteCheckedException e) {
throw U.convertException(e);
}
return rowsCache;
}
use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.
the class IgniteH2Indexing method executeSelect.
/**
* Execute an all-ready {@link SqlFieldsQuery}.
*
* @param qryDesc Plan key.
* @param qryParams Parameters.
* @param select Select.
* @param keepBinary Whether binary objects must not be deserialized automatically.
* @param cancel Query cancel state holder.
* @return Query result.
*/
private List<? extends FieldsQueryCursor<List<?>>> executeSelect(QueryDescriptor qryDesc, QueryParameters qryParams, QueryParserResultSelect select, boolean keepBinary, GridQueryCancel cancel) {
assert cancel != null;
// Register query.
long qryId = registerRunningQuery(qryDesc, qryParams, cancel, select.statement());
try (TraceSurroundings ignored = MTC.support(ctx.tracing().create(SQL_CURSOR_OPEN, MTC.span()))) {
GridNearTxLocal tx = null;
MvccQueryTracker tracker = null;
GridCacheContext mvccCctx = null;
boolean inTx = false;
if (select.mvccEnabled()) {
mvccCctx = ctx.cache().context().cacheContext(select.mvccCacheId());
if (mvccCctx == null)
throw new IgniteCheckedException("Cache has been stopped concurrently [cacheId=" + select.mvccCacheId() + ']');
boolean autoStartTx = !qryParams.autoCommit() && tx(ctx) == null;
// Start new user tx in case of autocommit == false.
if (autoStartTx)
txStart(ctx, qryParams.timeout());
tx = tx(ctx);
checkActive(tx);
inTx = tx != null;
tracker = MvccUtils.mvccTracker(mvccCctx, tx);
}
int timeout = operationTimeout(qryParams.timeout(), tx);
Iterable<List<?>> iter = executeSelect0(qryId, qryDesc, qryParams, select, keepBinary, tracker, cancel, inTx, timeout);
// Execute SELECT FOR UPDATE if needed.
if (select.forUpdate() && inTx)
iter = lockSelectedRows(iter, mvccCctx, timeout, qryParams.pageSize());
RegisteredQueryCursor<List<?>> cursor = new RegisteredQueryCursor<>(iter, cancel, runningQueryManager(), qryParams.lazy(), qryId, ctx.tracing());
cancel.add(cursor::cancel);
cursor.fieldsMeta(select.meta());
cursor.partitionResult(select.twoStepQuery() != null ? select.twoStepQuery().derivedPartitions() : null);
return singletonList(cursor);
} catch (Exception e) {
runningQryMgr.unregister(qryId, e);
if (e instanceof IgniteCheckedException)
throw U.convertException((IgniteCheckedException) e);
if (e instanceof RuntimeException)
throw (RuntimeException) e;
throw new IgniteSQLException("Failed to execute SELECT statement: " + qryDesc.sql(), e);
}
}
use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.
the class CommandProcessor method runCommandNativeDdl.
/**
* Run DDL statement.
*
* @param sql Original SQL.
* @param cmd Command.
*/
private void runCommandNativeDdl(String sql, SqlCommand cmd) {
IgniteInternalFuture fut = null;
try {
isDdlOnSchemaSupported(cmd.schemaName());
finishActiveTxIfNecessary();
if (cmd instanceof SqlCreateIndexCommand) {
SqlCreateIndexCommand cmd0 = (SqlCreateIndexCommand) cmd;
GridH2Table tbl = schemaMgr.dataTable(cmd0.schemaName(), cmd0.tableName());
if (tbl == null)
throw new SchemaOperationException(SchemaOperationException.CODE_TABLE_NOT_FOUND, cmd0.tableName());
assert tbl.rowDescriptor() != null;
ensureDdlSupported(tbl);
QueryIndex newIdx = new QueryIndex();
newIdx.setName(cmd0.indexName());
newIdx.setIndexType(cmd0.spatial() ? QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED);
LinkedHashMap<String, Boolean> flds = new LinkedHashMap<>();
// Let's replace H2's table and property names by those operated by GridQueryProcessor.
GridQueryTypeDescriptor typeDesc = tbl.rowDescriptor().type();
for (SqlIndexColumn col : cmd0.columns()) {
GridQueryProperty prop = typeDesc.property(col.name());
if (prop == null)
throw new SchemaOperationException(SchemaOperationException.CODE_COLUMN_NOT_FOUND, col.name());
flds.put(prop.name(), !col.descending());
}
newIdx.setFields(flds);
newIdx.setInlineSize(cmd0.inlineSize());
fut = ctx.query().dynamicIndexCreate(tbl.cacheName(), cmd.schemaName(), typeDesc.tableName(), newIdx, cmd0.ifNotExists(), cmd0.parallel());
} else if (cmd instanceof SqlDropIndexCommand) {
SqlDropIndexCommand cmd0 = (SqlDropIndexCommand) cmd;
GridH2Table tbl = schemaMgr.dataTableForIndex(cmd0.schemaName(), cmd0.indexName());
if (tbl != null) {
ensureDdlSupported(tbl);
fut = ctx.query().dynamicIndexDrop(tbl.cacheName(), cmd0.schemaName(), cmd0.indexName(), cmd0.ifExists());
} else {
if (cmd0.ifExists())
fut = new GridFinishedFuture();
else
throw new SchemaOperationException(SchemaOperationException.CODE_INDEX_NOT_FOUND, cmd0.indexName());
}
} else if (cmd instanceof SqlAlterTableCommand) {
SqlAlterTableCommand cmd0 = (SqlAlterTableCommand) cmd;
GridH2Table tbl = schemaMgr.dataTable(cmd0.schemaName(), cmd0.tableName());
if (tbl == null) {
throw new SchemaOperationException(SchemaOperationException.CODE_TABLE_NOT_FOUND, cmd0.tableName());
}
Boolean logging = cmd0.logging();
assert logging != null : "Only LOGGING/NOLOGGING are supported at the moment.";
IgniteCluster cluster = ctx.grid().cluster();
if (logging) {
boolean res = cluster.enableWal(tbl.cacheName());
if (!res)
throw new IgniteSQLException("Logging already enabled for table: " + cmd0.tableName());
} else {
boolean res = cluster.disableWal(tbl.cacheName());
if (!res)
throw new IgniteSQLException("Logging already disabled for table: " + cmd0.tableName());
}
fut = new GridFinishedFuture();
} else if (cmd instanceof SqlCreateUserCommand) {
SqlCreateUserCommand addCmd = (SqlCreateUserCommand) cmd;
ctx.security().createUser(addCmd.userName(), addCmd.password().toCharArray());
} else if (cmd instanceof SqlAlterUserCommand) {
SqlAlterUserCommand altCmd = (SqlAlterUserCommand) cmd;
ctx.security().alterUser(altCmd.userName(), altCmd.password().toCharArray());
} else if (cmd instanceof SqlDropUserCommand) {
SqlDropUserCommand dropCmd = (SqlDropUserCommand) cmd;
ctx.security().dropUser(dropCmd.userName());
} else if (cmd instanceof SqlAnalyzeCommand)
processAnalyzeCommand((SqlAnalyzeCommand) cmd);
else if (cmd instanceof SqlRefreshStatitsicsCommand)
processRefreshStatisticsCommand((SqlRefreshStatitsicsCommand) cmd);
else if (cmd instanceof SqlDropStatisticsCommand)
processDropStatisticsCommand((SqlDropStatisticsCommand) cmd);
else
throw new IgniteSQLException("Unsupported DDL operation: " + sql, IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
if (fut != null)
fut.get();
} catch (SchemaOperationException e) {
throw convert(e);
} catch (IgniteSQLException e) {
throw e;
} catch (Exception e) {
throw new IgniteSQLException(e.getMessage(), e);
}
}
use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.
the class CommandProcessor method processTxCommand.
/**
* Process transactional command.
* @param cmd Command.
* @param params Parameters.
* @throws IgniteCheckedException if failed.
*/
private void processTxCommand(SqlCommand cmd, QueryParameters params) throws IgniteCheckedException {
NestedTxMode nestedTxMode = params.nestedTxMode();
GridNearTxLocal tx = tx(ctx);
if (cmd instanceof SqlBeginTransactionCommand) {
if (!mvccEnabled(ctx))
throw new IgniteSQLException("MVCC must be enabled in order to start transaction.", IgniteQueryErrorCode.MVCC_DISABLED);
if (tx != null) {
if (nestedTxMode == null)
nestedTxMode = NestedTxMode.DEFAULT;
switch(nestedTxMode) {
case COMMIT:
doCommit(tx);
txStart(ctx, params.timeout());
break;
case IGNORE:
log.warning("Transaction has already been started, ignoring BEGIN command.");
break;
case ERROR:
throw new IgniteSQLException("Transaction has already been started.", IgniteQueryErrorCode.TRANSACTION_EXISTS);
default:
throw new IgniteSQLException("Unexpected nested transaction handling mode: " + nestedTxMode.name());
}
} else
txStart(ctx, params.timeout());
} else if (cmd instanceof SqlCommitTransactionCommand) {
// Do nothing if there's no transaction.
if (tx != null)
doCommit(tx);
} else {
assert cmd instanceof SqlRollbackTransactionCommand;
// Do nothing if there's no transaction.
if (tx != null)
doRollback(tx);
}
}
use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.
the class H2Utils method collectMvccEnabled.
/**
* Collect MVCC enabled flag.
*
* @param idx Indexing.
* @param cacheIds Cache IDs.
* @return {@code True} if indexing is enabled.
*/
public static boolean collectMvccEnabled(IgniteH2Indexing idx, List<Integer> cacheIds) {
if (cacheIds.isEmpty())
return false;
GridCacheSharedContext sharedCtx = idx.kernalContext().cache().context();
GridCacheContext cctx0 = null;
boolean mvccEnabled = false;
for (int i = 0; i < cacheIds.size(); i++) {
Integer cacheId = cacheIds.get(i);
GridCacheContext cctx = sharedCtx.cacheContext(cacheId);
if (cctx == null) {
throw new IgniteSQLException("Failed to find cache [cacheId=" + cacheId + ']', IgniteQueryErrorCode.TABLE_NOT_FOUND);
}
if (i == 0) {
mvccEnabled = cctx.mvccEnabled();
cctx0 = cctx;
} else if (cctx.mvccEnabled() != mvccEnabled)
MvccUtils.throwAtomicityModesMismatchException(cctx0.config(), cctx.config());
}
return mvccEnabled;
}
Aggregations