/* * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software;Designed and Developed mainly by many Chinese * opensource volunteers. you can redistribute it and/or modify it under the * terms of the GNU General Public License version 2 only, as published by the * Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Any questions about this component can be directed to it's project Web address * https://code.google.com/p/opencloudb/. * */ package org.opencloudb.parser; import java.sql.SQLSyntaxErrorException; import java.util.Map; import junit.framework.Assert; import org.junit.Test; import org.opencloudb.mpp.MergeCol; import org.opencloudb.mpp.OrderCol; import org.opencloudb.mpp.SelectParseInf; import org.opencloudb.mpp.SelectSQLAnalyser; import org.opencloudb.mpp.ShardingParseInfo; import org.opencloudb.route.RouteResultset; import com.foundationdb.sql.StandardException; import com.foundationdb.sql.parser.QueryTreeNode; public class MergeSQLParserTest { @Test public void testSQL() throws SQLSyntaxErrorException, StandardException { SelectParseInf parsInf = new SelectParseInf(); parsInf.ctx = new ShardingParseInfo(); String sql = null; QueryTreeNode ast = null; // test order by parse sql = "select o.* from Orders o group by o.name order by o.id asc ,o.age desc limit 5,10"; parsInf.clear(); ast = SQLParserDelegate.parse(sql, SQLParserDelegate.DEFAULT_CHARSET); SelectSQLAnalyser.analyse(parsInf, ast); RouteResultset rrs = new RouteResultset(sql,0); String sql2 = SelectSQLAnalyser.analyseMergeInf(rrs, ast, true,-1); Assert.assertEquals( "SELECT o.* FROM orders AS o GROUP BY o.name ORDER BY o.id, o.age DESC LIMIT 15 OFFSET 0", sql2); Assert.assertEquals("name", rrs.getGroupByCols()[0]); Assert.assertEquals(Integer.valueOf(OrderCol.COL_ORDER_TYPE_ASC), rrs.getOrderByCols().get("id")); Assert.assertEquals(5, rrs.getLimitStart()); Assert.assertEquals(10, rrs.getLimitSize()); sql = "select o.name,count(o.id) as total, max(o.mx) as maxOders,sum(MOD2(29,9)),min(o.price) from Orders o group by name"; ast = SQLParserDelegate.parse(sql, SQLParserDelegate.DEFAULT_CHARSET); rrs = new RouteResultset(sql,0); SelectSQLAnalyser.analyseMergeInf(rrs, ast, false,-1); Assert.assertEquals(true, rrs.isHasAggrColumn()); Assert.assertEquals(2, rrs.getMergeCols().size()); sql2 = SelectSQLAnalyser.analyseMergeInf(rrs, ast, false,-1); // aggregate column should has alias in order to used in oder by clause sql = "select count(*) from orders order by count(*) desc"; ast = SQLParserDelegate.parse(sql, SQLParserDelegate.DEFAULT_CHARSET); rrs = new RouteResultset(sql,0); SQLSyntaxErrorException e=null; try { SelectSQLAnalyser.analyseMergeInf(rrs, ast, false,-1); }catch(SQLSyntaxErrorException e1) { e=e1; } Assert.assertNotNull(e); Assert.assertEquals(true, rrs.isHasAggrColumn()); // aggregate column should has alias in order to used in oder by clause sql = "select count(*) as total from orders order by total desc"; ast = SQLParserDelegate.parse(sql, SQLParserDelegate.DEFAULT_CHARSET); rrs = new RouteResultset(sql,0); SelectSQLAnalyser.analyseMergeInf(rrs, ast, false,-1); Assert.assertEquals(true, rrs.isHasAggrColumn()); Assert.assertEquals(Integer.valueOf(OrderCol.COL_ORDER_TYPE_DESC), rrs.getOrderByCols().get("total")); // order by column has alias and should be 'modified' to alias sql = "select id as myid from person order by id"; ast = SQLParserDelegate.parse(sql, SQLParserDelegate.DEFAULT_CHARSET); rrs = new RouteResultset(sql,0); SelectSQLAnalyser.analyseMergeInf(rrs, ast, false,-1); Assert.assertEquals(Integer.valueOf(OrderCol.COL_ORDER_TYPE_ASC), rrs.getOrderByCols().get("myid")); // aggregate column has alias sql = "select counT(*) as TOTaL from person order by toTal"; ast = SQLParserDelegate.parse(sql, SQLParserDelegate.DEFAULT_CHARSET); rrs = new RouteResultset(sql,0); SelectSQLAnalyser.analyseMergeInf(rrs, ast, false,-1); Map<String,Integer> mergeCols=rrs.getMergeCols(); Assert.assertEquals(1,mergeCols.size()); Assert.assertEquals(Integer.valueOf(MergeCol.MERGE_COUNT),mergeCols.get("total")); Assert.assertEquals(1,rrs.getOrderByCols().size()); Assert.assertEquals(Integer.valueOf(OrderCol.COL_ORDER_TYPE_ASC),rrs.getOrderByCols().get("total")); } }