Expr AddSubIntervalExpr()

in MySQL.Data/src/X/Protocol/X/ExprParser.cs [1053:1101]


    Expr AddSubIntervalExpr()
    {
      Expr lhs = AtomicExpr();
      while ((CurrentTokenTypeEquals(TokenType.PLUS) || CurrentTokenTypeEquals(TokenType.MINUS)) && NextTokenTypeEquals(TokenType.INTERVAL))
      {
        Token op = this.tokens[this.tokenPos];
        this.tokenPos++;
        Operator builder = new Operator();
        builder.Param.Add(lhs);

        // INTERVAL expression
        ConsumeToken(TokenType.INTERVAL);

        if (op.type == TokenType.PLUS)
        {
          builder.Name = "date_add";
        }
        else
        {
          builder.Name = "date_sub";
        }

        builder.Param.Add(BitExpr()); // amount

        // ensure next token is an interval unit
        if (CurrentTokenTypeEquals(TokenType.MICROSECOND) || CurrentTokenTypeEquals(TokenType.SECOND) || CurrentTokenTypeEquals(TokenType.MINUTE)
                || CurrentTokenTypeEquals(TokenType.HOUR) || CurrentTokenTypeEquals(TokenType.DAY) || CurrentTokenTypeEquals(TokenType.WEEK)
                || CurrentTokenTypeEquals(TokenType.MONTH) || CurrentTokenTypeEquals(TokenType.QUARTER) || CurrentTokenTypeEquals(TokenType.YEAR)
                || CurrentTokenTypeEquals(TokenType.SECOND_MICROSECOND) || CurrentTokenTypeEquals(TokenType.MINUTE_MICROSECOND)
                || CurrentTokenTypeEquals(TokenType.MINUTE_SECOND) || CurrentTokenTypeEquals(TokenType.HOUR_MICROSECOND)
                || CurrentTokenTypeEquals(TokenType.HOUR_SECOND) || CurrentTokenTypeEquals(TokenType.HOUR_MINUTE)
                || CurrentTokenTypeEquals(TokenType.DAY_MICROSECOND) || CurrentTokenTypeEquals(TokenType.DAY_SECOND)
                || CurrentTokenTypeEquals(TokenType.DAY_MINUTE) || CurrentTokenTypeEquals(TokenType.DAY_HOUR)
                || CurrentTokenTypeEquals(TokenType.YEAR_MONTH))
        {
        }
        else
        {
          throw new ArgumentException("Expected interval units at " + this.tokenPos);
        }
        // xplugin demands that intervals be sent uppercase
        // TODO: we need to propagate the appropriate encoding here? it's ascii but it might not *always* be a superset encoding??
        builder.Param.Add(ExprUtil.BuildLiteralScalar(Encoding.UTF8.GetBytes(this.tokens[this.tokenPos].value.ToUpperInvariant())));
        this.tokenPos++;

        lhs = new Expr() { Type = Expr.Types.Type.Operator, Operator = builder };
      }
      return lhs;
    }