示例#1
0
 public Filter group(Filter filter) {
   if (filter instanceof FilterList) {
     FilterList fList = (FilterList) filter;
     // We need to create a new FL here taking up only the filters of our interest
     FilterList newFList = new FilterList(fList.getOperator());
     List<Filter> filters = fList.getFilters();
     if (fList.getOperator() == Operator.MUST_PASS_ONE) {
       for (Filter subFilter : filters) {
         Filter resultFilter = handleFilterWithinOR(subFilter);
         // If result filter is not SingleColumnValueFilter or filter list that means OR branch is
         // having different type of filter other than SCVF. In that case we should not consider
         // the OR branch for scanning.
         if (resultFilter instanceof FilterList) {
           newFList.addFilter(resultFilter);
         } else if (resultFilter != null) {
           // This means OR filter list have at least one filter other than SCVF(may be other
           // child OR branches).
           return null;
         }
       }
       addORColsToFinalList(newFList);
       if (newFList.getFilters().isEmpty()) {
         return null;
       }
       return newFList;
     } else {
       // AND condition as long as the condition is AND in one sub tree all those can be
       // grouped under one AND parent(new one).
       for (Filter subFilter : filters) {
         Filter group = handleFilterWithinAND(subFilter);
         // group is null means, all are AND conditions and will be handled at once with the
         // below createFinalFilter
         if (group != null) {
           newFList.addFilter(group);
         }
       }
       addANDColsToFinalList(newFList);
       if (newFList.getFilters().isEmpty()) {
         return null;
       }
       return newFList;
     }
   } else if (filter instanceof SingleColumnValueFilter
       || filter instanceof SingleColumnRangeFilter) {
     return filter;
   }
   return null;
 }
示例#2
0
 /**
  * Since you can use Filter Lists as children of Filter Lists, you can create a hierarchy of
  * filters to be evaluated. In the hierarchy if OR branch having any filter type other than SCVF
  * as child then we should not consider the branch for scanning because we cannot fetch seek
  * points from other type of filters without column and value details. Ex: AND AND
  * __________|_______ | | | --> SCVF OR SCVF _______|______ | | ROWFILTER SVCF If the OR is root
  * then we should skip index table scanning for this filter. OR _______|______ --> null | |
  * ROWFILTER SVCF If the OR is child of another OR branch then parent OR branch will be excluded
  * for scanning. Ex: AND AND __________|_______ | | | --> SCVF OR SCVF _______|______ | | OR SVCF
  * _______|______ | | ROWFILTER SVCF
  *
  * @param filter
  * @return if filter is filter list with AND condition then we will return AND branch after
  *     grouping. if filter is filter list with OR condition return null if no children is of type
  *     other than SCVF or filter list else return different filter. if filter is SCVF then return
  *     null. returning null means we are combining the filter(s) with children of parent OR filter
  *     to perform optimizations.
  */
 private Filter handleFilterWithinOR(Filter filter) {
   if (filter instanceof FilterList) {
     FilterList fList = (FilterList) filter;
     if (fList.getOperator() == Operator.MUST_PASS_ONE) {
       List<Filter> filters = fList.getFilters();
       Filter resultFilter = null;
       for (Filter subFilter : filters) {
         // If this OR branch in the filter list have filter type other than SCVF we should report
         // it to parent by returning the other type of filter in such a way that the branch will
         // be skipped from index scan.
         resultFilter = handleFilterWithinOR(subFilter);
         if (resultFilter == null || (resultFilter instanceof FilterList)) {
           continue;
         } else {
           return resultFilter;
         }
       }
       return null;
     } else {
       return new FilterGroupingWorker().group(fList);
     }
   } else if (filter instanceof SingleColumnValueFilter) {
     handleScvfOfOR((SingleColumnValueFilter) filter);
     return null;
   } // TODO when we expose SingleColumnRangeFilter to handle that also here.
   // filter other than SingleColumnValueFilter.
   return filter;
 }
示例#3
0
  @Test
  public void testParsedFilter() {
    String q1 = "@cluster = \"cluster1\" and @datacenter = \"dc1\" and @field3 = 100000";
    try {
      FilterList filterList = (FilterList) buildFilter(q1);
      Assert.assertEquals(FilterList.Operator.MUST_PASS_ONE, filterList.getOperator());
      Assert.assertEquals(1, filterList.getFilters().size());
      Assert.assertEquals(2, ((FilterList) filterList.getFilters().get(0)).getFilters().size());
    } catch (EagleQueryParseException e) {
      Assert.fail(e.getMessage());
    }

    String q2 =
        "@cluster = \"cluster1\" and @datacenter = \"dc1\" and ( @field3 = 100000 or @field3 < 100000)";
    try {
      FilterList filterList = (FilterList) buildFilter(q2);
      Assert.assertEquals(FilterList.Operator.MUST_PASS_ONE, filterList.getOperator());
      Assert.assertEquals(2, filterList.getFilters().size());
      Assert.assertEquals(2, ((FilterList) filterList.getFilters().get(0)).getFilters().size());
    } catch (EagleQueryParseException e) {
      Assert.fail(e.getMessage());
    }

    // Test parse success but bad type of value
    String q3 =
        "@cluster = \"cluster1\" and @datacenter = \"dc1\" and ( @field3 = 100000 or @field3 < \"bad_int_100000\")";
    boolean q3Ex = false;
    try {
      Assert.assertNull(buildFilter(q3));
    } catch (EagleQueryParseException e) {
      Assert.fail(e.getMessage());
    } catch (IllegalArgumentException e) {
      LOG.debug("Expect: ", e);
      Assert.assertTrue(e.getCause() instanceof NumberFormatException);
      q3Ex = true;
    }
    Assert.assertTrue(q3Ex);
  }
示例#4
0
 private Filter handleFilterWithinAND(Filter filter) {
   if (filter instanceof FilterList) {
     FilterList fList = (FilterList) filter;
     if (fList.getOperator() == Operator.MUST_PASS_ONE) {
       return new FilterGroupingWorker().group(fList);
     } else {
       List<Filter> filters = fList.getFilters();
       for (Filter subFilter : filters) {
         handleFilterWithinAND(subFilter);
       }
     }
   } else if (filter instanceof SingleColumnValueFilter) {
     handleScvf((SingleColumnValueFilter) filter);
   } // TODO when we expose SingleColumnRangeFilter to handle that also here.
   return null;
 }
  /**
   * Process a {@link org.plasma.query.model.LogicalOperator logical operator} query traversal start
   * event. If the {@link FilterList filter list} on the top of the filter stack is not an 'OR'
   * filter, since it's immutable and we cannot modify its operator, create an 'OR' filter and swaps
   * out the existing filters into the new 'OR' {@link FilterList filter list}.
   */
  public void start(LogicalOperator operator) {

    switch (operator.getValue()) {
      case AND:
        break; // default filter list oper is must-pass-all (AND)
      case OR:
        FilterList top = this.filterStack.peek();
        if (top.getOperator().ordinal() != FilterList.Operator.MUST_PASS_ONE.ordinal()) {
          FilterList orList = new FilterList(FilterList.Operator.MUST_PASS_ONE);
          for (Filter filter : top.getFilters()) orList.addFilter(filter);
          top.getFilters().clear();
          this.filterStack.pop();
          FilterList previous = this.filterStack.peek();
          if (!previous.getFilters().remove(top))
            throw new IllegalStateException("could not remove filter list");
          previous.addFilter(orList);
          this.filterStack.push(orList);
        }
        break;
    }
    super.start(operator);
  }