/*
* *************************************************************************************
* Copyright (C) 2008 EsperTech, Inc. All rights reserved. *
* http://esper.codehaus.org *
* http://www.espertech.com *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license *
* a copy of which has been included with this distribution in the license.txt file. *
* *************************************************************************************
*/
package com.espertech.esper.epl.parse;
import com.espertech.esper.collection.Pair;
import com.espertech.esper.support.bean.SupportBean;
import com.espertech.esper.support.epl.parse.SupportEPLTreeWalkerFactory;
import com.espertech.esper.support.epl.parse.SupportParserHelper;
import junit.framework.TestCase;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.tree.Tree;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class TestEPLParser extends TestCase
{
public void testDisplayAST() throws Exception
{
String className = SupportBean.class.getName();
String expression = "select * from A where exp > ANY (select a from B)";
log.debug(".testDisplayAST parsing: " + expression);
Pair<Tree, CommonTokenStream> ast = parse(expression);
SupportParserHelper.displayAST(ast.getFirst());
log.debug(".testDisplayAST walking...");
EPLTreeWalker walker = SupportEPLTreeWalkerFactory.makeWalker(ast.getFirst(), ast.getSecond());
walker.startEPLExpressionRule();
}
public void testInvalidCases() throws Exception
{
String className = SupportBean.class.getName();
assertIsInvalid(className + "(val=10000).");
assertIsInvalid(className + "().a:someview");
assertIsInvalid(className + "().a:someview(");
assertIsInvalid(className + "().a:someview)");
assertIsInvalid(className + "().lenght()");
assertIsInvalid(className + "().:lenght()");
assertIsInvalid(className + "().win:lenght(0,)");
assertIsInvalid(className + "().win:lenght(,0)");
assertIsInvalid(className + "().win:lenght(0,0,)");
assertIsInvalid(className + "().win:lenght(0,0,\")");
assertIsInvalid(className + "().win:lenght(\"\"5)");
assertIsInvalid(className + "().win:lenght(,\"\")");
assertIsInvalid(className + "().win:lenght.(,\"\")");
assertIsInvalid(className + "().win:lenght().");
assertIsInvalid(className + "().win:lenght().lenght");
assertIsInvalid(className + "().win:lenght().lenght(");
assertIsInvalid(className + "().win:lenght().lenght)");
assertIsInvalid(className + "().win:lenght().lenght().");
assertIsInvalid(className + "().win:lenght().lenght().lenght");
assertIsInvalid(className + "().win:lenght({}))");
assertIsInvalid(className + "().win:lenght({\"s\")");
assertIsInvalid(className + "().win:lenght(\"s\"})");
assertIsInvalid(className + "().win:lenght({{\"s\"})");
assertIsInvalid(className + "().win:lenght({{\"s\"}})");
assertIsInvalid(className + "().win:lenght({\"s\"}})");
assertIsInvalid(className + "().win:lenght('s\"");
assertIsInvalid(className + "().win:lenght(\"s')");
assertIsInvalid("select * from com.xxx().std:win(3) where a not is null");
assertIsInvalid("select * from com.xxx().std:win(3) where a = not null");
assertIsInvalid("select * from com.xxx().std:win(3) where not not");
assertIsInvalid("select * from com.xxx().std:win(3) where not ||");
assertIsInvalid("select * from com.xxx().std:win(3) where a ||");
assertIsInvalid("select * from com.xxx().std:win(3) where || a");
assertIsInvalid("select a] from com.xxx().std:win(3)");
assertIsInvalid("select * from com.xxx().std:win(3) where b('aaa)=5");
assertIsInvalid("select sum() from b.win:length(1)");
assertIsInvalid("select sum(1+) from b.win:length(1)");
assertIsInvalid("select sum(distinct) from b.win:length(1)");
assertIsInvalid("select sum(distinct distinct a) from b.win:length(1)");
assertIsInvalid("select avg() from b.win:length(1)");
assertIsInvalid("select count() from b.win:length(1)");
assertIsInvalid("select count(* *) from b.win:length(1)");
assertIsInvalid("select count(*2) from b.win:length(1)");
assertIsInvalid("select count(distinct *) from b.win:length(1)");
assertIsInvalid("select median() from b.win:length(1)");
assertIsInvalid("select stddev() from b.win:length(1)");
assertIsInvalid("select stddev(distinct) from b.win:length(1)");
assertIsInvalid("select avedev() from b.win:length(1)");
assertIsInvalid("select avedev(distinct) from b.win:length(1)");
// group-by
assertIsInvalid("select 1 from b.win:length(1) group by");
assertIsInvalid("select 1 from b.win:length(1) group by group");
assertIsInvalid("select 1 from b.win:length(1) group a");
assertIsInvalid("select 1 from b.win:length(1) group by a group by b");
assertIsInvalid("select 1 from b.win:length(1) by a ");
assertIsInvalid("select 1 from b.win:length(1) group by a a");
assertIsInvalid("select 1 from b.win:length(1) group by a as dummy");
// having
assertIsInvalid("select 1 from b.win:length(1) group by a having a>5,b<4");
// insert into
assertIsInvalid("insert into select 1 from b.win:length(1)");
assertIsInvalid("insert into 38484 select 1 from b.win:length(1)");
assertIsInvalid("insert into A B select 1 from b.win:length(1)");
assertIsInvalid("insert into A () select 1 from b.win:length(1)");
assertIsInvalid("insert into A (a,) select 1 from b.win:length(1)");
assertIsInvalid("insert into A (,) select 1 from b.win:length(1)");
assertIsInvalid("insert into A(,a) select 1 from b.win:length(1)");
assertIsInvalid("insert xxx into A(,a) select 1 from b.win:length(1)");
assertIsInvalid("select coalesce(processTimeEvent.price) from x");
// time periods
assertIsInvalid("select * from x.win:time(sec 99)");
assertIsInvalid("select * from x.win:time(99 min min)");
assertIsInvalid("select * from x.win:time(88 sec day)");
assertIsInvalid("select * from x.win:time(1 sec 88 days)");
assertIsInvalid("select * from x.win:time(1 day 2 hours 1 day)");
// in
assertIsInvalid("select * from x where a in()");
assertIsInvalid("select * from x where a in(a,)");
assertIsInvalid("select * from x where a in(,a)");
assertIsInvalid("select * from x where a in(, ,)");
assertIsInvalid("select * from x where a in not(1,2)");
// between
assertIsInvalid("select * from x where between a");
assertIsInvalid("select * from x where between and b");
assertIsInvalid("select * from x where between in and b");
assertIsInvalid("select * from x where between");
// like and regexp
assertIsInvalid("select * from x where like");
assertIsInvalid("select * from x where like escape");
assertIsInvalid("select * from x where like a escape");
assertIsInvalid("select * from x where order");
assertIsInvalid("select * from x where field rlike 'aa' escape '!'");
assertIsInvalid("select * from x where field regexp 'aa' escape '!'");
assertIsInvalid("select * from x where regexp 'aa'");
assertIsInvalid("select * from x where a like b escape c");
// database join
assertIsInvalid("select * from x, sql ");
assertIsInvalid("select * from x, sql:xx ");
assertIsInvalid("select * from x, sql:xx ");
assertIsInvalid("select * from x, sql:xx [' dsfsdf \"]");
assertIsInvalid("select * from x, sql:xx [\"sfsf ']");
// Previous and prior function
assertIsInvalid("select prior(10) from x");
assertIsInvalid("select prior(price, a*b) from x");
// subqueries
assertIsInvalid("select (select a) from x");
assertIsInvalid("select (select a from X group by b) from x");
assertIsInvalid("select (select a from X, Y) from x");
assertIsInvalid("select (select a from ) from x");
assertIsInvalid("select (select from X) from x");
assertIsInvalid("select * from x where (select q from pattern [A->B])");
assertIsInvalid("select c from A where q*9 in in (select g*5 from C.win:length(100)) and r=6");
assertIsInvalid("select c from A in (select g*5 from C.win:length(100)) and r=6");
assertIsInvalid("select c from A where a in (select g*5 from C.win:length(100)) 9");
// Substitution parameters
assertIsInvalid("select ? ? from A");
assertIsInvalid("select * from A(??)");
// cast, instanceof, isnumeric and exists dynamic property
assertIsInvalid("select * from A(boolean = exists(a, b))");
assertIsInvalid("select * from A (boolean = exists())");
assertIsInvalid("select * from A (boolean = exists(1))");
assertIsInvalid("select * from A where exists(1 + a.b.c?.d.e)");
assertIsInvalid("select * from A(boolean = instanceof(, a))");
assertIsInvalid("select * from A(boolean = instanceof(b))");
assertIsInvalid("select * from A(boolean = instanceof('agc', ,))");
assertIsInvalid("select * from A(boolean = instanceof(b com.espertech.esper.support.AClass))");
assertIsInvalid("select * from A(cast(b, +1))");
assertIsInvalid("select * from A(cast(b?, a + 1))");
assertIsInvalid("select * from A(cast((), a + 1))");
// named window
assertIsInvalid("create window AAA as MyType B");
assertIsInvalid("create window AAA as select from MyType");
assertIsInvalid("create window AAA as , *, b from MyType");
assertIsInvalid("create window as select a from MyType");
assertIsInvalid("create window AAA as select from MyType");
assertIsInvalid("create window AAA.win:length(10)");
assertIsInvalid("create window AAA");
assertIsInvalid("create window AAA as select a*5 from MyType");
// on-delete statement
assertIsInvalid("on MyEvent from MyNamedWindow");
assertIsInvalid("on delete from MyNamedWindow");
assertIsInvalid("on MyEvent abc def delete from MyNamedWindow");
assertIsInvalid("on MyEvent(a<2)(a) delete from MyNamedWindow");
assertIsInvalid("on MyEvent delete from MyNamedWindow where");
// on-select statement
assertIsInvalid("on MyEvent select from MyNamedWindow");
assertIsInvalid("on MyEvent select * from MyNamedWindow.win:time(30)");
assertIsInvalid("on MyEvent select * from MyNamedWindow where");
assertIsInvalid("on MyEvent insert into select * from MyNamedWindow");
assertIsInvalid("on MyEvent select a,c,b where a=y select 1,2,2,2 where 2=4");
assertIsInvalid("on MyEvent insert into A select a,c,b where a=y select 1,2,2,2 where 2=4");
assertIsInvalid("on MyEvent insert into A select a,c,b where a=y insert into D where 2=4");
assertIsInvalid("on MyEvent insert into A select a,c,b where a=y insert into D where 2=4 output xyz");
assertIsInvalid("on MyEvent insert into A select a,c,b where a=y insert into D where 2=4 output");
// on-set statement
assertIsInvalid("on MyEvent set");
assertIsInvalid("on MyEvent set a=dkdkd a");
assertIsInvalid("on MyEvent set a=, b=");
// on-update statement
assertIsInvalid("on MyEvent update ABC as abc");
assertIsInvalid("on MyEvent update ABC set");
assertIsInvalid("on pattern[every B] update ABC as abc set a=");
}
public void testValidCases() throws Exception
{
String className = SupportBean.class.getName();
String preFill = "select * from " + className;
// output rate limiting
assertIsValid("select a from B output snapshot every 1 milliseconds");
assertIsValid("select a from B output snapshot every 1 millisecond");
assertIsValid("select a from B output snapshot every 1 msec");
assertIsValid("select a from B output snapshot every 10 seconds");
assertIsValid("select a from B output snapshot every 10 second");
assertIsValid("select a from B output snapshot every 10 sec");
assertIsValid("select a from B output snapshot every 3 minutes");
assertIsValid("select a from B output snapshot every 3 minute");
assertIsValid("select a from B output snapshot every 3 min");
assertIsValid("select a from B output snapshot every 3 hours");
assertIsValid("select a from B output snapshot every 3 hour");
assertIsValid("select a from B output snapshot every 3 days");
assertIsValid("select a from B output snapshot every 3 day");
assertIsValid("select a from B output snapshot every 1 day 2 hours 3 minutes 4 seconds 5 milliseconds");
assertIsValid("select a from B output first every 5 events");
assertIsValid("select a from B output snapshot at (123, 333, 33, 33, 3)");
assertIsValid("select a from B output snapshot at (*, *, *, *, *)");
assertIsValid("select a from B output snapshot when myvar*count > 10");
assertIsValid("select a from B output snapshot when myvar*count > 10 then set myvar = 1, myvar2 = 2*5");
assertIsValid(preFill + "(string='test',intPrimitive=20).win:lenght(100)");
assertIsValid(preFill + "(string in ('b', 'a'))");
assertIsValid(preFill + "(string in ('b'))");
assertIsValid(preFill + "(string in ('b', 'c', 'x'))");
assertIsValid(preFill + "(string in [1:2))");
assertIsValid(preFill + "(string in [1:2])");
assertIsValid(preFill + "(string in (1:2))");
assertIsValid(preFill + "(string in (1:2])");
assertIsValid(preFill + "(intPrimitive between 1 and 2)");
assertIsValid(preFill + "(intPrimitive not between 1 and 2)");
assertIsValid(preFill + "(intPrimitive not in [1:2])");
assertIsValid(preFill + "(intPrimitive not in (1, 2, 3))");
assertIsValid(preFill + "().win:lenght()");
assertIsValid(preFill + "().win:lenght(4,5)");
assertIsValid(preFill + "().win:lenght(4)");
assertIsValid(preFill + "().win:lenght(\"\",5)");
assertIsValid(preFill + "().win:lenght(10.9,1E30,-4.4,\"\",5)");
assertIsValid(preFill + "().win:lenght(4).n:c(3.3, -3.3).n:other(\"price\")");
assertIsValid(preFill + "().win:lenght().n:c().n:da().n:e().n:f().n:g().n:xh(2.0)");
assertIsValid(preFill + "().win:lenght({\"s\"})");
assertIsValid(preFill + "().win:lenght({\"a\",\"b\"})");
assertIsValid(preFill + "().win:lenght({\"a\",\"b\",\"c\"})");
assertIsValid(preFill + "().win:lenght('')");
assertIsValid(preFill + "().win:lenght('s')");
assertIsValid(preFill + "().win:lenght('s',5)");
assertIsValid(preFill + "().win:lenght({'s','t'},5)");
assertIsValid(preFill + "().win:some_window('count','l','a').std:lastevent('s','tyr')");
assertIsValid(preFill + "().win:some_view({'count'},'l','a')");
assertIsValid(preFill + "().win:some_view({})");
assertIsValid(preFill + "(string != 'test').win:lenght(100)");
assertIsValid(preFill + "(string in (1:2) or katc=3 or lax like '%e%')");
assertIsValid(preFill + "(string in (1:2) and dodo=3, lax like '%e%' and oppol / yyy = 5, yunc(3))");
assertIsValid(preFill + "()[myprop]");
assertIsValid(preFill + "[myprop].win:keepall()");
assertIsValid(preFill + "[myprop as orderId][mythirdprop].win:keepall()");
assertIsValid(preFill + "[select *, abc, a.b from myprop as orderId where a=s][mythirdprop].win:keepall()");
assertIsValid(preFill + "[xyz][select *, abc, a.b from myprop].win:keepall()");
assertIsValid(preFill + "[xyz][myprop where a=x].win:keepall()");
assertIsValid("select * from A where (select * from B[myprop])");
assertIsValid("select max(intPrimitive, intBoxed) from " + className + "().std:win(20)");
assertIsValid("select max(intPrimitive, intBoxed, longBoxed) from " + className + "().std:win(20)");
assertIsValid("select min(intPrimitive, intBoxed) from " + className + "().std:win(20)");
assertIsValid("select min(intPrimitive, intBoxed, longBoxed) from " + className + "().std:win(20)");
assertIsValid(preFill + "().win:lenght(3) where a = null");
assertIsValid(preFill + "().win:lenght(3) where a is null");
assertIsValid(preFill + "().win:lenght(3) where 10 is a");
assertIsValid(preFill + "().win:lenght(3) where 10 is not a");
assertIsValid(preFill + "().win:lenght(3) where 10 <> a");
assertIsValid(preFill + "().win:lenght(3) where a <> 10");
assertIsValid(preFill + "().win:lenght(3) where a != 10");
assertIsValid(preFill + "().win:lenght(3) where 10 != a");
assertIsValid(preFill + "().win:lenght(3) where not (a = 5)");
assertIsValid(preFill + "().win:lenght(3) where not (a = 5 or b = 3)");
assertIsValid(preFill + "().win:lenght(3) where not 5 < 4");
assertIsValid(preFill + "().win:lenght(3) where a or (not b)");
assertIsValid(preFill + "().win:lenght(3) where a % 3 + 6 * (c%d)");
assertIsValid(preFill + "().win:lenght(3) where a || b = 'a'");
assertIsValid(preFill + "().win:lenght(3) where a || b || c = 'a'");
assertIsValid(preFill + "().win:lenght(3) where a + b + c = 'a'");
assertIsValid("select not a, not (b), not (a > 5) from " +
className + "(a=1).win:lenght(10) as win1," +
className + "(a=2).win:lenght(10) as win2 " +
"where win1.f1 = win2.f2"
);
assertIsValid("select intPrimitive from " +
className + "(a=1).win:lenght(10) as win1," +
className + "(a=2).win:lenght(10) as win2 " +
"where win1.f1 = win2.f2"
);
// outer joins
tryJoin("left");
tryJoin("right");
tryJoin("full");
assertIsValid("select * from A left outer join B on a = b and c=d");
assertIsValid("select * from A left outer join B on a = b and c=d inner join C on d=c");
// complex property access
assertIsValid("select array[1], map('a'), map(\"b\"), nested.nested " +
"from a.b(string='test',intPrimitive=20).win:lenght(100) " +
"where array[1].map('a').nested = 5");
assertIsValid("select array[1] as b " +
"from a.b(string[0]='test').win:lenght(100) as x " +
"left outer join " +
"a.b(string[0]='test').win:lenght(100) as y " +
"on y.array[1].map('a').nested = x.nested2");
assertIsValid("select * " +
"from A " +
"left outer join " +
"B" +
" on a = b and c=d");
assertIsValid("select a and b from b.win:length(1)");
assertIsValid("select a or b from b.win:length(1)");
assertIsValid("select a = b from b.win:length(1)");
assertIsValid("select a != b from b.win:length(1)");
assertIsValid("select a.* from b.win:length(1) as a");
assertIsValid("select a.* as myfield from b.win:length(1) as abc");
assertIsValid("select a.*, b.*, c.* from b.win:length(1) as a");
assertIsValid("select a.* as x1, b.* as x2, x.* as x3 from b.win:length(1) as a, t as x");
assertIsValid("select sum(a), avg(b) from b.win:length(1)");
assertIsValid("select sum(all a), avg(all b), avg(all b/c) from b.win:length(1)");
assertIsValid("select sum(distinct a), avg(distinct b) from b.win:length(1)");
assertIsValid("select sum(sum(a)) from b.win:length(1)");
assertIsValid("select sum(3*a), sum(a - b - c) from b.win:length(1)");
assertIsValid("select count(*), count(a), count(all b), count(distinct 2*a), count(5*a/2) from b.win:length(1)");
assertIsValid("select max(volume), min(volume), min(all volume/44), min(distinct 2*a), max(distinct 5*a/2) from b.win:length(1)");
assertIsValid("select median(volume), median(all volume*2/3), median(distinct 2*a) from b.win:length(1)");
assertIsValid("select stddev(volume), stddev(all volume), stddev(distinct 2*a) from b.win:length(1)");
assertIsValid("select avedev(volume), avedev(all volume), avedev(distinct 2*a) from b.win:length(1)");
// group-by
assertIsValid("select sum(a), x, y from b.win:length(1) group by a");
assertIsValid("select 1 from b.win:length(1) where a=b and b=d group by a,b,3*x,max(4, 3),'a', \"a\", true, 5*(1+a+y/2)");
assertIsValid("select 1 from b.win:length(1) where a"); // since a could be a boolean
assertIsValid("select sum(distinct a), x, y from b.win:length(1) group by a");
// having
assertIsValid("select sum(a), x, y from b.win:length(1) group by a having x > y");
assertIsValid("select 1 from b.win:length(1) where a=b and b=d group by a having (max(3*b - 2, 5) > 1) or 'a'=b");
assertIsValid("select 1 from b.win:length(1) group by a having a"); // a could be boolean
assertIsValid("select 1 from b.win:length(1) having a>5");
assertIsValid("SELECT 1 FROM b.win:length(1) WHERE a=b AND b=d GROUP BY a HAVING (max(3*b - 2, 5) > 1) OR 'a'=b");
// insert into
assertIsValid("insert into MyEvent select 1 from b.win:length(1)");
assertIsValid("insert into MyEvent (a) select 1 from b.win:length(1)");
assertIsValid("insert into MyEvent (a, b) select 1 from b.win:length(1)");
assertIsValid("insert into MyEvent (a, b, c) select 1 from b.win:length(1)");
assertIsValid("insert istream into MyEvent select 1 from b.win:length(1)");
assertIsValid("insert rstream into MyEvent select 1 from b.win:length(1)");
// pattern inside
assertIsValid("select * from pattern [a=" + SupportBean.class.getName() + "]");
assertIsValid("select * from pattern [a=" + SupportBean.class.getName() + "] as xyz");
assertIsValid("select * from pattern [a=" + SupportBean.class.getName() + "].win:length(100) as xyz");
assertIsValid("select * from pattern [a=" + SupportBean.class.getName() + "].win:length(100).std:someview() as xyz");
assertIsValid("select * from xxx");
assertIsValid("select rstream * from xxx");
assertIsValid("select istream * from xxx");
assertIsValid("select rstream 1, 2 from xxx");
assertIsValid("select istream 1, 2 from xxx");
// coalesce
assertIsValid("select coalesce(processTimeEvent.price, 0) from x");
assertIsValid("select coalesce(processTimeEvent.price, null, -1) from x");
assertIsValid("select coalesce(processTimeEvent.price, processTimeEvent.price, processTimeEvent.price, processTimeEvent.price) from x");
// time intervals
assertIsValid("select * from x.win:time(1 seconds)");
assertIsValid("select * from x.win:time(1.5 second)");
assertIsValid("select * from x.win:time(120230L sec)");
assertIsValid("select * from x.win:time(1.5d milliseconds)");
assertIsValid("select * from x.win:time(1E30 millisecond)");
assertIsValid("select * from x.win:time(1.0 msec)");
assertIsValid("select * from x.win:time(0001 minutes)");
assertIsValid("select * from x.win:time(.1 minute)");
assertIsValid("select * from x.win:time(1.1111001 min)");
assertIsValid("select * from x.win:time(5 hours)");
assertIsValid("select * from x.win:time(5 hour)");
assertIsValid("select * from x.win:time(5 days)");
assertIsValid("select * from x.win:time(5 day)");
assertIsValid("select * from x.win:time(3 years 1 month 2 weeks 5 days 2 hours 88 minutes 1 seconds 9.8 milliseconds)");
assertIsValid("select * from x.win:time(5 days 2 hours 88 minutes 1 seconds 9.8 milliseconds)");
assertIsValid("select * from x.win:time(5 day 2 hour 88 minute 1 second 9.8 millisecond)");
assertIsValid("select * from x.win:time(5 days 2 hours 88 minutes 1 seconds)");
assertIsValid("select * from x.win:time(5 days 2 hours 88 minutes)");
assertIsValid("select * from x.win:time(5 days 2 hours)");
assertIsValid("select * from x.win:time(2 hours 88 minutes 1 seconds 9.8 milliseconds)");
assertIsValid("select * from x.win:time(2 hours 88 minutes 1 seconds)");
assertIsValid("select * from x.win:time(2 hours 88 minutes)");
assertIsValid("select * from x.win:time(88 minutes 1 seconds 9.8 milliseconds)");
assertIsValid("select * from x.win:time(88 minutes 1 seconds)");
assertIsValid("select * from x.win:time(1 seconds 9.8 milliseconds)");
assertIsValid("select * from x.win:time(1 seconds 9.8 milliseconds).win:goodie(1 sec)");
assertIsValid("select * from x.win:time(1 seconds 9.8 milliseconds).win:goodie(1 sec).win:otto(1.1 days 1.1 msec)");
// in
assertIsValid("select * from x where a in('a')");
assertIsValid("select * from x where abc in ('a', 'b')");
assertIsValid("select * from x where abc in (8*2, 1.001, 'a' || 'b', coalesce(0,null), null)");
assertIsValid("select * from x where abc in (sum(x), max(2,2), true)");
assertIsValid("select * from x where abc in (y,z, y+z)");
assertIsValid("select * from x where abc not in (1)");
assertIsValid("select * from x where abc not in (1, 2, 3)");
assertIsValid("select * from x where abc*2/dog not in (1, 2, 3)");
// between
assertIsValid("select * from x where abc between 1 and 10");
assertIsValid("select * from x where abc between 'a' and 'x'");
assertIsValid("select * from x where abc between 1.1 and 1E1000");
assertIsValid("select * from x where abc between a and b");
assertIsValid("select * from x where abc between a*2 and sum(b)");
assertIsValid("select * from x where abc*3 between a*2 and sum(b)");
// custom aggregation func
assertIsValid("select myfunc(price) from x");
// like and regexp
assertIsValid("select * from x where abc like 'dog'");
assertIsValid("select * from x where abc like '_dog'");
assertIsValid("select * from x where abc like '%dog'");
assertIsValid("select * from x where abc like null");
assertIsValid("select * from x where abc like '%dog' escape '\\\\'");
assertIsValid("select * from x where abc like '%dog%' escape '!'");
assertIsValid("select * from x where abc like '%dog' escape \"a\"");
assertIsValid("select * from x where abc||'hairdo' like 'dog'");
assertIsValid("select * from x where abc not like 'dog'");
assertIsValid("select * from x where abc not regexp '[a-z]'");
assertIsValid("select * from x where abc regexp '[a-z]'");
assertIsValid("select * from x where a like b escape 'aa'");
// database joins
assertIsValid("select * from x, sql:mydb [\"whetever SQL $x.id google\"]");
assertIsValid("select * from x, sql:mydb ['whetever SQL $x.id google']");
assertIsValid("select * from x, sql:mydb ['']");
assertIsValid("select * from x, sql:mydb [' ']");
assertIsValid("select * from x, sql:mydb ['whetever SQL $x.id google' metadatasql 'select 1 as myint']");
// Previous and prior function
assertIsValid("select prev(10, price) from x");
assertIsValid("select prev(0, price) from x");
assertIsValid("select prev(1000, price) from x");
assertIsValid("select prev(index, price) from x");
assertIsValid("select prior(10, price) from x");
assertIsValid("select prior(0, price) from x");
assertIsValid("select prior(1000, price) from x");
assertIsValid("select prior(2, symbol) from x");
// array constants and expressions
assertIsValid("select {'a', 'b'} from x");
assertIsValid("select {'a'} from x");
assertIsValid("select {} from x");
assertIsValid("select {'a', 'b'} as yyy from x");
assertIsValid("select * from x where MyFunc.func({1,2}, xx)");
assertIsValid("select {1,2,3} from x");
assertIsValid("select {1.1,'2',3E5, 7L} from x");
assertIsValid("select * from x where oo = {1,2,3}");
assertIsValid("select {a, b}, {c, d} from x");
// subqueries
assertIsValid("select (select a from B) from x");
assertIsValid("select (select a, b,c from B) from x");
assertIsValid("select (select a||b||c from B) from x");
assertIsValid("select (select 3*222 from B) from x");
assertIsValid("select (select 3*222 from B.win:length(100)) from x");
assertIsValid("select (select x from B.win:length(100) where a=b) from x");
assertIsValid("select (select x from B.win:length(100) where a=b), (select y from C.w:g().e:o(11)) from x");
assertIsValid("select 3 + (select a from B) from x");
assertIsValid("select (select x from B) / 100, 9 * (select y from C.w:g().e:o(11))/2 from x");
assertIsValid("select * from x where id = (select a from B)");
assertIsValid("select * from x where id = -1 * (select a from B)");
assertIsValid("select * from x where id = (5-(select a from B))");
assertIsValid("select * from X where (select a from B where X.f = B.a) or (select a from B where X.f = B.c)");
assertIsValid("select * from X where exists (select * from B where X.f = B.a)");
assertIsValid("select * from X where exists (select * from B)");
assertIsValid("select * from X where not exists (select * from B where X.f = B.a)");
assertIsValid("select * from X where not exists (select * from B)");
assertIsValid("select exists (select * from B where X.f = B.a) from A");
assertIsValid("select B or exists (select * from B) from A");
assertIsValid("select c in (select * from C) from A");
assertIsValid("select c from A where b in (select * from C)");
assertIsValid("select c from A where b not in (select b from C)");
assertIsValid("select c from A where q*9 not in (select g*5 from C.win:length(100)) and r=6");
// dynamic properties
assertIsValid("select b.c.d? from E");
assertIsValid("select b.c.d?.e? from E");
assertIsValid("select b? from E");
assertIsValid("select b? as myevent from E");
assertIsValid("select * from pattern [every OrderEvent(item.name?)]");
assertIsValid("select * from pattern [every OrderEvent(item?.parent.name?='foo')]");
assertIsValid("select b.c[0].d? from E");
assertIsValid("select b.c[0]?.mapped('a')? from E");
assertIsValid("select b?.c[0].mapped('a') from E");
// Allow comments in EPL and patterns
assertIsValid("select b.c.d /* some comment */ from E");
assertIsValid("select b /* ajajaj */ .c.d /* some comment */ from E");
assertIsValid("select * from pattern [ /* filter */ every A() -> B() /* for B */]");
assertIsValid("select * from pattern [ \n// comment\nevery A() -> B() // same line\n]");
// Substitution parameters
assertIsValid(preFill + "(string=?)");
assertIsValid(preFill + "(string in (?, ?))");
assertIsValid(preFill + " where string=? and ?=val");
assertIsValid(preFill + " having avg(volume) > ?");
assertIsValid(preFill + " having avg(?) > ?");
assertIsValid("select sum(?) from b.win:length(1)");
assertIsValid("select ?||'a' from B(a=?) where c=? group by ? having d>? output every 10 events order by a, ?");
assertIsValid("select a from B output snapshot every 10 events order by a, ?");
// cast, instanceof, isnumeric and exists dynamic property
assertIsValid(preFill + "(boolean = exists(a))");
assertIsValid(preFill + "(boolean = exists(a?))");
assertIsValid(preFill + "(boolean = exists(a?))");
assertIsValid(preFill + " where exists(a.b.c?.d.e)");
assertIsValid(preFill + "(boolean = instanceof(a + 2, a))");
assertIsValid(preFill + "(boolean = instanceof(b, a))");
assertIsValid(preFill + "(boolean = instanceof('agc', string, String, java.lang.String))");
assertIsValid(preFill + "(boolean = instanceof(b, com.espertech.esper.support.AClass))");
assertIsValid(preFill + "(boolean = instanceof(b, com.espertech.esper.support.AClass, int, long, java.lang.Long))");
assertIsValid(preFill + "(cast(b as boolean))");
assertIsValid(preFill + "(cast(b? as Boolean))");
assertIsValid(preFill + "(cast(b, boolean))");
assertIsValid(preFill + "(cast(b?, Boolean))");
assertIsValid(preFill + "(cast(b?, java.lang.String))");
assertIsValid(preFill + "(cast(b?, long))");
assertIsValid(preFill + "(cast(a + 5, long))");
assertIsValid(preFill + "(isnumeric(b?))");
assertIsValid(preFill + "(isnumeric(b + 2))");
assertIsValid(preFill + "(isnumeric(\"aa\"))");
// timestamp
assertIsValid("select timestamp() from B.win:length(1)");
// named window
assertIsValid("create window AAA as MyType");
assertIsValid("create window AAA as com.myclass.MyType");
assertIsValid("create window AAA as select * from MyType");
assertIsValid("create window AAA as select a, *, b from MyType");
assertIsValid("create window AAA as select a from MyType");
assertIsValid("create window AAA.win:length(10) select a from MyType");
assertIsValid("create window AAA select a from MyType");
assertIsValid("create window AAA.win:length(10) as select a from MyType");
assertIsValid("create window AAA.win:length(10) as select a,b from MyType");
assertIsValid("create window AAA.win:length(10).win:time(1 sec) as select a,b from MyType");
assertIsValid("create window AAA as select 0 as val, 2 as noway, '' as stringval, true as boolval from MyType");
assertIsValid("create window AAA as (a b, c d, e f)");
assertIsValid("create window AAA (a b, c d, e f)");
assertIsValid("create window AAA as select * from MyOtherNamedWindow insert");
assertIsValid("create window AAA as MyOtherNamedWindow insert where b=4");
// on-delete statement
assertIsValid("on MyEvent delete from MyNamedWindow");
assertIsValid("on MyEvent delete from MyNamedWindow where key = myotherkey");
assertIsValid("on MyEvent(myval != 0) as myevent delete from MyNamedWindow as mywin where mywin.key = myevent.otherKey");
assertIsValid("on com.my.MyEvent(a=1, b=2 or c.d>3) as myevent delete from MyNamedWindow as mywin where a=b and c<d");
assertIsValid("on MyEvent yyy delete from MyNamedWindow xxx where mywin.key = myevent.otherKey");
assertIsValid("on pattern [every MyEvent or every MyEvent] delete from MyNamedWindow");
// on-select statement
assertIsValid("on MyEvent select * from MyNamedWindow");
assertIsValid("on MyEvent select a, b, c from MyNamedWindow");
assertIsValid("on MyEvent select a, b, c from MyNamedWindow where a<b");
assertIsValid("on MyEvent as event select a, b, c from MyNamedWindow as win where a.b = b.a");
assertIsValid("on MyEvent(hello) select *, c from MyNamedWindow");
assertIsValid("on pattern [every X] select a, b, c from MyNamedWindow");
assertIsValid("on MyEvent insert into YooStream select a, b, c from MyNamedWindow");
assertIsValid("on MyEvent insert into YooStream (p, q) select a, b, c from MyNamedWindow");
assertIsValid("on MyEvent select a, b, c from MyNamedWindow where a=b group by c having d>e order by f");
assertIsValid("on MyEvent insert into A select * where 1=2 insert into B select * where 2=4");
assertIsValid("on MyEvent insert into A select * where 1=2 insert into B select * where 2=4 insert into C select *");
assertIsValid("on MyEvent insert into A select a,c,b insert into G select 1,2,2,2 where 2=4 insert into C select * where a=x");
assertIsValid("on MyEvent insert into A select a,c,b where a=y group by p having q>r order by x,y insert into G select 1,2,2,2 where 2=4 insert into C select * where a=x");
assertIsValid("on MyEvent insert into A select a,c,b where a=y insert into D select * where 2=4 output first");
assertIsValid("on MyEvent insert into A select a,c,b where a=y insert into D select * where 2=4 output all");
// on-set statement
assertIsValid("on MyEvent set var=1");
assertIsValid("on MyEvent set var = true");
assertIsValid("on MyEvent as event set var = event.val");
assertIsValid("on MyEvent as event set var = event.val");
assertIsValid("on MyEvent as event set var = event.val * 2, var2='abc', var3='def'");
// on-update statement
assertIsValid("on MyEvent update ABC as abc set a=1, b=c");
assertIsValid("on MyEvent update ABC set a=1");
assertIsValid("on pattern[every B] update ABC as abc set a=1, b=abc.c");
// create variable
assertIsValid("create variable integer a = 77");
assertIsValid("create variable sometype b = 77");
assertIsValid("create variable sometype b");
// use variable in output clause
assertIsValid("select count(*) from A output every VAR1 events");
// join with method result
assertIsValid("select * from A, method:myClass.myname() as b where a.x = b.x");
assertIsValid("select method, a, b from A, METHOD:com.maypack.myClass.myname() as b where a.x = b.x");
assertIsValid("select method, a, b from A, someident:com.maypack.myClass.myname() as b where a.x = b.x");
// unidirectional join
assertIsValid("select * from A as x unidirectional, method:myClass.myname() as b where a.x = b.x");
assertIsValid("select a, b from A as y unidirectional, B as b where a.x = b.x");
assertIsValid("select a, b from A as y unidirectional, B unidirectional where a.x = b.x");
// expessions and event properties are view/guard/observer parameters
assertIsValid("select * from A.win:x(myprop.nested, a.c('s'), 'ss', abc, null)");
assertIsValid("select * from pattern[every X where a:b(myprop.nested, a.c('s'), 'ss', *, null)]");
assertIsValid("select * from pattern[every X:b(myprop.nested, a.c('s'), 'ss', *, null)]");
// properties escaped
assertIsValid("select a\\.b, a\\.b\\.c.d.e\\.f, zz\\.\\.\\.aa\\.\\.\\.b\\.\\. from A");
assertIsValid("select count from A");
// limit
assertIsValid("select count from A limit 1");
assertIsValid("select count from A limit 1,2");
assertIsValid("select count from A limit 1 offset 2");
assertIsValid("select count from A where a=b group by x having c=d output every 5 events order by r limit 1 offset 2");
assertIsValid("select count from A limit myvar");
assertIsValid("select count from A limit myvar,myvar2");
assertIsValid("select count from A limit myvar offset myvar2");
assertIsValid("select count from A limit -1");
// any, some, all
assertIsValid("select * from A where 1 = ANY (1, exp, 3)");
assertIsValid("select * from A where 1 = SOME ({1,2,3}, myvar, 2*2)");
assertIsValid("select * from A where exp = ALL ()");
assertIsValid("select * from A where 1 != ALL (select a from B)");
assertIsValid("select * from A where 1 = SOME (select a from B)");
assertIsValid("select * from A where exp > ANY (select a from B)");
assertIsValid("select * from A where 1 <= ANY (select a from B)");
assertIsValid("select * from A where {1,2,3} > ALL (1,2,3)");
// annotations
assertIsValid("@SOMEANNOTATION select * from B");
assertIsValid("@SomeOther(a=1, b=true, c='a', d=\"alal\") select * from B");
assertIsValid("@SomeOther(@inner2(a=3)) select * from B");
assertIsValid("@SomeOther(@inner1) select * from B");
assertIsValid("@SomeOther(a=com.myenum.VAL1,b=a.VAL2) select * from B");
assertIsValid("@SomeOther(tags=@inner1(a=4), moretags=@inner2(a=3)) select * from B");
assertIsValid("@SomeOther(innerdata={1, 2, 3}) select * from B");
assertIsValid("@SomeOther(innerdata={1, 2, 3}) select * from B");
String text = "@EPL(\n" +
" name=\"MyStmtName\", \n" +
" description=\"Selects all fields\", \n" +
" onUpdate=\"some test\", \n" +
" onUpdateRemove=\"some text\", \n" +
" tags=@Tags" +
")\n" +
"select * from MyField";
assertIsValid(text);
text = "@EPL(name=\"MyStmtName\"," +
" tags=@Tags(" +
" {@Tag(name=\"vehicleId\", type='int', value=100), " +
" @Tag(name=\"vehicleId\", type='int', value=100)" +
" } " +
" )" +
")\n" +
"select * from MyField";
assertIsValid(text);
assertIsValid("@Name('MyStatementName')\n" +
"@Description('This statement does ABC')\n" +
"@Tag(name='abc', value='cde')\n" +
"select a from B");
// row pattern recog
assertIsValid("select * from A match_recognize (measures A.symbol as A\n" +
"pattern (A B)\n" +
"define B as (B.price > A.price)" +
")");
assertIsValid("select * from A match_recognize (measures A.symbol as A\n" +
"pattern (A* B+ C D?)\n" +
"define B as (B.price > A.price)" +
")");
assertIsValid("select * from A match_recognize (measures A.symbol as A\n" +
"pattern (A | B)\n" +
"define B as (B.price > A.price)" +
")");
assertIsValid("select * from A match_recognize (measures A.symbol as A\n" +
"pattern ( (A B) | (C D))\n" +
"define B as (B.price > A.price)" +
")");
assertIsValid("select * from A match_recognize (measures A.symbol as A\n" +
"pattern ( (A | B) (C | D) )\n" +
"define B as (B.price > A.price)" +
")");
assertIsValid("select * from A match_recognize (measures A.symbol as A\n" +
"pattern ( (A) | (B | (D | E+)) )\n" +
"define B as (B.price > A.price)" +
")");
assertIsValid("select * from A match_recognize (measures A.symbol as A\n" +
"pattern ( A (C | D)? E )\n" +
"define B as (B.price > A.price)" +
")");
}
public void testBitWiseCases() throws Exception
{
String className = SupportBean.class.getName();
String eplSmt = "select (intPrimitive & intBoxed) from " + className;
assertIsValid(eplSmt + ".win:lenght()");
eplSmt = "select boolPrimitive|boolBoxed from " + className;
assertIsValid(eplSmt + "().std:win(20)");
eplSmt = "select bytePrimitive^byteBoxed from " + className;
assertIsValid(eplSmt + "().win:some_view({})");
}
public void testIfThenElseCase() throws Exception
{
String className = SupportBean.class.getName();
String eplSmt = "select case when 1 then (a + 1) when 2 then (a*2) end from " + className;
assertIsValid(eplSmt + ".win:lenght()");
eplSmt = "select case a when 1 then (a + 1) end from " + className;
assertIsValid(eplSmt + ".win:lenght()");
eplSmt = "select case count(*) when 10 then sum(a) when 20 then max(a*b) end from " + className;
assertIsValid(eplSmt + ".win:lenght()");
eplSmt = "select case (a>b) when true then a when false then b end from " + className;
assertIsValid(eplSmt + ".win:lenght()");
eplSmt = "select case a when true then a when false then b end from " + className;
assertIsValid(eplSmt + ".win:lenght()");
eplSmt = "select case when (a=b) then (a+b) when false then b end as p1 from " + className;
assertIsValid(eplSmt + ".win:lenght()");
eplSmt = "select case (a+b) when (a*b) then count(a+b) when false then a ^ b end as p1 from " + className;
assertIsValid(eplSmt + ".win:lenght()");
}
private void tryJoin(String joinType) throws Exception
{
String className = SupportBean.class.getName();
assertIsValid("select intPrimitive from " +
className + "(a=1).win:lenght(10) as win1 " +
joinType + " outer join " +
className + "(a=2).win:lenght(10) as win2 " +
"on win1.f1 = win2.f2"
);
assertIsValid("select intPrimitive from " +
className + "(a=1).win:lenght(10) as win1 " +
joinType + " outer join " +
className + "(a=2).win:lenght(10) as win2 " +
"on win1.f1 = win2.f2 " +
joinType + " outer join " +
className + "(a=2).win:lenght(10) as win3 " +
"on win1.f1 = win3.f3"
);
}
private void assertIsValid(String text) throws Exception
{
log.debug(".assertIsValid Trying text=" + text);
Pair<Tree, CommonTokenStream> ast = parse(text);
log.debug(".assertIsValid success, tree walking...");
SupportParserHelper.displayAST(ast.getFirst());
log.debug(".assertIsValid done");
}
private void assertIsInvalid(String text) throws Exception
{
log.debug(".assertIsInvalid Trying text=" + text);
try
{
parse(text);
assertFalse(true);
}
catch (Exception ex)
{
log.debug(".assertIsInvalid Expected ParseException exception was thrown and ignored, message=" + ex.getMessage());
}
}
private Pair<Tree, CommonTokenStream> parse(String expression) throws Exception
{
return SupportParserHelper.parseEPL(expression);
}
static Log log = LogFactory.getLog(TestEPLParser.class);
}