in pinot-common/src/main/java/org/apache/pinot/common/request/context/RequestContextUtils.java [124:262]
public static FilterContext getFilter(Function thriftFunction) {
String functionOperator = thriftFunction.getOperator();
// convert "WHERE startsWith(col, 'str')" to "WHERE startsWith(col, 'str') = true"
if (!EnumUtils.isValidEnum(FilterKind.class, functionOperator)) {
return FilterContext.forPredicate(
new EqPredicate(ExpressionContext.forFunction(getFunction(thriftFunction)), "true"));
}
FilterKind filterKind = FilterKind.valueOf(thriftFunction.getOperator().toUpperCase());
List<Expression> operands = thriftFunction.getOperands();
int numOperands = operands.size();
switch (filterKind) {
case AND: {
List<FilterContext> children = new ArrayList<>(numOperands);
for (Expression operand : operands) {
FilterContext filter = getFilter(operand);
if (!filter.isConstant()) {
children.add(filter);
} else {
if (filter.isConstantFalse()) {
return FilterContext.CONSTANT_FALSE;
}
}
}
int numChildren = children.size();
if (numChildren == 0) {
return FilterContext.CONSTANT_TRUE;
} else if (numChildren == 1) {
return children.get(0);
} else {
return FilterContext.forAnd(children);
}
}
case OR: {
List<FilterContext> children = new ArrayList<>(numOperands);
for (Expression operand : operands) {
FilterContext filter = getFilter(operand);
if (!filter.isConstant()) {
children.add(filter);
} else {
if (filter.isConstantTrue()) {
return FilterContext.CONSTANT_TRUE;
}
}
}
int numChildren = children.size();
if (numChildren == 0) {
return FilterContext.CONSTANT_FALSE;
} else if (numChildren == 1) {
return children.get(0);
} else {
return FilterContext.forOr(children);
}
}
case NOT: {
assert numOperands == 1;
FilterContext filter = getFilter(operands.get(0));
if (!filter.isConstant()) {
return FilterContext.forNot(filter);
} else {
return filter.isConstantTrue() ? FilterContext.CONSTANT_FALSE : FilterContext.CONSTANT_TRUE;
}
}
case EQUALS:
return FilterContext.forPredicate(
new EqPredicate(getExpression(operands.get(0)), getStringValue(operands.get(1))));
case NOT_EQUALS:
return FilterContext.forPredicate(
new NotEqPredicate(getExpression(operands.get(0)), getStringValue(operands.get(1))));
case IN: {
List<String> values = new ArrayList<>(numOperands - 1);
for (int i = 1; i < numOperands; i++) {
values.add(getStringValue(operands.get(i)));
}
return FilterContext.forPredicate(new InPredicate(getExpression(operands.get(0)), values));
}
case NOT_IN: {
List<String> values = new ArrayList<>(numOperands - 1);
for (int i = 1; i < numOperands; i++) {
values.add(getStringValue(operands.get(i)));
}
return FilterContext.forPredicate(new NotInPredicate(getExpression(operands.get(0)), values));
}
case GREATER_THAN:
return FilterContext.forPredicate(
new RangePredicate(getExpression(operands.get(0)), false, getStringValue(operands.get(1)), false,
RangePredicate.UNBOUNDED, new LiteralContext(operands.get(1).getLiteral()).getType()));
case GREATER_THAN_OR_EQUAL:
return FilterContext.forPredicate(
new RangePredicate(getExpression(operands.get(0)), true, getStringValue(operands.get(1)), false,
RangePredicate.UNBOUNDED, new LiteralContext(operands.get(1).getLiteral()).getType()));
case LESS_THAN:
return FilterContext.forPredicate(
new RangePredicate(getExpression(operands.get(0)), false, RangePredicate.UNBOUNDED, false,
getStringValue(operands.get(1)), new LiteralContext(operands.get(1).getLiteral()).getType()));
case LESS_THAN_OR_EQUAL:
return FilterContext.forPredicate(
new RangePredicate(getExpression(operands.get(0)), false, RangePredicate.UNBOUNDED, true,
getStringValue(operands.get(1)), new LiteralContext(operands.get(1).getLiteral()).getType()));
case BETWEEN:
return FilterContext.forPredicate(
new RangePredicate(getExpression(operands.get(0)), true, getStringValue(operands.get(1)), true,
getStringValue(operands.get(2)), new LiteralContext(operands.get(1).getLiteral()).getType()));
case RANGE:
return FilterContext.forPredicate(
new RangePredicate(getExpression(operands.get(0)), getStringValue(operands.get(1))));
case REGEXP_LIKE:
return FilterContext.forPredicate(
new RegexpLikePredicate(getExpression(operands.get(0)), getStringValue(operands.get(1))));
case LIKE:
return FilterContext.forPredicate(new RegexpLikePredicate(getExpression(operands.get(0)),
RegexpPatternConverterUtils.likeToRegexpLike(getStringValue(operands.get(1)))));
case TEXT_CONTAINS:
return FilterContext.forPredicate(
new TextContainsPredicate(getExpression(operands.get(0)), getStringValue(operands.get(1))));
case TEXT_MATCH:
return FilterContext.forPredicate(
new TextMatchPredicate(getExpression(operands.get(0)), getStringValue(operands.get(1))));
case JSON_MATCH:
return FilterContext.forPredicate(
new JsonMatchPredicate(getExpression(operands.get(0)), getStringValue(operands.get(1)),
operands.size() == 3 ? getStringValue(operands.get(2)) : null));
case VECTOR_SIMILARITY:
ExpressionContext lhs = getExpression(operands.get(0));
float[] vectorValue = getVectorValue(operands.get(1));
int topK = VectorSimilarityPredicate.DEFAULT_TOP_K;
if (operands.size() == 3) {
topK = operands.get(2).getLiteral().getIntValue();
}
return FilterContext.forPredicate(new VectorSimilarityPredicate(lhs, vectorValue, topK));
case IS_NULL:
return FilterContext.forPredicate(new IsNullPredicate(getExpression(operands.get(0))));
case IS_NOT_NULL:
return FilterContext.forPredicate(new IsNotNullPredicate(getExpression(operands.get(0))));
default:
throw new IllegalStateException();
}
}