use of org.h2.command.dml.Explain in project ignite by apache.
the class GridSqlQuerySplitter method split.
/**
* @param stmt Prepared statement.
* @param params Parameters.
* @param collocatedGrpBy Whether the query has collocated GROUP BY keys.
* @param distributedJoins If distributed joins enabled.
* @param enforceJoinOrder Enforce join order.
* @param h2 Indexing.
* @return Two step query.
* @throws SQLException If failed.
* @throws IgniteCheckedException If failed.
*/
public static GridCacheTwoStepQuery split(JdbcPreparedStatement stmt, Object[] params, boolean collocatedGrpBy, boolean distributedJoins, boolean enforceJoinOrder, IgniteH2Indexing h2) throws SQLException, IgniteCheckedException {
if (params == null)
params = GridCacheSqlQuery.EMPTY_PARAMS;
// Here we will just do initial query parsing. Do not use optimized
// subqueries because we do not have unique FROM aliases yet.
GridSqlQuery qry = parse(prepared(stmt), false);
String originalSql = qry.getSQL();
final boolean explain = qry.explain();
qry.explain(false);
GridSqlQuerySplitter splitter = new GridSqlQuerySplitter(params, collocatedGrpBy, h2.kernalContext());
// Normalization will generate unique aliases for all the table filters in FROM.
// Also it will collect all tables and schemas from the query.
splitter.normalizeQuery(qry);
Connection conn = stmt.getConnection();
// Here we will have correct normalized AST with optimized join order.
// The distributedJoins parameter is ignored because it is not relevant for
// the REDUCE query optimization.
qry = parse(optimize(h2, conn, qry.getSQL(), params, false, enforceJoinOrder), true);
// Do the actual query split. We will update the original query AST, need to be careful.
splitter.splitQuery(qry);
// We must have at least one map query.
assert !F.isEmpty(splitter.mapSqlQrys) : "map";
// We must have a reduce query.
assert splitter.rdcSqlQry != null : "rdc";
// distributed joins at all.
if (distributedJoins) {
boolean allCollocated = true;
for (GridCacheSqlQuery mapSqlQry : splitter.mapSqlQrys) {
Prepared prepared = optimize(h2, conn, mapSqlQry.query(), mapSqlQry.parameters(params), true, enforceJoinOrder);
allCollocated &= isCollocated((Query) prepared);
mapSqlQry.query(parse(prepared, true).getSQL());
}
// We do not need distributed joins if all MAP queries are collocated.
if (allCollocated)
distributedJoins = false;
}
// Setup resulting two step query and return it.
GridCacheTwoStepQuery twoStepQry = new GridCacheTwoStepQuery(originalSql, splitter.tbls);
twoStepQry.reduceQuery(splitter.rdcSqlQry);
for (GridCacheSqlQuery mapSqlQry : splitter.mapSqlQrys) twoStepQry.addMapQuery(mapSqlQry);
twoStepQry.skipMergeTable(splitter.rdcQrySimple);
twoStepQry.explain(explain);
twoStepQry.distributedJoins(distributedJoins);
// all map queries must have non-empty derivedPartitions to use this feature.
twoStepQry.derivedPartitions(mergePartitionsFromMultipleQueries(twoStepQry.mapQueries()));
return twoStepQry;
}
use of org.h2.command.dml.Explain in project ignite by apache.
the class GridSqlInsert method getSQL.
/**
* {@inheritDoc}
*/
@Override
public String getSQL() {
StatementBuilder buff = new StatementBuilder(explain() ? "EXPLAIN " : "");
buff.append("INSERT").append("\nINTO ").append(into.getSQL()).append('(');
for (GridSqlColumn col : cols) {
buff.appendExceptFirst(", ");
buff.append('\n').append(col.getSQL());
}
buff.append("\n)\n");
if (direct)
buff.append("DIRECT ");
if (sorted)
buff.append("SORTED ");
if (!rows.isEmpty()) {
buff.append("VALUES\n");
StatementBuilder valuesBuff = new StatementBuilder();
for (GridSqlElement[] row : rows()) {
valuesBuff.appendExceptFirst(",\n");
StatementBuilder rowBuff = new StatementBuilder("(");
for (GridSqlElement e : row) {
rowBuff.appendExceptFirst(", ");
rowBuff.append(e != null ? e.getSQL() : "DEFAULT");
}
rowBuff.append(')');
valuesBuff.append(rowBuff.toString());
}
buff.append(valuesBuff.toString());
} else
buff.append('\n').append(qry.getSQL());
return buff.toString();
}
use of org.h2.command.dml.Explain in project ignite by apache.
the class GridSqlMerge method getSQL.
/**
* {@inheritDoc}
*/
@Override
public String getSQL() {
StatementBuilder buff = new StatementBuilder(explain() ? "EXPLAIN " : "");
buff.append("MERGE INTO ").append(into.getSQL()).append("(");
for (GridSqlColumn col : cols) {
buff.appendExceptFirst(", ");
buff.append('\n').append(col.getSQL());
}
buff.append("\n)\n");
if (keys != null) {
buff.append("KEY(\n");
buff.resetCount();
for (GridSqlColumn c : keys) {
buff.appendExceptFirst(",\n");
buff.append(c.getSQL());
}
buff.append(")\n");
}
if (!rows.isEmpty()) {
buff.append("VALUES\n");
StatementBuilder valuesBuff = new StatementBuilder();
for (GridSqlElement[] row : rows()) {
valuesBuff.appendExceptFirst(",\n");
StatementBuilder rowBuff = new StatementBuilder("(");
for (GridSqlElement e : row) {
rowBuff.appendExceptFirst(", ");
rowBuff.append(e != null ? e.getSQL() : "DEFAULT");
}
rowBuff.append(')');
valuesBuff.append(rowBuff.toString());
}
buff.append(valuesBuff.toString());
} else
buff.append('\n').append(qry.getSQL());
return buff.toString();
}
use of org.h2.command.dml.Explain 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.h2.command.dml.Explain in project ignite by apache.
the class GridSqlUnion method getSQL.
/**
* {@inheritDoc}
*/
@Override
public String getSQL() {
StatementBuilder buff = new StatementBuilder(explain() ? "EXPLAIN \n" : "");
buff.append('(').append(left.getSQL()).append(')');
switch(unionType()) {
case SelectUnion.UNION_ALL:
buff.append("\nUNION ALL\n");
break;
case SelectUnion.UNION:
buff.append("\nUNION\n");
break;
case SelectUnion.INTERSECT:
buff.append("\nINTERSECT\n");
break;
case SelectUnion.EXCEPT:
buff.append("\nEXCEPT\n");
break;
default:
throw new CacheException("type=" + unionType);
}
buff.append('(').append(right.getSQL()).append(')');
getSortLimitSQL(buff);
return buff.toString();
}
Aggregations