private static Filter genericFunctionFilter(Function function, Context context) { if (function.valueType() != DataTypes.BOOLEAN) { raiseUnsupported(function); } // avoid field-cache // reason1: analyzed columns or columns with index off wouldn't work // substr(n, 1, 1) in the case of n => analyzed would throw an error because n would be an // array // reason2: would have to load each value into the field cache function = (Function) DocReferenceConverter.convertIf(function); final CollectInputSymbolVisitor.Context ctx = context.inputSymbolVisitor.extractImplementations(function); assert ctx.topLevelInputs().size() == 1; @SuppressWarnings("unchecked") final Input<Boolean> condition = (Input<Boolean>) ctx.topLevelInputs().get(0); @SuppressWarnings("unchecked") final List<LuceneCollectorExpression> expressions = ctx.docLevelExpressions(); final CollectorContext collectorContext = new CollectorContext( context.mapperService, context.fieldDataService, new CollectorFieldsVisitor(expressions.size())); for (LuceneCollectorExpression expression : expressions) { expression.startCollect(collectorContext); } return new Filter() { @Override public DocIdSet getDocIdSet(AtomicReaderContext context, Bits acceptDocs) throws IOException { for (LuceneCollectorExpression expression : expressions) { expression.setNextReader(context.reader().getContext()); } return BitsFilteredDocIdSet.wrap( new FunctionDocSet( context.reader(), collectorContext.visitor(), condition, expressions, context.reader().maxDoc(), acceptDocs), acceptDocs); } }; }
@Override protected boolean matchDoc(int doc) { if (fieldsVisitorEnabled) { fieldsVisitor.reset(); try { reader.document(doc, fieldsVisitor); } catch (IOException e) { throw Throwables.propagate(e); } } for (LuceneCollectorExpression expression : expressions) { expression.setNextDocId(doc); } Boolean value = condition.value(); if (value == null) { return false; } return value; }