| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.jackrabbit.oak.query.ast; |
| |
| import java.util.Collections; |
| import java.util.Set; |
| |
| import org.apache.jackrabbit.oak.spi.query.fulltext.FullTextExpression; |
| import org.apache.jackrabbit.oak.query.index.FilterImpl; |
| import org.jetbrains.annotations.NotNull; |
| |
| /** |
| * The base class for constraints. |
| */ |
| public abstract class ConstraintImpl extends AstElement { |
| |
| /** |
| * Simplify the expression if possible, for example by removing duplicate expressions. |
| * For example, "x=1 or x=1" should be simplified to "x=1". |
| * |
| * @return the simplified constraint, or "this" if it is not possible to simplify |
| */ |
| public ConstraintImpl simplify() { |
| return this; |
| } |
| |
| /** |
| * Get the negative constraint, if it is simpler, or null. For example, |
| * "not x = 1" returns "x = 1", but "x = 1" returns null. |
| * |
| * @return the negative constraint, or null |
| */ |
| ConstraintImpl not() { |
| return null; |
| } |
| |
| /** |
| * Evaluate the result using the currently set values. |
| * |
| * @return true if the constraint matches |
| */ |
| public abstract boolean evaluate(); |
| |
| /** |
| * Whether this condition will, from now on, always evaluate to false. This |
| * is the case for example for full-text constraints if there is no |
| * full-text index (unless FullTextComparisonWithoutIndex is enabled). This |
| * will also allow is to add conditions that stop further processing for |
| * other reasons, similar to {@code "WHERE ROWNUM < 10"} in Oracle. |
| * |
| * @return true if further processing should be stopped |
| */ |
| public boolean evaluateStop() { |
| return false; |
| } |
| |
| /** |
| * Get the set of property existence conditions that can be derived for this |
| * condition. For example, for the condition "x=1 or x=2", the property |
| * existence condition is "x is not null". For the condition "x=1 or y=2", |
| * there is no such condition. For the condition "x=1 and y=1", there are |
| * two (x is not null, and y is not null). |
| * |
| * @return the common property existence condition (possibly empty) |
| */ |
| public abstract Set<PropertyExistenceImpl> getPropertyExistenceConditions(); |
| |
| /** |
| * Get the (combined) full-text constraint. For constraints of the form |
| * "contains(*, 'x') or contains(*, 'y')", the combined expression is |
| * returned. If there is none, null is returned. For constraints of the form |
| * "contains(*, 'x') or z=1", null is returned as the full-text index cannot |
| * be used in this case for filtering (as it might filter out the z=1 |
| * nodes). |
| * |
| * @param s the selector |
| * @return the full-text constraint, if there is any, or null if not |
| */ |
| public FullTextExpression getFullTextConstraint(SelectorImpl s) { |
| return null; |
| } |
| |
| /** |
| * Get the set of selectors for the given condition. |
| * |
| * @return the set of selectors (possibly empty) |
| */ |
| public abstract Set<SelectorImpl> getSelectors(); |
| |
| /** |
| * Apply the condition to the filter, further restricting the filter if |
| * possible. This may also verify the data types are compatible, and that |
| * paths are valid. |
| * |
| * @param f the filter |
| */ |
| public abstract void restrict(FilterImpl f); |
| |
| /** |
| * Push as much of the condition down to this selector, further restricting |
| * the selector condition if possible. This is important for a join: for |
| * example, the query |
| * "select * from a inner join b on a.x=b.x where a.y=1 and b.y=1", the |
| * condition "a.y=1" can be pushed down to "a", and the condition "b.y=1" |
| * can be pushed down to "b". That means it is possible to use an index in |
| * this case. |
| * |
| * @param s the selector |
| */ |
| public abstract void restrictPushDown(SelectorImpl s); |
| |
| @Override |
| public boolean equals(Object other) { |
| if (other == this) { |
| return true; |
| } else if (!(other instanceof ConstraintImpl)) { |
| return false; |
| } |
| return toString().equals(other.toString()); |
| } |
| |
| @Override |
| public int hashCode() { |
| return toString().hashCode(); |
| } |
| |
| /** |
| * Whether the constraint contains a fulltext condition that requires |
| * using a fulltext index, because the condition can only be evaluated there. |
| * |
| * @return true if yes |
| */ |
| 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; |
| } |
| |
| /** |
| * Compute a set of sub-constraints that could be used for composing UNION |
| * statements. For example in case of "c=1 or c=2", it will return to the |
| * caller {@code [c=1, c=2]}. Those can be later on used for re-composing |
| * conditions. |
| * <p> |
| * If it is not possible to convert to a union, it must return an empty set. |
| * <p> |
| * The default implementation in {@link ConstraintImpl#convertToUnion()} |
| * always return an empty set. |
| * |
| * @return the set of union constraints, if available, or an empty set if |
| * conversion is not possible |
| */ |
| @NotNull |
| public Set<ConstraintImpl> convertToUnion() { |
| return Collections.emptySet(); |
| } |
| } |