/*
***************************************************************************************
* 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.*;
import com.espertech.esper.client.scopetest.EPAssertionUtil;
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.SupportMessageAssertUtil;
import junit.framework.TestCase;
public class TestTableUpdateAndIndex extends TestCase {
private EPServiceProvider epService;
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);
}
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.startTest(epService, this.getClass(), getName());}
}
public void tearDown() {
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.endTest();}
}
public void testEarlyUniqueIndexViolation() {
EPStatement stmtCreate = epService.getEPAdministrator().createEPL("create table MyTable as (pkey0 string primary key, pkey1 int primary key, thecnt count(*))");
epService.getEPAdministrator().createEPL("into table MyTable select count(*) as thecnt from SupportBean group by theString, intPrimitive");
epService.getEPRuntime().sendEvent(new SupportBean("E1", 10));
epService.getEPRuntime().sendEvent(new SupportBean("E1", 20));
// invalid index being created
SupportMessageAssertUtil.tryInvalid(epService, "create unique index SecIndex on MyTable(pkey0)",
"Unexpected exception starting statement: Unique index violation, index 'SecIndex' is a unique index and key 'E1' already exists [create unique index SecIndex on MyTable(pkey0)]");
// try fire-and-forget update of primary key to non-unique value
try {
epService.getEPRuntime().executeQuery("update MyTable set pkey1 = 0");
fail();
}
catch (EPException ex) {
SupportMessageAssertUtil.assertMessage(ex, "Error executing statement: Unique index violation, index 'primary-MyTable' is a unique index and key 'MultiKeyUntyped[E1, 0]' already exists [");
// assert events are unchanged - no update actually performed
EPAssertionUtil.assertPropsPerRowAnyOrder(stmtCreate.iterator(), "pkey0,pkey1".split(","), new Object[][]{{"E1", 10}, {"E1", 20}});
}
// try on-update unique index violation
epService.getEPAdministrator().createEPL("@name('on-update') on SupportBean_S1 update MyTable set pkey1 = 0");
try {
epService.getEPRuntime().sendEvent(new SupportBean_S1(0));
fail();
}
catch (EPException ex) {
SupportMessageAssertUtil.assertMessage(ex.getCause(), "Unexpected exception in statement 'on-update': Unique index violation, index 'primary-MyTable' is a unique index and key 'MultiKeyUntyped[E1, 0]' already exists");
// assert events are unchanged - no update actually performed
EPAssertionUtil.assertPropsPerRowAnyOrder(stmtCreate.iterator(), "pkey0,pkey1".split(","), new Object[][]{{"E1", 10}, {"E1", 20}});
}
// disallow on-merge unique key updates
try {
epService.getEPAdministrator().createEPL("@name('on-merge') on SupportBean_S1 merge MyTable when matched then update set pkey1 = 0");
fail();
}
catch (EPStatementException ex) {
SupportMessageAssertUtil.assertMessage(ex.getCause(), "Validation failed in when-matched (clause 1): On-merge statements may not update unique keys of tables");
}
}
public void testLateUniqueIndexViolation() {
EPStatement stmtCreate = epService.getEPAdministrator().createEPL("create table MyTable as (" +
"pkey0 string primary key, " +
"pkey1 int primary key, " +
"col0 int, " +
"thecnt count(*))");
epService.getEPAdministrator().createEPL("into table MyTable select count(*) as thecnt from SupportBean group by theString, intPrimitive");
epService.getEPRuntime().sendEvent(new SupportBean("E1", 10));
epService.getEPRuntime().sendEvent(new SupportBean("E2", 20));
// On-merge exists before creating a unique index
EPStatement onMerge = epService.getEPAdministrator().createEPL("@name('on-merge') on SupportBean_S1 merge MyTable " +
"when matched then update set col0 = 0");
try {
epService.getEPAdministrator().createEPL("create unique index MyUniqueSecondary on MyTable (col0)");
fail();
}
catch (EPStatementException ex) {
SupportMessageAssertUtil.assertMessage(ex, "Error starting statement: Failed to validate statement 'on-merge' as a recipient of the proposed index: On-merge statements may not update unique keys of tables [");
}
onMerge.destroy();
// on-update exists before creating a unique index
EPStatement stmtUpdate = epService.getEPAdministrator().createEPL("@name('on-update') on SupportBean_S1 update MyTable set pkey1 = 0");
epService.getEPAdministrator().createEPL("create unique index MyUniqueSecondary on MyTable (pkey1)");
try {
epService.getEPRuntime().sendEvent(new SupportBean_S1(0));
fail();
}
catch (EPException ex) {
SupportMessageAssertUtil.assertMessage(ex.getCause(), "Unexpected exception in statement 'on-update': Unique index violation, index 'MyUniqueSecondary' is a unique index and key '0' already exists");
// assert events are unchanged - no update actually performed
EPAssertionUtil.assertPropsPerRowAnyOrder(stmtCreate.iterator(), "pkey0,pkey1".split(","), new Object[][]{{"E1", 10}, {"E2", 20}});
}
// unregister
stmtUpdate.destroy();
}
public void testFAFUpdate() {
epService.getEPAdministrator().createEPL("create table MyTable as (pkey0 string primary key, col0 int, col1 int, thecnt count(*))");
epService.getEPAdministrator().createEPL("create index MyIndex on MyTable(col0)");
epService.getEPAdministrator().createEPL("into table MyTable select count(*) as thecnt from SupportBean group by theString");
epService.getEPRuntime().sendEvent(new SupportBean("E1", 0));
epService.getEPRuntime().sendEvent(new SupportBean("E2", 0));
epService.getEPRuntime().executeQuery("update MyTable set col0 = 1 where pkey0='E1'");
epService.getEPRuntime().executeQuery("update MyTable set col0 = 2 where pkey0='E2'");
assertFAFOneRowResult("select pkey0 from MyTable where col0=1", "pkey0", new Object[]{"E1"});
epService.getEPRuntime().executeQuery("update MyTable set col1 = 100 where pkey0='E1'");
assertFAFOneRowResult("select pkey0 from MyTable where col1=100", "pkey0", new Object[]{"E1"});
}
private void assertFAFOneRowResult(String epl, String fields, Object[] objects) {
EPOnDemandQueryResult result = epService.getEPRuntime().executeQuery(epl);
assertEquals(1, result.getArray().length);
EPAssertionUtil.assertProps(result.getArray()[0], fields.split(","), objects);
}
}