@Override protected Query applyArrayLiteral(Reference reference, Literal arrayLiteral, Context context) throws IOException { // col != ANY ([1,2,3]) --> not(col=1 and col=2 and col=3) String columnName = reference.info().ident().columnIdent().fqn(); QueryBuilderHelper builder = QueryBuilderHelper.forType(reference.valueType()); BooleanFilter filter = new BooleanFilter(); BooleanFilter notFilter = new BooleanFilter(); for (Object value : toIterable(arrayLiteral.value())) { notFilter.add(builder.eqFilter(columnName, value), BooleanClause.Occur.MUST); } filter.add(notFilter, BooleanClause.Occur.MUST_NOT); return new FilteredQuery(Queries.newMatchAllQuery(), filter); }
@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()); }
private void buildTermsQuery( BooleanFilter booleanFilter, Object value, String columnName, QueryBuilderHelper builder) { if (value == null) { return; } if (value.getClass().isArray()) { Object[] array = (Object[]) value; for (Object o : array) { buildTermsQuery(booleanFilter, o, columnName, builder); } } else { booleanFilter.add(builder.eqFilter(columnName, value), BooleanClause.Occur.MUST); } }
@Override public Query apply(Function input, Context context) { assert input != null; assert input.arguments().size() == 1; Symbol arg = input.arguments().get(0); if (arg.symbolType() != SymbolType.REFERENCE) { return null; } Reference reference = (Reference) arg; String columnName = reference.info().ident().columnIdent().fqn(); QueryBuilderHelper builderHelper = QueryBuilderHelper.forType(reference.valueType()); BooleanFilter boolFilter = new BooleanFilter(); boolFilter.add( builderHelper.rangeFilter(columnName, null, null, true, true), BooleanClause.Occur.MUST_NOT); return new FilteredQuery(Queries.newMatchAllQuery(), boolFilter); }