@ Nullable public static DimFilter toFilter ( final PlannerContext plannerContext , final DruidQuerySignature querySignature , final RexNode expression ) { final SqlKind kind = expression . getKind ( ) ; if ( kind == SqlKind . IS_TRUE || kind == SqlKind . IS_NOT_FALSE ) { return toFilter ( plannerContext , querySignature , Iterables . getOnlyElement ( ( ( RexCall ) expression ) . getOperands ( ) ) ) ; } else if ( kind == SqlKind . IS_FALSE || kind == SqlKind . IS_NOT_TRUE ) { return new NotDimFilter ( toFilter ( plannerContext , querySignature , Iterables . getOnlyElement ( ( ( RexCall ) expression ) . getOperands ( ) ) ) ) ; } else if ( kind == SqlKind . CAST && expression . getType ( ) . getSqlTypeName ( ) == SqlTypeName . BOOLEAN ) { // Calcite sometimes leaves errant, useless cast-to-booleans inside filters. Strip them and continue. return toFilter ( plannerContext , querySignature , Iterables . getOnlyElement ( ( ( RexCall ) expression ) . getOperands ( ) ) ) ; } else if ( kind == SqlKind . AND || kind == SqlKind . OR || kind == SqlKind . NOT ) { final List < DimFilter > filters = new ArrayList <> ( ) ; for ( final RexNode rexNode : ( ( RexCall ) expression ) . getOperands ( ) ) { final DimFilter nextFilter = toFilter ( plannerContext , querySignature , rexNode ) ; if ( nextFilter == null ) { return null ; } filters . add ( nextFilter ) ; } if ( kind == SqlKind . AND ) { return new AndDimFilter ( filters ) ; } else if ( kind == SqlKind . OR ) { return new OrDimFilter ( filters ) ; } else { assert kind == SqlKind . NOT ; return new NotDimFilter ( Iterables . getOnlyElement ( filters ) ) ; } } else { // Handle filter conditions on everything else. return toLeafFilter ( plannerContext , querySignature , expression ) ; } }
Translates condition to a Druid filter or returns null if we cannot translate the condition .