use of org.apache.jackrabbit.oak.query.ast.JoinConditionImpl in project jackrabbit-oak by apache.
the class QueryImpl method prepare.
@Override
public void prepare() {
if (prepared) {
return;
}
prepared = true;
List<SourceImpl> sources = source.getInnerJoinSelectors();
List<JoinConditionImpl> conditions = source.getInnerJoinConditions();
if (sources.size() <= 1) {
// simple case (no join)
estimatedCost = source.prepare().getEstimatedCost();
isSortedByIndex = canSortByIndex();
return;
}
// use a greedy algorithm
SourceImpl result = null;
Set<SourceImpl> available = new HashSet<SourceImpl>();
// the query is only slow if all possible join orders are slow
// (in theory, due to using the greedy algorithm, a query might be considered
// slow even thought there is a plan that doesn't need to use traversal, but
// only for 3-way and higher joins, and only if traversal is considered very fast)
boolean isPotentiallySlowJoin = true;
while (sources.size() > 0) {
int bestIndex = 0;
double bestCost = Double.POSITIVE_INFINITY;
ExecutionPlan bestPlan = null;
SourceImpl best = null;
for (int i = 0; i < sources.size(); i++) {
SourceImpl test = buildJoin(result, sources.get(i), conditions);
if (test == null) {
// no join condition
continue;
}
ExecutionPlan testPlan = test.prepare();
double cost = testPlan.getEstimatedCost();
if (best == null || cost < bestCost) {
bestPlan = testPlan;
bestCost = cost;
bestIndex = i;
best = test;
}
if (!potentiallySlowTraversalQuery) {
isPotentiallySlowJoin = false;
}
test.unprepare();
}
available.add(sources.remove(bestIndex));
result = best;
best.prepare(bestPlan);
}
potentiallySlowTraversalQuery = isPotentiallySlowJoin;
estimatedCost = result.prepare().getEstimatedCost();
source = result;
isSortedByIndex = canSortByIndex();
}
use of org.apache.jackrabbit.oak.query.ast.JoinConditionImpl in project jackrabbit-oak by apache.
the class SQL2Parser method parseJoinCondition.
private JoinConditionImpl parseJoinCondition() throws ParseException {
boolean identifier = currentTokenType == IDENTIFIER;
String name = readName();
JoinConditionImpl c;
if (identifier && readIf("(")) {
if ("ISSAMENODE".equalsIgnoreCase(name)) {
String selector1 = readName();
read(",");
String selector2 = readName();
if (readIf(",")) {
c = factory.sameNodeJoinCondition(selector1, selector2, readPath());
} else {
c = factory.sameNodeJoinCondition(selector1, selector2, ".");
}
} else if ("ISCHILDNODE".equalsIgnoreCase(name)) {
String childSelector = readName();
read(",");
c = factory.childNodeJoinCondition(childSelector, readName());
} else if ("ISDESCENDANTNODE".equalsIgnoreCase(name)) {
String descendantSelector = readName();
read(",");
c = factory.descendantNodeJoinCondition(descendantSelector, readName());
} else {
throw getSyntaxError("ISSAMENODE, ISCHILDNODE, or ISDESCENDANTNODE");
}
read(")");
return c;
} else {
String selector1 = name;
read(".");
String property1 = readName();
read("=");
String selector2 = readName();
read(".");
return factory.equiJoinCondition(selector1, property1, selector2, readName());
}
}
use of org.apache.jackrabbit.oak.query.ast.JoinConditionImpl in project jackrabbit-oak by apache.
the class QueryImpl method buildJoin.
private static SourceImpl buildJoin(SourceImpl result, SourceImpl last, List<JoinConditionImpl> conditions) {
if (result == null) {
return last;
}
List<SourceImpl> selectors = result.getInnerJoinSelectors();
Set<SourceImpl> oldSelectors = new HashSet<SourceImpl>();
oldSelectors.addAll(selectors);
Set<SourceImpl> newSelectors = new HashSet<SourceImpl>();
newSelectors.addAll(selectors);
newSelectors.add(last);
for (JoinConditionImpl j : conditions) {
// but couldn't be evaluated before
if (!j.canEvaluate(oldSelectors) && j.canEvaluate(newSelectors)) {
JoinImpl join = new JoinImpl(result, last, JoinType.INNER, j);
return join;
}
}
// no join condition was found
return null;
}
use of org.apache.jackrabbit.oak.query.ast.JoinConditionImpl in project jackrabbit-oak by apache.
the class SQL2Parser method parseSource.
private SourceImpl parseSource() throws ParseException {
SelectorImpl selector = parseSelector();
selectors.put(selector.getSelectorName(), selector);
SourceImpl source = selector;
while (true) {
JoinType joinType;
if (readIf("RIGHT")) {
read("OUTER");
joinType = JoinType.RIGHT_OUTER;
} else if (readIf("LEFT")) {
read("OUTER");
joinType = JoinType.LEFT_OUTER;
} else if (readIf("INNER")) {
joinType = JoinType.INNER;
} else {
break;
}
read("JOIN");
selector = parseSelector();
selectors.put(selector.getSelectorName(), selector);
read("ON");
JoinConditionImpl on = parseJoinCondition();
source = factory.join(source, selector, joinType, on);
}
return source;
}
Aggregations