public static FilterContext getFilter()

in pinot-common/src/main/java/org/apache/pinot/common/request/context/RequestContextUtils.java [295:424]


  public static FilterContext getFilter(FunctionContext filterFunction) {
    String functionOperator = filterFunction.getFunctionName().toUpperCase();

    // convert "WHERE startsWith(col, 'str')" to "WHERE startsWith(col, 'str') = true"
    if (!EnumUtils.isValidEnum(FilterKind.class, functionOperator)) {
      return FilterContext.forPredicate(new EqPredicate(ExpressionContext.forFunction(filterFunction), "true"));
    }

    FilterKind filterKind = FilterKind.valueOf(filterFunction.getFunctionName().toUpperCase());
    List<ExpressionContext> operands = filterFunction.getArguments();
    int numOperands = operands.size();
    switch (filterKind) {
      case AND: {
        List<FilterContext> children = new ArrayList<>(numOperands);
        for (ExpressionContext 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 (ExpressionContext 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(operands.get(0), getStringValue(operands.get(1))));
      case NOT_EQUALS:
        return FilterContext.forPredicate(new NotEqPredicate(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(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(operands.get(0), values));
      }
      case GREATER_THAN:
        return FilterContext.forPredicate(
            new RangePredicate(operands.get(0), false, getStringValue(operands.get(1)), false, RangePredicate.UNBOUNDED,
                operands.get(1).getLiteral().getType()));
      case GREATER_THAN_OR_EQUAL:
        return FilterContext.forPredicate(
            new RangePredicate(operands.get(0), true, getStringValue(operands.get(1)), false, RangePredicate.UNBOUNDED,
                operands.get(1).getLiteral().getType()));
      case LESS_THAN:
        return FilterContext.forPredicate(
            new RangePredicate(operands.get(0), false, RangePredicate.UNBOUNDED, false, getStringValue(operands.get(1)),
                operands.get(1).getLiteral().getType()));
      case LESS_THAN_OR_EQUAL:
        return FilterContext.forPredicate(
            new RangePredicate(operands.get(0), false, RangePredicate.UNBOUNDED, true, getStringValue(operands.get(1)),
                operands.get(1).getLiteral().getType()));
      case BETWEEN:
        return FilterContext.forPredicate(
            new RangePredicate(operands.get(0), true, getStringValue(operands.get(1)), true,
                getStringValue(operands.get(2)), operands.get(1).getLiteral().getType()));
      case RANGE:
        return FilterContext.forPredicate(new RangePredicate(operands.get(0), getStringValue(operands.get(1))));
      case REGEXP_LIKE:
        return FilterContext.forPredicate(new RegexpLikePredicate(operands.get(0), getStringValue(operands.get(1))));
      case LIKE:
        return FilterContext.forPredicate(new RegexpLikePredicate(operands.get(0),
            RegexpPatternConverterUtils.likeToRegexpLike(getStringValue(operands.get(1)))));
      case TEXT_CONTAINS:
        return FilterContext.forPredicate(new TextContainsPredicate(operands.get(0), getStringValue(operands.get(1))));
      case TEXT_MATCH:
        return FilterContext.forPredicate(new TextMatchPredicate(operands.get(0), getStringValue(operands.get(1))));
      case JSON_MATCH:
          return FilterContext.forPredicate(new JsonMatchPredicate(operands.get(0), getStringValue(operands.get(1)),
                  operands.size() == 3?getStringValue(operands.get(2)): null));
      case VECTOR_SIMILARITY:
        int topK = VectorSimilarityPredicate.DEFAULT_TOP_K;
        if (operands.size() == 3) {
          topK = (int) operands.get(2).getLiteral().getLongValue();
        }
        return FilterContext.forPredicate(
            new VectorSimilarityPredicate(operands.get(0), getVectorValue(operands.get(1)), topK));
      case IS_NULL:
        return FilterContext.forPredicate(new IsNullPredicate(operands.get(0)));
      case IS_NOT_NULL:
        return FilterContext.forPredicate(new IsNotNullPredicate(operands.get(0)));
      default:
        throw new IllegalStateException();
    }
  }