@Override
  public void visit(Function function) {
    // all aggregate functions (SUM, AVG, COUNT, MAX, MIN) have only one parameter (Expression)
    // although COUNT(*) has no parameters
    // EXTRACT_YEAR has one parameter
    // if you change this method, NameProjectVisitor.visit(Function) has to be changed as well
    ExpressionList params = function.getParameters();
    int numParams = 0;
    if (params != null) {
      params.accept(this);

      // in order to determine the size
      List<Expression> listParams = params.getExpressions();
      numParams = listParams.size();
    }
    List<ValueExpression> expressions = new ArrayList<ValueExpression>();
    for (int i = 0; i < numParams; i++) {
      expressions.add(_exprStack.pop());
    }
    Collections.reverse(expressions); // at the stack top is the lastly added VE

    String fnName = function.getName();
    if (fnName.equalsIgnoreCase("EXTRACT_YEAR")) {
      if (numParams != 1) {
        throw new RuntimeException("EXTRACT_YEAR function has exactly one parameter!");
      }
      ValueExpression expr = expressions.get(0);
      ValueExpression ve = new IntegerYearFromDate(expr);
      _exprStack.push(ve);
    }
  }
 @Override
 public void visit(Function function) {
   // all aggregate functions (SUM, AVG, COUNT, MAX, MIN) have only one parameter (Expression)
   // although COUNT(*) has no parameters
   // EXTRACT_YEAR has one parameter
   ExpressionList params = function.getParameters();
   if (params != null) {
     List<Expression> listParams = params.getExpressions();
     for (Expression param : listParams) {
       param.accept(this);
     }
   }
 }
  // my VISITOR methods
  @Override
  public void visit(Function function) {
    // all aggregate functions (SUM, AVG, COUNT, MAX, MIN) have only one parameter (Expression)
    // although COUNT(*) has no parameters
    // EXTRACT_YEAR has one parameter
    ExpressionList params = function.getParameters();
    int numParams = 0;
    if (params != null) {
      List<Expression> listParams = params.getExpressions();
      numParams = listParams.size();
      for (Expression param : listParams) {
        param.accept(this);
      }
    }
    List<ValueExpression> expressions = new ArrayList<ValueExpression>();
    for (int i = 0; i < numParams; i++) {
      expressions.add(_exprStack.pop());
    }

    String fnName = function.getName();
    if (fnName.equalsIgnoreCase("SUM")) {
      // there must be only one parameter, if not SQL parser will raise an exception
      ValueExpression expr = expressions.get(0);
      NumericConversion numConv = (NumericConversion) expr.getType();
      _agg = new AggregateSumOperator(numConv, expr, _map);

      // DISTINCT and agg are stored on the same component.
      if (function.isDistinct()) {
        DistinctOperator distinct = new DistinctOperator(_map, expressions);
        _agg.setDistinct(distinct);
      }
    } else if (fnName.equalsIgnoreCase("COUNT")) {
      // COUNT(R.A) and COUNT(1) have the same semantics as COUNT(*), since we do not have NULLs in
      // R.A
      _agg = new AggregateCountOperator(_map);

      // DISTINCT and agg are stored on the same component.
      if (function.isDistinct()) {
        DistinctOperator distinct = new DistinctOperator(_map, expressions);
        _agg.setDistinct(distinct);
      }
    } else if (fnName.equalsIgnoreCase("EXTRACT_YEAR")) {
      if (numParams != 1) {
        throw new RuntimeException("EXTRACT_YEAR function has exactly one parameter!");
      }
      ValueExpression expr = expressions.get(0);
      ValueExpression ve = new IntegerYearFromDate(expr);
      _exprStack.push(ve);
    }
  }
