use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.
the class IgniteH2Indexing method streamUpdateQuery.
/**
* {@inheritDoc}
*/
@Override
public long streamUpdateQuery(String schemaName, String qry, @Nullable Object[] params, IgniteDataStreamer<?, ?> streamer) throws IgniteCheckedException {
final Connection conn = connectionForSchema(schemaName);
final PreparedStatement stmt;
try {
stmt = prepareStatement(conn, qry, true);
} catch (SQLException e) {
throw new IgniteSQLException(e);
}
return dmlProc.streamUpdateQuery(schemaName, streamer, stmt, params);
}
use of org.apache.ignite.internal.processors.query.IgniteSQLException 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.internal.processors.query.IgniteSQLException in project ignite by apache.
the class IgniteH2Indexing method queryLocalSql.
/**
* Executes regular query.
*
* @param schemaName Schema name.
* @param cacheName Cache name.
* @param qry Query.
* @param alias Table alias.
* @param params Query parameters.
* @param type Query return type.
* @param filter Cache name and key filter.
* @param cancel Cancel object.
* @return Queried rows.
* @throws IgniteCheckedException If failed.
*/
@SuppressWarnings("unchecked")
<K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalSql(String schemaName, String cacheName, final String qry, String alias, @Nullable final Collection<Object> params, String type, final IndexingQueryFilter filter, GridQueryCancel cancel) throws IgniteCheckedException {
final H2TableDescriptor tbl = tableDescriptor(schemaName, cacheName, type);
if (tbl == null)
throw new IgniteSQLException("Failed to find SQL table for type: " + type, IgniteQueryErrorCode.TABLE_NOT_FOUND);
String sql = generateQuery(qry, alias, tbl);
Connection conn = connectionForThread(tbl.schemaName());
H2Utils.setupConnection(conn, false, false);
GridH2QueryContext.set(new GridH2QueryContext(nodeId, nodeId, 0, LOCAL).filter(filter).distributedJoinMode(OFF));
GridRunningQueryInfo run = new GridRunningQueryInfo(qryIdGen.incrementAndGet(), qry, SQL, schemaName, U.currentTimeMillis(), null, true);
runs.put(run.id(), run);
try {
ResultSet rs = executeSqlQueryWithTimer(conn, sql, params, true, 0, cancel);
return new H2KeyValueIterator(rs);
} finally {
GridH2QueryContext.clearThreadLocal();
runs.remove(run.id());
}
}
use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.
the class IgniteH2Indexing method querySqlFields.
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "StringEquality", "unchecked" })
@Override
public List<FieldsQueryCursor<List<?>>> querySqlFields(String schemaName, SqlFieldsQuery qry, @Nullable SqlClientContext cliCtx, boolean keepBinary, boolean failOnMultipleStmts, GridQueryCancel cancel) {
List<FieldsQueryCursor<List<?>>> res = tryQueryDistributedSqlFieldsNative(schemaName, qry.getSql(), cliCtx);
if (res != null)
return res;
{
// First, let's check if we already have a two-step query for this statement...
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();
res = Collections.singletonList(doRunDistributedQuery(schemaName, qry, twoStepQry, meta, keepBinary, cancel));
if (!twoStepQry.explain())
twoStepCache.putIfAbsent(cachedQryKey, new H2TwoStepCachedQuery(meta, twoStepQry.copy()));
return res;
}
}
{
// Second, let's check if we already have a parsed statement...
PreparedStatement cachedStmt;
if ((cachedStmt = cachedStatement(connectionForSchema(schemaName), qry.getSql())) != null) {
Prepared prepared = GridSqlQueryParser.prepared(cachedStmt);
// We may use this cached statement only for local queries and non queries.
if (qry.isLocal() || !prepared.isQuery())
return (List<FieldsQueryCursor<List<?>>>) doRunPrepared(schemaName, prepared, qry, null, null, keepBinary, cancel);
}
}
res = new ArrayList<>(1);
int firstArg = 0;
String remainingSql = qry.getSql();
while (remainingSql != null) {
ParsingResult parseRes = parseAndSplit(schemaName, remainingSql != qry.getSql() ? cloneFieldsQuery(qry).setSql(remainingSql) : qry, firstArg);
// Let's avoid second reflection getter call by returning Prepared object too
Prepared prepared = parseRes.prepared();
GridCacheTwoStepQuery twoStepQry = parseRes.twoStepQuery();
List<GridQueryFieldMetadata> meta = parseRes.meta();
SqlFieldsQuery newQry = parseRes.newQuery();
remainingSql = parseRes.remainingSql();
if (remainingSql != null && failOnMultipleStmts)
throw new IgniteSQLException("Multiple statements queries are not supported");
firstArg += prepared.getParameters().size();
res.addAll(doRunPrepared(schemaName, prepared, newQry, twoStepQry, meta, keepBinary, cancel));
if (parseRes.twoStepQuery() != null && parseRes.twoStepQueryKey() != null && !parseRes.twoStepQuery().explain())
twoStepCache.putIfAbsent(parseRes.twoStepQueryKey(), new H2TwoStepCachedQuery(meta, twoStepQry.copy()));
}
return res;
}
use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.
the class IgniteH2Indexing method queryLocalSqlFields.
/**
* Queries individual fields (generally used by JDBC drivers).
*
* @param schemaName Schema name.
* @param qry Query.
* @param params Query parameters.
* @param filter Cache name and key filter.
* @param enforceJoinOrder Enforce join order of tables in the query.
* @param timeout Query timeout in milliseconds.
* @param cancel Query cancel.
* @return Query result.
* @throws IgniteCheckedException If failed.
*/
@SuppressWarnings("unchecked")
GridQueryFieldsResult queryLocalSqlFields(final String schemaName, final String qry, @Nullable final Collection<Object> params, final IndexingQueryFilter filter, boolean enforceJoinOrder, final int timeout, final GridQueryCancel cancel) throws IgniteCheckedException {
final Connection conn = connectionForSchema(schemaName);
H2Utils.setupConnection(conn, false, enforceJoinOrder);
final PreparedStatement stmt = preparedStatementWithParams(conn, qry, params, true);
if (GridSqlQueryParser.checkMultipleStatements(stmt))
throw new IgniteSQLException("Multiple statements queries are not supported for local queries");
Prepared p = GridSqlQueryParser.prepared(stmt);
if (DmlStatementsProcessor.isDmlStatement(p)) {
SqlFieldsQuery fldsQry = new SqlFieldsQuery(qry);
if (params != null)
fldsQry.setArgs(params.toArray());
fldsQry.setEnforceJoinOrder(enforceJoinOrder);
fldsQry.setTimeout(timeout, TimeUnit.MILLISECONDS);
return dmlProc.updateSqlFieldsLocal(schemaName, conn, p, fldsQry, filter, cancel);
} else if (DdlStatementsProcessor.isDdlStatement(p))
throw new IgniteSQLException("DDL statements are supported for the whole cluster only", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
List<GridQueryFieldMetadata> meta;
try {
meta = H2Utils.meta(stmt.getMetaData());
} catch (SQLException e) {
throw new IgniteCheckedException("Cannot prepare query metadata", e);
}
final GridH2QueryContext ctx = new GridH2QueryContext(nodeId, nodeId, 0, LOCAL).filter(filter).distributedJoinMode(OFF);
return new GridQueryFieldsResultAdapter(meta, null) {
@Override
public GridCloseableIterator<List<?>> iterator() throws IgniteCheckedException {
assert GridH2QueryContext.get() == null;
GridH2QueryContext.set(ctx);
GridRunningQueryInfo run = new GridRunningQueryInfo(qryIdGen.incrementAndGet(), qry, SQL_FIELDS, schemaName, U.currentTimeMillis(), cancel, true);
runs.putIfAbsent(run.id(), run);
try {
ResultSet rs = executeSqlQueryWithTimer(stmt, conn, qry, params, timeout, cancel);
return new H2FieldsIterator(rs);
} finally {
GridH2QueryContext.clearThreadLocal();
runs.remove(run.id());
}
}
};
}
Aggregations