@Override
 protected Query applyArrayReference(
     Reference arrayReference, Literal literal, Context context) throws IOException {
   QueryBuilderHelper builder =
       QueryBuilderHelper.forType(((CollectionType) arrayReference.valueType()).innerType());
   return builder.eq(arrayReference.ident().columnIdent().fqn(), literal.value());
 }
      @Override
      public Query apply(Function input, Context context) {
        Tuple<Reference, Literal> tuple = super.prepare(input);
        if (tuple == null) {
          return null;
        }
        Reference reference = tuple.v1();
        Literal literal = tuple.v2();
        String columnName = reference.info().ident().columnIdent().fqn();
        if (DataTypes.isCollectionType(reference.valueType())
            && DataTypes.isCollectionType(literal.valueType())) {

          // create boolean filter with term filters to pre-filter the result before applying the
          // functionQuery.
          BooleanFilter boolTermsFilter = new BooleanFilter();
          DataType type = literal.valueType();
          while (DataTypes.isCollectionType(type)) {
            type = ((CollectionType) type).innerType();
          }
          QueryBuilderHelper builder = QueryBuilderHelper.forType(type);
          Object value = literal.value();
          buildTermsQuery(boolTermsFilter, value, columnName, builder);

          if (boolTermsFilter.clauses().isEmpty()) {
            // all values are null...
            return genericFunctionQuery(input, context);
          }

          // wrap boolTermsFilter and genericFunction filter in an additional BooleanFilter to
          // control the ordering of the filters
          // termsFilter is applied first
          // afterwards the more expensive genericFunctionFilter
          BooleanFilter filterClauses = new BooleanFilter();
          filterClauses.add(boolTermsFilter, BooleanClause.Occur.MUST);
          filterClauses.add(genericFunctionFilter(input, context), BooleanClause.Occur.MUST);
          return new FilteredQuery(Queries.newMatchAllQuery(), filterClauses);
        }
        QueryBuilderHelper builder = QueryBuilderHelper.forType(tuple.v1().valueType());
        return builder.eq(columnName, tuple.v2().value());
      }