use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperation in project ignite by apache.
the class GridSqlQuerySplitter method extractPartitionFromEquality.
/**
* Analyses the equality operation and extracts the partition if possible
*
* @param op AST equality operation.
* @param ctx Kernal Context.
* @return partition info, or {@code null} if none identified
*/
private static CacheQueryPartitionInfo extractPartitionFromEquality(GridSqlOperation op, GridKernalContext ctx) throws IgniteCheckedException {
assert op.operationType() == GridSqlOperationType.EQUAL;
GridSqlElement left = op.child(0);
GridSqlElement right = op.child(1);
if (!(left instanceof GridSqlColumn))
return null;
if (!(right instanceof GridSqlConst) && !(right instanceof GridSqlParameter))
return null;
GridSqlColumn column = (GridSqlColumn) left;
assert column.column().getTable() instanceof GridH2Table;
GridH2Table tbl = (GridH2Table) column.column().getTable();
GridH2RowDescriptor desc = tbl.rowDescriptor();
IndexColumn affKeyCol = tbl.getAffinityKeyColumn();
int colId = column.column().getColumnId();
if ((affKeyCol == null || colId != affKeyCol.column.getColumnId()) && !desc.isKeyColumn(colId))
return null;
if (right instanceof GridSqlConst) {
GridSqlConst constant = (GridSqlConst) right;
return new CacheQueryPartitionInfo(ctx.affinity().partition(tbl.cacheName(), constant.value().getObject()), null, null, -1, -1);
}
GridSqlParameter param = (GridSqlParameter) right;
return new CacheQueryPartitionInfo(-1, tbl.cacheName(), tbl.getName(), column.column().getType(), param.index());
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperation in project ignite by apache.
the class DmlAstUtils method injectKeysFilterParam.
/**
* Append additional condition to WHERE for it to select only specific keys.
*
* @param where Initial condition.
* @param keyCol Column to base the new condition on.
* @return New condition.
*/
private static GridSqlElement injectKeysFilterParam(GridSqlElement where, GridSqlColumn keyCol, int paramIdx) {
// Yes, we need a subquery for "WHERE _key IN ?" to work with param being an array without dirty query rewriting.
GridSqlSelect sel = new GridSqlSelect();
GridSqlFunction from = new GridSqlFunction(GridSqlFunctionType.TABLE);
sel.from(from);
GridSqlColumn col = new GridSqlColumn(null, from, null, "TABLE", "_IGNITE_ERR_KEYS");
sel.addColumn(col, true);
GridSqlAlias alias = new GridSqlAlias("_IGNITE_ERR_KEYS", new GridSqlParameter(paramIdx));
alias.resultType(keyCol.resultType());
from.addChild(alias);
GridSqlElement e = new GridSqlOperation(GridSqlOperationType.IN, keyCol, new GridSqlSubquery(sel));
if (where == null)
return e;
else
return new GridSqlOperation(GridSqlOperationType.AND, where, e);
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperation in project ignite by apache.
the class PartitionExtractor method extractFromEqual.
/**
* Extract partition information from equality.
*
* @param op Operation.
* @param tblModel Table model.
* @param disjunct Disjunction flag. When set possible join expression will not be processed.
* @return Partition.
*/
private PartitionNode extractFromEqual(GridSqlOperation op, PartitionTableModel tblModel, boolean disjunct) throws IgniteCheckedException {
assert op.operationType() == GridSqlOperationType.EQUAL;
GridSqlElement left = op.child(0);
GridSqlElement right = op.child(1);
GridSqlColumn leftCol = unwrapColumn(left);
if (leftCol == null)
return PartitionAllNode.INSTANCE;
if (!(leftCol.column().getTable() instanceof GridH2Table))
return PartitionAllNode.INSTANCE;
GridSqlConst rightConst;
GridSqlParameter rightParam;
if (right instanceof GridSqlConst) {
rightConst = (GridSqlConst) right;
rightParam = null;
} else if (right instanceof GridSqlParameter) {
rightConst = null;
rightParam = (GridSqlParameter) right;
} else {
if (right instanceof GridSqlColumn) {
if (!disjunct) {
PartitionJoinCondition cond = parseJoinCondition(op);
if (cond != null && !cond.cross())
tblModel.addJoin(cond);
}
}
return PartitionAllNode.INSTANCE;
}
PartitionSingleNode part = extractSingle(leftCol, rightConst, rightParam, tblModel);
return part != null ? part : PartitionAllNode.INSTANCE;
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperation in project ignite by apache.
the class PartitionExtractor method tryExtractBetween.
/**
* Try to extract partitions from {@code op} assuming that it's between operation or simple range.
*
* @param op Sql operation.
* @param tblModel Table model.
* @return {@code PartitionSingleNode} if operation reduced to one partition,
* {@code PartitionGroupNode} if operation reduced to multiple partitions or null if operation is neither
* between nor simple range. Null also returns if it's not possible to extract partitions from given operation.
* @throws IgniteCheckedException If failed.
*/
private PartitionNode tryExtractBetween(GridSqlOperation op, PartitionTableModel tblModel) throws IgniteCheckedException {
// Between operation (or similar range) should contain exact two children.
assert op.size() == 2;
GridSqlAst left = op.child();
GridSqlAst right = op.child(1);
GridSqlOperationType leftOpType = retrieveOperationType(left);
GridSqlOperationType rightOpType = retrieveOperationType(right);
if ((GridSqlOperationType.BIGGER == rightOpType || GridSqlOperationType.BIGGER_EQUAL == rightOpType) && (GridSqlOperationType.SMALLER == leftOpType || GridSqlOperationType.SMALLER_EQUAL == leftOpType)) {
GridSqlAst tmp = left;
left = right;
right = tmp;
} else if (!((GridSqlOperationType.BIGGER == leftOpType || GridSqlOperationType.BIGGER_EQUAL == leftOpType) && (GridSqlOperationType.SMALLER == rightOpType || GridSqlOperationType.SMALLER_EQUAL == rightOpType)))
return null;
// Try parse left AST.
GridSqlColumn leftCol;
if (left instanceof GridSqlOperation && left.child() instanceof GridSqlColumn && (((GridSqlColumn) left.child()).column().getTable() instanceof GridH2Table))
leftCol = left.child();
else
return null;
// Try parse right AST.
GridSqlColumn rightCol;
if (right instanceof GridSqlOperation && right.child() instanceof GridSqlColumn)
rightCol = right.child();
else
return null;
GridH2Table tbl = (GridH2Table) leftCol.column().getTable();
// Check that columns might be used for partition pruning.
if (!tbl.isColumnForPartitionPruning(leftCol.column()))
return null;
// Check that both left and right AST use same column.
if (!F.eq(leftCol.schema(), rightCol.schema()) || !F.eq(leftCol.columnName(), rightCol.columnName()) || !F.eq(leftCol.tableAlias(), rightCol.tableAlias()))
return null;
// Check columns type
if (!(leftCol.column().getType() == Value.BYTE || leftCol.column().getType() == Value.SHORT || leftCol.column().getType() == Value.INT || leftCol.column().getType() == Value.LONG))
return null;
// Try parse left AST right value (value to the right of '>' or '>=').
GridSqlConst leftConst;
if (left.child(1) instanceof GridSqlConst)
leftConst = left.child(1);
else
return null;
// Try parse right AST right value (value to the right of '<' or '<=').
GridSqlConst rightConst;
if (right.child(1) instanceof GridSqlConst)
rightConst = right.child(1);
else
return null;
long leftLongVal;
long rightLongVal;
try {
leftLongVal = leftConst.value().getLong();
rightLongVal = rightConst.value().getLong();
} catch (Exception e) {
return null;
}
// Increment left long value if '>' is used.
if (((GridSqlOperation) left).operationType() == GridSqlOperationType.BIGGER)
leftLongVal++;
// Decrement right long value if '<' is used.
if (((GridSqlOperation) right).operationType() == GridSqlOperationType.SMALLER)
rightLongVal--;
Set<PartitionSingleNode> parts = new HashSet<>();
PartitionTable tbl0 = tblModel.table(leftCol.tableAlias());
// If table is in ignored set, then we cannot use it for partition extraction.
if (tbl0 == null)
return null;
for (long i = leftLongVal; i <= rightLongVal; i++) {
int part = partResolver.partition(i, leftCol.column().getType(), tbl0.cacheName());
parts.add(new PartitionConstantNode(tbl0, part));
if (parts.size() > maxPartsCntBetween)
return null;
}
return parts.isEmpty() ? PartitionNoneNode.INSTANCE : parts.size() == 1 ? parts.iterator().next() : new PartitionGroupNode(parts);
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperation in project ignite by apache.
the class DmlAstUtils method isEqualityCondition.
/**
* @param op Operation.
* @param key true - check for key equality condition,
* otherwise check for value equality condition
* @return Whether this condition is of form {@code colName} = ?
*/
private static boolean isEqualityCondition(GridSqlOperation op, boolean key) {
if (op.operationType() != GridSqlOperationType.EQUAL)
return false;
GridSqlElement left = op.child(0);
GridSqlElement right = op.child(1);
if (!(left instanceof GridSqlColumn))
return false;
GridSqlColumn column = (GridSqlColumn) left;
if (!(column.column().getTable() instanceof GridH2Table))
return false;
GridH2RowDescriptor desc = ((GridH2Table) column.column().getTable()).rowDescriptor();
return (key ? desc.isKeyColumn(column.column().getColumnId()) : desc.isValueColumn(column.column().getColumnId())) && (right instanceof GridSqlConst || right instanceof GridSqlParameter);
}
Aggregations