This is an automated email from the ASF dual-hosted git repository.
jackie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new e01df9a7ce Data visitors (#10361)
e01df9a7ce is described below
commit e01df9a7ce4867aaf663ec5f6ba5b3df41a61ea4
Author: Gonzalo Ortiz Jaureguizar <[email protected]>
AuthorDate: Thu Mar 16 21:51:28 2023 +0100
Data visitors (#10361)
---
.../predicate/EqualsPredicateEvaluatorFactory.java | 78 ++++++++++++--
.../predicate/InPredicateEvaluatorFactory.java | 67 ++++++++++--
.../NotEqualsPredicateEvaluatorFactory.java | 72 +++++++++++--
.../predicate/NotInPredicateEvaluatorFactory.java | 68 ++++++++++--
.../predicate/InPredicateEvaluatorFactoryTest.java | 115 +++++++++++++++++++++
.../apache/pinot/spi/data/MultiValueVisitor.java | 99 ++++++++++++++++++
.../apache/pinot/spi/data/SingleValueVisitor.java | 45 ++++++++
7 files changed, 510 insertions(+), 34 deletions(-)
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/EqualsPredicateEvaluatorFactory.java
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/EqualsPredicateEvaluatorFactory.java
index dcc3f34f65..14616b36be 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/EqualsPredicateEvaluatorFactory.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/EqualsPredicateEvaluatorFactory.java
@@ -21,12 +21,15 @@ package org.apache.pinot.core.operator.filter.predicate;
import java.math.BigDecimal;
import java.util.Arrays;
import org.apache.pinot.common.request.context.predicate.EqPredicate;
+import org.apache.pinot.common.request.context.predicate.Predicate;
import org.apache.pinot.core.operator.filter.predicate.traits.DoubleValue;
import org.apache.pinot.core.operator.filter.predicate.traits.FloatValue;
import org.apache.pinot.core.operator.filter.predicate.traits.IntValue;
import org.apache.pinot.core.operator.filter.predicate.traits.LongValue;
import org.apache.pinot.segment.spi.index.reader.Dictionary;
import org.apache.pinot.spi.data.FieldSpec.DataType;
+import org.apache.pinot.spi.data.MultiValueVisitor;
+import org.apache.pinot.spi.data.SingleValueVisitor;
import org.apache.pinot.spi.utils.BooleanUtils;
import org.apache.pinot.spi.utils.BytesUtils;
import org.apache.pinot.spi.utils.TimestampUtils;
@@ -59,7 +62,7 @@ public class EqualsPredicateEvaluatorFactory {
* @param dataType Data type for the column
* @return Raw value based EQ predicate evaluator
*/
- public static BaseRawValueBasedPredicateEvaluator
newRawValueBasedEvaluator(EqPredicate eqPredicate,
+ public static EqRawPredicateEvaluator newRawValueBasedEvaluator(EqPredicate
eqPredicate,
DataType dataType) {
String value = eqPredicate.getValue();
switch (dataType) {
@@ -140,8 +143,25 @@ public class EqualsPredicateEvaluatorFactory {
}
}
- private static final class IntRawValueBasedEqPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator
- implements IntValue {
+ public static abstract class EqRawPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ public EqRawPredicateEvaluator(Predicate predicate) {
+ super(predicate);
+ }
+
+ /**
+ * Visits the matching value of this predicate.
+ */
+ public abstract <R> R accept(SingleValueVisitor<R> visitor);
+
+ /**
+ * Visits the matching value of this predicate, which will be transformed
into an array with a single value.
+ */
+ public <R> R accept(MultiValueVisitor<R> visitor) {
+ return accept(visitor.asSingleValueVisitor());
+ }
+ }
+
+ private static final class IntRawValueBasedEqPredicateEvaluator extends
EqRawPredicateEvaluator implements IntValue {
final int _matchingValue;
IntRawValueBasedEqPredicateEvaluator(EqPredicate eqPredicate, int
matchingValue) {
@@ -149,6 +169,11 @@ public class EqualsPredicateEvaluatorFactory {
_matchingValue = matchingValue;
}
+ @Override
+ public <R> R accept(SingleValueVisitor<R> visitor) {
+ return visitor.visitInt(_matchingValue);
+ }
+
@Override
public int getNumMatchingItems() {
return 1;
@@ -183,7 +208,7 @@ public class EqualsPredicateEvaluatorFactory {
}
}
- private static final class LongRawValueBasedEqPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator
+ private static final class LongRawValueBasedEqPredicateEvaluator extends
EqRawPredicateEvaluator
implements LongValue {
final long _matchingValue;
@@ -192,6 +217,16 @@ public class EqualsPredicateEvaluatorFactory {
_matchingValue = matchingValue;
}
+ @Override
+ public <R> R accept(SingleValueVisitor<R> visitor) {
+ return visitor.visitLong(_matchingValue);
+ }
+
+ @Override
+ public <R> R accept(MultiValueVisitor<R> visitor) {
+ return visitor.asSingleValueVisitor().visitLong(_matchingValue);
+ }
+
@Override
public int getNumMatchingItems() {
return 1;
@@ -226,7 +261,7 @@ public class EqualsPredicateEvaluatorFactory {
}
}
- private static final class FloatRawValueBasedEqPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator
+ private static final class FloatRawValueBasedEqPredicateEvaluator extends
EqRawPredicateEvaluator
implements FloatValue {
final float _matchingValue;
@@ -235,6 +270,11 @@ public class EqualsPredicateEvaluatorFactory {
_matchingValue = matchingValue;
}
+ @Override
+ public <R> R accept(SingleValueVisitor<R> visitor) {
+ return visitor.visitFloat(_matchingValue);
+ }
+
@Override
public int getNumMatchingItems() {
return 1;
@@ -269,7 +309,7 @@ public class EqualsPredicateEvaluatorFactory {
}
}
- private static final class DoubleRawValueBasedEqPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator
+ private static final class DoubleRawValueBasedEqPredicateEvaluator extends
EqRawPredicateEvaluator
implements DoubleValue {
final double _matchingValue;
@@ -278,6 +318,11 @@ public class EqualsPredicateEvaluatorFactory {
_matchingValue = matchingValue;
}
+ @Override
+ public <R> R accept(SingleValueVisitor<R> visitor) {
+ return visitor.visitDouble(_matchingValue);
+ }
+
@Override
public int getNumMatchingItems() {
return 1;
@@ -312,7 +357,7 @@ public class EqualsPredicateEvaluatorFactory {
}
}
- private static final class BigDecimalRawValueBasedEqPredicateEvaluator
extends BaseRawValueBasedPredicateEvaluator {
+ private static final class BigDecimalRawValueBasedEqPredicateEvaluator
extends EqRawPredicateEvaluator {
final BigDecimal _matchingValue;
BigDecimalRawValueBasedEqPredicateEvaluator(EqPredicate eqPredicate,
BigDecimal matchingValue) {
@@ -320,6 +365,11 @@ public class EqualsPredicateEvaluatorFactory {
_matchingValue = matchingValue;
}
+ @Override
+ public <R> R accept(SingleValueVisitor<R> visitor) {
+ return visitor.visitBigDecimal(_matchingValue);
+ }
+
@Override
public int getNumMatchingItems() {
return 1;
@@ -336,7 +386,7 @@ public class EqualsPredicateEvaluatorFactory {
}
}
- private static final class StringRawValueBasedEqPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ private static final class StringRawValueBasedEqPredicateEvaluator extends
EqRawPredicateEvaluator {
final String _matchingValue;
StringRawValueBasedEqPredicateEvaluator(EqPredicate eqPredicate, String
matchingValue) {
@@ -344,6 +394,11 @@ public class EqualsPredicateEvaluatorFactory {
_matchingValue = matchingValue;
}
+ @Override
+ public <R> R accept(SingleValueVisitor<R> visitor) {
+ return visitor.visitString(_matchingValue);
+ }
+
@Override
public int getNumMatchingItems() {
return 1;
@@ -360,7 +415,7 @@ public class EqualsPredicateEvaluatorFactory {
}
}
- private static final class BytesRawValueBasedEqPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ private static final class BytesRawValueBasedEqPredicateEvaluator extends
EqRawPredicateEvaluator {
final byte[] _matchingValue;
BytesRawValueBasedEqPredicateEvaluator(EqPredicate eqPredicate, byte[]
matchingValue) {
@@ -368,6 +423,11 @@ public class EqualsPredicateEvaluatorFactory {
_matchingValue = matchingValue;
}
+ @Override
+ public <R> R accept(SingleValueVisitor<R> visitor) {
+ return visitor.visitBytes(_matchingValue);
+ }
+
@Override
public int getNumMatchingItems() {
return 1;
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/InPredicateEvaluatorFactory.java
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/InPredicateEvaluatorFactory.java
index 9bbebcec57..9ad0a78014 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/InPredicateEvaluatorFactory.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/InPredicateEvaluatorFactory.java
@@ -34,10 +34,12 @@ import java.util.Set;
import java.util.TreeSet;
import javax.annotation.Nullable;
import org.apache.pinot.common.request.context.predicate.InPredicate;
+import org.apache.pinot.common.request.context.predicate.Predicate;
import org.apache.pinot.common.utils.HashUtil;
import org.apache.pinot.core.query.request.context.QueryContext;
import org.apache.pinot.segment.spi.index.reader.Dictionary;
import org.apache.pinot.spi.data.FieldSpec.DataType;
+import org.apache.pinot.spi.data.MultiValueVisitor;
import org.apache.pinot.spi.utils.ByteArray;
@@ -69,7 +71,7 @@ public class InPredicateEvaluatorFactory {
* @param dataType Data type for the column
* @return Raw value based IN predicate evaluator
*/
- public static BaseRawValueBasedPredicateEvaluator
newRawValueBasedEvaluator(InPredicate inPredicate,
+ public static InRawPredicateEvaluator newRawValueBasedEvaluator(InPredicate
inPredicate,
DataType dataType) {
switch (dataType) {
case INT: {
@@ -207,7 +209,18 @@ public class InPredicateEvaluatorFactory {
}
}
- private static final class IntRawValueBasedInPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ public static abstract class InRawPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ public InRawPredicateEvaluator(Predicate predicate) {
+ super(predicate);
+ }
+
+ /**
+ * Visits the matching value of this predicate.
+ */
+ public abstract <R> R accept(MultiValueVisitor<R> visitor);
+ }
+
+ private static final class IntRawValueBasedInPredicateEvaluator extends
InRawPredicateEvaluator {
final IntSet _matchingValues;
IntRawValueBasedInPredicateEvaluator(InPredicate inPredicate, IntSet
matchingValues) {
@@ -242,9 +255,14 @@ public class InPredicateEvaluatorFactory {
}
return matches;
}
+
+ @Override
+ public <R> R accept(MultiValueVisitor<R> visitor) {
+ return visitor.visitInt(_matchingValues.toIntArray());
+ }
}
- private static final class LongRawValueBasedInPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ private static final class LongRawValueBasedInPredicateEvaluator extends
InRawPredicateEvaluator {
final LongSet _matchingValues;
LongRawValueBasedInPredicateEvaluator(InPredicate inPredicate, LongSet
matchingValues) {
@@ -279,9 +297,14 @@ public class InPredicateEvaluatorFactory {
}
return matches;
}
+
+ @Override
+ public <R> R accept(MultiValueVisitor<R> visitor) {
+ return visitor.visitLong(_matchingValues.toLongArray());
+ }
}
- private static final class FloatRawValueBasedInPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ private static final class FloatRawValueBasedInPredicateEvaluator extends
InRawPredicateEvaluator {
final FloatSet _matchingValues;
FloatRawValueBasedInPredicateEvaluator(InPredicate inPredicate, FloatSet
matchingValues) {
@@ -316,9 +339,14 @@ public class InPredicateEvaluatorFactory {
}
return matches;
}
+
+ @Override
+ public <R> R accept(MultiValueVisitor<R> visitor) {
+ return visitor.visitFloat(_matchingValues.toFloatArray());
+ }
}
- private static final class DoubleRawValueBasedInPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ private static final class DoubleRawValueBasedInPredicateEvaluator extends
InRawPredicateEvaluator {
final DoubleSet _matchingValues;
DoubleRawValueBasedInPredicateEvaluator(InPredicate inPredicate, DoubleSet
matchingValues) {
@@ -353,9 +381,14 @@ public class InPredicateEvaluatorFactory {
}
return matches;
}
+
+ @Override
+ public <R> R accept(MultiValueVisitor<R> visitor) {
+ return visitor.visitDouble(_matchingValues.toDoubleArray());
+ }
}
- private static final class BigDecimalRawValueBasedInPredicateEvaluator
extends BaseRawValueBasedPredicateEvaluator {
+ private static final class BigDecimalRawValueBasedInPredicateEvaluator
extends InRawPredicateEvaluator {
// Note: BigDecimal's compareTo is not consistent with equals (e.g.
compareTo(3.0, 3) returns zero when
// equals(3.0, 3) returns false).
// - HashSet implementation consider both hashCode() and equals() for the
key.
@@ -383,9 +416,14 @@ public class InPredicateEvaluatorFactory {
public boolean applySV(BigDecimal value) {
return _matchingValues.contains(value);
}
+
+ @Override
+ public <R> R accept(MultiValueVisitor<R> visitor) {
+ return visitor.visitBigDecimal(_matchingValues.toArray(new
BigDecimal[0]));
+ }
}
- private static final class StringRawValueBasedInPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ private static final class StringRawValueBasedInPredicateEvaluator extends
InRawPredicateEvaluator {
final Set<String> _matchingValues;
StringRawValueBasedInPredicateEvaluator(InPredicate inPredicate,
Set<String> matchingValues) {
@@ -407,9 +445,14 @@ public class InPredicateEvaluatorFactory {
public boolean applySV(String value) {
return _matchingValues.contains(value);
}
+
+ @Override
+ public <R> R accept(MultiValueVisitor<R> visitor) {
+ return visitor.visitString(_matchingValues.toArray(new String[0]));
+ }
}
- private static final class BytesRawValueBasedInPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ private static final class BytesRawValueBasedInPredicateEvaluator extends
InRawPredicateEvaluator {
final Set<ByteArray> _matchingValues;
BytesRawValueBasedInPredicateEvaluator(InPredicate inPredicate,
Set<ByteArray> matchingValues) {
@@ -431,5 +474,13 @@ public class InPredicateEvaluatorFactory {
public boolean applySV(byte[] value) {
return _matchingValues.contains(new ByteArray(value));
}
+
+ @Override
+ public <R> R accept(MultiValueVisitor<R> visitor) {
+ byte[][] bytes = _matchingValues.stream()
+ .map(ByteArray::getBytes)
+ .toArray(byte[][]::new);
+ return visitor.visitBytes(bytes);
+ }
}
}
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/NotEqualsPredicateEvaluatorFactory.java
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/NotEqualsPredicateEvaluatorFactory.java
index f091039f1d..54ce7df58c 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/NotEqualsPredicateEvaluatorFactory.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/NotEqualsPredicateEvaluatorFactory.java
@@ -21,8 +21,11 @@ package org.apache.pinot.core.operator.filter.predicate;
import java.math.BigDecimal;
import java.util.Arrays;
import org.apache.pinot.common.request.context.predicate.NotEqPredicate;
+import org.apache.pinot.common.request.context.predicate.Predicate;
import org.apache.pinot.segment.spi.index.reader.Dictionary;
import org.apache.pinot.spi.data.FieldSpec.DataType;
+import org.apache.pinot.spi.data.MultiValueVisitor;
+import org.apache.pinot.spi.data.SingleValueVisitor;
import org.apache.pinot.spi.utils.BooleanUtils;
import org.apache.pinot.spi.utils.BytesUtils;
import org.apache.pinot.spi.utils.TimestampUtils;
@@ -55,7 +58,7 @@ public class NotEqualsPredicateEvaluatorFactory {
* @param dataType Data type for the column
* @return Raw value based NOT_EQ predicate evaluator
*/
- public static BaseRawValueBasedPredicateEvaluator
newRawValueBasedEvaluator(NotEqPredicate notEqPredicate,
+ public static NeqRawPredicateEvaluator
newRawValueBasedEvaluator(NotEqPredicate notEqPredicate,
DataType dataType) {
String value = notEqPredicate.getValue();
switch (dataType) {
@@ -155,7 +158,25 @@ public class NotEqualsPredicateEvaluatorFactory {
}
}
- private static final class IntRawValueBasedNeqPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ public static abstract class NeqRawPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ public NeqRawPredicateEvaluator(Predicate predicate) {
+ super(predicate);
+ }
+
+ /**
+ * Visits the not matching value of this predicate.
+ */
+ public abstract <R> R accept(SingleValueVisitor<R> visitor);
+
+ /**
+ * Visits the not matching value of this predicate, which will be
transformed into an array with a single value.
+ */
+ public <R> R accept(MultiValueVisitor<R> visitor) {
+ return accept(visitor.asSingleValueVisitor());
+ }
+ }
+
+ private static final class IntRawValueBasedNeqPredicateEvaluator extends
NeqRawPredicateEvaluator {
final int _nonMatchingValue;
IntRawValueBasedNeqPredicateEvaluator(NotEqPredicate notEqPredicate, int
nonMatchingValue) {
@@ -190,9 +211,14 @@ public class NotEqualsPredicateEvaluatorFactory {
}
return matches;
}
+
+ @Override
+ public <R> R accept(SingleValueVisitor<R> visitor) {
+ return visitor.visitInt(_nonMatchingValue);
+ }
}
- private static final class LongRawValueBasedNeqPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ private static final class LongRawValueBasedNeqPredicateEvaluator extends
NeqRawPredicateEvaluator {
final long _nonMatchingValue;
LongRawValueBasedNeqPredicateEvaluator(NotEqPredicate notEqPredicate, long
nonMatchingValue) {
@@ -227,9 +253,14 @@ public class NotEqualsPredicateEvaluatorFactory {
}
return matches;
}
+
+ @Override
+ public <R> R accept(SingleValueVisitor<R> visitor) {
+ return visitor.visitLong(_nonMatchingValue);
+ }
}
- private static final class FloatRawValueBasedNeqPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ private static final class FloatRawValueBasedNeqPredicateEvaluator extends
NeqRawPredicateEvaluator {
final float _nonMatchingValue;
FloatRawValueBasedNeqPredicateEvaluator(NotEqPredicate notEqPredicate,
float nonMatchingValue) {
@@ -264,9 +295,14 @@ public class NotEqualsPredicateEvaluatorFactory {
}
return matches;
}
+
+ @Override
+ public <R> R accept(SingleValueVisitor<R> visitor) {
+ return visitor.visitFloat(_nonMatchingValue);
+ }
}
- private static final class DoubleRawValueBasedNeqPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ private static final class DoubleRawValueBasedNeqPredicateEvaluator extends
NeqRawPredicateEvaluator {
final double _nonMatchingValue;
DoubleRawValueBasedNeqPredicateEvaluator(NotEqPredicate notEqPredicate,
double nonMatchingValue) {
@@ -301,9 +337,14 @@ public class NotEqualsPredicateEvaluatorFactory {
}
return matches;
}
+
+ @Override
+ public <R> R accept(SingleValueVisitor<R> visitor) {
+ return visitor.visitDouble(_nonMatchingValue);
+ }
}
- private static final class BigDecimalRawValueBasedNeqPredicateEvaluator
extends BaseRawValueBasedPredicateEvaluator {
+ private static final class BigDecimalRawValueBasedNeqPredicateEvaluator
extends NeqRawPredicateEvaluator {
final BigDecimal _nonMatchingValue;
BigDecimalRawValueBasedNeqPredicateEvaluator(NotEqPredicate
notEqPredicate, BigDecimal nonMatchingValue) {
@@ -325,9 +366,14 @@ public class NotEqualsPredicateEvaluatorFactory {
public boolean applySV(BigDecimal value) {
return _nonMatchingValue.compareTo(value) != 0;
}
+
+ @Override
+ public <R> R accept(SingleValueVisitor<R> visitor) {
+ return visitor.visitBigDecimal(_nonMatchingValue);
+ }
}
- private static final class StringRawValueBasedNeqPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ private static final class StringRawValueBasedNeqPredicateEvaluator extends
NeqRawPredicateEvaluator {
final String _nonMatchingValue;
StringRawValueBasedNeqPredicateEvaluator(NotEqPredicate notEqPredicate,
String nonMatchingValue) {
@@ -349,9 +395,14 @@ public class NotEqualsPredicateEvaluatorFactory {
public boolean applySV(String value) {
return !_nonMatchingValue.equals(value);
}
+
+ @Override
+ public <R> R accept(SingleValueVisitor<R> visitor) {
+ return visitor.visitString(_nonMatchingValue);
+ }
}
- private static final class BytesRawValueBasedNeqPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ private static final class BytesRawValueBasedNeqPredicateEvaluator extends
NeqRawPredicateEvaluator {
final byte[] _nonMatchingValue;
BytesRawValueBasedNeqPredicateEvaluator(NotEqPredicate notEqPredicate,
byte[] nonMatchingValue) {
@@ -373,5 +424,10 @@ public class NotEqualsPredicateEvaluatorFactory {
public boolean applySV(byte[] value) {
return !Arrays.equals(_nonMatchingValue, value);
}
+
+ @Override
+ public <R> R accept(SingleValueVisitor<R> visitor) {
+ return visitor.visitBytes(_nonMatchingValue);
+ }
}
}
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/NotInPredicateEvaluatorFactory.java
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/NotInPredicateEvaluatorFactory.java
index a0e2bf6a8d..5fe7b51d35 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/NotInPredicateEvaluatorFactory.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/predicate/NotInPredicateEvaluatorFactory.java
@@ -34,10 +34,12 @@ import java.util.Set;
import java.util.TreeSet;
import javax.annotation.Nullable;
import org.apache.pinot.common.request.context.predicate.NotInPredicate;
+import org.apache.pinot.common.request.context.predicate.Predicate;
import org.apache.pinot.common.utils.HashUtil;
import org.apache.pinot.core.query.request.context.QueryContext;
import org.apache.pinot.segment.spi.index.reader.Dictionary;
import org.apache.pinot.spi.data.FieldSpec.DataType;
+import org.apache.pinot.spi.data.MultiValueVisitor;
import org.apache.pinot.spi.utils.ByteArray;
@@ -69,7 +71,7 @@ public class NotInPredicateEvaluatorFactory {
* @param dataType Data type for the column
* @return Raw value based NOT_IN predicate evaluator
*/
- public static BaseRawValueBasedPredicateEvaluator
newRawValueBasedEvaluator(NotInPredicate notInPredicate,
+ public static NotInRawPredicateEvaluator
newRawValueBasedEvaluator(NotInPredicate notInPredicate,
DataType dataType) {
switch (dataType) {
case INT: {
@@ -225,7 +227,18 @@ public class NotInPredicateEvaluatorFactory {
}
}
- private static final class IntRawValueBasedNotInPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ public static abstract class NotInRawPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ public NotInRawPredicateEvaluator(Predicate predicate) {
+ super(predicate);
+ }
+
+ /**
+ * Visits the not matching value of this predicate.
+ */
+ public abstract <R> R accept(MultiValueVisitor<R> visitor);
+ }
+
+ private static final class IntRawValueBasedNotInPredicateEvaluator extends
NotInRawPredicateEvaluator {
final IntSet _nonMatchingValues;
IntRawValueBasedNotInPredicateEvaluator(NotInPredicate notInPredicate,
IntSet nonMatchingValues) {
@@ -260,9 +273,14 @@ public class NotInPredicateEvaluatorFactory {
}
return matches;
}
+
+ @Override
+ public <R> R accept(MultiValueVisitor<R> visitor) {
+ return visitor.visitInt(_nonMatchingValues.toIntArray());
+ }
}
- private static final class LongRawValueBasedNotInPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ private static final class LongRawValueBasedNotInPredicateEvaluator extends
NotInRawPredicateEvaluator {
final LongSet _nonMatchingValues;
LongRawValueBasedNotInPredicateEvaluator(NotInPredicate notInPredicate,
LongSet nonMatchingValues) {
@@ -297,9 +315,14 @@ public class NotInPredicateEvaluatorFactory {
}
return matches;
}
+
+ @Override
+ public <R> R accept(MultiValueVisitor<R> visitor) {
+ return visitor.visitLong(_nonMatchingValues.toLongArray());
+ }
}
- private static final class FloatRawValueBasedNotInPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ private static final class FloatRawValueBasedNotInPredicateEvaluator extends
NotInRawPredicateEvaluator {
final FloatSet _nonMatchingValues;
FloatRawValueBasedNotInPredicateEvaluator(NotInPredicate notInPredicate,
FloatSet nonMatchingValues) {
@@ -334,9 +357,14 @@ public class NotInPredicateEvaluatorFactory {
}
return matches;
}
+
+ @Override
+ public <R> R accept(MultiValueVisitor<R> visitor) {
+ return visitor.visitFloat(_nonMatchingValues.toFloatArray());
+ }
}
- private static final class DoubleRawValueBasedNotInPredicateEvaluator
extends BaseRawValueBasedPredicateEvaluator {
+ private static final class DoubleRawValueBasedNotInPredicateEvaluator
extends NotInRawPredicateEvaluator {
final DoubleSet _nonMatchingValues;
DoubleRawValueBasedNotInPredicateEvaluator(NotInPredicate notInPredicate,
DoubleSet nonMatchingValues) {
@@ -371,10 +399,14 @@ public class NotInPredicateEvaluatorFactory {
}
return matches;
}
+
+ @Override
+ public <R> R accept(MultiValueVisitor<R> visitor) {
+ return visitor.visitDouble(_nonMatchingValues.toDoubleArray());
+ }
}
- private static final class BigDecimalRawValueBasedNotInPredicateEvaluator
- extends BaseRawValueBasedPredicateEvaluator {
+ private static final class BigDecimalRawValueBasedNotInPredicateEvaluator
extends NotInRawPredicateEvaluator {
// See: BigDecimalRawValueBasedInPredicateEvaluator.
final TreeSet<BigDecimal> _nonMatchingValues;
@@ -398,9 +430,14 @@ public class NotInPredicateEvaluatorFactory {
public boolean applySV(BigDecimal value) {
return !_nonMatchingValues.contains(value);
}
+
+ @Override
+ public <R> R accept(MultiValueVisitor<R> visitor) {
+ return visitor.visitBigDecimal(_nonMatchingValues.toArray(new
BigDecimal[0]));
+ }
}
- private static final class StringRawValueBasedNotInPredicateEvaluator
extends BaseRawValueBasedPredicateEvaluator {
+ private static final class StringRawValueBasedNotInPredicateEvaluator
extends NotInRawPredicateEvaluator {
final Set<String> _nonMatchingValues;
StringRawValueBasedNotInPredicateEvaluator(NotInPredicate notInPredicate,
Set<String> nonMatchingValues) {
@@ -422,9 +459,14 @@ public class NotInPredicateEvaluatorFactory {
public boolean applySV(String value) {
return !_nonMatchingValues.contains(value);
}
+
+ @Override
+ public <R> R accept(MultiValueVisitor<R> visitor) {
+ return visitor.visitString(_nonMatchingValues.toArray(new String[0]));
+ }
}
- private static final class BytesRawValueBasedNotInPredicateEvaluator extends
BaseRawValueBasedPredicateEvaluator {
+ private static final class BytesRawValueBasedNotInPredicateEvaluator extends
NotInRawPredicateEvaluator {
final Set<ByteArray> _nonMatchingValues;
BytesRawValueBasedNotInPredicateEvaluator(NotInPredicate notInPredicate,
Set<ByteArray> nonMatchingValues) {
@@ -446,5 +488,13 @@ public class NotInPredicateEvaluatorFactory {
public boolean applySV(byte[] value) {
return !_nonMatchingValues.contains(new ByteArray(value));
}
+
+ @Override
+ public <R> R accept(MultiValueVisitor<R> visitor) {
+ byte[][] bytes = _nonMatchingValues.stream()
+ .map(ByteArray::getBytes)
+ .toArray(byte[][]::new);
+ return visitor.visitBytes(bytes);
+ }
}
}
diff --git
a/pinot-core/src/test/java/org/apache/pinot/core/operator/filter/predicate/InPredicateEvaluatorFactoryTest.java
b/pinot-core/src/test/java/org/apache/pinot/core/operator/filter/predicate/InPredicateEvaluatorFactoryTest.java
new file mode 100644
index 0000000000..8e83e2b217
--- /dev/null
+++
b/pinot-core/src/test/java/org/apache/pinot/core/operator/filter/predicate/InPredicateEvaluatorFactoryTest.java
@@ -0,0 +1,115 @@
+/**
+ * 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.pinot.core.operator.filter.predicate;
+
+import com.google.common.collect.Lists;
+import java.math.BigDecimal;
+import org.apache.pinot.common.request.context.ExpressionContext;
+import org.apache.pinot.common.request.context.predicate.InPredicate;
+import org.apache.pinot.spi.data.FieldSpec;
+import org.apache.pinot.spi.data.MultiValueVisitor;
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+
+public class InPredicateEvaluatorFactoryTest {
+
+ MultiValueVisitor<Integer> createValueLengthVisitor() {
+ return new MultiValueVisitor<Integer>() {
+ @Override
+ public Integer visitInt(int[] value) {
+ return value.length;
+ }
+
+ @Override
+ public Integer visitLong(long[] value) {
+ return value.length;
+ }
+
+ @Override
+ public Integer visitFloat(float[] value) {
+ return value.length;
+ }
+
+ @Override
+ public Integer visitDouble(double[] value) {
+ return value.length;
+ }
+
+ @Override
+ public Integer visitBigDecimal(BigDecimal[] value) {
+ return value.length;
+ }
+
+ @Override
+ public Integer visitBoolean(boolean[] value) {
+ return value.length;
+ }
+
+ @Override
+ public Integer visitTimestamp(long[] value) {
+ return value.length;
+ }
+
+ @Override
+ public Integer visitString(String[] value) {
+ return value.length;
+ }
+
+ @Override
+ public Integer visitJson(String[] value) {
+ return value.length;
+ }
+
+ @Override
+ public Integer visitBytes(byte[][] value) {
+ return value.length;
+ }
+ };
+ }
+
+ @Test
+ void canBeVisited() {
+ // Given a visitor
+ MultiValueVisitor<Integer> valueLengthVisitor =
Mockito.spy(createValueLengthVisitor());
+
+ // When int predicate is used
+ InPredicate predicate = new
InPredicate(ExpressionContext.forIdentifier("ident"), Lists.newArrayList("1",
"2"));
+
+ InPredicateEvaluatorFactory.InRawPredicateEvaluator intEvaluator =
+ InPredicateEvaluatorFactory.newRawValueBasedEvaluator(predicate,
FieldSpec.DataType.INT);
+
+ // Only the int[] method is called
+ int length = intEvaluator.accept(valueLengthVisitor);
+ Assert.assertEquals(length, 2);
+ Mockito.verify(valueLengthVisitor).visitInt(new int[] {2, 1});
+ Mockito.verifyNoMoreInteractions(valueLengthVisitor);
+
+ // And given a string predicate
+ InPredicateEvaluatorFactory.InRawPredicateEvaluator strEvaluator =
+ InPredicateEvaluatorFactory.newRawValueBasedEvaluator(predicate,
FieldSpec.DataType.STRING);
+
+ // Only the string[] method is called
+ length = strEvaluator.accept(valueLengthVisitor);
+ Assert.assertEquals(length, 2);
+ Mockito.verify(valueLengthVisitor).visitString(new String[] {"2", "1"});
+ Mockito.verifyNoMoreInteractions(valueLengthVisitor);
+ }
+}
diff --git
a/pinot-spi/src/main/java/org/apache/pinot/spi/data/MultiValueVisitor.java
b/pinot-spi/src/main/java/org/apache/pinot/spi/data/MultiValueVisitor.java
new file mode 100644
index 0000000000..13fc4d3568
--- /dev/null
+++ b/pinot-spi/src/main/java/org/apache/pinot/spi/data/MultiValueVisitor.java
@@ -0,0 +1,99 @@
+/**
+ * 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.pinot.spi.data;
+
+import java.math.BigDecimal;
+
+
+public interface MultiValueVisitor<R> {
+
+ R visitInt(int[] value);
+
+ R visitLong(long[] value);
+
+ R visitFloat(float[] value);
+
+ R visitDouble(double[] value);
+
+ R visitBigDecimal(BigDecimal[] value);
+
+ R visitBoolean(boolean[] value);
+
+ R visitTimestamp(long[] value);
+
+ R visitString(String[] value);
+
+ R visitJson(String[] value);
+
+ R visitBytes(byte[][] value);
+
+ default SingleValueVisitor<R> asSingleValueVisitor() {
+ return new SingleValueVisitor<R>() {
+ @Override
+ public R visitInt(int value) {
+ return MultiValueVisitor.this.visitInt(new int[] {value});
+ }
+
+ @Override
+ public R visitLong(long value) {
+ return MultiValueVisitor.this.visitLong(new long[] {value});
+ }
+
+ @Override
+ public R visitFloat(float value) {
+ return MultiValueVisitor.this.visitFloat(new float[] {value});
+ }
+
+ @Override
+ public R visitDouble(double value) {
+ return MultiValueVisitor.this.visitDouble(new double[] {value});
+ }
+
+ @Override
+ public R visitBigDecimal(BigDecimal value) {
+ return MultiValueVisitor.this.visitBigDecimal(new BigDecimal[]
{value});
+ }
+
+ @Override
+ public R visitBoolean(boolean value) {
+ return MultiValueVisitor.this.visitBoolean(new boolean[] {value});
+ }
+
+ @Override
+ public R visitTimestamp(long value) {
+ return MultiValueVisitor.this.visitLong(new long[] {value});
+ }
+
+ @Override
+ public R visitString(String value) {
+ return MultiValueVisitor.this.visitString(new String[] {value});
+ }
+
+ @Override
+ public R visitJson(String value) {
+ return MultiValueVisitor.this.visitString(new String[] {value});
+ }
+
+ @Override
+ public R visitBytes(byte[] value) {
+ return MultiValueVisitor.this.visitBytes(new byte[][] {value});
+ }
+ };
+ }
+}
diff --git
a/pinot-spi/src/main/java/org/apache/pinot/spi/data/SingleValueVisitor.java
b/pinot-spi/src/main/java/org/apache/pinot/spi/data/SingleValueVisitor.java
new file mode 100644
index 0000000000..6184bbf057
--- /dev/null
+++ b/pinot-spi/src/main/java/org/apache/pinot/spi/data/SingleValueVisitor.java
@@ -0,0 +1,45 @@
+/**
+ * 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.pinot.spi.data;
+
+import java.math.BigDecimal;
+
+
+public interface SingleValueVisitor<R> {
+
+ R visitInt(int value);
+
+ R visitLong(long value);
+
+ R visitFloat(float value);
+
+ R visitDouble(double value);
+
+ R visitBigDecimal(BigDecimal value);
+
+ R visitBoolean(boolean value);
+
+ R visitTimestamp(long value);
+
+ R visitString(String value);
+
+ R visitJson(String value);
+
+ R visitBytes(byte[] value);
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]