use of org.h2.table.Table in project ignite by apache.
the class GridSqlQueryParser method collectOptimizedTableFiltersOrder.
/**
* @param qry Query.
*/
private void collectOptimizedTableFiltersOrder(Query qry) {
if (qry instanceof SelectUnion) {
collectOptimizedTableFiltersOrder(((SelectUnion) qry).getLeft());
collectOptimizedTableFiltersOrder(((SelectUnion) qry).getRight());
} else {
Select select = (Select) qry;
TableFilter filter = select.getTopTableFilter();
int i = 0;
do {
assert0(filter != null, select);
assert0(filter.getNestedJoin() == null, select);
// Here all the table filters must have generated unique aliases,
// thus we can store them in the same map for all the subqueries.
optimizedTableFilterOrder.put(filter.getTableAlias(), i++);
Table tbl = filter.getTable();
// Go down and collect inside of optimized subqueries.
if (tbl instanceof TableView) {
ViewIndex viewIdx = (ViewIndex) filter.getIndex();
collectOptimizedTableFiltersOrder(viewIdx.getQuery());
}
filter = filter.getJoin();
} while (filter != null);
}
}
use of org.h2.table.Table in project ignite by apache.
the class GridSqlQueryParser method parseTable.
/**
* @param tbl Table.
*/
private GridSqlElement parseTable(Table tbl) {
GridSqlElement res = (GridSqlElement) h2ObjToGridObj.get(tbl);
if (res == null) {
// Table here is semantically equivalent to a table filter.
if (tbl instanceof TableBase)
return new GridSqlTable(tbl);
// different table filters anyways. Thus the semantics will be correct.
if (tbl instanceof TableView) {
Query qry = VIEW_QUERY.get((TableView) tbl);
res = new GridSqlSubquery(parseQuery(qry));
} else if (tbl instanceof FunctionTable)
res = parseExpression(FUNC_EXPR.get((FunctionTable) tbl), false);
else if (tbl instanceof RangeTable) {
res = new GridSqlFunction(GridSqlFunctionType.SYSTEM_RANGE);
res.addChild(parseExpression(RANGE_MIN.get((RangeTable) tbl), false));
res.addChild(parseExpression(RANGE_MAX.get((RangeTable) tbl), false));
} else if (tbl instanceof MetaTable)
res = new GridSqlTable(tbl);
else
assert0(false, "Unexpected Table implementation [cls=" + tbl.getClass().getSimpleName() + ']');
h2ObjToGridObj.put(tbl, res);
}
return res;
}
use of org.h2.table.Table in project ignite by apache.
the class GridSqlQueryParser method parseMerge.
/**
* @param merge Merge.
* @see <a href="http://h2database.com/html/grammar.html#merge">H2 merge spec</a>
*/
private GridSqlMerge parseMerge(Merge merge) {
GridSqlMerge res = (GridSqlMerge) h2ObjToGridObj.get(merge);
if (res != null)
return res;
res = new GridSqlMerge();
h2ObjToGridObj.put(merge, res);
Table srcTbl = MERGE_TABLE.get(merge);
GridSqlElement tbl = parseTable(srcTbl);
res.into(tbl);
Column[] srcCols = MERGE_COLUMNS.get(merge);
GridSqlColumn[] cols = new GridSqlColumn[srcCols.length];
for (int i = 0; i < srcCols.length; i++) {
cols[i] = new GridSqlColumn(srcCols[i], tbl, null, null, srcCols[i].getName());
cols[i].resultType(fromColumn(srcCols[i]));
}
res.columns(cols);
Column[] srcKeys = MERGE_KEYS.get(merge);
GridH2Table intoTbl = DmlAstUtils.gridTableForElement(tbl).dataTable();
GridH2RowDescriptor rowDesc = intoTbl.rowDescriptor();
GridSqlColumn[] keys = new GridSqlColumn[srcKeys.length];
for (int i = 0; i < srcKeys.length; i++) {
String colName = srcKeys[i].getName();
int colId = intoTbl.getColumn(colName).getColumnId();
if (!rowDesc.isKeyColumn(colId) && !F.eq(colName, rowDesc.type().affinityKey()))
throw new IgniteSQLException("Invalid column name in KEYS clause of MERGE - it may include only " + "key and/or affinity columns: " + colName, IgniteQueryErrorCode.PARSING);
keys[i] = new GridSqlColumn(srcKeys[i], tbl, null, null, colName);
}
res.keys(keys);
List<Expression[]> srcRows = MERGE_ROWS.get(merge);
if (!srcRows.isEmpty()) {
List<GridSqlElement[]> rows = new ArrayList<>(srcRows.size());
for (Expression[] srcRow : srcRows) {
GridSqlElement[] row = new GridSqlElement[srcRow.length];
for (int i = 0; i < srcRow.length; i++) row[i] = parseExpression(srcRow[i], false);
rows.add(row);
}
res.rows(rows);
} else {
res.rows(Collections.<GridSqlElement[]>emptyList());
res.query(parseQuery(MERGE_QUERY.get(merge)));
}
return res;
}
use of org.h2.table.Table in project ignite by apache.
the class GridSqlQueryParser method parseSelect.
/**
* @param select Select.
*/
private GridSqlSelect parseSelect(Select select) {
GridSqlSelect res = (GridSqlSelect) h2ObjToGridObj.get(select);
if (res != null)
return res;
res = new GridSqlSelect();
h2ObjToGridObj.put(select, res);
res.distinct(select.isDistinct());
Expression where = CONDITION.get(select);
res.where(parseExpression(where, true));
ArrayList<TableFilter> tableFilters = new ArrayList<>();
TableFilter filter = select.getTopTableFilter();
do {
assert0(filter != null, select);
assert0(filter.getNestedJoin() == null, select);
// Can use optimized join order only if we are not inside of an expression.
if (parsingSubQryExpression == 0 && optimizedTableFilterOrder != null) {
String tblAlias = filter.getTableAlias();
int idx = optimizedTableFilterOrder.get(tblAlias);
setElementAt(tableFilters, idx, filter);
} else
tableFilters.add(filter);
filter = filter.getJoin();
} while (filter != null);
// Build FROM clause from correctly ordered table filters.
GridSqlElement from = null;
for (int i = 0; i < tableFilters.size(); i++) {
TableFilter f = tableFilters.get(i);
GridSqlElement gridFilter = parseTableFilter(f);
from = from == null ? gridFilter : new GridSqlJoin(from, gridFilter, f.isJoinOuter(), parseExpression(f.getJoinCondition(), true));
}
res.from(from);
ArrayList<Expression> expressions = select.getExpressions();
for (int i = 0; i < expressions.size(); i++) res.addColumn(parseExpression(expressions.get(i), true), i < select.getColumnCount());
int[] grpIdx = GROUP_INDEXES.get(select);
if (grpIdx != null)
res.groupColumns(grpIdx);
int havingIdx = HAVING_INDEX.get(select);
if (havingIdx >= 0)
res.havingColumn(havingIdx);
processSortOrder(select.getSortOrder(), res);
res.limit(parseExpression(select.getLimit(), false));
res.offset(parseExpression(select.getOffset(), false));
return res;
}
use of org.h2.table.Table in project ignite by apache.
the class GridSqlQuerySplitter method split.
/**
* @param conn Connection.
* @param prepared Prepared.
* @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(Connection conn, Prepared prepared, 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, false);
String originalSql = qry.getSQL();
// debug("ORIGINAL", originalSql);
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);
// debug("NORMALIZED", qry.getSQL());
// 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 prepared0 = optimize(h2, conn, mapSqlQry.query(), mapSqlQry.parameters(params), true, enforceJoinOrder);
allCollocated &= isCollocated((Query) prepared0);
mapSqlQry.query(parse(prepared0, 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;
}
Aggregations