use of com.alibaba.cobar.parser.ast.expression.arithmeic.ArithmeticModExpression in project cobar by alibaba.
the class MySQLExprParser method primaryExpression.
private Expression primaryExpression(final String consumed, String consumedUp) throws SQLSyntaxErrorException {
if (consumed != null) {
return startedFromIdentifier(consumed, consumedUp);
}
String tempStr;
String tempStrUp;
StringBuilder tempSb;
Number tempNum;
Expression tempExpr;
Expression tempExpr2;
List<Expression> tempExprList;
switch(lexer.token()) {
case PLACE_HOLDER:
tempStr = lexer.stringValue();
tempStrUp = lexer.stringValueUppercase();
lexer.nextToken();
return createPlaceHolder(tempStr, tempStrUp);
case LITERAL_BIT:
tempStr = lexer.stringValue();
lexer.nextToken();
return new LiteralBitField(null, tempStr).setCacheEvalRst(cacheEvalRst);
case LITERAL_HEX:
LiteralHexadecimal hex = new LiteralHexadecimal(null, lexer.getSQL(), lexer.getOffsetCache(), lexer.getSizeCache(), charset);
lexer.nextToken();
return hex.setCacheEvalRst(cacheEvalRst);
case LITERAL_BOOL_FALSE:
lexer.nextToken();
return new LiteralBoolean(false).setCacheEvalRst(cacheEvalRst);
case LITERAL_BOOL_TRUE:
lexer.nextToken();
return new LiteralBoolean(true).setCacheEvalRst(cacheEvalRst);
case LITERAL_NULL:
lexer.nextToken();
return new LiteralNull().setCacheEvalRst(cacheEvalRst);
case LITERAL_NCHARS:
tempSb = new StringBuilder();
do {
lexer.appendStringContent(tempSb);
} while (lexer.nextToken() == LITERAL_CHARS);
return new LiteralString(null, tempSb.toString(), true).setCacheEvalRst(cacheEvalRst);
case LITERAL_CHARS:
tempSb = new StringBuilder();
do {
lexer.appendStringContent(tempSb);
} while (lexer.nextToken() == LITERAL_CHARS);
return new LiteralString(null, tempSb.toString(), false).setCacheEvalRst(cacheEvalRst);
case LITERAL_NUM_PURE_DIGIT:
tempNum = lexer.integerValue();
lexer.nextToken();
return new LiteralNumber(tempNum).setCacheEvalRst(cacheEvalRst);
case LITERAL_NUM_MIX_DIGIT:
tempNum = lexer.decimalValue();
lexer.nextToken();
return new LiteralNumber(tempNum).setCacheEvalRst(cacheEvalRst);
case QUESTION_MARK:
int index = lexer.paramIndex();
lexer.nextToken();
return createParam(index);
case KW_CASE:
lexer.nextToken();
return caseWhenExpression();
case KW_INTERVAL:
lexer.nextToken();
return intervalExpression();
case KW_EXISTS:
lexer.nextToken();
match(PUNC_LEFT_PAREN);
tempExpr = subQuery();
match(PUNC_RIGHT_PAREN);
return new ExistsPrimary((QueryExpression) tempExpr).setCacheEvalRst(cacheEvalRst);
case USR_VAR:
tempStr = lexer.stringValue();
tempExpr = new UsrDefVarPrimary(tempStr).setCacheEvalRst(cacheEvalRst);
if (lexer.nextToken() == OP_ASSIGN) {
lexer.nextToken();
tempExpr2 = expression();
return new AssignmentExpression(tempExpr, tempExpr2);
}
return tempExpr;
case SYS_VAR:
return systemVariale();
case KW_MATCH:
lexer.nextToken();
return matchExpression();
case PUNC_LEFT_PAREN:
lexer.nextToken();
if (lexer.token() == KW_SELECT) {
tempExpr = subQuery();
match(PUNC_RIGHT_PAREN);
return tempExpr;
}
tempExpr = expression();
switch(lexer.token()) {
case PUNC_RIGHT_PAREN:
lexer.nextToken();
return tempExpr;
case PUNC_COMMA:
lexer.nextToken();
tempExprList = new LinkedList<Expression>();
tempExprList.add(tempExpr);
tempExprList = expressionList(tempExprList);
return new RowExpression(tempExprList).setCacheEvalRst(cacheEvalRst);
default:
throw err("unexpected token: " + lexer.token());
}
case KW_UTC_DATE:
lexer.nextToken();
if (lexer.token() == PUNC_LEFT_PAREN) {
lexer.nextToken();
match(PUNC_RIGHT_PAREN);
}
return new UtcDate(null).setCacheEvalRst(cacheEvalRst);
case KW_UTC_TIME:
lexer.nextToken();
if (lexer.token() == PUNC_LEFT_PAREN) {
lexer.nextToken();
match(PUNC_RIGHT_PAREN);
}
return new UtcTime(null).setCacheEvalRst(cacheEvalRst);
case KW_UTC_TIMESTAMP:
lexer.nextToken();
if (lexer.token() == PUNC_LEFT_PAREN) {
lexer.nextToken();
match(PUNC_RIGHT_PAREN);
}
return new UtcTimestamp(null).setCacheEvalRst(cacheEvalRst);
case KW_CURRENT_DATE:
lexer.nextToken();
if (lexer.token() == PUNC_LEFT_PAREN) {
lexer.nextToken();
match(PUNC_RIGHT_PAREN);
}
return new Curdate().setCacheEvalRst(cacheEvalRst);
case KW_CURRENT_TIME:
lexer.nextToken();
if (lexer.token() == PUNC_LEFT_PAREN) {
lexer.nextToken();
match(PUNC_RIGHT_PAREN);
}
return new Curtime().setCacheEvalRst(cacheEvalRst);
case KW_CURRENT_TIMESTAMP:
case KW_LOCALTIME:
case KW_LOCALTIMESTAMP:
lexer.nextToken();
if (lexer.token() == PUNC_LEFT_PAREN) {
lexer.nextToken();
match(PUNC_RIGHT_PAREN);
}
return new Now().setCacheEvalRst(cacheEvalRst);
case KW_CURRENT_USER:
lexer.nextToken();
if (lexer.token() == PUNC_LEFT_PAREN) {
lexer.nextToken();
match(PUNC_RIGHT_PAREN);
}
return new CurrentUser().setCacheEvalRst(cacheEvalRst);
case KW_DEFAULT:
if (lexer.nextToken() == PUNC_LEFT_PAREN) {
return ordinaryFunction(lexer.stringValue(), lexer.stringValueUppercase());
}
return new DefaultValue().setCacheEvalRst(cacheEvalRst);
case KW_DATABASE:
case KW_IF:
case KW_INSERT:
case KW_LEFT:
case KW_REPEAT:
case KW_REPLACE:
case KW_RIGHT:
case KW_SCHEMA:
case KW_VALUES:
tempStr = lexer.stringValue();
tempStrUp = lexer.stringValueUppercase();
String tempStrUp2 = MySQLToken.keyWordToString(lexer.token());
if (!tempStrUp2.equals(tempStrUp)) {
tempStrUp = tempStr = tempStrUp2;
}
if (lexer.nextToken() == PUNC_LEFT_PAREN) {
return ordinaryFunction(tempStr, tempStrUp);
}
throw err("keyword not followed by '(' is not expression: " + tempStr);
case KW_MOD:
lexer.nextToken();
match(PUNC_LEFT_PAREN);
tempExpr = expression();
match(PUNC_COMMA);
tempExpr2 = expression();
match(PUNC_RIGHT_PAREN);
return new ArithmeticModExpression(tempExpr, tempExpr2).setCacheEvalRst(cacheEvalRst);
case KW_CHAR:
lexer.nextToken();
match(PUNC_LEFT_PAREN);
return functionChar();
case KW_CONVERT:
lexer.nextToken();
match(PUNC_LEFT_PAREN);
return functionConvert();
case IDENTIFIER:
tempStr = lexer.stringValue();
tempStrUp = lexer.stringValueUppercase();
lexer.nextToken();
return startedFromIdentifier(tempStr, tempStrUp);
case OP_ASTERISK:
lexer.nextToken();
return new Wildcard(null).setCacheEvalRst(cacheEvalRst);
default:
throw err("unrecognized token as first token of primary: " + lexer.token());
}
}
use of com.alibaba.cobar.parser.ast.expression.arithmeic.ArithmeticModExpression in project cobar by alibaba.
the class MySQLExprParserTest method testArithmetic.
public void testArithmetic() throws Exception {
String sql = "? + @usrVar1 * c/@@version- e % -f diV g";
MySQLExprParser parser = new MySQLExprParser(new MySQLLexer(sql));
Expression expr = parser.expression();
String output = output2MySQL(expr, sql);
Assert.assertEquals("? + @usrVar1 * c / @@version - e % - f DIV g", output);
ArithmeticSubtractExpression sub = (ArithmeticSubtractExpression) expr;
ArithmeticAddExpression add = (ArithmeticAddExpression) sub.getLeftOprand();
ArithmeticIntegerDivideExpression idiv = (ArithmeticIntegerDivideExpression) sub.getRightOprand();
ArithmeticModExpression mod = (ArithmeticModExpression) idiv.getLeftOprand();
ArithmeticDivideExpression div = (ArithmeticDivideExpression) add.getRightOprand();
ArithmeticMultiplyExpression mt = (ArithmeticMultiplyExpression) div.getLeftOprand();
MinusExpression mi = (MinusExpression) mod.getRightOprand();
Assert.assertEquals("c", ((Identifier) mt.getRightOprand()).getIdText());
Assert.assertEquals("f", ((Identifier) mi.getOperand()).getIdText());
sql = "a+-b";
parser = new MySQLExprParser(new MySQLLexer(sql));
expr = parser.expression();
output = output2MySQL(expr, sql);
Assert.assertEquals("a + - b", output);
sql = "a+--b";
parser = new MySQLExprParser(new MySQLLexer(sql));
expr = parser.expression();
output = output2MySQL(expr, sql);
Assert.assertEquals("a + - - b", output);
sql = "a++b";
parser = new MySQLExprParser(new MySQLLexer(sql));
expr = parser.expression();
output = output2MySQL(expr, sql);
Assert.assertEquals("a + b", output);
sql = "a+++b";
parser = new MySQLExprParser(new MySQLLexer(sql));
expr = parser.expression();
output = output2MySQL(expr, sql);
Assert.assertEquals("a + b", output);
sql = "a++-b";
parser = new MySQLExprParser(new MySQLLexer(sql));
expr = parser.expression();
output = output2MySQL(expr, sql);
Assert.assertEquals("a + - b", output);
sql = "a + b mod (-((select id from t1 limit 1)- e) ) ";
parser = new MySQLExprParser(new MySQLLexer(sql));
expr = parser.expression();
output = output2MySQL(expr, sql);
Assert.assertEquals("a + b % - ((SELECT id FROM t1 LIMIT 0, 1) - e)", output);
add = (ArithmeticAddExpression) expr;
mod = (ArithmeticModExpression) add.getRightOprand();
mi = (MinusExpression) mod.getRightOprand();
sub = (ArithmeticSubtractExpression) mi.getOperand();
Assert.assertTrue(QueryExpression.class.isAssignableFrom(sub.getLeftOprand().getClass()));
Assert.assertEquals("e", ((Identifier) sub.getRightOprand()).getIdText());
}
use of com.alibaba.cobar.parser.ast.expression.arithmeic.ArithmeticModExpression in project cobar by alibaba.
the class MySQLExprParserTest method testExpr1.
public void testExpr1() throws Exception {
String sql = "\"abc\" /* */ '\\'s' + id2/ id3, 123-456*(ii moD d)";
MySQLLexer lexer = new MySQLLexer(sql);
MySQLExprParser parser = new MySQLExprParser(lexer);
Expression expr = parser.expression();
String output = output2MySQL(expr, sql);
Assert.assertEquals("'abc\\'s' + id2 / id3", output);
Assert.assertEquals(ArithmeticAddExpression.class, expr.getClass());
BinaryOperatorExpression bex = (BinaryOperatorExpression) ((ArithmeticAddExpression) expr).getRightOprand();
Assert.assertEquals(ArithmeticDivideExpression.class, bex.getClass());
Assert.assertEquals(Identifier.class, bex.getRightOprand().getClass());
lexer.nextToken();
parser = new MySQLExprParser(lexer);
expr = parser.expression();
output = output2MySQL(expr, sql);
Assert.assertEquals("123 - 456 * (ii % d)", output);
Assert.assertEquals(ArithmeticSubtractExpression.class, expr.getClass());
sql = "(n'\"abc\"' \"abc\" /* */ '\\'s' + 1.123e1/ id3)*(.1e3-a||b)mod x'abc'&&(select 0b1001^b'0000')";
lexer = new MySQLLexer(sql);
parser = new MySQLExprParser(lexer);
expr = parser.expression();
output = output2MySQL(expr, sql);
Assert.assertEquals("(N'\"abc\"abc\\'s' + 11.23 / id3) * (1E+2 - a OR b) % x'abc' AND (SELECT b'1001' ^ b'0000')", output);
Assert.assertEquals(LogicalAndExpression.class, expr.getClass());
bex = (BinaryOperatorExpression) ((LogicalAndExpression) expr).getOperand(0);
Assert.assertEquals(ArithmeticModExpression.class, bex.getClass());
bex = (BinaryOperatorExpression) ((ArithmeticModExpression) bex).getLeftOprand();
Assert.assertEquals(ArithmeticMultiplyExpression.class, bex.getClass());
bex = (BinaryOperatorExpression) ((ArithmeticMultiplyExpression) bex).getLeftOprand();
Assert.assertEquals(ArithmeticAddExpression.class, bex.getClass());
Assert.assertEquals(LiteralString.class, ((ArithmeticAddExpression) bex).getLeftOprand().getClass());
bex = (BinaryOperatorExpression) ((ArithmeticAddExpression) bex).getRightOprand();
Assert.assertEquals(ArithmeticDivideExpression.class, bex.getClass());
Assert.assertEquals(DMLSelectStatement.class, ((LogicalAndExpression) expr).getOperand(1).getClass());
sql = "not! ~`select` in (1,current_date,`current_date`)like `all` div a between (c&&d) and (d|e)";
lexer = new MySQLLexer(sql);
parser = new MySQLExprParser(lexer);
expr = parser.expression();
output = output2MySQL(expr, sql);
Assert.assertEquals("NOT ! ~ `select` IN (1, CURDATE(), `current_date`) LIKE `all` DIV a BETWEEN (c AND d) AND d | e", output);
Assert.assertEquals(LogicalNotExpression.class, expr.getClass());
TernaryOperatorExpression tex = (TernaryOperatorExpression) ((LogicalNotExpression) expr).getOperand();
Assert.assertEquals(BetweenAndExpression.class, tex.getClass());
Assert.assertEquals(LikeExpression.class, tex.getFirst().getClass());
Assert.assertEquals(LogicalAndExpression.class, tex.getSecond().getClass());
Assert.assertEquals(BitOrExpression.class, tex.getThird().getClass());
tex = (TernaryOperatorExpression) ((BetweenAndExpression) tex).getFirst();
Assert.assertEquals(InExpression.class, tex.getFirst().getClass());
Assert.assertEquals(ArithmeticIntegerDivideExpression.class, tex.getSecond().getClass());
bex = (BinaryOperatorExpression) (InExpression) tex.getFirst();
Assert.assertEquals(NegativeValueExpression.class, bex.getLeftOprand().getClass());
Assert.assertEquals(InExpressionList.class, bex.getRightOprand().getClass());
UnaryOperatorExpression uex = (UnaryOperatorExpression) ((NegativeValueExpression) bex.getLeftOprand());
Assert.assertEquals(BitInvertExpression.class, uex.getOperand().getClass());
sql = " binary case ~a||b&&c^d xor e when 2>any(select a ) then 3 else 4 end is not null =a";
lexer = new MySQLLexer(sql);
parser = new MySQLExprParser(lexer);
expr = parser.expression();
output = output2MySQL(expr, sql);
Assert.assertEquals("BINARY CASE ~ a OR b AND c ^ d XOR e WHEN 2 > ANY (SELECT a) THEN 3 ELSE 4 END IS NOT NULL = a", output);
Assert.assertEquals(ComparisionEqualsExpression.class, expr.getClass());
bex = (BinaryOperatorExpression) ((ComparisionEqualsExpression) expr);
Assert.assertEquals(ComparisionIsExpression.class, bex.getLeftOprand().getClass());
Assert.assertEquals(Identifier.class, bex.getRightOprand().getClass());
ComparisionIsExpression cex = (ComparisionIsExpression) bex.getLeftOprand();
Assert.assertEquals(CastBinaryExpression.class, cex.getOperand().getClass());
uex = (UnaryOperatorExpression) cex.getOperand();
Assert.assertEquals(CaseWhenOperatorExpression.class, uex.getOperand().getClass());
CaseWhenOperatorExpression cwex = (CaseWhenOperatorExpression) uex.getOperand();
Assert.assertEquals(LogicalOrExpression.class, cwex.getComparee().getClass());
PolyadicOperatorExpression pex = (LogicalOrExpression) cwex.getComparee();
Assert.assertEquals(BitInvertExpression.class, pex.getOperand(0).getClass());
Assert.assertEquals(LogicalXORExpression.class, pex.getOperand(1).getClass());
bex = (LogicalXORExpression) pex.getOperand(1);
Assert.assertEquals(LogicalAndExpression.class, bex.getLeftOprand().getClass());
Assert.assertEquals(Identifier.class, bex.getRightOprand().getClass());
pex = (LogicalAndExpression) bex.getLeftOprand();
Assert.assertEquals(Identifier.class, pex.getOperand(0).getClass());
Assert.assertEquals(BitXORExpression.class, pex.getOperand(1).getClass());
sql = " !interval(a,b)<=>a>>b collate x /?+a!=@@1 or @var sounds like -(a-b) mod -(d or e)";
lexer = new MySQLLexer(sql);
parser = new MySQLExprParser(lexer);
expr = parser.expression();
output = output2MySQL(expr, sql);
Assert.assertEquals("! INTERVAL(a, b) <=> a >> b COLLATE x / ? + a != @@1 OR @var SOUNDS LIKE - (a - b) % - (d OR e)", output);
Assert.assertEquals(LogicalOrExpression.class, expr.getClass());
pex = (LogicalOrExpression) expr;
Assert.assertEquals(ComparisionNotEqualsExpression.class, pex.getOperand(0).getClass());
Assert.assertEquals(SoundsLikeExpression.class, pex.getOperand(1).getClass());
bex = (BinaryOperatorExpression) pex.getOperand(0);
Assert.assertEquals(ComparisionNullSafeEqualsExpression.class, bex.getLeftOprand().getClass());
Assert.assertEquals(SysVarPrimary.class, bex.getRightOprand().getClass());
bex = (BinaryOperatorExpression) bex.getLeftOprand();
Assert.assertEquals(NegativeValueExpression.class, bex.getLeftOprand().getClass());
Assert.assertEquals(BitShiftExpression.class, bex.getRightOprand().getClass());
bex = (BinaryOperatorExpression) bex.getRightOprand();
Assert.assertEquals(Identifier.class, bex.getLeftOprand().getClass());
Assert.assertEquals(ArithmeticAddExpression.class, bex.getRightOprand().getClass());
bex = (BinaryOperatorExpression) bex.getRightOprand();
Assert.assertEquals(ArithmeticDivideExpression.class, bex.getLeftOprand().getClass());
Assert.assertEquals(Identifier.class, bex.getRightOprand().getClass());
bex = (BinaryOperatorExpression) bex.getLeftOprand();
Assert.assertEquals(CollateExpression.class, bex.getLeftOprand().getClass());
Assert.assertEquals(ParamMarker.class, bex.getRightOprand().getClass());
bex = (BinaryOperatorExpression) ((LogicalOrExpression) expr).getOperand(1);
Assert.assertEquals(UsrDefVarPrimary.class, bex.getLeftOprand().getClass());
Assert.assertEquals(ArithmeticModExpression.class, bex.getRightOprand().getClass());
bex = (BinaryOperatorExpression) bex.getRightOprand();
Assert.assertEquals(MinusExpression.class, bex.getLeftOprand().getClass());
Assert.assertEquals(MinusExpression.class, bex.getRightOprand().getClass());
uex = (UnaryOperatorExpression) bex.getLeftOprand();
Assert.assertEquals(ArithmeticSubtractExpression.class, uex.getOperand().getClass());
uex = (UnaryOperatorExpression) bex.getRightOprand();
Assert.assertEquals(LogicalOrExpression.class, uex.getOperand().getClass());
}
use of com.alibaba.cobar.parser.ast.expression.arithmeic.ArithmeticModExpression in project cobar by alibaba.
the class MySQLExprParser method arithmeticFactorOperatorExpression.
/**
* <code>higherExpr ( ('*'|'/'|'%'|'DIV'|'MOD') higherExpr)+</code>
*/
private Expression arithmeticFactorOperatorExpression(String consumed, String consumedUp) throws SQLSyntaxErrorException {
Expression temp;
for (Expression expr = bitXORExpression(consumed, consumedUp); ; ) {
switch(lexer.token()) {
case OP_ASTERISK:
lexer.nextToken();
temp = bitXORExpression(null, null);
expr = new ArithmeticMultiplyExpression(expr, temp).setCacheEvalRst(cacheEvalRst);
break;
case OP_SLASH:
lexer.nextToken();
temp = bitXORExpression(null, null);
expr = new ArithmeticDivideExpression(expr, temp).setCacheEvalRst(cacheEvalRst);
break;
case KW_DIV:
lexer.nextToken();
temp = bitXORExpression(null, null);
expr = new ArithmeticIntegerDivideExpression(expr, temp).setCacheEvalRst(cacheEvalRst);
break;
case OP_PERCENT:
case KW_MOD:
lexer.nextToken();
temp = bitXORExpression(null, null);
expr = new ArithmeticModExpression(expr, temp).setCacheEvalRst(cacheEvalRst);
break;
default:
return expr;
}
}
}
Aggregations