use of org.apache.ignite.IgniteCheckedException in project ignite by apache.
the class IgniteH2Indexing method createSortedIndex.
/**
* Create sorted index.
*
* @param name Index name,
* @param tbl Table.
* @param pk Primary key flag.
* @param cols Columns.
* @param inlineSize Index inline size.
* @return Index.
*/
GridH2IndexBase createSortedIndex(String name, GridH2Table tbl, boolean pk, List<IndexColumn> cols, int inlineSize) {
try {
GridCacheContext cctx = tbl.cache();
if (log.isDebugEnabled())
log.debug("Creating cache index [cacheId=" + cctx.cacheId() + ", idxName=" + name + ']');
final int segments = tbl.rowDescriptor().context().config().getQueryParallelism();
H2RowCache cache = rowCache.forGroup(cctx.groupId());
return new H2TreeIndex(cctx, cache, tbl, name, pk, cols, inlineSize, segments);
} catch (IgniteCheckedException e) {
throw new IgniteException(e);
}
}
use of org.apache.ignite.IgniteCheckedException in project ignite by apache.
the class IgniteH2Indexing method doRunPrepared.
/**
* Execute an all-ready {@link SqlFieldsQuery}.
* @param schemaName Schema name.
* @param prepared H2 command.
* @param qry Fields query with flags.
* @param twoStepQry Two-step query if this query must be executed in a distributed way.
* @param meta Metadata for {@code twoStepQry}.
* @param keepBinary Whether binary objects must not be deserialized automatically.
* @param cancel Query cancel state holder. @return Query result.
*/
private List<? extends FieldsQueryCursor<List<?>>> doRunPrepared(String schemaName, Prepared prepared, SqlFieldsQuery qry, GridCacheTwoStepQuery twoStepQry, List<GridQueryFieldMetadata> meta, boolean keepBinary, GridQueryCancel cancel) {
String sqlQry = qry.getSql();
boolean loc = qry.isLocal();
IndexingQueryFilter filter = (loc ? backupFilter(null, qry.getPartitions()) : null);
if (!prepared.isQuery()) {
if (DmlStatementsProcessor.isDmlStatement(prepared)) {
try {
Connection conn = connectionForSchema(schemaName);
if (!loc)
return dmlProc.updateSqlFieldsDistributed(schemaName, conn, prepared, qry, cancel);
else {
final GridQueryFieldsResult updRes = dmlProc.updateSqlFieldsLocal(schemaName, conn, prepared, qry, filter, cancel);
return Collections.singletonList(new QueryCursorImpl<>(new Iterable<List<?>>() {
@Override
public Iterator<List<?>> iterator() {
try {
return new GridQueryCacheObjectsIterator(updRes.iterator(), objectContext(), true);
} catch (IgniteCheckedException e) {
throw new IgniteException(e);
}
}
}, cancel));
}
} catch (IgniteCheckedException e) {
throw new IgniteSQLException("Failed to execute DML statement [stmt=" + sqlQry + ", params=" + Arrays.deepToString(qry.getArgs()) + "]", e);
}
}
if (DdlStatementsProcessor.isDdlStatement(prepared)) {
if (loc)
throw new IgniteSQLException("DDL statements are not supported for LOCAL caches", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
try {
return Collections.singletonList(ddlProc.runDdlStatement(sqlQry, prepared));
} catch (IgniteCheckedException e) {
throw new IgniteSQLException("Failed to execute DDL statement [stmt=" + sqlQry + ']', e);
}
}
if (prepared instanceof NoOperation) {
QueryCursorImpl<List<?>> resCur = (QueryCursorImpl<List<?>>) new QueryCursorImpl(Collections.singletonList(Collections.singletonList(0L)), null, false);
resCur.fieldsMeta(UPDATE_RESULT_META);
return Collections.singletonList(resCur);
}
throw new IgniteSQLException("Unsupported DDL/DML operation: " + prepared.getClass().getName());
}
if (twoStepQry != null) {
if (log.isDebugEnabled())
log.debug("Parsed query: `" + sqlQry + "` into two step query: " + twoStepQry);
checkQueryType(qry, true);
return Collections.singletonList(doRunDistributedQuery(schemaName, qry, twoStepQry, meta, keepBinary, cancel));
}
// We've encountered a local query, let's just run it.
try {
return Collections.singletonList(queryLocalSqlFields(schemaName, qry, keepBinary, filter, cancel));
} catch (IgniteCheckedException e) {
throw new IgniteSQLException("Failed to execute local statement [stmt=" + sqlQry + ", params=" + Arrays.deepToString(qry.getArgs()) + "]", e);
}
}
use of org.apache.ignite.IgniteCheckedException in project ignite by apache.
the class IgniteH2Indexing method connectionForThread.
/**
* Gets DB connection.
*
* @param schema Whether to set schema for connection or not.
* @return DB connection.
* @throws IgniteCheckedException In case of error.
*/
private Connection connectionForThread(@Nullable String schema) throws IgniteCheckedException {
H2ConnectionWrapper c = connCache.get();
if (c == null)
throw new IgniteCheckedException("Failed to get DB connection for thread (check log for details).");
if (schema != null && !F.eq(c.schema(), schema)) {
Statement stmt = null;
try {
stmt = c.connection().createStatement();
stmt.executeUpdate("SET SCHEMA " + H2Utils.withQuotes(schema));
if (log.isDebugEnabled())
log.debug("Set schema: " + schema);
c.schema(schema);
} catch (SQLException e) {
throw new IgniteSQLException("Failed to set schema for DB connection for thread [schema=" + schema + "]", e);
} finally {
U.close(stmt, log);
}
}
return c.connection();
}
use of org.apache.ignite.IgniteCheckedException in project ignite by apache.
the class IgniteH2Indexing method parseAndSplit.
/**
* Parse and split query if needed, cache either two-step query or statement.
* @param schemaName Schema name.
* @param qry Query.
* @param firstArg Position of the first argument of the following {@code Prepared}.
* @return Result: prepared statement, H2 command, two-step query (if needed),
* metadata for two-step query (if needed), evaluated query local execution flag.
*/
private ParsingResult parseAndSplit(String schemaName, SqlFieldsQuery qry, int firstArg) {
Connection c = connectionForSchema(schemaName);
// For queries that are explicitly local, we rely on the flag specified in the query
// because this parsing result will be cached and used for queries directly.
// For other queries, we enforce join order at this stage to avoid premature optimizations
// (and therefore longer parsing) as long as there'll be more parsing at split stage.
boolean enforceJoinOrderOnParsing = (!qry.isLocal() || qry.isEnforceJoinOrder());
H2Utils.setupConnection(c, /*distributedJoins*/
false, /*enforceJoinOrder*/
enforceJoinOrderOnParsing);
boolean loc = qry.isLocal();
PreparedStatement stmt = prepareStatementAndCaches(c, qry.getSql());
if (loc && GridSqlQueryParser.checkMultipleStatements(stmt))
throw new IgniteSQLException("Multiple statements queries are not supported for local queries");
GridSqlQueryParser.PreparedWithRemaining prep = GridSqlQueryParser.preparedWithRemaining(stmt);
Prepared prepared = prep.prepared();
checkQueryType(qry, prepared.isQuery());
String remainingSql = prep.remainingSql();
int paramsCnt = prepared.getParameters().size();
Object[] argsOrig = qry.getArgs();
Object[] args = null;
if (!DmlUtils.isBatched(qry) && paramsCnt > 0) {
if (argsOrig == null || argsOrig.length < firstArg + paramsCnt) {
throw new IgniteException("Invalid number of query parameters. " + "Cannot find " + (argsOrig != null ? argsOrig.length + 1 - firstArg : 1) + " parameter.");
}
args = Arrays.copyOfRange(argsOrig, firstArg, firstArg + paramsCnt);
}
if (prepared.isQuery()) {
try {
bindParameters(stmt, F.asList(args));
} catch (IgniteCheckedException e) {
U.closeQuiet(stmt);
throw new IgniteSQLException("Failed to bind parameters: [qry=" + prepared.getSQL() + ", params=" + Arrays.deepToString(args) + "]", IgniteQueryErrorCode.PARSING, e);
}
GridSqlQueryParser parser = null;
if (!loc) {
parser = new GridSqlQueryParser(false);
GridSqlStatement parsedStmt = parser.parse(prepared);
// Legit assertion - we have H2 query flag above.
assert parsedStmt instanceof GridSqlQuery;
loc = parser.isLocalQuery(qry.isReplicatedOnly());
}
if (loc) {
if (parser == null) {
parser = new GridSqlQueryParser(false);
parser.parse(prepared);
}
GridCacheContext cctx = parser.getFirstPartitionedCache();
if (cctx != null && cctx.config().getQueryParallelism() > 1) {
loc = false;
qry.setDistributedJoins(true);
}
}
}
SqlFieldsQuery newQry = cloneFieldsQuery(qry).setSql(prepared.getSQL()).setArgs(args);
boolean hasTwoStep = !loc && prepared.isQuery();
// Let's not cache multiple statements and distributed queries as whole two step query will be cached later on.
if (remainingSql != null || hasTwoStep)
getStatementsCacheForCurrentThread().remove(schemaName, qry.getSql());
if (!hasTwoStep)
return new ParsingResult(prepared, newQry, remainingSql, null, null, null);
final UUID locNodeId = ctx.localNodeId();
// Now we're sure to have a distributed query. Let's try to get a two-step plan from the cache, or perform the
// split if needed.
H2TwoStepCachedQueryKey cachedQryKey = new H2TwoStepCachedQueryKey(schemaName, qry.getSql(), qry.isCollocated(), qry.isDistributedJoins(), qry.isEnforceJoinOrder(), qry.isLocal());
H2TwoStepCachedQuery cachedQry;
if ((cachedQry = twoStepCache.get(cachedQryKey)) != null) {
checkQueryType(qry, true);
GridCacheTwoStepQuery twoStepQry = cachedQry.query().copy();
List<GridQueryFieldMetadata> meta = cachedQry.meta();
return new ParsingResult(prepared, newQry, remainingSql, twoStepQry, cachedQryKey, meta);
}
try {
GridH2QueryContext.set(new GridH2QueryContext(locNodeId, locNodeId, 0, PREPARE).distributedJoinMode(distributedJoinMode(qry.isLocal(), qry.isDistributedJoins())));
try {
return new ParsingResult(prepared, newQry, remainingSql, split(prepared, newQry), cachedQryKey, H2Utils.meta(stmt.getMetaData()));
} catch (IgniteCheckedException e) {
throw new IgniteSQLException("Failed to bind parameters: [qry=" + newQry.getSql() + ", params=" + Arrays.deepToString(newQry.getArgs()) + "]", IgniteQueryErrorCode.PARSING, e);
} catch (SQLException e) {
throw new IgniteSQLException(e);
} finally {
U.close(stmt, log);
}
} finally {
GridH2QueryContext.clearThreadLocal();
}
}
use of org.apache.ignite.IgniteCheckedException in project ignite by apache.
the class IgniteH2Indexing method executeSqlQueryWithTimer.
/**
* Executes sql query and prints warning if query is too slow.
*
* @param stmt Prepared statement for query.
* @param conn Connection.
* @param sql Sql query.
* @param params Parameters.
* @param timeoutMillis Query timeout.
* @param cancel Query cancel.
* @return Result.
* @throws IgniteCheckedException If failed.
*/
private ResultSet executeSqlQueryWithTimer(PreparedStatement stmt, Connection conn, String sql, @Nullable Collection<Object> params, int timeoutMillis, @Nullable GridQueryCancel cancel) throws IgniteCheckedException {
long start = U.currentTimeMillis();
try {
ResultSet rs = executeSqlQuery(conn, stmt, timeoutMillis, cancel);
long time = U.currentTimeMillis() - start;
long longQryExecTimeout = ctx.config().getLongQueryWarningTimeout();
if (time > longQryExecTimeout) {
String msg = "Query execution is too long (" + time + " ms): " + sql;
ResultSet plan = executeSqlQuery(conn, preparedStatementWithParams(conn, "EXPLAIN " + sql, params, false), 0, null);
plan.next();
// Add SQL explain result message into log.
String longMsg = "Query execution is too long [time=" + time + " ms, sql='" + sql + '\'' + ", plan=" + U.nl() + plan.getString(1) + U.nl() + ", parameters=" + (params == null ? "[]" : Arrays.deepToString(params.toArray())) + "]";
LT.warn(log, longMsg, msg);
}
return rs;
} catch (SQLException e) {
onSqlException();
throw new IgniteCheckedException(e);
}
}
Aggregations