Beispiel #4
0
  /**
   * Recursive methods to create a {@link Function} starting from a {@link BinaryExpression} We
   * consider all possible values of the left and right expressions
   *
   * @param pred
   * @param lookupTable
   * @return
   */
  private Function getFunction(Expression pred, LookupTable lookupTable) {
    if (pred instanceof BinaryExpression) {
      return getFunction((BinaryExpression) pred, lookupTable);
    } else if (pred instanceof IsNullExpression) {
      return getFunction((IsNullExpression) pred, lookupTable);
    } else if (pred instanceof Parenthesis) {
      Expression inside = ((Parenthesis) pred).getExpression();
      return getFunction(inside, lookupTable);
    } else if (pred instanceof Between) {
      Between between = (Between) pred;
      Expression left = between.getLeftExpression();
      Expression e1 = between.getBetweenExpressionStart();
      Expression e2 = between.getBetweenExpressionEnd();

      GreaterThanEquals gte = new GreaterThanEquals();
      gte.setLeftExpression(left);
      gte.setRightExpression(e1);

      MinorThanEquals mte = new MinorThanEquals();
      mte.setLeftExpression(left);
      mte.setRightExpression(e2);

      AndExpression ande = new AndExpression(gte, mte);
      return getFunction(ande, lookupTable);
    } else if (pred instanceof InExpression) {
      InExpression inExpr = (InExpression) pred;
      Expression left = inExpr.getLeftExpression();
      ExpressionList ilist = (ExpressionList) inExpr.getRightItemsList();

      List<EqualsTo> eqList = new ArrayList<EqualsTo>();
      for (Expression item : ilist.getExpressions()) {
        EqualsTo eq = new EqualsTo();
        eq.setLeftExpression(left);
        eq.setRightExpression(item);
        eqList.add(eq);
      }
      int size = eqList.size();
      if (size > 1) {
        OrExpression or = new OrExpression(eqList.get(size - 1), eqList.get(size - 2));
        for (int i = size - 3; i >= 0; i--) {
          OrExpression orexpr = new OrExpression(eqList.get(i), or);
          or = orexpr;
        }
        return getFunction(or, lookupTable);
      } else {
        return getFunction(eqList.get(0), lookupTable);
      }
    } else return null;
  }
 @Override
 public void visit(ExpressionList el) {
   for (Iterator iter = el.getExpressions().iterator(); iter.hasNext(); ) {
     Expression expression = (Expression) iter.next();
     expression.accept(this);
   }
 }
  @Override
  public void visit(Function function) {
    boolean recognized = isRecognized(function);
    if (!recognized) {
      // try to extract SUM
      // parameters for COUNT are ignored, as explained in super
      final String fnName = function.getName();
      if (fnName.equalsIgnoreCase("SUM")) {
        recognized = isRecognized(function.getParameters());
        if (recognized) {
          final ValueExpression expr = popFromExprStack();
          createSum(expr, function.isDistinct());
        }
      } else if (fnName.equalsIgnoreCase("COUNT")) {
        final List<ValueExpression> expressions = new ArrayList<ValueExpression>();

        if (function.isDistinct()) {
          // putting something on stack only if isDistinct is set to
          // true
          recognized = isRecognized(function.getParameters());
          // it might happen that we put on stack something we don't
          // use
          // this is the case only when some exprs are recognized and
          // the others not
          if (recognized) {

            // create a list of expressions
            int numParams = 0;
            final ExpressionList params = function.getParameters();
            if (params != null) numParams = params.getExpressions().size();

            for (int i = 0; i < numParams; i++) expressions.add(popFromExprStack());
          }
        } else recognized = true;
        if (recognized)
          // finally, create CountAgg out of expressions (empty if
          // nonDistinct)
          createCount(expressions, function.isDistinct());
      }
    }
    if (!recognized)
      // normal call to parent
      super.visit(function);
  }
  /*
   * Has to be separate because ExpressionList does not extend Expression
   */
  private boolean isRecognized(ExpressionList params) {
    if (params == null) return true;

    final List<Expression> exprs = params.getExpressions();
    if (exprs == null || exprs.isEmpty()) return true;

    // if any of the children is not recognized, we have to go to super
    // if some of exprs are recognized and some not, we will have some extra
    // elements on stack
    for (final Expression expr : exprs) if (!isRecognized(expr)) return false;

    // all exprs recognized
    return true;
  }
Beispiel #8
0
 public void visit(ExpressionList expressionList) throws Exception {
   for (Iterator iter = expressionList.getExpressions().iterator(); iter.hasNext(); ) {
     Expression expression = (Expression) iter.next();
     expression.accept(this);
   }
 }