use of org.apache.ignite.internal.sql.optimizer.affinity.PartitionConstantNode 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.sql.optimizer.affinity.PartitionConstantNode in project ignite by apache.
the class PartitionExtractor method extractSingle.
/**
* Extract single partition.
*
* @param leftCol Left column.
* @param rightConst Right constant.
* @param rightParam Right parameter.
* @param tblModel Table model.
* @return Partition or {@code null} if failed to extract.
*/
@Nullable
private PartitionSingleNode extractSingle(GridSqlColumn leftCol, GridSqlConst rightConst, GridSqlParameter rightParam, PartitionTableModel tblModel) throws IgniteCheckedException {
assert leftCol != null;
Column leftCol0 = leftCol.column();
assert leftCol0.getTable() != null;
assert leftCol0.getTable() instanceof GridH2Table;
GridH2Table tbl = (GridH2Table) leftCol0.getTable();
if (!tbl.isColumnForPartitionPruning(leftCol0))
return null;
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;
if (rightConst != null) {
int part = partResolver.partition(rightConst.value().getObject(), leftCol0.getType(), tbl.cacheName());
return new PartitionConstantNode(tbl0, part);
} else if (rightParam != null) {
int colType = leftCol0.getType();
return new PartitionParameterNode(tbl0, partResolver, rightParam.index(), leftCol0.getType(), mappedType(colType));
} else
return null;
}
Aggregations