blerer commented on code in PR #3095: URL: https://github.com/apache/cassandra/pull/3095#discussion_r1574677409
########## src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java: ########## @@ -1,829 +0,0 @@ -/* - * 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.cassandra.cql3.restrictions; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.apache.cassandra.cql3.Operator; -import org.apache.cassandra.cql3.QueryOptions; -import org.apache.cassandra.cql3.terms.Term; -import org.apache.cassandra.cql3.terms.Terms; -import org.apache.cassandra.db.marshal.ListType; -import org.apache.cassandra.schema.ColumnMetadata; -import org.apache.cassandra.cql3.functions.Function; -import org.apache.cassandra.cql3.statements.Bound; -import org.apache.cassandra.db.MultiCBuilder; -import org.apache.cassandra.db.filter.RowFilter; -import org.apache.cassandra.index.Index; -import org.apache.cassandra.index.IndexRegistry; -import org.apache.cassandra.utils.ByteBufferUtil; -import org.apache.cassandra.utils.Pair; - -import static org.apache.cassandra.cql3.statements.RequestValidations.checkBindValueSet; -import static org.apache.cassandra.cql3.statements.RequestValidations.checkFalse; -import static org.apache.cassandra.cql3.statements.RequestValidations.checkNotNull; -import static org.apache.cassandra.cql3.statements.RequestValidations.checkTrue; -import static org.apache.cassandra.cql3.statements.RequestValidations.invalidRequest; - -public abstract class SingleColumnRestriction implements SingleRestriction -{ - /** - * The definition of the column to which apply the restriction. - */ - protected final ColumnMetadata columnDef; - - public SingleColumnRestriction(ColumnMetadata columnDef) - { - this.columnDef = columnDef; - } - - @Override - public List<ColumnMetadata> getColumnDefs() - { - return Collections.singletonList(columnDef); - } - - @Override - public ColumnMetadata getFirstColumn() - { - return columnDef; - } - - @Override - public ColumnMetadata getLastColumn() - { - return columnDef; - } - - @Override - public boolean hasSupportingIndex(IndexRegistry indexRegistry) - { - for (Index index : indexRegistry.listIndexes()) - if (isSupportedBy(index)) - return true; - - return false; - } - - @Override - public Index findSupportingIndex(IndexRegistry indexRegistry) - { - for (Index index : indexRegistry.listIndexes()) - if (isSupportedBy(index)) - return index; - - return null; - } - - @Override - public Index findSupportingIndexFromQueryPlan(Index.QueryPlan indexQueryPlan) - { - for (Index index : indexQueryPlan.getIndexes()) - if (isSupportedBy(index)) - return index; - - return null; - } - - @Override - public boolean needsFiltering(Index.Group indexGroup) - { - for (Index index : indexGroup.getIndexes()) - if (isSupportedBy(index)) - return false; - - return true; - } - - @Override - public final SingleRestriction mergeWith(SingleRestriction otherRestriction) - { - // We want to allow query like: b > ? AND (b,c) < (?, ?) - if (otherRestriction.isMultiColumn() && canBeConvertedToMultiColumnRestriction()) - { - return toMultiColumnRestriction().mergeWith(otherRestriction); - } - - return doMergeWith(otherRestriction); - } - - protected abstract SingleRestriction doMergeWith(SingleRestriction otherRestriction); - - /** - * Converts this <code>SingleColumnRestriction</code> into a {@link MultiColumnRestriction} - * - * @return the <code>MultiColumnRestriction</code> corresponding to this - */ - abstract MultiColumnRestriction toMultiColumnRestriction(); - - /** - * Checks if this <code>Restriction</code> can be converted into a {@link MultiColumnRestriction} - * - * @return <code>true</code> if this <code>Restriction</code> can be converted into a - * {@link MultiColumnRestriction}, <code>false</code> otherwise. - */ - boolean canBeConvertedToMultiColumnRestriction() - { - return true; - } - - /** - * Check if this type of restriction is supported by the specified index. - * - * @param index the secondary index - * @return <code>true</code> this type of restriction is supported by the specified index, - * <code>false</code> otherwise. - */ - protected abstract boolean isSupportedBy(Index index); - - public static final class EQRestriction extends SingleColumnRestriction - { - private final Term value; - - public EQRestriction(ColumnMetadata columnDef, Term value) - { - super(columnDef); - this.value = value; - } - - @Override - public void addFunctionsTo(List<Function> functions) - { - value.addFunctionsTo(functions); - } - - @Override - public boolean isEQ() - { - return true; - } - - @Override - MultiColumnRestriction toMultiColumnRestriction() - { - return new MultiColumnRestriction.EQRestriction(Collections.singletonList(columnDef), value); - } - - @Override - public void addToRowFilter(RowFilter filter, - IndexRegistry indexRegistry, - QueryOptions options) - { - filter.add(columnDef, Operator.EQ, value.bindAndGet(options)); - } - - @Override - public MultiCBuilder appendTo(MultiCBuilder builder, QueryOptions options) - { - builder.addElementToAll(value.bindAndGet(options)); - checkFalse(builder.containsNull(), "Invalid null value in condition for column %s", columnDef.name); - checkFalse(builder.containsUnset(), "Invalid unset value for column %s", columnDef.name); - return builder; - } - - @Override - public String toString() - { - return String.format("EQ(%s)", value); - } - - @Override - public SingleRestriction doMergeWith(SingleRestriction otherRestriction) - { - throw invalidRequest("%s cannot be restricted by more than one relation if it includes an Equal", columnDef.name); - } - - @Override - protected boolean isSupportedBy(Index index) - { - return index.supportsExpression(columnDef, Operator.EQ); - } - } - - public static class INRestriction extends SingleColumnRestriction - { - private final Terms values; - - public INRestriction(ColumnMetadata columnDef, Terms values) - { - super(columnDef); - this.values = values; - } - - @Override - MultiColumnRestriction toMultiColumnRestriction() - { - return new MultiColumnRestriction.INRestriction(Collections.singletonList(columnDef), values); - } - - @Override - public void addFunctionsTo(List<Function> functions) - { - values.addFunctionsTo(functions); - } - - @Override - public final boolean isIN() - { - return true; - } - - @Override - public final SingleRestriction doMergeWith(SingleRestriction otherRestriction) - { - throw invalidRequest("%s cannot be restricted by more than one relation if it includes a IN", columnDef.name); - } - - @Override - public MultiCBuilder appendTo(MultiCBuilder builder, QueryOptions options) - { - List<ByteBuffer> buffers = values.bindAndGet(options); - checkNotNull(buffers, "Invalid null value for column %s", columnDef.name); - checkFalse(buffers == Terms.UNSET_LIST, "Invalid unset value for column %s", columnDef.name); - builder.addEachElementToAll(buffers); - checkFalse(builder.containsNull(), "Invalid null value in condition for column %s", columnDef.name); - checkFalse(builder.containsUnset(), "Invalid unset value for column %s", columnDef.name); - return builder; - } - - @Override - public void addToRowFilter(RowFilter filter, - IndexRegistry indexRegistry, - QueryOptions options) - { - List<ByteBuffer> elements = values.bindAndGet(options); - ListType<?> type = ListType.getInstance(columnDef.type, false); - ByteBuffer buffer = type.pack(elements); - filter.add(columnDef, Operator.IN, buffer); - } - - @Override - protected final boolean isSupportedBy(Index index) - { - return index.supportsExpression(columnDef, Operator.IN); - } - } - - public static class SliceRestriction extends SingleColumnRestriction - { - private final TermSlice slice; - - public SliceRestriction(ColumnMetadata columnDef, Bound bound, boolean inclusive, Term term) - { - super(columnDef); - slice = TermSlice.newInstance(bound, inclusive, term); - } - - @Override - public void addFunctionsTo(List<Function> functions) - { - slice.addFunctionsTo(functions); - } - - @Override - MultiColumnRestriction toMultiColumnRestriction() - { - return new MultiColumnRestriction.SliceRestriction(Collections.singletonList(columnDef), slice); - } - - @Override - public boolean isSlice() - { - return true; - } - - @Override - public MultiCBuilder appendTo(MultiCBuilder builder, QueryOptions options) - { - throw new UnsupportedOperationException(); - } - - @Override - public boolean hasBound(Bound b) - { - return slice.hasBound(b); - } - - @Override - public MultiCBuilder appendBoundTo(MultiCBuilder builder, Bound bound, QueryOptions options) - { - Bound b = bound.reverseIfNeeded(getFirstColumn()); - - if (!hasBound(b)) - return builder; - - ByteBuffer value = slice.bound(b).bindAndGet(options); - checkBindValueSet(value, "Invalid unset value for column %s", columnDef.name); - return builder.addElementToAll(value); - - } - - @Override - public boolean isInclusive(Bound b) - { - return slice.isInclusive(b); - } - - @Override - public SingleRestriction doMergeWith(SingleRestriction otherRestriction) - { - checkTrue(otherRestriction.isSlice(), - "Column \"%s\" cannot be restricted by both an equality and an inequality relation", - columnDef.name); - - SingleColumnRestriction.SliceRestriction otherSlice = (SingleColumnRestriction.SliceRestriction) otherRestriction; - - checkFalse(hasBound(Bound.START) && otherSlice.hasBound(Bound.START), - "More than one restriction was found for the start bound on %s", columnDef.name); - - checkFalse(hasBound(Bound.END) && otherSlice.hasBound(Bound.END), - "More than one restriction was found for the end bound on %s", columnDef.name); - - return new SliceRestriction(columnDef, slice.merge(otherSlice.slice)); - } - - @Override - public void addToRowFilter(RowFilter filter, IndexRegistry indexRegistry, QueryOptions options) - { - for (Bound b : Bound.values()) - if (hasBound(b)) - filter.add(columnDef, slice.getIndexOperator(b), slice.bound(b).bindAndGet(options)); - } - - @Override - protected boolean isSupportedBy(Index index) - { - return slice.isSupportedBy(columnDef, index); - } - - @Override - public String toString() - { - return String.format("SLICE%s", slice); - } - - private SliceRestriction(ColumnMetadata columnDef, TermSlice slice) - { - super(columnDef); - this.slice = slice; - } - } - - // This holds CONTAINS, CONTAINS_KEY, and map[key] = value restrictions because we might want to have any combination of them. - public static final class ContainsRestriction extends SingleColumnRestriction - { - private final List<Term> values = new ArrayList<>(); // for CONTAINS - private final List<Term> keys = new ArrayList<>(); // for CONTAINS_KEY - private final List<Term> entryKeys = new ArrayList<>(); // for map[key] = value - private final List<Term> entryValues = new ArrayList<>(); // for map[key] = value - - public ContainsRestriction(ColumnMetadata columnDef, Term t, boolean isKey) - { - super(columnDef); - if (isKey) - keys.add(t); - else - values.add(t); - } - - public ContainsRestriction(ColumnMetadata columnDef, Term mapKey, Term mapValue) - { - super(columnDef); - entryKeys.add(mapKey); - entryValues.add(mapValue); - } - - @Override - MultiColumnRestriction toMultiColumnRestriction() - { - throw new UnsupportedOperationException(); - } - - @Override - boolean canBeConvertedToMultiColumnRestriction() - { - return false; - } - - @Override - public MultiCBuilder appendTo(MultiCBuilder builder, QueryOptions options) - { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isContains() - { - return true; - } - - @Override - public SingleRestriction doMergeWith(SingleRestriction otherRestriction) - { - checkTrue(otherRestriction.isContains(), Review Comment: Good point. I will re-add it. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]

