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;
}