use of org.h2.table.TableFilter in project ignite by apache.
the class CollocationModel method isAffinityColumn.
/**
* @param f Table filter.
* @param expCol Expression column.
* @param validate Query validation flag.
* @return {@code true} It it is an affinity column.
*/
@SuppressWarnings("IfMayBeConditional")
private static boolean isAffinityColumn(TableFilter f, ExpressionColumn expCol, boolean validate) {
Column col = expCol.getColumn();
if (col == null)
return false;
Table t = col.getTable();
if (t.isView()) {
Query qry;
if (f.getIndex() != null)
qry = getSubQuery(f);
else
qry = GridSqlQueryParser.VIEW_QUERY.get((TableView) t);
return isAffinityColumn(qry, expCol, validate);
}
if (t instanceof GridH2Table) {
GridH2Table t0 = (GridH2Table) t;
if (validate && t0.isCustomAffinityMapper())
throw customAffinityError((t0).cacheName());
IndexColumn affCol = t0.getAffinityKeyColumn();
return affCol != null && col.getColumnId() == affCol.column.getColumnId();
}
return false;
}
use of org.h2.table.TableFilter in project ignite by apache.
the class CollocationModel method joinedWithCollocated.
/**
* @param f Filter.
* @return Affinity join type.
*/
@SuppressWarnings("ForLoopReplaceableByForEach")
private CollocationModelAffinity joinedWithCollocated(int f) {
TableFilter tf = childFilters[f];
GridH2Table tbl = (GridH2Table) tf.getTable();
if (validate) {
if (tbl.isCustomAffinityMapper())
throw customAffinityError(tbl.cacheName());
if (F.isEmpty(tf.getIndexConditions())) {
throw new CacheException("Failed to prepare distributed join query: " + "join condition does not use index [joinedCache=" + tbl.cacheName() + ", plan=" + tf.getSelect().getPlanSQL() + ']');
}
}
IndexColumn affCol = tbl.getAffinityKeyColumn();
boolean affKeyCondFound = false;
if (affCol != null) {
ArrayList<IndexCondition> idxConditions = tf.getIndexConditions();
int affColId = affCol.column.getColumnId();
for (int i = 0; i < idxConditions.size(); i++) {
IndexCondition c = idxConditions.get(i);
int colId = c.getColumn().getColumnId();
int cmpType = c.getCompareType();
if ((cmpType == Comparison.EQUAL || cmpType == Comparison.EQUAL_NULL_SAFE) && (colId == affColId || tbl.rowDescriptor().isKeyColumn(colId)) && c.isEvaluatable()) {
affKeyCondFound = true;
Expression exp = c.getExpression();
exp = exp.getNonAliasExpression();
if (exp instanceof ExpressionColumn) {
ExpressionColumn expCol = (ExpressionColumn) exp;
// This is one of our previous joins.
TableFilter prevJoin = expCol.getTableFilter();
if (prevJoin != null) {
CollocationModel cm = child(indexOf(prevJoin), true);
// different affinity columns from different tables.
if (cm != null && !cm.view) {
CollocationModelType t = cm.type(true);
if (t.isPartitioned() && t.isCollocated() && isAffinityColumn(prevJoin, expCol, validate))
return CollocationModelAffinity.COLLOCATED_JOIN;
}
}
}
}
}
}
return affKeyCondFound ? CollocationModelAffinity.HAS_AFFINITY_CONDITION : CollocationModelAffinity.NONE;
}
use of org.h2.table.TableFilter in project ignite by apache.
the class GridH2SpatialIndex method findByGeometry.
/**
* {@inheritDoc}
*/
@Override
public Cursor findByGeometry(TableFilter filter, SearchRow first, SearchRow last, SearchRow intersection) {
Value v = intersection.getValue(columnIds[0]);
Geometry g = ((ValueGeometry) v.convertTo(Value.GEOMETRY)).getGeometry();
int seg = segmentsCount() == 1 ? 0 : H2Utils.context(filter.getSession()).segment();
GridCursor<IndexRow> cursor = delegate.findByGeometry(seg, filter, g);
GridCursor<H2Row> h2cursor = new IndexValueCursor<>(cursor, this::mapIndexRow);
return new H2Cursor(h2cursor);
}
use of org.h2.table.TableFilter in project ignite by apache.
the class H2TreeIndex method createLookupBatch.
/**
* {@inheritDoc}
*/
@Override
public IndexLookupBatch createLookupBatch(TableFilter[] filters, int filter) {
QueryContext qctx = H2Utils.context(filters[filter].getSession());
if (qctx == null || qctx.distributedJoinContext() == null || !getTable().isPartitioned())
return null;
IndexColumn affCol = getTable().getAffinityKeyColumn();
GridH2RowDescriptor desc = getTable().rowDescriptor();
int affColId = -1;
boolean ucast = false;
if (affCol != null) {
affColId = affCol.column.getColumnId();
int[] masks = filters[filter].getMasks();
if (masks != null) {
ucast = (masks[affColId] & IndexCondition.EQUALITY) != 0 || desc.checkKeyIndexCondition(masks, IndexCondition.EQUALITY);
}
}
return new DistributedLookupBatch(this, cctx, ucast, affColId);
}
use of org.h2.table.TableFilter 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();
boolean isForUpdate = SELECT_IS_FOR_UPDATE.get(select);
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);
if (isForUpdate) {
if (!(from instanceof GridSqlTable || (from instanceof GridSqlAlias && from.size() == 1 && from.child() instanceof GridSqlTable))) {
throw new IgniteSQLException("SELECT FOR UPDATE with joins is not supported.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
GridSqlTable gridTbl = from instanceof GridSqlTable ? (GridSqlTable) from : ((GridSqlAlias) from).child();
GridH2Table tbl = gridTbl.dataTable();
if (tbl == null) {
throw new IgniteSQLException("SELECT FOR UPDATE query must involve Ignite table.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
if (select.getLimit() != null || select.getOffset() != null) {
throw new IgniteSQLException("LIMIT/OFFSET clauses are not supported for SELECT FOR UPDATE.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
if (SELECT_IS_GROUP_QUERY.get(select)) {
throw new IgniteSQLException("SELECT FOR UPDATE with aggregates and/or GROUP BY is not supported.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
if (select.isDistinct())
throw new IgniteSQLException("DISTINCT clause is not supported for SELECT FOR UPDATE.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
if (SplitterUtils.hasSubQueries(res))
throw new IgniteSQLException("Sub queries are not supported for SELECT FOR UPDATE.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
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);
res.forUpdate(isForUpdate);
processSortOrder(select.getSortOrder(), res);
res.limit(parseExpression(select.getLimit(), false));
res.offset(parseExpression(select.getOffset(), false));
return res;
}
Aggregations