/* * ************************************************************************************* * 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.spec; import com.espertech.esper.collection.Pair; import com.espertech.esper.epl.expression.ExprAndNode; import com.espertech.esper.epl.expression.ExprValidationException; import com.espertech.esper.epl.parse.EPLTreeWalker; import com.espertech.esper.filter.*; import com.espertech.esper.support.bean.SupportBean; import com.espertech.esper.support.epl.parse.SupportEPLTreeWalkerFactory; import com.espertech.esper.support.epl.parse.SupportParserHelper; import com.espertech.esper.support.view.SupportStatementContextFactory; import junit.framework.TestCase; import org.antlr.runtime.CommonTokenStream; import org.antlr.runtime.tree.Tree; import java.util.*; public class TestFilterStreamSpecRaw extends TestCase { public void testNoExpr() throws Exception { FilterStreamSpecRaw raw = makeSpec("select * from " + SupportBean.class.getName()); FilterSpecCompiled spec = compile(raw); assertEquals(SupportBean.class, spec.getFilterForEventType().getUnderlyingType()); assertEquals(0, spec.getParameters().size()); } public void testMultipleExpr() throws Exception { FilterStreamSpecRaw raw = makeSpec("select * from " + SupportBean.class.getName() + "(intPrimitive-1>2 and intBoxed-5>3)"); FilterSpecCompiled spec = compile(raw); assertEquals(SupportBean.class, spec.getFilterForEventType().getUnderlyingType()); assertEquals(1, spec.getParameters().size()); // expecting unoptimized expressions to condense to a single boolean expression, more efficient this way FilterSpecParamExprNode exprNode = (FilterSpecParamExprNode) spec.getParameters().getFirst(); assertEquals(FilterSpecCompiler.PROPERTY_NAME_BOOLEAN_EXPRESSION, exprNode.getLookupable().getExpression()); assertEquals(FilterOperator.BOOLEAN_EXPRESSION, exprNode.getFilterOperator()); assertTrue(exprNode.getExprNode() instanceof ExprAndNode); } public void testInvalid() throws Exception { tryInvalid("select * from " + SupportBean.class.getName() + "(intPrimitive=5L)"); tryInvalid("select * from " + SupportBean.class.getName() + "(5d = byteBoxed)"); tryInvalid("select * from " + SupportBean.class.getName() + "(5d > longBoxed)"); tryInvalid("select * from " + SupportBean.class.getName() + "(longBoxed in (5d, 1.1d))"); } private void tryInvalid(String text) throws Exception { try { FilterStreamSpecRaw raw = makeSpec(text); compile(raw); fail(); } catch (ExprValidationException ex) { // expected } } public void testEquals() throws Exception { FilterStreamSpecRaw raw = makeSpec("select * from " + SupportBean.class.getName() + "(intPrimitive=5)"); FilterSpecCompiled spec = compile(raw); assertEquals(1, spec.getParameters().size()); assertEquals("intPrimitive", spec.getParameters().getFirst().getLookupable().getExpression()); assertEquals(FilterOperator.EQUAL, spec.getParameters().getFirst().getFilterOperator()); assertEquals(5, getConstant(spec.getParameters().getFirst())); } public void testEqualsAndLess() throws Exception { FilterStreamSpecRaw raw = makeSpec("select * from " + SupportBean.class.getName() + "(theString='a' and intPrimitive<9)"); FilterSpecCompiled spec = compile(raw); assertEquals(2, spec.getParameters().size()); Map<String, FilterSpecParam> parameters = mapParameters(spec.getParameters()); assertEquals(FilterOperator.EQUAL, parameters.get("theString").getFilterOperator()); assertEquals("a", getConstant(parameters.get("theString"))); assertEquals(FilterOperator.LESS, parameters.get("intPrimitive").getFilterOperator()); assertEquals(9, getConstant(parameters.get("intPrimitive"))); } private Map<String, FilterSpecParam> mapParameters(ArrayDeque<FilterSpecParam> parameters) { Map<String, FilterSpecParam> map = new HashMap<String, FilterSpecParam>(); for (FilterSpecParam param : parameters) { map.put(param.getLookupable().getExpression(), param); } return map; } public void testCommaAndCompar() throws Exception { FilterStreamSpecRaw raw = makeSpec("select * from " + SupportBean.class.getName() + "(doubleBoxed>1.11, doublePrimitive>=9.11 and intPrimitive<=9, theString || 'a' = 'sa')"); FilterSpecCompiled spec = compile(raw); assertEquals(4, spec.getParameters().size()); Map<String, FilterSpecParam> parameters = mapParameters(spec.getParameters()); assertEquals(FilterOperator.GREATER, parameters.get("doubleBoxed").getFilterOperator()); assertEquals(1.11, getConstant(parameters.get("doubleBoxed"))); assertEquals(FilterOperator.GREATER_OR_EQUAL, parameters.get("doublePrimitive").getFilterOperator()); assertEquals(9.11, getConstant(parameters.get("doublePrimitive"))); assertEquals(FilterOperator.LESS_OR_EQUAL, parameters.get("intPrimitive").getFilterOperator()); assertEquals(9, getConstant(parameters.get("intPrimitive"))); assertEquals(FilterOperator.BOOLEAN_EXPRESSION, parameters.get(FilterSpecCompiler.PROPERTY_NAME_BOOLEAN_EXPRESSION).getFilterOperator()); assertTrue(parameters.get(FilterSpecCompiler.PROPERTY_NAME_BOOLEAN_EXPRESSION) instanceof FilterSpecParamExprNode); } public void testNestedAnd() throws Exception { FilterStreamSpecRaw raw = makeSpec("select * from " + SupportBean.class.getName() + "((doubleBoxed=1 and doublePrimitive=2) and (intPrimitive=3 and (theString like '%_a' and theString = 'a')))"); FilterSpecCompiled spec = compile(raw); assertEquals(5, spec.getParameters().size()); Map<String, FilterSpecParam> parameters = mapParameters(spec.getParameters()); assertEquals(FilterOperator.EQUAL, parameters.get("doubleBoxed").getFilterOperator()); assertEquals(1.0, getConstant(parameters.get("doubleBoxed"))); assertEquals(FilterOperator.EQUAL, parameters.get("doublePrimitive").getFilterOperator()); assertEquals(2.0, getConstant(parameters.get("doublePrimitive"))); assertEquals(FilterOperator.EQUAL, parameters.get("intPrimitive").getFilterOperator()); assertEquals(3, getConstant(parameters.get("intPrimitive"))); assertEquals(FilterOperator.EQUAL, parameters.get("theString").getFilterOperator()); assertEquals("a", getConstant(parameters.get("theString"))); assertEquals(FilterOperator.BOOLEAN_EXPRESSION, parameters.get(FilterSpecCompiler.PROPERTY_NAME_BOOLEAN_EXPRESSION).getFilterOperator()); assertTrue(parameters.get(FilterSpecCompiler.PROPERTY_NAME_BOOLEAN_EXPRESSION) instanceof FilterSpecParamExprNode); } public void testIn() throws Exception { FilterStreamSpecRaw raw = makeSpec("select * from " + SupportBean.class.getName() + "(doubleBoxed in (1, 2, 3))"); FilterSpecCompiled spec = compile(raw); assertEquals(1, spec.getParameters().size()); assertEquals("doubleBoxed", spec.getParameters().getFirst().getLookupable().getExpression()); assertEquals(FilterOperator.IN_LIST_OF_VALUES, spec.getParameters().getFirst().getFilterOperator()); FilterSpecParamIn inParam = (FilterSpecParamIn) spec.getParameters().getFirst(); assertEquals(3, inParam.getListOfValues().size()); assertEquals(1.0, getConstant(inParam.getListOfValues().get(0))); assertEquals(2.0, getConstant(inParam.getListOfValues().get(1))); assertEquals(3.0, getConstant(inParam.getListOfValues().get(2))); } public void testNotIn() throws Exception { FilterStreamSpecRaw raw = makeSpec("select * from " + SupportBean.class.getName() + "(theString not in (\"a\"))"); FilterSpecCompiled spec = compile(raw); assertEquals(1, spec.getParameters().size()); assertEquals("theString", spec.getParameters().getFirst().getLookupable().getExpression()); assertEquals(FilterOperator.NOT_IN_LIST_OF_VALUES, spec.getParameters().getFirst().getFilterOperator()); FilterSpecParamIn inParam = (FilterSpecParamIn) spec.getParameters().getFirst(); assertEquals(1, inParam.getListOfValues().size()); assertEquals("a", getConstant(inParam.getListOfValues().get(0))); } public void testRanges() throws Exception { FilterStreamSpecRaw raw = makeSpec("select * from " + SupportBean.class.getName() + "(intBoxed in [1:5] and doubleBoxed in (2:6) and floatBoxed in (3:7] and byteBoxed in [0:1))"); FilterSpecCompiled spec = compile(raw); assertEquals(4, spec.getParameters().size()); Map<String, FilterSpecParam> parameters = mapParameters(spec.getParameters()); assertEquals(FilterOperator.RANGE_CLOSED, parameters.get("intBoxed").getFilterOperator()); FilterSpecParamRange rangeParam = (FilterSpecParamRange) parameters.get("intBoxed"); assertEquals(1.0, getConstant(rangeParam.getMin())); assertEquals(5.0, getConstant(rangeParam.getMax())); assertEquals(FilterOperator.RANGE_OPEN, parameters.get("doubleBoxed").getFilterOperator()); rangeParam = (FilterSpecParamRange) parameters.get("doubleBoxed"); assertEquals(2.0, getConstant(rangeParam.getMin())); assertEquals(6.0, getConstant(rangeParam.getMax())); assertEquals(FilterOperator.RANGE_HALF_CLOSED, parameters.get("floatBoxed").getFilterOperator()); rangeParam = (FilterSpecParamRange) parameters.get("floatBoxed"); assertEquals(3.0, getConstant(rangeParam.getMin())); assertEquals(7.0, getConstant(rangeParam.getMax())); assertEquals(FilterOperator.RANGE_HALF_OPEN, parameters.get("byteBoxed").getFilterOperator()); rangeParam = (FilterSpecParamRange) parameters.get("byteBoxed"); assertEquals(0.0, getConstant(rangeParam.getMin())); assertEquals(1.0, getConstant(rangeParam.getMax())); } public void testRangesNot() throws Exception { FilterStreamSpecRaw raw = makeSpec("select * from " + SupportBean.class.getName() + "(intBoxed not in [1:5] and doubleBoxed not in (2:6) and floatBoxed not in (3:7] and byteBoxed not in [0:1))"); FilterSpecCompiled spec = compile(raw); assertEquals(4, spec.getParameters().size()); Map<String, FilterSpecParam> parameters = mapParameters(spec.getParameters()); assertEquals(FilterOperator.NOT_RANGE_CLOSED, parameters.get("intBoxed").getFilterOperator()); FilterSpecParamRange rangeParam = (FilterSpecParamRange) parameters.get("intBoxed"); assertEquals(1.0, getConstant(rangeParam.getMin())); assertEquals(5.0, getConstant(rangeParam.getMax())); assertEquals(FilterOperator.NOT_RANGE_OPEN, parameters.get("doubleBoxed").getFilterOperator()); rangeParam = (FilterSpecParamRange) parameters.get("doubleBoxed"); assertEquals(2.0, getConstant(rangeParam.getMin())); assertEquals(6.0, getConstant(rangeParam.getMax())); assertEquals(FilterOperator.NOT_RANGE_HALF_CLOSED, parameters.get("floatBoxed").getFilterOperator()); rangeParam = (FilterSpecParamRange) parameters.get("floatBoxed"); assertEquals(3.0, getConstant(rangeParam.getMin())); assertEquals(7.0, getConstant(rangeParam.getMax())); assertEquals(FilterOperator.NOT_RANGE_HALF_OPEN, parameters.get("byteBoxed").getFilterOperator()); rangeParam = (FilterSpecParamRange) parameters.get("byteBoxed"); assertEquals(0.0, getConstant(rangeParam.getMin())); assertEquals(1.0, getConstant(rangeParam.getMax())); } private double getConstant(FilterSpecParamRangeValue param) { return ((RangeValueDouble) param).getDoubleValue(); } private Object getConstant(FilterSpecParamInValue param) { InSetOfValuesConstant constant = (InSetOfValuesConstant) param; return constant.getConstant(); } private Object getConstant(FilterSpecParam param) { FilterSpecParamConstant constant = (FilterSpecParamConstant) param; return constant.getFilterConstant(); } private FilterSpecCompiled compile(FilterStreamSpecRaw raw) throws Exception { FilterStreamSpecCompiled compiled = (FilterStreamSpecCompiled) raw.compile(SupportStatementContextFactory.makeContext(), new HashSet<String>(), false, Collections.<Integer>emptyList()); return compiled.getFilterSpec(); } private static FilterStreamSpecRaw makeSpec(String expression) throws Exception { Pair<Tree, CommonTokenStream> ast = SupportParserHelper.parseEPL(expression); SupportParserHelper.displayAST(ast.getFirst()); EPLTreeWalker walker = SupportEPLTreeWalkerFactory.makeWalker(ast.getFirst(), ast.getSecond()); walker.startEPLExpressionRule(); return (FilterStreamSpecRaw) walker.getStatementSpec().getStreamSpecs().get(0); } }