/*
***************************************************************************************
* Copyright (C) 2006 EsperTech, Inc. All rights reserved. *
* http://www.espertech.com/esper *
* 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.regression.epl;
import com.espertech.esper.client.*;
import com.espertech.esper.client.scopetest.EPAssertionUtil;
import com.espertech.esper.client.scopetest.SupportUpdateListener;
import com.espertech.esper.epl.join.plan.*;
import com.espertech.esper.epl.join.util.QueryPlanIndexDescOnExpr;
import com.espertech.esper.epl.join.util.QueryPlanIndexDescSubquery;
import com.espertech.esper.epl.lookup.*;
import com.espertech.esper.supportregression.bean.SupportBean;
import com.espertech.esper.supportregression.bean.SupportBean_S0;
import com.espertech.esper.supportregression.bean.SupportBean_S1;
import com.espertech.esper.supportregression.bean.SupportBean_S2;
import com.espertech.esper.supportregression.client.SupportConfigFactory;
import com.espertech.esper.supportregression.epl.SupportExprNodeFactory;
import com.espertech.esper.supportregression.epl.SupportQueryPlanBuilder;
import com.espertech.esper.supportregression.epl.SupportQueryPlanIndexHelper;
import com.espertech.esper.supportregression.epl.SupportQueryPlanIndexHook;
import com.espertech.esper.supportregression.util.IndexBackingTableInfo;
import junit.framework.TestCase;
import java.util.Collection;
import java.util.Map;
public class TestInKeywordQueryPlan extends TestCase implements IndexBackingTableInfo
{
private EPServiceProvider epService;
private SupportUpdateListener listener;
public void setUp()
{
Configuration configuration = SupportConfigFactory.getConfiguration();
configuration.getEngineDefaults().getLogging().setEnableQueryPlan(true);
epService = EPServiceProviderManager.getDefaultProvider(configuration);
epService.initialize();
listener = new SupportUpdateListener();
epService.getEPAdministrator().getConfiguration().addEventType("S0", SupportBean_S0.class);
epService.getEPAdministrator().getConfiguration().addEventType("S1", SupportBean_S1.class);
epService.getEPAdministrator().getConfiguration().addEventType("S2", SupportBean_S2.class);
epService.getEPAdministrator().getConfiguration().addEventType(SupportBean.class);
}
protected void tearDown() throws Exception {
listener = null;
}
public void testNotIn()
{
SupportQueryPlanIndexHook.reset();
String epl = INDEX_CALLBACK_HOOK + "select * from S0 as s0 unidirectional, S1#keepall as s1 " +
"where p00 not in (p10, p11)";
EPStatement stmt = epService.getEPAdministrator().createEPL(epl);
stmt.addListener(listener);
Map<TableLookupIndexReqKey, QueryPlanIndexItem> items = SupportQueryPlanIndexHook.assertJoinAndReset().getIndexSpecs()[1].getItems();
assertEquals("null", SupportQueryPlanIndexHelper.getIndexedExpressions(items));
}
public void testMultiIdxMultipleInAndMultirow()
{
// assert join
SupportQueryPlanIndexHook.reset();
String epl = INDEX_CALLBACK_HOOK + "select * from S0 as s0 unidirectional, S1#keepall as s1 " +
"where p00 in (p10, p11) and p01 in (p12, p13)";
EPStatement stmt = epService.getEPAdministrator().createEPL(epl);
stmt.addListener(listener);
Map<TableLookupIndexReqKey, QueryPlanIndexItem> items = SupportQueryPlanIndexHook.assertJoinAndReset().getIndexSpecs()[1].getItems();
assertEquals("[p10][p11]", SupportQueryPlanIndexHelper.getIndexedExpressions(items));
runAssertionMultiIdx();
epService.getEPAdministrator().destroyAllStatements();
// assert named window
epService.getEPAdministrator().createEPL("create window S1Window#keepall as S1");
epService.getEPAdministrator().createEPL("insert into S1Window select * from S1");
String eplNamedWindow = INDEX_CALLBACK_HOOK + "on S0 as s0 select * from S1Window as s1 " +
"where p00 in (p10, p11) and p01 in (p12, p13)";
EPStatement stmtNamedWindow = epService.getEPAdministrator().createEPL(eplNamedWindow);
stmtNamedWindow.addListener(listener);
QueryPlanIndexDescOnExpr onExprNamedWindow = SupportQueryPlanIndexHook.assertOnExprAndReset();
assertEquals(SubordInKeywordMultiTableLookupStrategyFactory.class.getSimpleName(), onExprNamedWindow.getTableLookupStrategy());
runAssertionMultiIdx();
// assert table
epService.getEPAdministrator().createEPL("create table S1Table(id int primary key, p10 string primary key, p11 string primary key, p12 string primary key, p13 string primary key)");
epService.getEPAdministrator().createEPL("insert into S1Table select * from S1");
epService.getEPAdministrator().createEPL("create index S1Idx1 on S1Table(p10)");
epService.getEPAdministrator().createEPL("create index S1Idx2 on S1Table(p11)");
epService.getEPAdministrator().createEPL("create index S1Idx3 on S1Table(p12)");
epService.getEPAdministrator().createEPL("create index S1Idx4 on S1Table(p13)");
String eplTable = INDEX_CALLBACK_HOOK + "on S0 as s0 select * from S1Table as s1 " +
"where p00 in (p10, p11) and p01 in (p12, p13)";
EPStatement stmtTable = epService.getEPAdministrator().createEPL(eplTable);
stmtTable.addListener(listener);
QueryPlanIndexDescOnExpr onExprTable = SupportQueryPlanIndexHook.assertOnExprAndReset();
assertEquals(SubordInKeywordMultiTableLookupStrategyFactory.class.getSimpleName(), onExprTable.getTableLookupStrategy());
runAssertionMultiIdx();
}
public void testMultiIdxSubquery() {
String epl = INDEX_CALLBACK_HOOK + "select s0.id as c0," +
"(select * from S1#keepall as s1 " +
" where s0.p00 in (s1.p10, s1.p11) and s0.p01 in (s1.p12, s1.p13))" +
".selectFrom(a=>S1.id) as c1 " +
"from S0 as s0";
EPStatement stmt = epService.getEPAdministrator().createEPL(epl);
stmt.addListener(listener);
QueryPlanIndexDescSubquery subquery = SupportQueryPlanIndexHook.assertSubqueryAndReset();
assertEquals(SubordInKeywordMultiTableLookupStrategyFactory.class.getSimpleName(), subquery.getTableLookupStrategy());
// single row tests
epService.getEPRuntime().sendEvent(new SupportBean_S1(101, "a", "b", "c", "d"));
epService.getEPRuntime().sendEvent(new SupportBean_S0(1, "a", "x"));
assertSubqueryC0C1(1, null);
epService.getEPRuntime().sendEvent(new SupportBean_S0(2, "x", "c"));
assertSubqueryC0C1(2, null);
epService.getEPRuntime().sendEvent(new SupportBean_S0(3, "a", "c"));
assertSubqueryC0C1(3, new Integer[] {101});
epService.getEPRuntime().sendEvent(new SupportBean_S0(4, "b", "d"));
assertSubqueryC0C1(4, new Integer[] {101});
epService.getEPRuntime().sendEvent(new SupportBean_S0(5, "a", "d"));
assertSubqueryC0C1(5, new Integer[] {101});
// 2-row tests
epService.getEPRuntime().sendEvent(new SupportBean_S1(102, "a1", "a", "d1", "d"));
epService.getEPRuntime().sendEvent(new SupportBean_S0(10, "a", "x"));
assertSubqueryC0C1(10, null);
epService.getEPRuntime().sendEvent(new SupportBean_S0(11, "x", "c"));
assertSubqueryC0C1(11, null);
epService.getEPRuntime().sendEvent(new SupportBean_S0(12, "a", "c"));
assertSubqueryC0C1(12, new Integer[]{101});
epService.getEPRuntime().sendEvent(new SupportBean_S0(13, "a", "d"));
assertSubqueryC0C1(13, new Integer[]{101, 102});
epService.getEPRuntime().sendEvent(new SupportBean_S0(14, "a1", "d"));
assertSubqueryC0C1(14, new Integer[]{102});
epService.getEPRuntime().sendEvent(new SupportBean_S0(15, "a", "d1"));
assertSubqueryC0C1(15, new Integer[]{102});
// 3-row tests
epService.getEPRuntime().sendEvent(new SupportBean_S1(103, "a", "a2", "d", "d2"));
epService.getEPRuntime().sendEvent(new SupportBean_S0(20, "a", "c"));
assertSubqueryC0C1(20, new Integer[]{101});
epService.getEPRuntime().sendEvent(new SupportBean_S0(21, "a", "d"));
assertSubqueryC0C1(21, new Integer[]{101, 102, 103});
epService.getEPRuntime().sendEvent(new SupportBean_S0(22, "a2", "d"));
assertSubqueryC0C1(22, new Integer[]{103});
epService.getEPRuntime().sendEvent(new SupportBean_S0(23, "a", "d2"));
assertSubqueryC0C1(23, new Integer[]{103});
// test coercion absence - types the same
String eplCoercion = INDEX_CALLBACK_HOOK + "select *," +
"(select * from S0#keepall as s0 where sb.longPrimitive in (id)) from SupportBean as sb";
epService.getEPAdministrator().createEPL(eplCoercion);
QueryPlanIndexDescSubquery subqueryCoercion = SupportQueryPlanIndexHook.assertSubqueryAndReset();
assertEquals(SubordFullTableScanLookupStrategyFactory.class.getSimpleName(), subqueryCoercion.getTableLookupStrategy());
}
public void testSingleIdxMultipleInAndMultirow() {
// assert join
SupportQueryPlanIndexHook.reset();
String epl = INDEX_CALLBACK_HOOK + "select * from S0#keepall as s0, S1 as s1 unidirectional " +
"where p00 in (p10, p11) and p01 in (p12, p13)";
EPStatement stmt = epService.getEPAdministrator().createEPL(epl);
stmt.addListener(listener);
Map<TableLookupIndexReqKey, QueryPlanIndexItem> items = SupportQueryPlanIndexHook.assertJoinAndReset().getIndexSpecs()[0].getItems();
assertEquals("[p00]", SupportQueryPlanIndexHelper.getIndexedExpressions(items));
runAssertionSingleIdx();
epService.getEPAdministrator().destroyAllStatements();
// assert named window
epService.getEPAdministrator().createEPL("create window S0Window#keepall as S0");
epService.getEPAdministrator().createEPL("insert into S0Window select * from S0");
String eplNamedWindow = INDEX_CALLBACK_HOOK + "on S1 as s1 select * from S0Window as s0 " +
"where p00 in (p10, p11) and p01 in (p12, p13)";
EPStatement stmtNamedWindow = epService.getEPAdministrator().createEPL(eplNamedWindow);
stmtNamedWindow.addListener(listener);
QueryPlanIndexDescOnExpr onExprNamedWindow = SupportQueryPlanIndexHook.assertOnExprAndReset();
assertEquals(SubordInKeywordSingleTableLookupStrategyFactory.class.getSimpleName(), onExprNamedWindow.getTableLookupStrategy());
runAssertionSingleIdx();
// assert table
epService.getEPAdministrator().createEPL("create table S0Table(id int primary key, p00 string primary key, p01 string primary key, p02 string primary key, p03 string primary key)");
epService.getEPAdministrator().createEPL("insert into S0Table select * from S0");
epService.getEPAdministrator().createEPL("create index S0Idx1 on S0Table(p00)");
epService.getEPAdministrator().createEPL("create index S0Idx2 on S0Table(p01)");
String eplTable = INDEX_CALLBACK_HOOK + "on S1 as s1 select * from S0Table as s0 " +
"where p00 in (p10, p11) and p01 in (p12, p13)";
EPStatement stmtTable = epService.getEPAdministrator().createEPL(eplTable);
stmtTable.addListener(listener);
QueryPlanIndexDescOnExpr onExprTable = SupportQueryPlanIndexHook.assertOnExprAndReset();
assertEquals(SubordInKeywordSingleTableLookupStrategyFactory.class.getSimpleName(), onExprTable.getTableLookupStrategy());
runAssertionSingleIdx();
}
public void testSingleIdxSubquery() {
SupportQueryPlanIndexHook.reset();
String epl = INDEX_CALLBACK_HOOK + "select s1.id as c0," +
"(select * from S0#keepall as s0 " +
" where s0.p00 in (s1.p10, s1.p11) and s0.p01 in (s1.p12, s1.p13))" +
".selectFrom(a=>S0.id) as c1 " +
" from S1 as s1";
EPStatement stmt = epService.getEPAdministrator().createEPL(epl);
stmt.addListener(listener);
QueryPlanIndexDescSubquery subquery = SupportQueryPlanIndexHook.assertSubqueryAndReset();
assertEquals(SubordInKeywordSingleTableLookupStrategyFactory.class.getSimpleName(), subquery.getTableLookupStrategy());
// single row tests
epService.getEPRuntime().sendEvent(new SupportBean_S0(100, "a", "c"));
epService.getEPRuntime().sendEvent(new SupportBean_S1(1, "a1", "b", "c", "d"));
assertSubqueryC0C1(1, null);
epService.getEPRuntime().sendEvent(new SupportBean_S1(2, "a", "b", "x", "d"));
assertSubqueryC0C1(2, null);
epService.getEPRuntime().sendEvent(new SupportBean_S1(3, "a", "b", "c", "d"));
assertSubqueryC0C1(3, new Integer[] {100});
epService.getEPRuntime().sendEvent(new SupportBean_S1(4, "x", "a", "x", "c"));
assertSubqueryC0C1(4, new Integer[] {100});
// 2-rows available tests
epService.getEPRuntime().sendEvent(new SupportBean_S0(101, "a", "d"));
epService.getEPRuntime().sendEvent(new SupportBean_S1(10, "a1", "b", "c", "d"));
assertSubqueryC0C1(10, null);
epService.getEPRuntime().sendEvent(new SupportBean_S1(11, "a", "b", "x", "c1"));
assertSubqueryC0C1(11, null);
epService.getEPRuntime().sendEvent(new SupportBean_S1(12, "a", "b", "c", "d"));
assertSubqueryC0C1(12, new Integer[] {100, 101});
epService.getEPRuntime().sendEvent(new SupportBean_S1(13, "x", "a", "x", "c"));
assertSubqueryC0C1(13, new Integer[] {100});
epService.getEPRuntime().sendEvent(new SupportBean_S1(14, "x", "a", "d", "x"));
assertSubqueryC0C1(14, new Integer[] {101});
// 3-rows available tests
epService.getEPRuntime().sendEvent(new SupportBean_S0(102, "b", "c"));
epService.getEPRuntime().sendEvent(new SupportBean_S1(20, "a1", "b", "c1", "d"));
assertSubqueryC0C1(20, null);
epService.getEPRuntime().sendEvent(new SupportBean_S1(21, "a", "b", "x", "c1"));
assertSubqueryC0C1(21, null);
epService.getEPRuntime().sendEvent(new SupportBean_S1(22, "a", "b", "c", "d"));
assertSubqueryC0C1(22, new Integer[] {100, 101, 102});
epService.getEPRuntime().sendEvent(new SupportBean_S1(23, "b", "a", "x", "c"));
assertSubqueryC0C1(23, new Integer[] {100, 102});
epService.getEPRuntime().sendEvent(new SupportBean_S1(24, "b", "a", "d", "c"));
assertSubqueryC0C1(24, new Integer[] {100, 101, 102});
epService.getEPRuntime().sendEvent(new SupportBean_S1(25, "b", "x", "x", "c"));
assertSubqueryC0C1(25, new Integer[] {102});
// test coercion absence - types the same
String eplCoercion = INDEX_CALLBACK_HOOK + "select *," +
"(select * from SupportBean#keepall as sb where sb.longPrimitive in (s0.id)) from S0 as s0";
epService.getEPAdministrator().createEPL(eplCoercion);
QueryPlanIndexDescSubquery subqueryCoercion = SupportQueryPlanIndexHook.assertSubqueryAndReset();
assertEquals(SubordFullTableScanLookupStrategyFactory.class.getSimpleName(), subqueryCoercion.getTableLookupStrategy());
}
private void runAssertionSingleIdx()
{
String[] fields = "s0.id,s1.id".split(",");
// single row tests
epService.getEPRuntime().sendEvent(new SupportBean_S0(100, "a", "c"));
epService.getEPRuntime().sendEvent(new SupportBean_S1(0, "a1", "b", "c", "d"));
epService.getEPRuntime().sendEvent(new SupportBean_S1(0, "a", "b", "x", "d"));
assertFalse(listener.isInvoked());
epService.getEPRuntime().sendEvent(new SupportBean_S1(1, "a", "b", "c", "d"));
EPAssertionUtil.assertPropsPerRow(listener.getAndResetLastNewData(), fields, new Object[][] {{100, 1}});
epService.getEPRuntime().sendEvent(new SupportBean_S1(2, "x", "a", "x", "c"));
EPAssertionUtil.assertPropsPerRow(listener.getAndResetLastNewData(), fields, new Object[][] {{100, 2}});
// 2-rows available tests
epService.getEPRuntime().sendEvent(new SupportBean_S0(101, "a", "d"));
epService.getEPRuntime().sendEvent(new SupportBean_S1(0, "a1", "b", "c", "d"));
epService.getEPRuntime().sendEvent(new SupportBean_S1(0, "a", "b", "x", "c1"));
assertFalse(listener.isInvoked());
epService.getEPRuntime().sendEvent(new SupportBean_S1(10, "a", "b", "c", "d"));
EPAssertionUtil.assertPropsPerRow(listener.getAndResetLastNewData(), fields, new Object[][] {{100, 10}, {101, 10}});
epService.getEPRuntime().sendEvent(new SupportBean_S1(11, "x", "a", "x", "c"));
EPAssertionUtil.assertPropsPerRow(listener.getAndResetLastNewData(), fields, new Object[][] {{100, 11}});
epService.getEPRuntime().sendEvent(new SupportBean_S1(12, "x", "a", "d", "x"));
EPAssertionUtil.assertPropsPerRow(listener.getAndResetLastNewData(), fields, new Object[][] {{101, 12}});
// 3-rows available tests
epService.getEPRuntime().sendEvent(new SupportBean_S0(102, "b", "c"));
epService.getEPRuntime().sendEvent(new SupportBean_S1(0, "a1", "b", "c1", "d"));
epService.getEPRuntime().sendEvent(new SupportBean_S1(0, "a", "b", "x", "c1"));
assertFalse(listener.isInvoked());
epService.getEPRuntime().sendEvent(new SupportBean_S1(20, "a", "b", "c", "d"));
EPAssertionUtil.assertPropsPerRow(listener.getAndResetLastNewData(), fields, new Object[][] {{100, 20}, {101, 20}, {102, 20}});
epService.getEPRuntime().sendEvent(new SupportBean_S1(21, "b", "a", "x", "c"));
EPAssertionUtil.assertPropsPerRowAnyOrder(listener.getAndResetLastNewData(), fields, new Object[][]{{100, 21}, {102, 21}});
epService.getEPRuntime().sendEvent(new SupportBean_S1(22, "b", "a", "d", "c"));
EPAssertionUtil.assertPropsPerRowAnyOrder(listener.getAndResetLastNewData(), fields, new Object[][]{{100, 22}, {101, 22}, {102, 22}});
epService.getEPRuntime().sendEvent(new SupportBean_S1(23, "b", "x", "x", "c"));
EPAssertionUtil.assertPropsPerRowAnyOrder(listener.getAndResetLastNewData(), fields, new Object[][] {{102, 23}});
epService.getEPAdministrator().destroyAllStatements();
}
private void runAssertionMultiIdx() {
String[] fields = "s0.id,s1.id".split(",");
// single row tests
epService.getEPRuntime().sendEvent(new SupportBean_S1(101, "a", "b", "c", "d"));
epService.getEPRuntime().sendEvent(new SupportBean_S0(0, "a", "x"));
epService.getEPRuntime().sendEvent(new SupportBean_S0(0, "x", "c"));
assertFalse(listener.isInvoked());
epService.getEPRuntime().sendEvent(new SupportBean_S0(1, "a", "c"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{1, 101});
epService.getEPRuntime().sendEvent(new SupportBean_S0(2, "b", "d"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{2, 101});
epService.getEPRuntime().sendEvent(new SupportBean_S0(3, "a", "d"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{3, 101});
// 2-row tests
epService.getEPRuntime().sendEvent(new SupportBean_S1(102, "a1", "a", "d1", "d"));
epService.getEPRuntime().sendEvent(new SupportBean_S0(0, "a", "x"));
epService.getEPRuntime().sendEvent(new SupportBean_S0(0, "x", "c"));
assertFalse(listener.isInvoked());
epService.getEPRuntime().sendEvent(new SupportBean_S0(10, "a", "c"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{10, 101});
epService.getEPRuntime().sendEvent(new SupportBean_S0(11, "a", "d"));
EPAssertionUtil.assertPropsPerRow(listener.getAndResetLastNewData(), fields, new Object[][]{{11, 101}, {11, 102}});
epService.getEPRuntime().sendEvent(new SupportBean_S0(12, "a1", "d"));
EPAssertionUtil.assertPropsPerRow(listener.getAndResetLastNewData(), fields, new Object[][]{{12, 102}});
epService.getEPRuntime().sendEvent(new SupportBean_S0(13, "a", "d1"));
EPAssertionUtil.assertPropsPerRow(listener.getAndResetLastNewData(), fields, new Object[][]{{13, 102}});
// 3-row tests
epService.getEPRuntime().sendEvent(new SupportBean_S1(103, "a", "a2", "d", "d2"));
epService.getEPRuntime().sendEvent(new SupportBean_S0(20, "a", "c"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{20, 101});
epService.getEPRuntime().sendEvent(new SupportBean_S0(21, "a", "d"));
EPAssertionUtil.assertPropsPerRowAnyOrder(listener.getAndResetLastNewData(), fields, new Object[][]{{21, 101}, {21, 102}, {21, 103}});
epService.getEPRuntime().sendEvent(new SupportBean_S0(22, "a2", "d"));
EPAssertionUtil.assertPropsPerRow(listener.getAndResetLastNewData(), fields, new Object[][]{{22, 103}});
epService.getEPRuntime().sendEvent(new SupportBean_S0(23, "a", "d2"));
EPAssertionUtil.assertPropsPerRow(listener.getAndResetLastNewData(), fields, new Object[][]{{23, 103}});
epService.getEPAdministrator().destroyAllStatements();
}
public void testSingleIdxConstants()
{
SupportQueryPlanIndexHook.reset();
String epl = INDEX_CALLBACK_HOOK + "select * from S0 as s0 unidirectional, S1#keepall as s1 " +
"where p10 in ('a', 'b')";
String[] fields = "s0.id,s1.id".split(",");
EPStatement stmt = epService.getEPAdministrator().createEPL(epl);
stmt.addListener(listener);
Map<TableLookupIndexReqKey, QueryPlanIndexItem> items = SupportQueryPlanIndexHook.assertJoinAndReset().getIndexSpecs()[1].getItems();
assertEquals("[p10]", SupportQueryPlanIndexHelper.getIndexedExpressions(items));
epService.getEPRuntime().sendEvent(new SupportBean_S1(100, "x"));
epService.getEPRuntime().sendEvent(new SupportBean_S1(101, "a"));
epService.getEPRuntime().sendEvent(new SupportBean_S0(1));
EPAssertionUtil.assertPropsPerRowAnyOrder(listener.getAndResetLastNewData(), fields, new Object[][]{{1, 101}});
epService.getEPRuntime().sendEvent(new SupportBean_S1(102, "b"));
epService.getEPRuntime().sendEvent(new SupportBean_S0(2));
EPAssertionUtil.assertPropsPerRowAnyOrder(listener.getAndResetLastNewData(), fields, new Object[][]{{2, 101}, {2, 102}});
}
public void testMultiIdxConstants()
{
SupportQueryPlanIndexHook.reset();
String epl = INDEX_CALLBACK_HOOK + "select * from S0 as s0 unidirectional, S1#keepall as s1 " +
"where 'a' in (p10, p11)";
String[] fields = "s0.id,s1.id".split(",");
EPStatement stmt = epService.getEPAdministrator().createEPL(epl);
stmt.addListener(listener);
Map<TableLookupIndexReqKey, QueryPlanIndexItem> items = SupportQueryPlanIndexHook.assertJoinAndReset().getIndexSpecs()[1].getItems();
assertEquals("[p10][p11]", SupportQueryPlanIndexHelper.getIndexedExpressions(items));
epService.getEPRuntime().sendEvent(new SupportBean_S1(100, "x", "y"));
epService.getEPRuntime().sendEvent(new SupportBean_S1(101, "x", "a"));
epService.getEPRuntime().sendEvent(new SupportBean_S0(1));
EPAssertionUtil.assertPropsPerRowAnyOrder(listener.getAndResetLastNewData(), fields, new Object[][]{{1, 101}});
epService.getEPRuntime().sendEvent(new SupportBean_S1(102, "b", "a"));
epService.getEPRuntime().sendEvent(new SupportBean_S0(2));
EPAssertionUtil.assertPropsPerRowAnyOrder(listener.getAndResetLastNewData(), fields, new Object[][]{{2, 101}, {2, 102}});
}
public void testQueryPlan3Stream()
{
String epl = "select * from S0 as s0 unidirectional, S1#keepall, S2#keepall ";
// 3-stream join with in-multiindex directional
InKeywordTableLookupPlanMultiIdx planInMidx = new InKeywordTableLookupPlanMultiIdx(0, 1, getIndexKeys("i1a", "i1b"), SupportExprNodeFactory.makeIdentExprNode("p00"));
runAssertion(epl + " where p00 in (p10, p11)",
SupportQueryPlanBuilder.start(3)
.addIndexHashSingleNonUnique(1, "i1a", "p10")
.addIndexHashSingleNonUnique(1, "i1b", "p11")
.setIndexFullTableScan(2, "i2")
.setLookupPlanInstruction(0, "s0", new LookupInstructionPlan[]{
new LookupInstructionPlan(0, "s0", new int[] {1},
new TableLookupPlan[] {planInMidx}, null, new boolean[3]),
new LookupInstructionPlan(0, "s0", new int[] {2},
new TableLookupPlan[] {new FullTableScanLookupPlan(1, 2, getIndexKey("i2"))}, null, new boolean[3])
})
.get());
InKeywordTableLookupPlanMultiIdx planInMidxMulitiSrc = new InKeywordTableLookupPlanMultiIdx(0, 1, getIndexKeys("i1", "i2"), SupportExprNodeFactory.makeIdentExprNode("p00"));
runAssertion(epl + " where p00 in (p10, p20)",
SupportQueryPlanBuilder.start(3)
.setIndexFullTableScan(1, "i1")
.setIndexFullTableScan(2, "i2")
.setLookupPlanInstruction(0, "s0", new LookupInstructionPlan[]{
new LookupInstructionPlan(0, "s0", new int[] {1},
new TableLookupPlan[] {new FullTableScanLookupPlan(0, 1, getIndexKey("i1"))}, null, new boolean[3]),
new LookupInstructionPlan(0, "s0", new int[] {2},
new TableLookupPlan[] {new FullTableScanLookupPlan(1, 2, getIndexKey("i2"))}, null, new boolean[3])
})
.get());
// 3-stream join with in-singleindex directional
InKeywordTableLookupPlanSingleIdx planInSidx = new InKeywordTableLookupPlanSingleIdx(0, 1, getIndexKey("i1"), SupportExprNodeFactory.makeIdentExprNodes("p00", "p01"));
runAssertion(epl + " where p10 in (p00, p01)", getSingleIndexPlan(planInSidx));
// 3-stream join with in-singleindex multi-sourced
InKeywordTableLookupPlanSingleIdx planInSingleMultiSrc = new InKeywordTableLookupPlanSingleIdx(0, 1, getIndexKey("i1"), SupportExprNodeFactory.makeIdentExprNodes("p00"));
runAssertion(epl + " where p10 in (p00, p20)", getSingleIndexPlan(planInSingleMultiSrc));
}
public void testQueryPlan2Stream()
{
String epl = "select * from S0 as s0 unidirectional, S1#keepall ";
QueryPlan fullTableScan = SupportQueryPlanBuilder.start(2)
.setIndexFullTableScan(1, "a")
.setLookupPlanInner(0, new FullTableScanLookupPlan(0, 1, getIndexKey("a"))).get();
// 2-stream unidirectional joins
runAssertion(epl, fullTableScan);
QueryPlan planEquals = SupportQueryPlanBuilder.start(2)
.addIndexHashSingleNonUnique(1, "a", "p10")
.setLookupPlanInner(0, new IndexedTableLookupPlanSingle(0, 1, getIndexKey("a"), SupportExprNodeFactory.makeKeyed("p00"))).get();
runAssertion(epl + "where p00 = p10", planEquals);
runAssertion(epl + "where p00 = p10 and p00 in (p11, p12, p13)", planEquals);
QueryPlan planInMultiInner = SupportQueryPlanBuilder.start(2)
.addIndexHashSingleNonUnique(1, "a", "p11")
.addIndexHashSingleNonUnique(1, "b", "p12")
.setLookupPlanInner(0, new InKeywordTableLookupPlanMultiIdx(0, 1, getIndexKeys("a", "b"), SupportExprNodeFactory.makeIdentExprNode("p00"))).get();
runAssertion(epl + "where p00 in (p11, p12)", planInMultiInner);
runAssertion(epl + "where p00 = p11 or p00 = p12", planInMultiInner);
QueryPlan planInMultiOuter = SupportQueryPlanBuilder.start(planInMultiInner)
.setLookupPlanOuter(0, new InKeywordTableLookupPlanMultiIdx(0, 1, getIndexKeys("a", "b"), SupportExprNodeFactory.makeIdentExprNode("p00"))).get();
String eplOuterJoin = "select * from S0 as s0 unidirectional full outer join S1#keepall ";
runAssertion(eplOuterJoin + "where p00 in (p11, p12)", planInMultiOuter);
QueryPlan planInMultiWConst = SupportQueryPlanBuilder.start(2)
.addIndexHashSingleNonUnique(1, "a", "p11")
.addIndexHashSingleNonUnique(1, "b", "p12")
.setLookupPlanInner(0, new InKeywordTableLookupPlanMultiIdx(0, 1, getIndexKeys("a", "b"), SupportExprNodeFactory.makeConstExprNode("A"))).get();
runAssertion(epl + "where 'A' in (p11, p12)", planInMultiWConst);
runAssertion(epl + "where 'A' = p11 or 'A' = p12", planInMultiWConst);
QueryPlan planInMultiWAddConst = SupportQueryPlanBuilder.start(2)
.addIndexHashSingleNonUnique(1, "a", "p12")
.setLookupPlanInner(0, new InKeywordTableLookupPlanMultiIdx(0, 1, getIndexKeys("a"), SupportExprNodeFactory.makeConstExprNode("A"))).get();
runAssertion(epl + "where 'A' in ('B', p12)", planInMultiWAddConst);
runAssertion(epl + "where 'A' in ('B', 'C')", fullTableScan);
QueryPlan planInSingle = SupportQueryPlanBuilder.start(2)
.addIndexHashSingleNonUnique(1, "a", "p10")
.setLookupPlanInner(0, new InKeywordTableLookupPlanSingleIdx(0, 1, getIndexKey("a"), SupportExprNodeFactory.makeIdentExprNodes("p00", "p01"))).get();
runAssertion(epl + "where p10 in (p00, p01)", planInSingle);
QueryPlan planInSingleWConst = SupportQueryPlanBuilder.start(2)
.addIndexHashSingleNonUnique(1, "a", "p10")
.setLookupPlanInner(0, new InKeywordTableLookupPlanSingleIdx(0, 1, getIndexKey("a"), SupportExprNodeFactory.makeConstAndIdentNode("A", "p01"))).get();
runAssertion(epl + "where p10 in ('A', p01)", planInSingleWConst);
QueryPlan planInSingleJustConst = SupportQueryPlanBuilder.start(2)
.addIndexHashSingleNonUnique(1, "a", "p10")
.setLookupPlanInner(0, new InKeywordTableLookupPlanSingleIdx(0, 1, getIndexKey("a"), SupportExprNodeFactory.makeConstAndConstNode("A", "B"))).get();
runAssertion(epl + "where p10 in ('A', 'B')", planInSingleJustConst);
}
private void runAssertion(String epl, QueryPlan expectedPlan)
{
SupportQueryPlanIndexHook.reset();
epl = INDEX_CALLBACK_HOOK + epl;
epService.getEPAdministrator().createEPL(epl);
QueryPlan actualPlan = SupportQueryPlanIndexHook.assertJoinAndReset();
SupportQueryPlanIndexHelper.compareQueryPlans(expectedPlan, actualPlan);
epService.getEPAdministrator().destroyAllStatements();
}
private void assertSubqueryC0C1(int c0, Integer[] c1) {
EventBean event = listener.assertOneGetNewAndReset();
assertEquals(c0, event.get("c0"));
Collection<Object> c1Coll = ((Collection<Object>) event.get("c1"));
EPAssertionUtil.assertEqualsAnyOrder(c1, c1Coll == null ? null : c1Coll.toArray());
}
private QueryPlan getSingleIndexPlan(InKeywordTableLookupPlanSingleIdx plan) {
return SupportQueryPlanBuilder.start(3)
.addIndexHashSingleNonUnique(1, "i1", "p10")
.setIndexFullTableScan(2, "i2")
.setLookupPlanInstruction(0, "s0", new LookupInstructionPlan[]{
new LookupInstructionPlan(0, "s0", new int[] {1},
new TableLookupPlan[] {plan}, null, new boolean[3]),
new LookupInstructionPlan(0, "s0", new int[] {2},
new TableLookupPlan[] {new FullTableScanLookupPlan(1, 2, getIndexKey("i2"))}, null, new boolean[3])
})
.get();
}
private static TableLookupIndexReqKey[] getIndexKeys(String ... names) {
TableLookupIndexReqKey[] keys = new TableLookupIndexReqKey[names.length];
for (int i = 0; i < names.length; i++) {
keys[i] = new TableLookupIndexReqKey(names[i]);
}
return keys;
}
private static TableLookupIndexReqKey getIndexKey(String name) {
return new TableLookupIndexReqKey(name);
}
}