Author: thomasm
Date: Fri Nov 20 13:04:18 2015
New Revision: 1715347
URL: http://svn.apache.org/viewvc?rev=1715347&view=rev
Log:
OAK-2539 SQL2 query not working with filter (s.[stringa] = 'a' OR
CONTAINS(s.[stringb], 'b'))
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AndImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ConstraintImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NativeFunctionImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotFullTextImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SimilarImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SpellcheckImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SuggestImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/package-info.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryCostOverheadTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java?rev=1715347&r1=1715346&r2=1715347&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
Fri Nov 20 13:04:18 2015
@@ -180,18 +180,12 @@ public interface Query {
boolean isInternal();
/**
- * <p>
- * Some queries can bring with them a cost overhead that the query engine
could consider when
- * electing the best query between the original SQL2 and the possible
available optimisations.
- * </p>
- * <p>
- * For example for the case of <a
href="https://issues.apache.org/jira/browse/OAK-2660" /> if
- * you have a case where {@code (a = 'v' OR CONTAINS(b, 'v1') OR
CONTAINS(c, 'v2')) AND (...)}
- * currently the query engine does not know how to leverage indexes and
post conditions and the
- * query is better suited with a UNION.
- * </p>
+ * Whether the condition contains a fulltext condition that can not be
+ * applied to the filter, for example because it is part of an "or"
condition
+ * of the form "where a=1 or contains(., 'x')".
*
- * @return a positive number or 0. <strong>Cannot be negative.</strong>
- */
- double getCostOverhead();
+ * @return true if yes
+ */
+ boolean containsUnfilteredFullTextCondition();
+
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java?rev=1715347&r1=1715346&r2=1715347&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
Fri Nov 20 13:04:18 2015
@@ -295,51 +295,41 @@ public abstract class QueryEngineImpl im
if (checkNotNull(queries).size() == 1) {
- // Optimisation. We only have the original query so we prepare and
return it.
+ // we only have the original query so we prepare and return it.
cheapest = queries.iterator().next();
cheapest.prepare();
LOG.debug("No optimisations found. Cheapest is the original query:
{}", cheapest);
map = new MdcAndPrepared(setupMDC(cheapest), cheapest);
} else {
- double bestCost = Double.MAX_VALUE;
- double originalCost = Double.MAX_VALUE;
- boolean firstLoop = true;
+ double bestCost = Double.POSITIVE_INFINITY;
+ double originalCost = Double.POSITIVE_INFINITY;
Query original = null;
// always prepare all of the queries and compute the cheapest as
it's the default behaviour.
// It should trigger more errors during unit and integration
testing. Changing
// `forceOptimised` flag should be in case used only during
testing.
for (Query q : checkNotNull(queries)) {
- LOG.debug("Preparing: {}", q);
q.prepare();
-
- double actualCost = q.getEstimatedCost();
- double costOverhead = q.getCostOverhead();
- double overallCost = Math.min(actualCost + costOverhead,
Double.MAX_VALUE);
-
- LOG.debug("actualCost: {} - costOverhead: {} - overallCost:
{}", actualCost,
- costOverhead, overallCost);
-
- if (firstLoop) {
- // first time we're always the best cost. Avoiding
situations where the original
- // query has an overall cost as Double.MAX_VALUE.
- bestCost = overallCost;
- cheapest = q;
- firstLoop = false;
- } else if (overallCost < bestCost) {
- bestCost = overallCost;
+ double cost = q.getEstimatedCost();
+ LOG.debug("cost: {} for query {}", cost, q);
+ if (q.containsUnfilteredFullTextCondition()) {
+ LOG.debug("contains an unfiltered fulltext condition");
+ cost = Double.POSITIVE_INFINITY;
+ }
+ if (cheapest == null || cost < bestCost) {
cheapest = q;
+ bestCost = cost;
}
if (!q.isOptimised()) {
original = q;
- originalCost = overallCost;
+ originalCost = cost;
}
}
if (original != null && bestCost == originalCost && cheapest !=
original) {
// if the optimised cost is the same as the original SQL2
query we prefer the original. As
// we deal with references the `cheapest!=original` should
work.
- LOG.trace("Same cost for original and optimised. Forcing
original");
+ LOG.trace("Same cost for original and optimised. Using
original");
cheapest = original;
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java?rev=1715347&r1=1715346&r2=1715347&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
Fri Nov 20 13:04:18 2015
@@ -86,7 +86,6 @@ import org.apache.jackrabbit.oak.query.p
import org.apache.jackrabbit.oak.query.plan.SelectorExecutionPlan;
import org.apache.jackrabbit.oak.spi.query.Filter;
import org.apache.jackrabbit.oak.spi.query.PropertyValues;
-import org.apache.jackrabbit.oak.spi.query.QueryConstants;
import org.apache.jackrabbit.oak.spi.query.QueryIndex;
import org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvancedQueryIndex;
import org.apache.jackrabbit.oak.spi.query.QueryIndex.IndexPlan;
@@ -1321,48 +1320,8 @@ public class QueryImpl implements Query
}
@Override
- public double getCostOverhead() {
- return oak2660CostOverhead(getConstraint());
+ public boolean containsUnfilteredFullTextCondition() {
+ return constraint.containsUnfilteredFullTextCondition();
}
- /**
- * compute a cost overhead for the OAK-2660 use case. The query engine
better perform/compute
- * the use case `(a = 'v' OR CONTAINS(b, 'v1') OR CONTAINS(c, 'v2') AND
(...)` as a UNION query
- * to leverage different indexes. In this case we return an 'Infinity'
overhead for make the
- * query engine choose a union query instead.
- *
- * @param constraint the constraint to analyse. Cannot be null.
- * @return
- */
- private double oak2660CostOverhead(@Nonnull ConstraintImpl constraint) {
- if (checkNotNull(constraint) instanceof OrImpl) {
- boolean fulltext = false, plain = false;
- for (ConstraintImpl c : constraint.getConstraints()) {
- if (c instanceof FullTextSearchImpl) {
- fulltext = true;
- } else {
- plain = true;
- }
-
- if (fulltext && plain) {
- return Double.MAX_VALUE;
- }
- }
- } else {
- List<ConstraintImpl> cs = constraint.getConstraints();
- if (cs == null) {
- return 0;
- } else {
- double cost = 0;
- for (ConstraintImpl c : cs) {
- cost += oak2660CostOverhead(c);
- if (cost == Double.MAX_VALUE) {
- return cost;
- }
- }
- return cost;
- }
- }
- return 0;
- }
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java?rev=1715347&r1=1715346&r2=1715347&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java
Fri Nov 20 13:04:18 2015
@@ -184,7 +184,7 @@ public class SQL2Parser {
* as {@link #parse(String, boolean)} by providing {@code true} to the
initialisation flag.
*
* @param query
- * @return
+ * @return the parsed query
* @throws ParseException
*/
public Query parse(final String query) throws ParseException {
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java?rev=1715347&r1=1715346&r2=1715347&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java
Fri Nov 20 13:04:18 2015
@@ -137,7 +137,9 @@ public class UnionQueryImpl implements Q
@Override
public double getEstimatedCost() {
- return left.getEstimatedCost() + right.getEstimatedCost();
+ // the cost is higher than the cost of both parts, so that
+ // non-union queries are preferred over union ones
+ return 10 + left.getEstimatedCost() + right.getEstimatedCost();
}
@Override
@@ -398,8 +400,9 @@ public class UnionQueryImpl implements Q
}
@Override
- public double getCostOverhead() {
- // for now we don't really have any case where a union query should
suffer from overheads.
- return 0;
+ public boolean containsUnfilteredFullTextCondition() {
+ return left.containsUnfilteredFullTextCondition() ||
+ right.containsUnfilteredFullTextCondition();
}
+
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AndImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AndImpl.java?rev=1715347&r1=1715346&r2=1715347&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AndImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AndImpl.java
Fri Nov 20 13:04:18 2015
@@ -43,7 +43,7 @@ public class AndImpl extends ConstraintI
private final List<ConstraintImpl> constraints;
- AndImpl(List<ConstraintImpl> constraints) {
+ public AndImpl(List<ConstraintImpl> constraints) {
checkArgument(!constraints.isEmpty());
this.constraints = constraints;
}
@@ -52,7 +52,6 @@ public class AndImpl extends ConstraintI
this(Arrays.asList(constraint1, constraint2));
}
- @Override
public List<ConstraintImpl> getConstraints() {
return constraints;
}
@@ -225,7 +224,7 @@ public class AndImpl extends ConstraintI
Set<ConstraintImpl> result = Sets.newHashSet();
Set<ConstraintImpl> nonUnion = Sets.newHashSet();
- for (ConstraintImpl c : getConstraints()) {
+ for (ConstraintImpl c : constraints) {
Set<ConstraintImpl> ccc = c.simplifyForUnion();
if (ccc.isEmpty()) {
nonUnion.add(c);
@@ -248,5 +247,25 @@ public class AndImpl extends ConstraintI
return result;
}
+
+ @Override
+ public boolean requiresFullTextIndex() {
+ for (ConstraintImpl c : constraints) {
+ if (c.requiresFullTextIndex()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean containsUnfilteredFullTextCondition() {
+ for (ConstraintImpl c : constraints) {
+ if (c.containsUnfilteredFullTextCondition()) {
+ return true;
+ }
+ }
+ return false;
+ }
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java?rev=1715347&r1=1715346&r2=1715347&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java
Fri Nov 20 13:04:18 2015
@@ -30,14 +30,11 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.query.fulltext.LikePattern;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.query.PropertyValues;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* A comparison operation (including "like").
*/
public class ComparisonImpl extends ConstraintImpl {
- private static final Logger LOG =
LoggerFactory.getLogger(ComparisonImpl.class);
private final DynamicOperandImpl operand1;
private final Operator operator;
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ConstraintImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ConstraintImpl.java?rev=1715347&r1=1715346&r2=1715347&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ConstraintImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ConstraintImpl.java
Fri Nov 20 13:04:18 2015
@@ -17,11 +17,9 @@
package org.apache.jackrabbit.oak.query.ast;
import java.util.Collections;
-import java.util.List;
import java.util.Set;
import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
import org.apache.jackrabbit.oak.query.fulltext.FullTextExpression;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
@@ -142,13 +140,24 @@ public abstract class ConstraintImpl ext
}
/**
+ * Whether the constraint contains a fulltext condition that requires
+ * using a fulltext index, because the condition can only be evaluated
there.
*
- * @return the list of {@link ConstraintImpl} that the current constraint
could hold. Default
- * implementation returns {@code null}.
+ * @return true if yes
*/
- @Nullable
- public List<ConstraintImpl> getConstraints() {
- return null;
+ public boolean requiresFullTextIndex() {
+ return false;
+ }
+
+ /**
+ * Whether the condition contains a fulltext condition that can not be
+ * applied to the filter, for example because it is part of an "or"
condition
+ * of the form "where a=1 or contains(., 'x')".
+ *
+ * @return true if yes
+ */
+ public boolean containsUnfilteredFullTextCondition() {
+ return false;
}
/**
@@ -165,7 +174,7 @@ public abstract class ConstraintImpl ext
* set.
* </p>
*
- * @return
+ * @return the set of constraints, if available
*/
@Nonnull
public Set<ConstraintImpl> simplifyForUnion() {
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java?rev=1715347&r1=1715346&r2=1715347&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchImpl.java
Fri Nov 20 13:04:18 2015
@@ -308,4 +308,10 @@ public class FullTextSearchImpl extends
public AstElement copyOf() {
return new FullTextSearchImpl(selectorName, propertyName,
fullTextSearchExpression);
}
+
+ @Override
+ public boolean requiresFullTextIndex() {
+ return true;
+ }
+
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NativeFunctionImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NativeFunctionImpl.java?rev=1715347&r1=1715346&r2=1715347&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NativeFunctionImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NativeFunctionImpl.java
Fri Nov 20 13:04:18 2015
@@ -111,4 +111,10 @@ public class NativeFunctionImpl extends
public AstElement copyOf() {
return new NativeFunctionImpl(selectorName, language,
nativeSearchExpression);
}
+
+ @Override
+ public boolean requiresFullTextIndex() {
+ return true;
+ }
+
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotFullTextImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotFullTextImpl.java?rev=1715347&r1=1715346&r2=1715347&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotFullTextImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotFullTextImpl.java
Fri Nov 20 13:04:18 2015
@@ -51,6 +51,14 @@ public class NotFullTextImpl extends Not
@Override
public FullTextExpression getFullTextConstraint(SelectorImpl s) {
+ // TODO is this correct?
+ ;
return getConstraint().getFullTextConstraint(s);
}
+
+ @Override
+ public boolean requiresFullTextIndex() {
+ return true;
+ }
+
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.java?rev=1715347&r1=1715346&r2=1715347&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/NotImpl.java
Fri Nov 20 13:04:18 2015
@@ -116,4 +116,20 @@ public class NotImpl extends ConstraintI
public AstElement copyOf() {
return new NotImpl((ConstraintImpl)
copyElementAndCheckReference(constraint));
}
+
+ @Override
+ public boolean requiresFullTextIndex() {
+ return constraint.requiresFullTextIndex();
+ }
+
+ @Override
+ public boolean containsUnfilteredFullTextCondition() {
+ // If the constraint is a fulltext condition,
+ // then we can not apply it, as in "not contains(., 'x')".
+ // Also, if the constraint _contains_ a unfiltered fulltext condition,
as in
+ // "not (x=1 or contains(., 'x')".
+ return constraint.requiresFullTextIndex() ||
+ constraint.requiresFullTextIndex();
+ }
+
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrImpl.java?rev=1715347&r1=1715346&r2=1715347&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/OrImpl.java
Fri Nov 20 13:04:18 2015
@@ -47,7 +47,7 @@ public class OrImpl extends ConstraintIm
private final List<ConstraintImpl> constraints;
- OrImpl(List<ConstraintImpl> constraints) {
+ public OrImpl(List<ConstraintImpl> constraints) {
checkArgument(!constraints.isEmpty());
this.constraints = constraints;
}
@@ -56,7 +56,6 @@ public class OrImpl extends ConstraintIm
this(Arrays.asList(constraint1, constraint2));
}
- @Override
public List<ConstraintImpl> getConstraints() {
return constraints;
}
@@ -371,4 +370,41 @@ public class OrImpl extends ConstraintIm
}
return cc;
}
+
+ @Override
+ public boolean requiresFullTextIndex() {
+ for (ConstraintImpl c : getConstraints()) {
+ if (c.requiresFullTextIndex()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean containsUnfilteredFullTextCondition() {
+ boolean fulltext = false;
+ boolean plain = false;
+ for (ConstraintImpl c : constraints) {
+ // this part of the condition already contains an unfiltered
+ // condition, so we don't need to check further
+ if (c.containsUnfilteredFullTextCondition()) {
+ return true;
+ }
+ if (c.requiresFullTextIndex()) {
+ // for example "contains(a, 'x')"
+ fulltext = true;
+ } else {
+ // for example "b=123"
+ plain = true;
+ }
+ // the full-text index contains both typescan not be used for
conditions
+ // of the form "contains(a, 'x') or b=123"
+ if (fulltext && plain) {
+ return true;
+ }
+ }
+ return false;
+ }
+
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SimilarImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SimilarImpl.java?rev=1715347&r1=1715346&r2=1715347&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SimilarImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SimilarImpl.java
Fri Nov 20 13:04:18 2015
@@ -132,4 +132,9 @@ public class SimilarImpl extends Constra
return new SimilarImpl(selectorName, propertyName, pathExpression);
}
+ @Override
+ public boolean requiresFullTextIndex() {
+ return true;
+ }
+
}
\ No newline at end of file
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SpellcheckImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SpellcheckImpl.java?rev=1715347&r1=1715346&r2=1715347&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SpellcheckImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SpellcheckImpl.java
Fri Nov 20 13:04:18 2015
@@ -119,4 +119,9 @@ public class SpellcheckImpl extends Cons
return new SpellcheckImpl(selectorName, expression);
}
+ @Override
+ public boolean requiresFullTextIndex() {
+ return true;
+ }
+
}
\ No newline at end of file
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SuggestImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SuggestImpl.java?rev=1715347&r1=1715346&r2=1715347&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SuggestImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SuggestImpl.java
Fri Nov 20 13:04:18 2015
@@ -118,4 +118,10 @@ public class SuggestImpl extends Constra
public AstElement copyOf() {
return new SuggestImpl(selectorName, expression);
}
+
+ @Override
+ public boolean requiresFullTextIndex() {
+ return true;
+ }
+
}
\ No newline at end of file
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/package-info.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/package-info.java?rev=1715347&r1=1715346&r2=1715347&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/package-info.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/package-info.java
Fri Nov 20 13:04:18 2015
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@Version("2.5")
+@Version("3.0")
@Export(optional = "provide:=true")
package org.apache.jackrabbit.oak.query;
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryCostOverheadTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryCostOverheadTest.java?rev=1715347&r1=1715346&r2=1715347&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryCostOverheadTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryCostOverheadTest.java
Fri Nov 20 13:04:18 2015
@@ -17,9 +17,9 @@
package org.apache.jackrabbit.oak.query;
import static com.google.common.collect.ImmutableList.of;
-import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
import org.apache.jackrabbit.oak.query.ast.AndImpl;
import org.apache.jackrabbit.oak.query.ast.ComparisonImpl;
@@ -32,70 +32,64 @@ import org.junit.Test;
public class QueryCostOverheadTest {
@Test
public void getCostOverhead() {
- final double allowedDelta = 10;
QueryImpl query;
UnionQueryImpl union;
ConstraintImpl c, c1, c2, c3, c4, c5;
- union = new UnionQueryImpl(false, null, null, null);
- assertEquals("we always expect 0 from a `UnionQueryImpl`", 0,
union.getCostOverhead(),
- allowedDelta);
+ c1 = new ComparisonImpl(null, null, null);
+ c2 = new FullTextSearchImpl(null, null, null);
+ union = new UnionQueryImpl(false,
+ new QueryImpl(null, null, c1, null, null, null),
+ new QueryImpl(null, null, c2, null, null, null),
+ null);
+ assertFalse("we always expect false from a `UnionQueryImpl`",
+ union.containsUnfilteredFullTextCondition());
- c = mock(OrImpl.class);
- c1 = mock(ComparisonImpl.class);
- c2 = mock(FullTextSearchImpl.class);
- when(c.getConstraints()).thenReturn(of(c1, c2));
- query = new QueryImpl(null, null, c, null, null, null);
- assertEquals(Double.MAX_VALUE, query.getCostOverhead(), allowedDelta);
-
- c = mock(OrImpl.class);
- c1 = mock(ComparisonImpl.class);
- c2 = mock(FullTextSearchImpl.class);
- c3 = mock(FullTextSearchImpl.class);
- when(c.getConstraints()).thenReturn(of(c1, c2, c3));
+ c1 = new ComparisonImpl(null, null, null);
+ c2 = new FullTextSearchImpl(null, null, null);
+ c = new OrImpl(c1, c2);
+ query = new QueryImpl(null, null, c, null, null, null);
+ assertTrue(query.containsUnfilteredFullTextCondition());
+
+ c1 = new ComparisonImpl(null, null, null);
+ c2 = new FullTextSearchImpl(null, null, null);
+ c3 = new FullTextSearchImpl(null, null, null);
+ c = new OrImpl(of(c1, c2, c3));
query = new QueryImpl(null, null, c, null, null, null);
- assertEquals(Double.MAX_VALUE, query.getCostOverhead(), allowedDelta);
+ assertTrue(query.containsUnfilteredFullTextCondition());
- c1 = mock(OrImpl.class);
- c2 = mock(FullTextSearchImpl.class);
- c3 = mock(FullTextSearchImpl.class);
- c4 = mock(ComparisonImpl.class);
- when(c1.getConstraints()).thenReturn(of(c2, c3, c4));
- c = mock(AndImpl.class);
+ c2 = new FullTextSearchImpl(null, null, null);
+ c3 = new FullTextSearchImpl(null, null, null);
+ c4 = new ComparisonImpl(null, null, null);
+ c1 = new OrImpl(of(c2, c3, c4));
c5 = mock(DescendantNodeImpl.class);
- when(c.getConstraints()).thenReturn(of(c1, c5));
+ c = new AndImpl(c1, c5);
query = new QueryImpl(null, null, c, null, null, null);
- assertEquals(Double.MAX_VALUE, query.getCostOverhead(), allowedDelta);
+ assertTrue(query.containsUnfilteredFullTextCondition());
- c = mock(FullTextSearchImpl.class);
+ c = new FullTextSearchImpl(null, null, null);
query = new QueryImpl(null, null, c, null, null, null);
- assertEquals(0, query.getCostOverhead(), allowedDelta);
+ assertFalse(query.containsUnfilteredFullTextCondition());
- c = mock(OrImpl.class);
- c1 = mock(FullTextSearchImpl.class);
- c2 = mock(FullTextSearchImpl.class);
- c3 = mock(FullTextSearchImpl.class);
- when(c.getConstraints()).thenReturn(of(c1, c2, c3));
+ c1 = new FullTextSearchImpl(null, null, null);
+ c2 = new FullTextSearchImpl(null, null, null);
+ c3 = new FullTextSearchImpl(null, null, null);
+ c = new OrImpl(of(c1, c2, c3));
query = new QueryImpl(null, null, c, null, null, null);
- assertEquals(0, query.getCostOverhead(), allowedDelta);
+ assertFalse(query.containsUnfilteredFullTextCondition());
- c = mock(AndImpl.class);
- c1 = mock(ComparisonImpl.class);
- c2 = mock(FullTextSearchImpl.class);
- c3 = mock(FullTextSearchImpl.class);
- when(c.getConstraints()).thenReturn(of(c1, c2, c3));
+ c1 = new ComparisonImpl(null, null, null);
+ c2 = new FullTextSearchImpl(null, null, null);
+ c3 = new FullTextSearchImpl(null, null, null);
+ c = new AndImpl(of(c1, c2, c3));
+ query = new QueryImpl(null, null, c, null, null, null);
+ assertFalse(query.containsUnfilteredFullTextCondition());
+
+ c1 = new ComparisonImpl(null, null, null);
+ c2 = new ComparisonImpl(null, null, null);
+ c = new AndImpl(of(c1, c2, c3));
query = new QueryImpl(null, null, c, null, null, null);
- assertEquals(0, query.getCostOverhead(), allowedDelta);
+ assertFalse(query.containsUnfilteredFullTextCondition());
- c = mock(AndImpl.class);
- c1 = mock(ComparisonImpl.class);
- c2 = mock(ComparisonImpl.class);
- when(c.getConstraints()).thenReturn(of(c1, c2, c3));
- query = new QueryImpl(null, null, c, null, null, null);
- assertEquals(0, query.getCostOverhead(), allowedDelta);
-
- c2 = mock(ComparisonImpl.class);
- query = new QueryImpl(null, null, c, null, null, null);
- assertEquals(0, query.getCostOverhead(), allowedDelta);
}
}