Class PostPreProcessFilterSplittingVisitor

  • All Implemented Interfaces:
    ExpressionVisitor, FilterVisitor
    Direct Known Subclasses:
    ComplexFilterSplitter, JsonPointerFilterSplittingVisitor, MongoFilterSplitter, VectorMosaicPostPreFilterSplitter

    public class PostPreProcessFilterSplittingVisitor
    extends Object
    implements FilterVisitor, ExpressionVisitor
    Determines what queries can be processed server side and which can be processed client side.

    IMPLEMENTATION NOTE: This class is implemented as a stack processor. If you're curious how it works, compare it with the old SQLUnpacker class, which did the same thing using recursion in a more straightforward way.

    Here's a non-implementors best-guess at the algorithm: Starting at the top of the filter, split each filter into its constituent parts. If the given FilterCapabilities support the given operator, then keep checking downwards.

    The key is in knowing whether or not something "down the tree" from you wound up being supported or not. This is where the stacks come in. Right before handing off to accept() the sub- filters, we count how many things are currently on the "can be proccessed by the underlying datastore" stack (the preStack) and we count how many things are currently on the "need to be post- processed" stack.

    After the accept() call returns, we look again at the preStack.size() and postStack.size(). If the postStack has grown, that means that there was stuff down in the accept()-ed filter that wasn't supportable. Usually this means that our filter isn't supportable, but not always.

    In some cases a sub-filter being unsupported isn't necessarily bad, as we can 'unpack' OR statements into AND statements (DeMorgans rule/modus poens) and still see if we can handle the other side of the OR. Same with NOT and certain kinds of AND statements.

    In addition this class supports the case where we're doing an split in the middle of a client-side transaction. I.e. imagine doing a against a WFS-T where you have to filter against actions that happened previously in the transaction. That's what the ClientTransactionAccessor interface does, and this class splits filters while respecting the information about deletes and updates that have happened previously in the Transaction. I can't say with certainty exactly how the logic for that part of this works, but the test suite does seem to test it and the tests do pass.

    dzwiers, commented and ported from gt to ogc filters by saul.farber TODO: check if possible to deprecate @ deprecated use CapabilitiesFilterSplitter instead for geoapi FilterCapabilities