示例#1
0
    private void handleFilter(FilterTuple filterTuple, FilterExpr expr) {

      /*
       * CompareEQ expressions are inserted as bindings if possible
       *
       * if the filtertuple contains all vars of the filterexpr, we
       * can evaluate the filter expr safely on the filterTuple
       *
       * if there is no intersection of variables, the filter is
       * irrelevant for this expr
       *
       * if there is some intersection, we cannot remove the filter
       * and have to keep it in the query plan for postfiltering
       */
      int intersected = 0;
      for (String filterVar : expr.getVars()) {
        if (filterTuple.getFreeVars().contains(filterVar)) intersected++;
      }

      // filter expression is irrelevant
      if (intersected == 0) return;

      // push eq comparison into stmt as bindings
      if (expr.isCompareEq()) {

        if (handleCompare(filterTuple, (Compare) expr.getExpression())) return;
      }

      // filter contains all variables => push filter
      if (intersected == expr.getVars().size()) filterTuple.addFilterExpr(expr);

      // filter is still needed for post filtering
      else {
        canRemove = false;
      }
    }
示例#2
0
  @Override
  public void meet(Filter filter) {

    if (filter.getArg() instanceof EmptyResult) {
      log.debug(
          "Argument of filter expression does not yield results at the provided sources, replacing Filter node.");
      filter.replaceWith(filter.getArg());
      return;
    }

    /*
     * TODO idea:
     * if we have a FILTER such as ?s='a' OR ?s='b' OR ?s='c' handle this appropriately
     */

    ValueExpr valueExpr = filter.getCondition();

    /*
     * TODO transform condition into some normal form, e.g. CNF
     */

    // determine conjunctive expressions
    List<ValueExpr> conjunctiveExpressions = new ArrayList<ValueExpr>();
    getConjunctiveExpressions(valueExpr, conjunctiveExpressions);

    FilterExprInsertVisitor filterExprVst = new FilterExprInsertVisitor();
    List<ValueExpr> remainingExpr = new ArrayList<ValueExpr>(conjunctiveExpressions.size());

    for (ValueExpr cond : conjunctiveExpressions) {

      /*
       * Determine if this filter is applicable for optimization.
       * Currently only leaf expressions are applicable, i.e.
       * not combined expressions.
       */
      if (isCompatibleExpr(cond)) {

        HashSet<String> exprVars = new VarFinder().findVars(cond);
        FilterExpr filterExpr = new FilterExpr(cond, exprVars);

        filterExprVst.initialize(filterExpr);
        filter.getArg().visit(filterExprVst);

        // if the filter expr. is handled in the stmt we do not have to keep it
        if (filterExprVst.canRemove()) continue;

        remainingExpr.add(filterExpr.getExpression());

      } else {
        remainingExpr.add(cond);
      }
    }

    if (remainingExpr.size() == 0) {
      filter.replaceWith(filter.getArg()); // remove the filter	
    } else if (remainingExpr.size() == 1) {
      filter.setCondition(remainingExpr.get(0)); // just apply the remaining condition
    } else {

      // construct conjunctive value expr
      And root = new And();
      root.setLeftArg(remainingExpr.get(0));
      And tmp = root;
      for (int i = 1; i < remainingExpr.size() - 1; i++) {
        And _a = new And();
        _a.setLeftArg(remainingExpr.get(i));
        tmp.setRightArg(_a);
        tmp = _a;
      }
      tmp.setRightArg(remainingExpr.get(remainingExpr.size() - 1));

      filter.setCondition(root);
    }
  }