use of org.apache.ignite.internal.sql.optimizer.affinity.PartitionJoinCondition 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.sql.optimizer.affinity.PartitionJoinCondition in project ignite by apache.
the class PartitionExtractor method prepareTableModel0.
/**
* Prepare tables which will be used in join model.
*
* @param from From flag.
* @param model Table model.
* @return {@code True} if extracted tables successfully, {@code false} if failed to extract.
*/
private List<PartitionTable> prepareTableModel0(GridSqlAst from, PartitionTableModel model) {
if (from instanceof GridSqlJoin) {
// Process JOIN recursively.
GridSqlJoin join = (GridSqlJoin) from;
List<PartitionTable> leftTbls = prepareTableModel0(join.leftTable(), model);
List<PartitionTable> rightTbls = prepareTableModel0(join.rightTable(), model);
if (join.isLeftOuter()) {
// If a condition is met on "b" afterwards, we will ignore it.
for (PartitionTable rightTbl : rightTbls) model.addExcludedTable(rightTbl.alias());
return leftTbls;
}
// Extract equi-join or cross-join from condition. For normal INNER JOINs most likely we will have "1=1"
// cross join here, real join condition will be found in WHERE clause later.
PartitionJoinCondition cond = parseJoinCondition(join.on());
if (cond != null && !cond.cross())
model.addJoin(cond);
ArrayList<PartitionTable> res = new ArrayList<>(leftTbls.size() + rightTbls.size());
res.addAll(leftTbls);
res.addAll(rightTbls);
return res;
}
PartitionTable tbl = prepareTable(from, model);
return tbl != null ? Collections.singletonList(tbl) : Collections.emptyList();
}
use of org.apache.ignite.internal.sql.optimizer.affinity.PartitionJoinCondition in project ignite by apache.
the class PartitionExtractor method parseJoinCondition.
/**
* Try parsing condition as simple JOIN codition. Only equijoins are supported for now, so anything more complex
* than "A.a = B.b" are not processed.
*
* @param on Initial AST.
* @return Join condition or {@code null} if not simple equijoin.
*/
private static PartitionJoinCondition parseJoinCondition(GridSqlElement on) {
if (on instanceof GridSqlOperation) {
GridSqlOperation on0 = (GridSqlOperation) on;
if (on0.operationType() == GridSqlOperationType.EQUAL) {
// Check for cross-join first.
GridSqlConst leftConst = unwrapConst(on0.child(0));
GridSqlConst rightConst = unwrapConst(on0.child(1));
if (leftConst != null && rightConst != null) {
try {
int leftConstval = leftConst.value().getInt();
int rightConstVal = rightConst.value().getInt();
if (leftConstval == rightConstVal)
return PartitionJoinCondition.CROSS;
} catch (Exception ignore) {
// No-op.
}
}
// This is not cross-join, neither normal join between columns.
if (leftConst != null || rightConst != null)
return null;
// Check for normal equi-join.
GridSqlColumn left = unwrapColumn(on0.child(0));
GridSqlColumn right = unwrapColumn(on0.child(1));
if (left != null && right != null) {
String leftAlias = left.tableAlias();
String rightAlias = right.tableAlias();
String leftCol = left.columnName();
String rightCol = right.columnName();
return new PartitionJoinCondition(leftAlias, rightAlias, leftCol, rightCol);
}
}
}
return null;
}
Aggregations