Added a check in query rewriting for overflowing costs.
@@ -112,6 +112,10 @@ public class QueryRewriter {
for (Atom atom : usedAtoms) {
if (canRemove(atom, usedAtoms)) {
double cost = estimateQuerySize(costEstimator, usedAtoms, atom, tableStats, dataStore);
+ if (cost < 0.0) {
+ log.trace("Planned Cost for (" + usedAtoms + " - " + atom + "): MAX");
+ continue;
+ }
log.trace("Planned Cost for (" + usedAtoms + " - " + atom + "): " + cost);
@@ -126,6 +130,11 @@ public class QueryRewriter {
break;
}
+ // We couldn't find any viable plans.
+ if (bestAtom == null) {
+ break;
+ }
+
// We expect the cost to go up, but will cut it off at some point.
if (bestCost > (baseCost * allowedTotalCostIncrease) || bestCost > (currentCost * allowedStepCostIncrease)) {
break;
@@ -166,6 +175,7 @@ public class QueryRewriter {
* Estimate the cost of the query (conjunctive query over the given atoms) using histogram stats.
* Based off of: http://consystlab.unl.edu/Documents/StudentReports/Working-Note2-2008.pdf
* @param ignore if not null, then do not include it in the cost computation.
+ * @return negative if we exceed max size and should just discard this plan.
*/
private static double estimateQuerySizeWithHistorgram(Set<Atom> atoms, Atom ignore, Map<Predicate, TableStats> tableStats, RDBMSDataStore dataStore) {
double cost = 1.0;
@@ -212,6 +222,11 @@ public class QueryRewriter {
}
}
+ long joinSize = joinHistogram.size();
+ if (joinSize == Long.MAX_VALUE) {
+ return -1.0;
+ }
+
cost *= (joinHistogram.size() / crossProductSize);
}
