/* *************************************************************************************** * 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.nwtable; import com.espertech.esper.client.EPServiceProvider; import com.espertech.esper.client.EPServiceProviderManager; import com.espertech.esper.client.EPStatement; import com.espertech.esper.client.EventBean; import com.espertech.esper.client.scopetest.EPAssertionUtil; import com.espertech.esper.client.scopetest.SupportUpdateListener; import com.espertech.esper.metrics.instrumentation.InstrumentationHelper; 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.client.SupportConfigFactory; import com.espertech.esper.supportregression.util.SupportModelHelper; import com.espertech.esper.util.support.SupportEventTypeAssertionEnum; import com.espertech.esper.util.support.SupportEventTypeAssertionUtil; import junit.framework.TestCase; import java.util.Collection; import java.util.Map; public class TestTableOnMerge extends TestCase { private EPServiceProvider epService; private SupportUpdateListener listener; private SupportUpdateListener listenerMerge; public void setUp() { epService = EPServiceProviderManager.getDefaultProvider(SupportConfigFactory.getConfiguration()); epService.initialize(); for (Class clazz : new Class[] {SupportBean.class, SupportBean_S0.class, SupportBean_S1.class}) { epService.getEPAdministrator().getConfiguration().addEventType(clazz); } listener = new SupportUpdateListener(); listenerMerge = new SupportUpdateListener(); if (InstrumentationHelper.ENABLED) { InstrumentationHelper.startTest(epService, this.getClass(), getName());} } public void tearDown() { if (InstrumentationHelper.ENABLED) { InstrumentationHelper.endTest();} listener = null; listenerMerge = null; } public void testMergeWhereWithMethodRead() { epService.getEPAdministrator().createEPL("create table varagg (keyOne string primary key, cnt count(*))"); epService.getEPAdministrator().createEPL("into table varagg select count(*) as cnt " + "from SupportBean#lastevent group by theString"); epService.getEPAdministrator().createEPL("select varagg[p00].keyOne as c0 from SupportBean_S0").addListener(listener); epService.getEPAdministrator().createEPL("on SupportBean_S1 merge varagg where cnt = 0 when matched then delete"); epService.getEPRuntime().sendEvent(new SupportBean("G1", 0)); epService.getEPRuntime().sendEvent(new SupportBean("G2", 0)); assertKeyFound("G1,G2,G3", new boolean[]{true, true, false}); epService.getEPRuntime().sendEvent(new SupportBean_S1(0)); // delete assertKeyFound("G1,G2,G3", new boolean[] {false, true, false}); epService.getEPRuntime().sendEvent(new SupportBean("G3", 0)); assertKeyFound("G1,G2,G3", new boolean[]{false, true, true}); epService.getEPRuntime().sendEvent(new SupportBean_S1(0)); // delete assertKeyFound("G1,G2,G3", new boolean[] {false, false, true}); } public void testMergeSelectWithAggReadAndEnum() { epService.getEPAdministrator().createEPL("create table varagg (" + "eventset window(*) @type(SupportBean), total sum(int))"); epService.getEPAdministrator().createEPL("into table varagg select window(*) as eventset, " + "sum(intPrimitive) as total from SupportBean#length(2)"); epService.getEPAdministrator().createEPL("on SupportBean_S0 merge varagg " + "when matched then insert into ResultStream select eventset, total, eventset.takeLast(1) as c0"); epService.getEPAdministrator().createEPL("select * from ResultStream").addListener(listener); SupportBean e1 = new SupportBean("E1", 15); epService.getEPRuntime().sendEvent(e1); assertResultAggRead(new Object[] {e1}, 15); SupportBean e2 = new SupportBean("E2", 20); epService.getEPRuntime().sendEvent(e2); assertResultAggRead(new Object[]{e1, e2}, 35); SupportBean e3 = new SupportBean("E3", 30); epService.getEPRuntime().sendEvent(e3); assertResultAggRead(new Object[]{e2, e3}, 50); } private void assertResultAggRead(Object[] objects, int total) { String[] fields = "eventset,total".split(","); epService.getEPRuntime().sendEvent(new SupportBean_S0(0)); EventBean event = listener.assertOneGetNewAndReset(); EPAssertionUtil.assertProps(event, fields, new Object[] {objects, total}); EPAssertionUtil.assertEqualsExactOrder(new Object[] {objects[objects.length-1]}, ((Collection)event.get("c0")).toArray()); } private void assertKeyFound(String keyCsv, boolean[] expected) { String[] split = keyCsv.split(","); for (int i = 0; i < split.length; i++) { String key = split[i]; epService.getEPRuntime().sendEvent(new SupportBean_S0(0, key)); String expectedString = expected[i] ? key : null; assertEquals("failed for key '" + key + "'", expectedString, listener.assertOneGetNewAndReset().get("c0")); } } public void testOnMergePlainPropsAnyKeyed() { runOnMergeInsertUpdDeleteSingleKey(true); runOnMergeInsertUpdDeleteSingleKey(false); runOnMergeInsertUpdDeleteTwoKey(true); runOnMergeInsertUpdDeleteTwoKey(false); runOnMergeInsertUpdDeleteUngrouped(true); } public void runOnMergeInsertUpdDeleteUngrouped(boolean soda) { String eplDeclare = "create table varagg (p0 string, sumint sum(int))"; SupportModelHelper.createByCompileOrParse(epService, soda, eplDeclare); String[] fields = "c0,c1".split(","); String eplRead = "select varagg.p0 as c0, varagg.sumint as c1, varagg as c2 from SupportBean_S0"; EPStatement stmtRead = SupportModelHelper.createByCompileOrParse(epService, soda, eplRead); stmtRead.addListener(listener); // assert selected column types Object[][] expectedAggType = new Object[][]{{"c0", String.class}, {"c1", Integer.class}}; SupportEventTypeAssertionUtil.assertEventTypeProperties(expectedAggType, stmtRead.getEventType(), SupportEventTypeAssertionEnum.NAME, SupportEventTypeAssertionEnum.TYPE); // assert no row epService.getEPRuntime().sendEvent(new SupportBean_S0(0)); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {null, null}); // create merge String eplMerge = "on SupportBean merge varagg" + " when not matched then" + " insert select theString as p0" + " when matched and theString like \"U%\" then" + " update set p0=\"updated\"" + " when matched and theString like \"D%\" then" + " delete"; SupportModelHelper.createByCompileOrParse(epService, soda, eplMerge); // merge for varagg epService.getEPRuntime().sendEvent(new SupportBean("E1", 0)); // assert epService.getEPRuntime().sendEvent(new SupportBean_S0(0)); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"E1", null}); // also aggregate-into the same key SupportModelHelper.createByCompileOrParse(epService, soda, "into table varagg select sum(50) as sumint from SupportBean_S1"); epService.getEPRuntime().sendEvent(new SupportBean_S1(0)); epService.getEPRuntime().sendEvent(new SupportBean_S0(0)); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"E1", 50}); // update for varagg epService.getEPRuntime().sendEvent(new SupportBean("U2", 10)); epService.getEPRuntime().sendEvent(new SupportBean_S0(0)); EventBean received = listener.assertOneGetNewAndReset(); EPAssertionUtil.assertProps(received, fields, new Object[] {"updated", 50}); EPAssertionUtil.assertPropsMap((Map) received.get("c2"), "p0,sumint".split(","), new Object[] {"updated", 50}); // delete for varagg epService.getEPRuntime().sendEvent(new SupportBean("D3", 0)); epService.getEPRuntime().sendEvent(new SupportBean_S0(0)); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {null, null}); epService.getEPAdministrator().destroyAllStatements(); } public void runOnMergeInsertUpdDeleteSingleKey(boolean soda) { String[] fieldsTable = "key,p0,p1,p2,sumint".split(","); String eplDeclare = "create table varagg (key int primary key, p0 string, p1 int, p2 int[], sumint sum(int))"; SupportModelHelper.createByCompileOrParse(epService, soda, eplDeclare); String[] fields = "c0,c1,c2,c3".split(","); String eplRead = "select varagg[id].p0 as c0, varagg[id].p1 as c1, varagg[id].p2 as c2, varagg[id].sumint as c3 from SupportBean_S0"; EPStatement stmtRead = SupportModelHelper.createByCompileOrParse(epService, soda, eplRead); stmtRead.addListener(listener); // assert selected column types Object[][] expectedAggType = new Object[][]{{"c0", String.class}, {"c1", Integer.class}, {"c2", Integer[].class}, {"c3", Integer.class}}; SupportEventTypeAssertionUtil.assertEventTypeProperties(expectedAggType, stmtRead.getEventType(), SupportEventTypeAssertionEnum.NAME, SupportEventTypeAssertionEnum.TYPE); // assert no row epService.getEPRuntime().sendEvent(new SupportBean_S0(10)); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {null, null, null, null}); // create merge String eplMerge = "on SupportBean merge varagg" + " where intPrimitive=key" + " when not matched then" + " insert select intPrimitive as key, \"v1\" as p0, 1000 as p1, {1,2} as p2" + " when matched and theString like \"U%\" then" + " update set p0=\"v2\", p1=2000, p2={3,4}" + " when matched and theString like \"D%\" then" + " delete"; EPStatement stmtMerge = SupportModelHelper.createByCompileOrParse(epService, soda, eplMerge); stmtMerge.addListener(listenerMerge); // merge for varagg[10] epService.getEPRuntime().sendEvent(new SupportBean("E1", 10)); EPAssertionUtil.assertProps(listenerMerge.assertOneGetNewAndReset(), fieldsTable, new Object[] {10, "v1", 1000, new int[] {1, 2}, null}); // assert key "10" epService.getEPRuntime().sendEvent(new SupportBean_S0(10)); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"v1", 1000, new Integer[] {1, 2}, null}); // also aggregate-into the same key SupportModelHelper.createByCompileOrParse(epService, soda, "into table varagg select sum(50) as sumint from SupportBean_S1 group by id"); epService.getEPRuntime().sendEvent(new SupportBean_S1(10)); epService.getEPRuntime().sendEvent(new SupportBean_S0(10)); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"v1", 1000, new Integer[] {1, 2}, 50}); // update for varagg[10] epService.getEPRuntime().sendEvent(new SupportBean("U2", 10)); EPAssertionUtil.assertProps(listenerMerge.getLastNewData()[0], fieldsTable, new Object[] {10, "v2", 2000, new int[] {3, 4}, 50}); EPAssertionUtil.assertProps(listenerMerge.getAndResetLastOldData()[0], fieldsTable, new Object[] {10, "v1", 1000, new int[] {1, 2}, 50}); epService.getEPRuntime().sendEvent(new SupportBean_S0(10)); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"v2", 2000, new Integer[] {3, 4}, 50}); // delete for varagg[10] epService.getEPRuntime().sendEvent(new SupportBean("D3", 10)); EPAssertionUtil.assertProps(listenerMerge.assertOneGetOldAndReset(), fieldsTable, new Object[] {10, "v2", 2000, new int[] {3, 4}, 50}); epService.getEPRuntime().sendEvent(new SupportBean_S0(10)); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {null, null, null, null}); epService.getEPAdministrator().destroyAllStatements(); epService.getEPAdministrator().getConfiguration().removeEventType("table_varagg__internal", false); epService.getEPAdministrator().getConfiguration().removeEventType("table_varagg__public", false); } public void runOnMergeInsertUpdDeleteTwoKey(boolean soda) { String eplDeclare = "create table varagg (keyOne int primary key, keyTwo string primary key, prop string)"; SupportModelHelper.createByCompileOrParse(epService, soda, eplDeclare); String[] fields = "c0,c1,c2".split(","); String eplRead = "select varagg[id,p00].keyOne as c0, varagg[id,p00].keyTwo as c1, varagg[id,p00].prop as c2 from SupportBean_S0"; EPStatement stmtRead = SupportModelHelper.createByCompileOrParse(epService, soda, eplRead); stmtRead.addListener(listener); // assert selected column types Object[][] expectedAggType = new Object[][]{{"c0", Integer.class}, {"c1", String.class}, {"c2", String.class},}; SupportEventTypeAssertionUtil.assertEventTypeProperties(expectedAggType, stmtRead.getEventType(), SupportEventTypeAssertionEnum.NAME, SupportEventTypeAssertionEnum.TYPE); // assert no row epService.getEPRuntime().sendEvent(new SupportBean_S0(10, "A")); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {null, null, null}); // create merge String eplMerge = "on SupportBean merge varagg" + " where intPrimitive=keyOne and theString=keyTwo" + " when not matched then" + " insert select intPrimitive as keyOne, theString as keyTwo, \"inserted\" as prop" + " when matched and longPrimitive>0 then" + " update set prop=\"updated\"" + " when matched and longPrimitive<0 then" + " delete"; EPStatement stmtMerge = SupportModelHelper.createByCompileOrParse(epService, soda, eplMerge); Object[][] expectedType = new Object[][]{{"keyOne", Integer.class},{"keyTwo", String.class},{"prop", String.class}}; SupportEventTypeAssertionUtil.assertEventTypeProperties(expectedType, stmtMerge.getEventType(), SupportEventTypeAssertionEnum.NAME, SupportEventTypeAssertionEnum.TYPE); // merge for varagg[10, "A"] epService.getEPRuntime().sendEvent(new SupportBean("A", 10)); // assert key {"10", "A"} epService.getEPRuntime().sendEvent(new SupportBean_S0(10, "A")); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {10, "A", "inserted"}); // update for varagg[10, "A"] epService.getEPRuntime().sendEvent(makeSupportBean("A", 10, 1)); epService.getEPRuntime().sendEvent(new SupportBean_S0(10, "A")); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {10, "A", "updated"}); // test typable output epService.getEPAdministrator().getConfiguration().addEventType(LocalBean.class); EPStatement stmtConvert = epService.getEPAdministrator().createEPL("insert into LocalBean select varagg[10, 'A'] as val0 from SupportBean_S1"); stmtConvert.addListener(listener); epService.getEPRuntime().sendEvent(new SupportBean_S1(2)); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), "val0.keyOne".split(","), new Object[]{10}); // delete for varagg[10, "A"] epService.getEPRuntime().sendEvent(makeSupportBean("A", 10, -1)); epService.getEPRuntime().sendEvent(new SupportBean_S0(10, "A")); EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{null, null, null}); epService.getEPAdministrator().destroyAllStatements(); epService.getEPAdministrator().getConfiguration().removeEventType("table_varagg__internal", false); epService.getEPAdministrator().getConfiguration().removeEventType("table_varagg__public", false); } private SupportBean makeSupportBean(String theString, int intPrimitive, long longPrimitive) { SupportBean bean = new SupportBean(theString, intPrimitive); bean.setLongPrimitive(longPrimitive); return bean; } private static class LocalSubBean { private int keyOne; private String keyTwo; private String prop; public int getKeyOne() { return keyOne; } public void setKeyOne(int keyOne) { this.keyOne = keyOne; } public String getKeyTwo() { return keyTwo; } public void setKeyTwo(String keyTwo) { this.keyTwo = keyTwo; } public String getProp() { return prop; } public void setProp(String prop) { this.prop = prop; } } private static class LocalBean { private LocalSubBean val0; public LocalSubBean getVal0() { return val0; } public void setVal0(LocalSubBean val0) { this.val0 = val0; } } }