package com.taobao.tddl.optimizer.parse; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; import com.taobao.tddl.common.jdbc.ParameterContext; import com.taobao.tddl.common.jdbc.ParameterMethod; import com.taobao.tddl.common.model.SqlType; import com.taobao.tddl.optimizer.BaseOptimizerTest; import com.taobao.tddl.optimizer.core.ASTNodeFactory; import com.taobao.tddl.optimizer.core.ast.QueryTreeNode; import com.taobao.tddl.optimizer.core.ast.dml.DeleteNode; import com.taobao.tddl.optimizer.core.ast.dml.InsertNode; import com.taobao.tddl.optimizer.core.ast.dml.UpdateNode; import com.taobao.tddl.optimizer.core.ast.query.JoinNode; import com.taobao.tddl.optimizer.core.ast.query.KVIndexNode; import com.taobao.tddl.optimizer.core.ast.query.QueryNode; import com.taobao.tddl.optimizer.core.ast.query.TableNode; import com.taobao.tddl.optimizer.core.expression.IBooleanFilter; import com.taobao.tddl.optimizer.core.expression.IColumn; import com.taobao.tddl.optimizer.core.expression.IFilter; import com.taobao.tddl.optimizer.core.expression.IFilter.OPERATION; import com.taobao.tddl.optimizer.core.expression.IFunction; import com.taobao.tddl.optimizer.core.expression.bean.BindVal; import com.taobao.tddl.optimizer.exceptions.QueryException; import com.taobao.tddl.optimizer.exceptions.SqlParserException; import com.taobao.tddl.common.utils.logger.Logger; import com.taobao.tddl.common.utils.logger.LoggerFactory; /** * @author jianghang 2013-11-15 下午3:55:47 * @since 5.0.0 */ public class SqlParserTest extends BaseOptimizerTest { private static final Logger logger = LoggerFactory.getLogger(SqlParserTest.class); @Test public void testQuery_简单主键查询() throws SqlParserException, QueryException { String sql = "select * from table1 where id=1 or id = 2"; QueryTreeNode qn = query(sql); qn.build(); QueryTreeNode qnExpected = new TableNode("TABLE1").query("ID=1 or ID=2"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_字段别名() throws SqlParserException, QueryException { String sql = "SELECT ID AS TID,NAME,SCHOOL FROM TABLE1 WHERE ID=1"; QueryTreeNode qn = query(sql); qn.build(); QueryTreeNode qnExpected = new TableNode("TABLE1").select("ID AS TID,NAME,SCHOOL").query("ID=1"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_字段别名_表别名() throws SqlParserException, QueryException { String sql = "SELECT T.ID AS TID,T.NAME,T.SCHOOL FROM TABLE1 T WHERE ID=1"; QueryTreeNode qn = query(sql); qn.build(); QueryTreeNode qnExpected = new TableNode("TABLE1").alias("T").select("ID AS TID,NAME,SCHOOL").query("ID=1"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_函数别名() throws SqlParserException, QueryException { String sql = "SELECT T.ID , LENGTH(NAME) AS LEN FROM TABLE1 T WHERE ID=1"; QueryTreeNode qn = query(sql); qn.build(); IFunction function = ASTNodeFactory.getInstance().createFunction(); function.setColumnName("LENGTH(NAME)"); function.setAlias("LEN"); function.setFunctionName("LENGTH"); QueryTreeNode qnExpected = new TableNode("TABLE1").alias("T").select("T.ID").query("ID=1"); qnExpected.addColumnsSelected(function); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_普通join() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 A JOIN TABLE2 B ON A.ID=B.ID WHERE A.NAME=1"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); TableNode table2 = new TableNode("TABLE2"); QueryTreeNode qnExpected = table1.alias("A") .join(table2.alias("B")) .addJoinKeys("A.ID", "B.ID") .query("A.NAME=1"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_内连接() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 A INNER JOIN TABLE2 B ON A.ID=B.ID WHERE A.NAME=1"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); TableNode table2 = new TableNode("TABLE2"); QueryTreeNode qnExpected = table1.alias("A") .join(table2.alias("B")) .setInnerJoin() .addJoinKeys("A.ID", "B.ID") .query("A.NAME=1"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_左连接() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 A LEFT JOIN TABLE2 B ON A.ID=B.ID WHERE A.NAME=1"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); TableNode table2 = new TableNode("TABLE2"); QueryTreeNode qnExpected = table1.alias("A") .join(table2.alias("B")) .setLeftOuterJoin() .addJoinKeys("A.ID", "B.ID") .query("A.NAME=1"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_右连接() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 A RIGHT JOIN TABLE2 B ON A.ID=B.ID WHERE A.NAME=1"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); TableNode table2 = new TableNode("TABLE2"); QueryTreeNode qnExpected = table1.alias("A") .join(table2.alias("B")) .setRightOuterJoin() .addJoinKeys("A.ID", "B.ID") .query("A.NAME=1"); qnExpected.build(); assertEquals(qn, qnExpected); } @Ignore("mysql parser语法上暂时不支持,需要修改") @Test public void testQuery_outter连接() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 A OUTER JOIN TABLE2 B ON A.ID=B.ID WHERE A.NAME=1"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); TableNode table2 = new TableNode("TABLE2"); QueryTreeNode qnExpected = table1.alias("A") .join(table2.alias("B")) .setOuterJoin() .addJoinKeys("A.ID", "B.ID") .query("A.NAME=1"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_普通链接_多个连接条件() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 A INNER JOIN TABLE2 B ON A.ID=B.ID AND A.NAME = B.NAME WHERE A.NAME=1"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); TableNode table2 = new TableNode("TABLE2"); QueryTreeNode qnExpected = table1.alias("A") .join(table2.alias("B")) .addJoinKeys("A.ID", "B.ID") .addJoinKeys("A.NAME", "B.NAME") .query("A.NAME=1"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_普通链接_字段别名() throws SqlParserException, QueryException { String sql = "SELECT A.ID AS AID,A.SCHOOL AS ASCHOOL,B.* FROM TABLE1 A INNER JOIN TABLE2 B ON A.ID=B.ID AND A.NAME = B.NAME WHERE A.NAME=1"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); TableNode table2 = new TableNode("TABLE2"); QueryTreeNode qnExpected = table1.alias("A") .join(table2.alias("B")) .addJoinKeys("A.ID", "B.ID") .addJoinKeys("A.NAME", "B.NAME") .query("A.NAME=1") .select("A.ID AS AID,A.SCHOOL AS ASCHOOL,B.*"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_普通链接_order_group_having() throws SqlParserException, QueryException { String sql = "SELECT A.ID AS AID,A.SCHOOL AS ASCHOOL,B.* FROM TABLE1 A INNER JOIN TABLE2 B ON A.ID=B.ID AND A.NAME = B.NAME WHERE A.NAME=1"; sql += " GROUP BY AID HAVING AID > 0 ORDER BY A.ID ASC "; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); TableNode table2 = new TableNode("TABLE2"); QueryTreeNode qnExpected = table1.alias("A") .join(table2.alias("B")) .addJoinKeys("A.ID", "B.ID") .addJoinKeys("A.NAME", "B.NAME") .query("A.NAME=1") .select("A.ID AS AID,A.SCHOOL AS ASCHOOL,B.*") .groupBy("AID") .having("AID > 0") .orderBy("A.ID", true); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_普通链接_函数() throws SqlParserException, QueryException { String sql = "SELECT A.ID as AID,A.ID,COUNT(A.ID),COUNT(*) FROM TABLE1 A INNER JOIN TABLE2 B ON A.ID=B.ID AND A.NAME = B.NAME WHERE A.NAME=1"; sql += " GROUP BY AID HAVING AID > 0 ORDER BY A.ID ASC "; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); TableNode table2 = new TableNode("TABLE2"); QueryTreeNode qnExpected = table1.alias("A") .join(table2.alias("B")) .addJoinKeys("A.ID", "B.ID") .addJoinKeys("A.NAME", "B.NAME") .query("A.NAME=1") .select("A.ID AS AID,A.ID") .groupBy("AID") .having("AID > 0") .orderBy("A.ID", true); IFunction function1 = ASTNodeFactory.getInstance().createFunction(); function1.setColumnName("COUNT(A.ID)"); function1.setFunctionName("COUNT"); IFunction function2 = ASTNodeFactory.getInstance().createFunction(); function2.setColumnName("COUNT(*)"); function2.setFunctionName("COUNT"); qnExpected.addColumnsSelected(function1); qnExpected.addColumnsSelected(function2); qnExpected.build(); assertEquals(qn, qnExpected); } // @Test // 后续调整 public void testQuery_内连接_OR条件_不支持() throws Exception { String sql = "SELECT * FROM TABLE1 A INNER JOIN TABLE2 B ON A.ID=B.ID OR A.NAME = B.NAME WHERE A.NAME=1"; try { QueryTreeNode qn = query(sql); qn.build(); Assert.fail(); } catch (Exception e) { Assert.assertEquals("java.lang.IllegalArgumentException: not support 'or' in join on statment ", e.getCause().getMessage()); } } @Test public void testQuery_多表join() throws Exception { String sql = "SELECT * FROM TABLE1 JOIN TABLE2 LEFT JOIN TABLE3 ON (TABLE3.ID=TABLE2.ID) LEFT JOIN TABLE4 ON (TABLE4.ID=TABLE1.ID) WHERE TABLE2.ID= TABLE4.ID"; QueryTreeNode qn = query(sql); qn.build(); Assert.assertTrue(qn instanceof JoinNode); } @Test public void testQuery_正常orderby() throws Exception { String sql = "SELECT ID,NAME FROM TABLE1 WHERE ID=1 ORDER BY ID"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.select("ID,NAME").query("ID=1").orderBy("ID"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_OrderByAsc() throws Exception { String sql = "SELECT ID,NAME FROM TABLE1 WHERE ID=1 ORDER BY ID ASC"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.select("ID,NAME").query("ID=1").orderBy("ID", true); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_OrderByDesc() throws Exception { String sql = "SELECT ID,NAME FROM TABLE1 WHERE ID=1 ORDER BY ID DESC"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.select("ID,NAME").query("ID=1").orderBy("ID", false); qnExpected.build(); assertEquals(qn, qnExpected); } public void testQuery_OrderByIdAndNameASC() throws Exception { String sql = "SELECT ID,NAME FROM TABLE1 WHERE ID=1 ORDER BY ID,NAME"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.select("ID,NAME").query("ID=1").orderBy("ID").orderBy("NAME"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_OrderByIdAndNameDesc() throws Exception { String sql = "SELECT ID,NAME FROM TABLE1 WHERE ID=1 ORDER BY ID,NAME DESC"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.select("ID,NAME").query("ID=1").orderBy("ID").orderBy("NAME", false); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_OrderByIdDescAndNameDesc() throws Exception { String sql = "SELECT ID,NAME FROM TABLE1 WHERE ID=1 ORDER BY ID DESC,NAME DESC"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.select("ID,NAME").query("ID=1").orderBy("ID", false).orderBy("NAME", false); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_OrExpression() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 WHERE NAME = 2323 OR ID=1"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.query("NAME=2323 || ID=1"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_复杂条件() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 WHERE (SCHOOL=1 OR NAME=2) AND (ID=1)"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.query("(SCHOOL=1 || NAME=2) && (ID=1)"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testJoin_多表主键关联() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1,TABLE2 WHERE TABLE1.NAME=1 AND TABLE1.ID=TABLE2.ID"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.join("TABLE2").query("TABLE1.NAME=1 AND TABLE1.ID=TABLE2.ID"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testJoin_多表主键关联_表别名() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 T1,TABLE2 WHERE T1.NAME=1"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); TableNode table2 = new TableNode("TABLE2"); QueryTreeNode qnExpected = table1.alias("T1").join(table2).query("T1.NAME=1"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_and表达式() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 T1 WHERE ID<=10 AND ID>=5"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.alias("T1").query("ID<=10 AND ID>=5"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_and表达式_别名() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 T1 WHERE T1.ID=4 AND T1.ID>=2"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.select("*").alias("T1").query("T1.ID=4 && T1.ID>=2"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_and表达式_字符串() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 T1 WHERE NAME='4' AND ID<=2"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.alias("T1").query("NAME=4 && ID<=2"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_or表达式() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 T1 WHERE ID<5 OR ID<=6 OR ID=3"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.alias("T1").query("ID<5 || ID<=6 || ID=3"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQueryWith_or表达式_别名() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 T1 WHERE ID<5 OR ID<=6 OR ID=7"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.alias("T1").query(" ID<5 || ID<=6 || ID=7"); table1.build(); assertEquals(qn, qnExpected); } @Test public void testFunction() throws SqlParserException, QueryException { String sql = "SELECT COUNT(*) FROM TABLE1 T1 WHERE ID = 1"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); IFunction f = ASTNodeFactory.getInstance().createFunction(); f.setFunctionName("COUNT"); IColumn c = ASTNodeFactory.getInstance().createColumn(); c.setColumnName("*"); List args = new ArrayList(); args.add(c); f.setArgs(args); f.setTableName("TABLE1"); f.setColumnName("COUNT(*)"); QueryTreeNode qnExpected = table1.alias("T1").query("ID=1").select(f); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testFunction1() throws SqlParserException, QueryException { String sql = "SELECT COUNT(ID) FROM TABLE1 T1 WHERE ID = 1"; QueryTreeNode qn = query(sql); TableNode table1 = new TableNode("TABLE1"); IFunction f = ASTNodeFactory.getInstance().createFunction(); f.setFunctionName("COUNT"); f.setColumnName("COUNT(ID)"); IColumn c = ASTNodeFactory.getInstance().createColumn(); c.setColumnName("ID"); List args = new ArrayList(); args.add(c); f.setArgs(args); QueryTreeNode qnExpected = table1.alias("T1").query("ID=1").select(f); assertEquals(qn, qnExpected); } @Test public void testFunction_double_function() throws SqlParserException, QueryException { String sql = "SELECT COUNT(ID),AVG(ID) FROM TABLE1 T1 WHERE ID = 1"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.alias("T1").query("ID=1").select("COUNT(ID),AVG(ID)"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testFunction_to_char() throws Exception { String sql = "SELECT * FROM TABLE1 T1 WHERE DATE_ADD(ID, INTERVAL 1 SECOND)= '2012-11-11'"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); IFunction f = ASTNodeFactory.getInstance().createFunction(); f.setFunctionName("DATE_ADD"); IColumn c = ASTNodeFactory.getInstance().createColumn(); c.setColumnName("ID"); List args = new ArrayList(); args.add(c); args.add("INTERVAL 1 SECOND"); f.setArgs(args); f.setColumnName("DATE_ADD(ID, INTERVAL 1 SECOND)"); IFilter filter = ASTNodeFactory.getInstance().createBooleanFilter(); filter.setOperation(OPERATION.EQ); ((IBooleanFilter) filter).setColumn(f); ((IBooleanFilter) filter).setValue("2012-11-11"); QueryTreeNode qnExpected = table1.alias("T1").query(filter); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testFunction_twoArgs() throws Exception { String sql = "SELECT * FROM TABLE1 T1 WHERE IFNULL(STR_TO_DATE(ID, '%d,%m,%y'),1) = '1'"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); IFunction f = ASTNodeFactory.getInstance().createFunction(); f.setFunctionName("STR_TO_DATE"); IFunction f2 = ASTNodeFactory.getInstance().createFunction(); f2.setFunctionName("IFNULL"); f2.setColumnName("IFNULL(STR_TO_DATE(ID, '%d,%m,%y'), 1)"); IColumn c = ASTNodeFactory.getInstance().createColumn(); c.setColumnName("ID"); List args = new ArrayList(); args.add(c); args.add("%d,%m,%y"); f.setArgs(args); f.setColumnName("STR_TO_DATE(id, '%d,%m,%Y')"); args = new ArrayList(); args.add(f); args.add(1); f2.setArgs(args); IFilter filter = ASTNodeFactory.getInstance().createBooleanFilter(); filter.setOperation(OPERATION.EQ); ((IBooleanFilter) filter).setColumn(f2); ((IBooleanFilter) filter).setValue('1'); QueryTreeNode qnExpected = table1.alias("T1").query(filter); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testFunction_noArgs() throws Exception { String sql = "SELECT * FROM TABLE1 T1 WHERE ID = NOW()"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); IFunction f = ASTNodeFactory.getInstance().createFunction(); f.setFunctionName("NOW"); f.setColumnName("NOW()"); IColumn c = ASTNodeFactory.getInstance().createColumn(); c.setColumnName("ID"); IFilter filter = ASTNodeFactory.getInstance().createBooleanFilter(); filter.setOperation(OPERATION.EQ); ((IBooleanFilter) filter).setColumn(c); ((IBooleanFilter) filter).setValue(f); QueryTreeNode qnExpected = table1.alias("T1").query(filter); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testGroupBY() throws Exception { String sql = "SELECT * FROM TABLE1 T1 WHERE ID = 1 GROUP BY NAME "; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.alias("T1").query(" ID=1").groupBy("NAME"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testFunction_提前计算() throws SqlParserException, QueryException { String sql = "SELECT 1+1 FROM TABLE1"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.select("2"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testFunction_提前计算_bindVal() throws SqlParserException, QueryException { String sql = "SELECT 1+? FROM TABLE1"; QueryTreeNode qn = query(sql, Arrays.asList(Integer.valueOf(1))); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.select("1+?");// 不做计算,否则解析结果不能缓存 assertEquals(qn, qnExpected); } @Test public void testJoin_条件提前计算() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 A JOIN TABLE2 B ON A.ID=B.ID WHERE A.ID>1+4 AND B.ID<12-1"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); TableNode table2 = new TableNode("TABLE2"); QueryTreeNode qnExpected = table1.alias("A") .join(table2.alias("B")) .addJoinKeys("ID", "ID") .query("A.ID>5 && B.ID<11"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testUpdate_正常() throws SqlParserException, QueryException { String sql = "UPDATE TABLE1 SET NAME=2 WHERE ID>=5 AND ID<=5"; UpdateNode un = update(sql); un.build(); TableNode table1 = new TableNode("TABLE1"); UpdateNode unExpected = table1.update("NAME", new Comparable[] { 2 }); table1.query("ID>=5 AND ID<=5"); unExpected.build(); assertEquals(un, unExpected); } @Test public void testDelete_正常() throws SqlParserException, QueryException { String sql = "DELETE FROM TABLE1 WHERE ID>=5 AND ID<=5"; DeleteNode dn = delete(sql); dn.build(); TableNode table1 = new TableNode("TABLE1"); DeleteNode dnExpected = table1.delete(); table1.query("ID>=5 AND ID<=5"); dnExpected.build(); assertEquals(dn, dnExpected); } @Test public void testInsert_无字段() throws SqlParserException, QueryException { String sql = "INSERT INTO TABLE1(ID) VALUES (2)"; InsertNode in = insert(sql); in.build(); TableNode table1 = new TableNode("TABLE1"); InsertNode inExpected = table1.insert("ID", new Comparable[] { 2 }); inExpected.build(); assertEquals(in, inExpected); } @Test public void testInsert_多字段() throws SqlParserException, QueryException { String sql = "INSERT INTO TABLE1(ID, NAME, SCHOOL) VALUES (2, 'sun', 'sysu')"; InsertNode in = insert(sql); in.build(); TableNode table1 = new TableNode("TABLE1"); InsertNode inExpected = table1.insert("ID NAME SCHOOL", new Comparable[] { 2, "sun", "sysu" }); inExpected.build(); assertEquals(in, inExpected); } @Test public void testLimit() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 LIMIT 1,10"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.limit(1, 10); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testLimit1() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 WHERE ID = 10 LIMIT 10"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.query("id=10").setLimitFrom(0).setLimitTo(10); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testLimit_bindval1() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 WHERE TABLE1.ID = 10 LIMIT ?,10"; QueryTreeNode qn = query(sql); qn.build(); Assert.assertTrue(qn.getLimitFrom() instanceof BindVal); BindVal bv = (BindVal) qn.getLimitFrom(); Assert.assertEquals(1, bv.getBindVal()); Assert.assertEquals(10L, qn.getLimitTo()); } @Test public void testLimit_bindval2() throws SqlParserException, QueryException { String sql = "select * from table1 where table1.id = 10 limit 1,?"; QueryTreeNode qn = query(sql); qn.build(); Assert.assertTrue(qn.getLimitTo() instanceof BindVal); BindVal bv = (BindVal) qn.getLimitTo(); Assert.assertEquals(1, bv.getBindVal()); Assert.assertEquals(1L, qn.getLimitFrom()); } @Test public void testLimit_bindval3() throws SqlParserException, QueryException { String sql = "select * from table1 where table1.id = 10 limit ?,?"; QueryTreeNode qn = query(sql); qn.build(); Assert.assertTrue(qn.getLimitFrom() instanceof BindVal); BindVal bv = (BindVal) qn.getLimitFrom(); Assert.assertEquals(1, bv.getBindVal()); Assert.assertTrue(qn.getLimitTo() instanceof BindVal); bv = (BindVal) qn.getLimitTo(); Assert.assertEquals(2, bv.getBindVal()); } @Test public void testPreparedInsertSql() throws SqlParserException, QueryException { String sql = "INSERT INTO TABLE1(ID,NAME,SCHOOL) VALUES (?, ?, ?)"; InsertNode in = insert(sql); Map<Integer, ParameterContext> parameterSettings = null; parameterSettings = new TreeMap<Integer, ParameterContext>(); ParameterContext p1 = new ParameterContext(ParameterMethod.setObject1, new Object[] { 0, 2 }); ParameterContext p2 = new ParameterContext(ParameterMethod.setObject1, new Object[] { 1, "sun" }); ParameterContext p3 = new ParameterContext(ParameterMethod.setObject1, new Object[] { 2, "sysu" }); parameterSettings.put(1, p1); parameterSettings.put(2, p2); parameterSettings.put(3, p3); in.assignment(parameterSettings); in.build(); TableNode table1 = new TableNode("TABLE1"); InsertNode inExpected = table1.insert("ID NAME SCHOOL", new Comparable[] { 2, "sun", "sysu" }); inExpected.build(); assertEquals(in, inExpected); } @Test public void testPreparedUpdateSql() throws SqlParserException, QueryException { String sql = "UPDATE TABLE1 SET ID=? WHERE ID>=? AND ID<=?"; UpdateNode un = update(sql); Map<Integer, ParameterContext> parameterSettings = null; parameterSettings = new TreeMap<Integer, ParameterContext>(); ParameterContext p1 = new ParameterContext(ParameterMethod.setObject1, new Object[] { 0, 2 }); ParameterContext p2 = new ParameterContext(ParameterMethod.setObject1, new Object[] { 1, 3 }); ParameterContext p3 = new ParameterContext(ParameterMethod.setObject1, new Object[] { 2, 5 }); parameterSettings.put(1, p1); parameterSettings.put(2, p2); parameterSettings.put(3, p3); un.assignment(parameterSettings); un.build(); TableNode table1 = new TableNode("TABLE1"); UpdateNode unExpected = table1.update("ID", new Comparable[] { 2 }); table1.query("ID>=3 AND ID<=5"); unExpected.build(); assertEquals(un, unExpected); } @Test public void testPreparedDeleteSql() throws SqlParserException, QueryException { String sql = "DELETE FROM TABLE1 WHERE ID>=? AND ID<=?"; DeleteNode dn = delete(sql); Map<Integer, ParameterContext> parameterSettings = null; parameterSettings = new TreeMap<Integer, ParameterContext>(); ParameterContext p1 = new ParameterContext(ParameterMethod.setObject1, new Object[] { 0, 3 }); ParameterContext p2 = new ParameterContext(ParameterMethod.setObject1, new Object[] { 1, 5 }); parameterSettings.put(1, p1); parameterSettings.put(2, p2); dn.assignment(parameterSettings); dn.build(); TableNode table1 = new TableNode("TABLE1"); DeleteNode dnExpected = table1.delete(); table1.query("ID>=3 AND ID<=5"); dnExpected.build(); assertEquals(dn, dnExpected); } @Test public void testDistinct() throws SqlParserException, QueryException { String sql = "SELECT COUNT(DISTINCT ID) FROM TABLE1"; QueryTreeNode qn = query(sql); TableNode table1 = new TableNode("TABLE1"); IColumn c = ASTNodeFactory.getInstance().createColumn(); c.setColumnName("ID"); c.setDistinct(true); IFunction f = ASTNodeFactory.getInstance().createFunction(); f.setFunctionName("COUNT"); f.setColumnName("COUNT(DISTINCT ID)"); List args = new ArrayList(); args.add(c); f.setArgs(args); qn.build(); QueryTreeNode qnExpected = table1.select(f); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_orderBy加函数() throws Exception { String sql = "SELECT * FROM TABLE1 WHERE ID=1 ORDER BY COUNT(ID)"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); IColumn c = ASTNodeFactory.getInstance().createColumn(); c.setColumnName("ID"); IFunction f = ASTNodeFactory.getInstance().createFunction(); f.setFunctionName("COUNT"); List args = new ArrayList(); args.add(c); f.setArgs(args); f.setColumnName("COUNT(ID)"); QueryTreeNode qnExpected = table1.query("ID=1").orderBy(f, true); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testQuery_Like() throws SqlParserException, QueryException { String sql = "SELECT NAME FROM TABLE1 WHERE NAME LIKE '%XASX%'"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.select("NAME").query("NAME LIKE '%XASX%'"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testMultiAnd() throws QueryException, SqlParserException { String sql = "SELECT NAME FROM TABLE1 WHERE NAME=? AND (ID>? AND ID<?)"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.select("NAME").query("NAME=? AND ID>? AND ID<?"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testMultiOr() throws QueryException, SqlParserException { String sql = "SELECT NAME FROM TABLE1 WHERE NAME=? OR(ID>? OR ID<?)"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.select("NAME").query("NAME=? OR(ID>? OR ID<?)"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testMultiAndOr() throws QueryException, SqlParserException { String sql = "SELECT NAME FROM TABLE1 WHERE NAME=? AND NAME>? AND (ID=? OR ID<?)"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.select("NAME").query("NAME=? AND NAME>? AND (ID=? OR ID<?)"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testWhere_字段子查询() throws QueryException, SqlParserException { String sql = "SELECT NAME FROM TABLE1 WHERE NAME=(SELECT NAME FROM TABLE2 B WHERE B.ID=1)"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.select("NAME"); TableNode table2 = new TableNode("TABLE2"); table2.alias("B").select("NAME").query("B.ID=1"); table1.query("NAME=(SELECT NAME FROM TABLE2 B WHERE B.ID=1)"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testWhere_字段多级子查询() throws QueryException, SqlParserException { String subSql = "SELECT B.* FROM TABLE2 B WHERE B.ID=1 GROUP BY SCHOOL HAVING COUNT(*) > 1 ORDER BY ID DESC LIMIT 1"; String sql = "SELECT NAME FROM TABLE1 WHERE NAME=(SELECT C.NAME FROM (" + subSql + ") C )"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); QueryTreeNode qnExpected = table1.select("NAME"); TableNode table2 = new TableNode("TABLE2"); table2.alias("C").setSubAlias("B").select("*").query("B.ID=1"); table2.groupBy("SCHOOL"); table2.having("COUNT(*) > 1"); table2.orderBy("ID", false); table2.limit(0, 1); table2.setSubQuery(true); QueryNode subQuery = new QueryNode(table2); subQuery.select("C.NAME"); IColumn column = ASTNodeFactory.getInstance().createColumn().setColumnName("NAME"); IBooleanFilter filter = ASTNodeFactory.getInstance() .createBooleanFilter() .setColumn(column) .setValue(subQuery) .setOperation(OPERATION.EQ); table1.query(filter); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testWhere_表子查询() throws QueryException, SqlParserException { String sql = "SELECT NAME FROM (SELECT * FROM TABLE1 A WHERE A.ID=1) B"; QueryTreeNode qn = query(sql); qn.build(); TableNode table1 = new TableNode("TABLE1"); table1.subAlias("A").alias("B").query("A.ID=1"); QueryTreeNode qnExpected = new QueryNode(table1); qnExpected.select("NAME"); qnExpected.build(); assertEquals(qn, qnExpected); } @Test public void testWhere_字段_表_复杂子查询() throws QueryException, SqlParserException { String subSql = "SELECT B.* FROM TABLE2 B WHERE B.ID=1 GROUP BY SCHOOL HAVING COUNT(*) > 1 ORDER BY ID DESC LIMIT 1"; String sql = "SELECT NAME FROM (SELECT * FROM TABLE1 A WHERE A.ID=1) A WHERE NAME=(SELECT C.NAME FROM (" + subSql + ") C )"; QueryTreeNode qn = query(sql); qn.build(); System.out.println(qn); } @Test public void testQuery_join子查询_join表() throws SqlParserException, QueryException { String sql = "SELECT * FROM (SELECT A.ID,A.NAME FROM TABLE1 A JOIN TABLE2 B ON A.ID=B.ID WHERE A.NAME=1) C JOIN TABLE3 D ON C.ID = D.ID"; QueryTreeNode qn = query(sql); qn.build(); // System.out.println(qn); Assert.assertTrue(((JoinNode) qn).getLeftNode() instanceof JoinNode); } @Test public void testQuery_join子查询() throws SqlParserException, QueryException { String sql = "SELECT * FROM (SELECT A.ID,A.NAME FROM TABLE1 A JOIN TABLE2 B ON A.ID=B.ID WHERE A.NAME=1) C WHERE C.ID = 6"; QueryTreeNode qn = query(sql); qn.build(); // System.out.println(qn); // 第一级是QueryNode // 第二级是JoinNode Assert.assertTrue(qn instanceof QueryNode); Assert.assertTrue(((QueryNode) qn).getChild() instanceof JoinNode); } @Test public void testQuery_join_子查询_多级组合() throws SqlParserException, QueryException { String joinSql = "SELECT TABLE1.ID,TABLE1.NAME FROM TABLE1 JOIN TABLE2 ON TABLE1.ID=TABLE1.ID WHERE TABLE1.NAME=1"; String subsql = "SELECT * FROM (" + joinSql + " ) S WHERE S.NAME = 1"; String sql = "SELECT * FROM (" + subsql + ") B , (" + subsql + ") C WHERE B.NAME = 6 AND B.ID = C.ID"; QueryTreeNode qn = query(sql); qn.build(); // System.out.println(qn); // 第一级是JoinNode // 第二级是QuerNode / QueryNode // 第三级是JoinNode / JoinNode Assert.assertTrue(qn instanceof JoinNode); Assert.assertTrue(((JoinNode) qn).getLeftNode() instanceof QueryNode); Assert.assertTrue(((JoinNode) qn).getRightNode() instanceof QueryNode); Assert.assertTrue(((QueryNode) ((JoinNode) qn).getLeftNode()).getChild() instanceof JoinNode); Assert.assertTrue(((QueryNode) ((JoinNode) qn).getRightNode()).getChild() instanceof JoinNode); } @Test public void testQuery_多字段in() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 WHERE (ID,NAME) IN ((1,2),(2,3))"; QueryTreeNode qn = query(sql); qn.build(); System.out.println(qn); } public void testQuery_join_子查询_in模式() throws SqlParserException, QueryException { String sql = "SELECT * FROM TABLE1 WHERE ID IN (SELECT ID FROM TABLE2)"; QueryTreeNode qn = query(sql); qn.build(); System.out.println(qn); } // @Test public void testQuery_join_子查询_exist模式() throws SqlParserException, QueryException { // ExistsPrimary String sql = "SELECT * FROM TABLE1 WHERE EXISTS (SELECT ID FROM TABLE2)"; QueryTreeNode qn = query(sql); qn.build(); System.out.println(qn); } // @Test public void testQuery_join_子查询_all模式() throws SqlParserException, QueryException { // SubqueryAllExpression String sql = "SELECT * FROM TABLE1 WHERE ID > ALL (SELECT ID FROM TABLE2)"; QueryTreeNode qn = query(sql); qn.build(); System.out.println(qn); } // @Test public void testQuery_join_子查询_any模式() throws SqlParserException, QueryException { // SubqueryAnyExpression String sql = "SELECT * FROM TABLE1 WHERE ID > ANY (SELECT ID FROM TABLE2)"; QueryTreeNode qn = query(sql); qn.build(); System.out.println(qn); } // @Test public void testQuery_不带表() throws SqlParserException, QueryException { String sql = "SELECT 1"; QueryTreeNode qn = query(sql); qn.build(); System.out.println(qn); } // ================================================== private QueryTreeNode query(String sql) throws SqlParserException { SqlAnalysisResult sm = parser.parse(sql, false); QueryTreeNode qn = null; if (sm.getSqlType() == SqlType.SELECT) { qn = sm.getQueryTreeNode(null); } else { qn = new KVIndexNode(null); qn.setSql(sql); } return qn; } private QueryTreeNode query(String sql, List args) throws SqlParserException { SqlAnalysisResult sm = parser.parse(sql, false); QueryTreeNode qn = null; if (sm.getSqlType() == SqlType.SELECT) { qn = sm.getQueryTreeNode(convert(args)); } else { qn = new KVIndexNode(null); qn.setSql(sql); } return qn; } private UpdateNode update(String sql) throws SqlParserException { SqlAnalysisResult sm = parser.parse(sql, false); UpdateNode qn = null; if (sm.getSqlType() == SqlType.UPDATE) { qn = sm.getUpdateNode(null); } return qn; } private DeleteNode delete(String sql) throws SqlParserException { SqlAnalysisResult sm = parser.parse(sql, false); DeleteNode qn = null; if (sm.getSqlType() == SqlType.DELETE) { qn = sm.getDeleteNode(null); } return qn; } private InsertNode insert(String sql) throws SqlParserException { SqlAnalysisResult sm = parser.parse(sql, false); InsertNode qn = null; if (sm.getSqlType() == SqlType.INSERT) { qn = sm.getInsertNode(null); } return qn; } private void assertEquals(QueryTreeNode qn, QueryTreeNode qnExpected) { logger.debug(qn.toString()); Assert.assertEquals(qnExpected.toString(), qn.toString()); } private void assertEquals(UpdateNode un, UpdateNode unExpected) { logger.debug(un.toString()); Assert.assertEquals(unExpected.toString(), un.toString()); } private void assertEquals(DeleteNode dn, DeleteNode dnExpected) { logger.debug(dn.toString()); Assert.assertEquals(dnExpected.toString(), dn.toString()); } private void assertEquals(InsertNode in, InsertNode inExpected) { logger.debug(in.toString()); Assert.assertEquals(inExpected.toString(), in.toString()); } }