/* This file is part of VoltDB.
* Copyright (C) 2008-2017 VoltDB Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
package org.voltdb.catalog;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import org.voltdb.TableHelper;
import org.voltdb.VoltTable;
import org.voltdb.benchmark.tpcc.TPCCProjectBuilder;
import org.voltdb.compiler.CatalogBuilder;
import org.voltdb.compiler.VoltProjectBuilder;
import org.voltdb.compiler.VoltProjectBuilder.RoleInfo;
import org.voltdb.compiler.VoltProjectBuilder.UserInfo;
import org.voltdb.compiler.deploymentfile.DeploymentType;
import org.voltdb.utils.BuildDirectoryUtils;
import org.voltdb.utils.CatalogUtil;
import org.voltdb.utils.MiscUtils;
import org.voltdb.utils.VoltFile;
import junit.framework.TestCase;
public class TestCatalogDiffs extends TestCase {
static final String m_dir = "/tmp" + File.separator + System.getProperty("user.name");
Class<?>[] BASEPROCS = { org.voltdb.benchmark.tpcc.procedures.InsertNewOrder.class,
org.voltdb.benchmark.tpcc.procedures.delivery.class };
Class<?>[] EXPANDEDPROCS = { org.voltdb.benchmark.tpcc.procedures.InsertNewOrder.class,
org.voltdb.benchmark.tpcc.procedures.delivery.class,
org.voltdb.benchmark.tpcc.procedures.slev.class };
Class<?>[] FEWERPROCS = { org.voltdb.benchmark.tpcc.procedures.InsertNewOrder.class };
Class<?>[] CONFLICTPROCS = { org.voltdb.catalog.InsertNewOrder.class,
org.voltdb.benchmark.tpcc.procedures.delivery.class };
protected String compile(String name, Class<?>... procList) {
return compileWithGroups(false, null, null, null, name, procList);
}
protected String compileWithGroups(
boolean securityEnabled, String securityProvider,
RoleInfo[] gi, UserInfo[] ui,
String name, Class<?>... procList) {
TPCCProjectBuilder builder = new TPCCProjectBuilder();
builder.addDefaultSchema();
builder.addDefaultPartitioning();
builder.addProcedures(procList);
builder.setSecurityEnabled(securityEnabled, true);
if (gi != null && gi.length > 0)
builder.addRoles(gi);
if (ui != null && ui.length > 0)
builder.addUsers(ui);
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
String retval = testDir + File.separator + "tpcc-catalogcheck-" + name + ".jar";
assertTrue("Failed to compile schema", builder.compile(retval));
return retval;
}
public static Catalog catalogForJar(String pathToJar) throws IOException {
byte[] bytes = MiscUtils.fileToBytes(new File(pathToJar));
String serializedCatalog = CatalogUtil.getSerializedCatalogStringFromJar(
CatalogUtil.loadAndUpgradeCatalogFromJar(bytes, false).getFirst());
assertNotNull(serializedCatalog);
Catalog c = new Catalog();
c.execute(serializedCatalog);
return c;
}
private String verifyDiff(
Catalog catOriginal,
Catalog catUpdated)
{
//Default expect no generation roll, but with EE diff commands.
return verifyDiff(catOriginal, catUpdated, null, null, true, false, true);
}
private String verifyDiff(
Catalog catOriginal,
Catalog catUpdated,
boolean expectApplyCatalogDiffToEE)
{
//Default expect no generation roll.
return verifyDiff(catOriginal, catUpdated, null, null, expectApplyCatalogDiffToEE, false, true);
}
private String verifyDiff(
Catalog catOriginal,
Catalog catUpdated,
Boolean expectSnapshotIsolation,
Boolean worksWithElastic,
Boolean expectApplyCatalogDiffToEE,
Boolean expectedNewGeneration, Boolean execute)
{
CatalogDiffEngine diff = new CatalogDiffEngine(catOriginal, catUpdated);
String commands = diff.commands();
System.out.println("DIFF COMMANDS:");
System.out.println(commands);
//If we want to just compare catalogs back and forth keep catalog intact.
if (execute) {
catOriginal.execute(commands);
}
assertTrue(diff.supported());
assertEquals(0, diff.tablesThatMustBeEmpty()[0].length);
if (expectSnapshotIsolation != null) {
assertEquals((boolean) expectSnapshotIsolation, diff.requiresSnapshotIsolation());
}
if (worksWithElastic != null) {
assertEquals((boolean)worksWithElastic, diff.worksWithElastic());
}
if (expectApplyCatalogDiffToEE != null) {
assertEquals(expectApplyCatalogDiffToEE.booleanValue(), diff.requiresCatalogDiffCmdsApplyToEE());
}
if (expectedNewGeneration != null) {
//TODO: Enable real check.
assertEquals(true, diff.requiresNewExportGeneration());
}
if (execute) {
String updatedOriginalSerialized = catOriginal.serialize();
assertEquals(updatedOriginalSerialized, catUpdated.serialize());
}
String desc = diff.getDescriptionOfChanges(false);
System.out.println("========================");
System.out.println(desc);
System.out.println("========================");
return desc;
}
private void verifyDiffRejected(
Catalog catOriginal,
Catalog catUpdated)
{
CatalogDiffEngine diff = new CatalogDiffEngine(catOriginal, catUpdated);
String originalSerialized = catOriginal.serialize();
catOriginal.execute(diff.commands());
String updatedOriginalSerialized = catOriginal.serialize();
if (diff.supported()) {
System.out.println("TCD DEBUG Unexpectedly accepted difference:\n");
System.out.println("TCD DEBUG BEFORE: " + originalSerialized);
System.out.println("TCD DEBUG AFTER: " + updatedOriginalSerialized);
}
assertFalse(diff.supported());
assertEquals(updatedOriginalSerialized, catUpdated.serialize());
}
private void verifyDiffIfEmptyTable(
Catalog catOriginal,
Catalog catUpdated)
{
CatalogDiffEngine diff = new CatalogDiffEngine(catOriginal, catUpdated);
catOriginal.execute(diff.commands());
String updatedOriginalSerialized = catOriginal.serialize();
assertTrue(diff.supported());
assertTrue(diff.tablesThatMustBeEmpty()[0].length > 0);
assertEquals(updatedOriginalSerialized, catUpdated.serialize());
}
public void testAddProcedure() throws IOException {
String original = compile("base", BASEPROCS);
Catalog catOriginal = catalogForJar(original);
String updated = compile("expanded", EXPANDEDPROCS);
Catalog catUpdated = catalogForJar(updated);
String report = verifyDiff(catOriginal, catUpdated, false);
assertTrue(report.contains("Procedure slev added."));
}
public void testModifyProcedureCode() throws IOException {
String original = compile("base", BASEPROCS);
Catalog catOriginal = catalogForJar(original);
String updated = compile("conflict", CONFLICTPROCS);
Catalog catUpdated = catalogForJar(updated);
String report = verifyDiff(catOriginal, catUpdated, false);
assertTrue(report.contains("Procedure InsertNewOrder has been modified."));
}
public void testDeleteProcedure() throws IOException {
String original = compile("base", BASEPROCS);
Catalog catOriginal = catalogForJar(original);
String updated = compile("fewer", FEWERPROCS);
Catalog catUpdated = catalogForJar(updated);
String report = verifyDiff(catOriginal, catUpdated, false);
assertTrue(report.contains("Procedure delivery dropped."));
}
public void testAddGroup() throws IOException {
String original = compile("base", BASEPROCS);
Catalog catOriginal = catalogForJar(original);
RoleInfo gi[] = new RoleInfo[1];
gi[0] = new RoleInfo("group1", true, true, true, true, true, true);
String updated = compileWithGroups(false, null, gi, null, "base", BASEPROCS);
Catalog catUpdated = catalogForJar(updated);
verifyDiff(catOriginal, catUpdated, false);
}
public void testAddGroupAndUser() throws IOException {
String original = compile("base", BASEPROCS);
Catalog catOriginal = catalogForJar(original);
RoleInfo gi[] = new RoleInfo[1];
gi[0] = new RoleInfo("group1", true, true, true, true, true, false);
UserInfo ui[] = new UserInfo[1];
ui[0] = new UserInfo("user1", "password", new String[] {"group1"});
String updated = compileWithGroups(false, null, gi, ui, "base", BASEPROCS);
Catalog catUpdated = catalogForJar(updated);
verifyDiff(catOriginal, catUpdated, false);
}
public void testModifyUser() throws IOException {
RoleInfo gi[] = new RoleInfo[1];
gi[0] = new RoleInfo("group1", true, true, true, true, false, false);
UserInfo ui[] = new UserInfo[1];
ui[0] = new UserInfo("user1", "password", new String[] {"group1"});
String original = compileWithGroups(false, null, gi, ui, "base", BASEPROCS);
Catalog catOriginal = catalogForJar(original);
RoleInfo gi2[] = new RoleInfo[1];
gi2[0] = new RoleInfo("group2", true, true, true, true, true, true);
// change a user.
ui[0] = new UserInfo("user1", "drowssap", new String[] {"group2"});
String updated = compileWithGroups(false, null, gi2, ui, "base", BASEPROCS);
Catalog catUpdated = catalogForJar(updated);
verifyDiff(catOriginal, catUpdated, false);
}
public void testDeleteUser() throws IOException {
RoleInfo gi[] = new RoleInfo[1];
gi[0] = new RoleInfo("group1", true, true, true, true, false, false);
UserInfo ui[] = new UserInfo[1];
ui[0] = new UserInfo("user1", "password", new String[] {"group1"});
String original = compileWithGroups(false, null, gi, ui, "base", BASEPROCS);
Catalog catOriginal = catalogForJar(original);
// no users this time
String updated = compileWithGroups(false, null, gi, null, "base", BASEPROCS);
Catalog catUpdated = catalogForJar(updated);
verifyDiff(catOriginal, catUpdated, false);
}
public void testDeleteGroupAndUser() throws IOException {
RoleInfo gi[] = new RoleInfo[1];
gi[0] = new RoleInfo("group1", true, true, true, true, false, false);
UserInfo ui[] = new UserInfo[1];
ui[0] = new UserInfo("user1", "password", new String[] {"group1"});
String original = compileWithGroups(false, null, gi, ui, "base", BASEPROCS);
Catalog catOriginal = catalogForJar(original);
// no groups or users this time
String updated = compileWithGroups(false, null, null, null, "base", BASEPROCS);
Catalog catUpdated = catalogForJar(updated);
verifyDiff(catOriginal, catUpdated, false);
}
public void testChangeUsersAssignedGroups() throws IOException {
RoleInfo gi[] = new RoleInfo[2];
gi[0] = new RoleInfo("group1", true, true, true, true, false, false);
gi[1] = new RoleInfo("group2", true, true, true, true, false, true);
UserInfo ui[] = new UserInfo[2];
ui[0] = new UserInfo("user1", "password", new String[] {"group1"});
ui[1] = new UserInfo("user2", "password", new String[] {"group2"});
String original = compileWithGroups(false, null, gi, ui, "base", BASEPROCS);
Catalog catOriginal = catalogForJar(original);
// swap the user's group assignments
ui[0] = new UserInfo("user1", "password", new String[] {"group2"});
ui[1] = new UserInfo("user2", "password", new String[] {"group1"});
String updated = compileWithGroups(false, null, gi, ui, "base", BASEPROCS);
Catalog catUpdated = catalogForJar(updated);
verifyDiff(catOriginal, catUpdated, false);
}
public void testChangeSecurityEnabled() throws IOException {
RoleInfo gi[] = new RoleInfo[2];
gi[0] = new RoleInfo("group1", true, true, true, true, false, true);
gi[1] = new RoleInfo("group2", true, true, true, true, false, false);
UserInfo ui[] = new UserInfo[2];
ui[0] = new UserInfo("user1", "password", new String[] {"group1"});
ui[1] = new UserInfo("user2", "password", new String[] {"group2"});
String original = compileWithGroups(false, null, gi, ui, "base", BASEPROCS);
Catalog catOriginal = catalogForJar(original);
// just turn on security
String updated = compileWithGroups(true, "hash", gi, ui, "base", BASEPROCS);
Catalog catUpdated = catalogForJar(updated);
verifyDiff (catOriginal, catUpdated, false);
}
public void testChangeSecurityProvider() throws IOException {
RoleInfo gi[] = new RoleInfo[2];
gi[0] = new RoleInfo("group1", true, true, true, true, false, false);
gi[1] = new RoleInfo("group2", true, true, true, true, false, false);
UserInfo ui[] = new UserInfo[2];
ui[0] = new UserInfo("user1", "password", new String[] {"group1"});
ui[1] = new UserInfo("user2", "password", new String[] {"group2"});
String original = compileWithGroups(true, "hash", gi, ui, "base", BASEPROCS);
Catalog catOriginal = catalogForJar(original);
// just turn on security
String updated = compileWithGroups(true, "kerberos", gi, ui, "base", BASEPROCS);
Catalog catUpdated = catalogForJar(updated);
verifyDiff (catOriginal, catUpdated, false);
}
public void testDiffOfIdenticalCatalogs() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C1, NUM) AS " +
"\n SELECT C1, COUNT(*) FROM A GROUP BY C1;");
builder.addLiteralSchema("\nCREATE VIEW MATVIEWJOIN(C1, NUM) AS " +
"\n SELECT A.C1, COUNT(*) FROM A JOIN B ON A.C1=B.C2 GROUP BY A.C1;");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "identical3.jar"));
Catalog c3 = catalogForJar(testDir + File.separator + "identical3.jar");
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C1, NUM) AS " +
"\n SELECT C1, COUNT(*) FROM A GROUP BY C1;");
builder.addLiteralSchema("\nCREATE VIEW MATVIEWJOIN(C1, NUM) AS " +
"\n SELECT A.C1, COUNT(*) FROM A JOIN B ON A.C1=B.C2 GROUP BY A.C1;");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "identical4.jar"));
Catalog c4 = catalogForJar(testDir + File.separator + "identical4.jar");
CatalogDiffEngine diff = new CatalogDiffEngine(c3, c4);
// don't reach this point.
c3.execute(diff.commands());
assertTrue(diff.supported());
String updatedOriginalSerialized = c3.serialize();
assertEquals(updatedOriginalSerialized, c4.serialize());
}
// N.B. Some of the testcases assume this exact table structure... if you change it,
// check the callers.
Catalog getCatalogForTable(String tableName, String catname) throws IOException {
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("CREATE TABLE " + tableName + " (C1 BIGINT NOT NULL, PRIMARY KEY(C1));");
builder.addPartitionInfo(tableName, "C1");
if (tableName.equals("A"))
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
else
builder.addProcedures(org.voltdb.catalog.ProcedureB.class);
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "test-" + catname + ".jar"));
Catalog cat = catalogForJar(testDir + File.separator + "test-" + catname + ".jar");
return cat;
}
Catalog getCatalogForTable(String tableName, String catname, VoltTable t) throws IOException {
return getCatalogForTable(tableName, catname, t, false);
}
Catalog getExportCatalogForTable(String tableName, String catname, VoltTable t) throws IOException {
return getCatalogForTable(tableName, catname, t, true);
}
private Catalog getCatalogForTable(String tableName, String catname, VoltTable t, boolean export) throws IOException {
CatalogBuilder builder = new CatalogBuilder();
builder.addLiteralSchema(TableHelper.ddlForTable(t, export));
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "test-" + catname + ".jar"));
Catalog cat = catalogForJar(testDir + File.separator + "test-" + catname + ".jar");
return cat;
}
// N.B. Some of the testcases assume this exact table structure .. if you change it,
// check the callers...
Catalog get2ColumnCatalogForTable(String tableName, String catname) throws IOException {
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("CREATE TABLE " + tableName + " (C1 BIGINT NOT NULL, C2 BIGINT DEFAULT 0 NOT NULL, PRIMARY KEY(C1));");
builder.addPartitionInfo(tableName, "C1");
if (tableName.equals("A"))
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
else
builder.addProcedures(org.voltdb.catalog.ProcedureB.class);
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "test-" + catname + ".jar"));
Catalog cat = catalogForJar(testDir + File.separator + "test-" + catname + ".jar");
return cat;
}
public void testAddTable() throws IOException {
// Start with table A.
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("CREATE TABLE A (C1 BIGINT NOT NULL, PRIMARY KEY(C1));");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testaddtable1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "testaddtable1.jar");
// Add table B and recompile
builder.addLiteralSchema("CREATE TABLE B (C1 BIGINT NOT NULL, PRIMARY KEY(C1));");
builder.addPartitionInfo("B", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureB.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testaddtable2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "testaddtable2.jar");
verifyDiff(catOriginal, catUpdated, false, null, true, false, true);
}
public void testDropTable() throws IOException {
// Start with table A and B.
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, PRIMARY KEY(C1));" +
"\nCREATE TABLE B (C1 BIGINT NOT NULL, PRIMARY KEY(C1));");
builder.addPartitionInfo("A", "C1");
builder.addPartitionInfo("B", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class,
org.voltdb.catalog.ProcedureB.class);
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testdroptable1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "testdroptable1.jar");
// Create a catalog with just table A
Catalog catUpdated = getCatalogForTable("A", "droptable2");
verifyDiff(catOriginal, catUpdated, false, null, true, false, true);
}
public void testViewConversion() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// Start with table A, B and a single table view.
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C1, NUM) AS SELECT C1, COUNT(*) FROM A GROUP BY C1;");
builder.addPartitionInfo("A", "C1");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "convertmatview1.jar"));
Catalog catOriginalSingle = catalogForJar(testDir + File.separator + "convertmatview1.jar");
// table A, B and a join query view.
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C1, NUM) AS " +
"\n SELECT A.C1, COUNT(*) FROM A JOIN B ON A.C1=B.C2 GROUP BY A.C1;");
builder.addPartitionInfo("A", "C1");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "convertmatview2.jar"));
Catalog catOriginalJoin = catalogForJar(testDir + File.separator + "convertmatview2.jar");
// table A, B and a normal table instead of a view.
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE MATVIEW(C1 BIGINT NOT NULL, NUM INTEGER);");
builder.addPartitionInfo("A", "C1");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "convertmatview3.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "convertmatview3.jar");
verifyDiffRejected(catOriginalSingle, catUpdated);
verifyDiffRejected(catOriginalJoin, catUpdated);
}
public void testAddTableColumn() throws IOException {
Catalog catOriginal = getCatalogForTable("A", "addtablecolumnrejected1");
Catalog catUpdated = get2ColumnCatalogForTable("A", "addtablecolumnrejected2");
verifyDiff(catOriginal, catUpdated, true, null, true, false, true);
VoltTable t1 = TableHelper.quickTable("(INTEGER, VARCHAR40)");
VoltTable t2 = TableHelper.quickTable("(INTEGER, VARCHAR40, VARCHAR120)");
catOriginal = getExportCatalogForTable("A", "addtablecolumn1", t1);
catUpdated = getExportCatalogForTable("A", "addtablecolumn2", t2);
verifyDiffRejected(catOriginal, catUpdated);
}
public void testRemoveTableColumn() throws IOException {
Catalog catOriginal = get2ColumnCatalogForTable("A", "removetablecolumn2");
Catalog catUpdated = getCatalogForTable("A", "removetablecolumn1");
verifyDiff(catOriginal, catUpdated, true, null, true, false, true);
VoltTable t1 = TableHelper.quickTable("(INTEGER, VARCHAR40, VARCHAR120)");
VoltTable t2 = TableHelper.quickTable("(INTEGER, VARCHAR40)");
catOriginal = getExportCatalogForTable("A", "droptablecolumn1", t1);
catUpdated = getExportCatalogForTable("A", "droptablecolumn2", t2);
verifyDiffRejected(catOriginal, catUpdated);
}
public void testModifyTableColumn() throws IOException {
// should pass
VoltTable t1 = TableHelper.quickTable("(SMALLINT, VARCHAR30, VARCHAR80)");
VoltTable t2 = TableHelper.quickTable("(INTEGER, VARCHAR40, VARCHAR120)");
Catalog catOriginal = getCatalogForTable("A", "modtablecolumn1", t1);
Catalog catUpdated = getCatalogForTable("A", "modtablecolumn2", t2);
verifyDiff(catOriginal, catUpdated, true, null, true, false, true);
// even pass when crossing the inline/out-of-line boundary
t1 = TableHelper.quickTable("(VARBINARY30)");
t2 = TableHelper.quickTable("(VARBINARY70)");
catOriginal = getCatalogForTable("A", "modtablecolumn1", t1);
catUpdated = getCatalogForTable("A", "modtablecolumn2", t2);
verifyDiff(catOriginal, catUpdated, true, null, true, false, true);
// fail integer contraction if non-empty empty
t1 = TableHelper.quickTable("(BIGINT)");
t2 = TableHelper.quickTable("(INTEGER)");
catOriginal = getCatalogForTable("A", "modtablecolumn1", t1);
catUpdated = getCatalogForTable("A", "modtablecolumn2", t2);
verifyDiffIfEmptyTable(catOriginal, catUpdated);
// fail string contraction if non-empty table
t1 = TableHelper.quickTable("(VARCHAR35)");
t2 = TableHelper.quickTable("(VARCHAR34)");
catOriginal = getCatalogForTable("A", "modtablecolumn1", t1);
catUpdated = getCatalogForTable("A", "modtablecolumn2", t2);
verifyDiffIfEmptyTable(catOriginal, catUpdated);
// fail - change export schema if non-empty
t1 = TableHelper.quickTable("(VARCHAR35)");
t2 = TableHelper.quickTable("(VARCHAR34)");
catOriginal = getExportCatalogForTable("A", "modtablecolumn1", t1);
catUpdated = getExportCatalogForTable("A", "modtablecolumn2", t2);
verifyDiffRejected(catOriginal, catUpdated);
}
public void testModifyVarcharColumns() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
Catalog catOriginal, catUpdated;
VoltProjectBuilder builder;
String report;
// start with a table
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT, v1 varchar(5), v2 varchar(5 BYTES) ) ;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testVarchar0.jar"));
catOriginal = catalogForJar(testDir + File.separator + "testVarchar0.jar");
// change from character to bytes
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT, v1 varchar(20 BYTES), v2 varchar(5 BYTES) );");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testVarchar1.jar"));
catUpdated = catalogForJar(testDir + File.separator + "testVarchar1.jar");
report = verifyDiff(catOriginal, catUpdated);
assert(report.contains("Table A has been modified."));
// size not satisfied if non-empty table
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT, v1 varchar(15 BYTES), v2 varchar(5 BYTES) );");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testVarchar2.jar"));
catUpdated = catalogForJar(testDir + File.separator + "testVarchar2.jar");
verifyDiffIfEmptyTable(catOriginal, catUpdated);
// inline character to not in line bytes.
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT, v1 varchar(100 BYTES), v2 varchar(5 BYTES) );");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testVarchar3.jar"));
catUpdated = catalogForJar(testDir + File.separator + "testVarchar3.jar");
report = verifyDiff(catOriginal, catUpdated);
assert(report.contains("Table A has been modified."));
// bytes to character
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT, v1 varchar(5), v2 varchar(5 BYTES) ) ;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testVarchar0.jar"));
catOriginal = catalogForJar(testDir + File.separator + "testVarchar0.jar");
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT, v1 varchar(5), v2 varchar(5) );");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testVarchar4.jar"));
catUpdated = catalogForJar(testDir + File.separator + "testVarchar4.jar");
report = verifyDiff(catOriginal, catUpdated);
assert(report.contains("Table A has been modified."));
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT, v1 varchar(5), v2 varchar(15) );");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testVarchar5.jar"));
catUpdated = catalogForJar(testDir + File.separator + "testVarchar5.jar");
report = verifyDiff(catOriginal, catUpdated);
assert(report.contains("Table A has been modified."));
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT, v1 varchar(5), v2 varchar(150) );");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testVarchar6.jar"));
catUpdated = catalogForJar(testDir + File.separator + "testVarchar6.jar");
report = verifyDiff(catOriginal, catUpdated);
assert(report.contains("Table A has been modified."));
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT, v1 varchar(5), v2 varchar(3) );");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testVarchar6.jar"));
catUpdated = catalogForJar(testDir + File.separator + "testVarchar6.jar");
verifyDiffIfEmptyTable(catOriginal, catUpdated);
}
public void testAddNonNullityRejected() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// start with a table
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT , PRIMARY KEY(C1));");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testAddNonNullity1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "testAddNonNullity1.jar");
// add a non-null constraint
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL, PRIMARY KEY(C1));");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testAddNonNullity2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "testAddNonNullity2.jar");
verifyDiffIfEmptyTable(catOriginal, catUpdated);
}
public void testDropNonNullity() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// start with a table
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL, PRIMARY KEY(C1));");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testDropNonNullity1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "testDropNonNullity1.jar");
// add a non-null constraint
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT , PRIMARY KEY(C1));");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testDropNonNullity2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "testDropNonNullity2.jar");
String report = verifyDiff(catOriginal, catUpdated);
assert(report.contains("Table A has been modified."));
}
public void testAddUniqueCoveringTableIndex() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// start with a table
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL, PRIMARY KEY(C1));");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testAddUniqueCoveringTableIndex1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "testAddUniqueCoveringTableIndex1.jar");
// add an index
builder.addLiteralSchema("\nCREATE UNIQUE INDEX IDX ON A(C1,C2);");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testAddUniqueCoveringTableIndex2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "testAddUniqueCoveringTableIndex2.jar");
verifyDiff(catOriginal, catUpdated, false, null, true, false, true);
}
public void testAddUniqueNonCoveringTableIndexRejectedIfNotEmpty() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// start with a table
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL, PRIMARY KEY(C1));");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testAddUniqueNonCoveringTableIndexRejected1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "testAddUniqueNonCoveringTableIndexRejected1.jar");
// add an index
builder.addLiteralSchema("\nCREATE ASSUMEUNIQUE INDEX IDX ON A(C2);");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testAddUniqueNonCoveringTableIndexRejected2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "testAddUniqueNonCoveringTableIndexRejected2.jar");
verifyDiffIfEmptyTable(catOriginal, catUpdated);
}
public void testShrinkUniqueNonCoveringTableIndexRejectedIfNonEmpty() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// start with a table
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL, PRIMARY KEY(C1, C2));");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testAddUniqueNonCoveringTableIndexRejected1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "testAddUniqueNonCoveringTableIndexRejected1.jar");
// shrink the pkey index
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL, PRIMARY KEY(C1));");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testAddUniqueNonCoveringTableIndexRejected2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "testAddUniqueNonCoveringTableIndexRejected2.jar");
verifyDiffIfEmptyTable(catOriginal, catUpdated);
}
public void testExpandUniqueNonCoveringTableIndex() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// start with a table
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL, PRIMARY KEY(C1));");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testAddUniqueNonCoveringTableIndexRejected1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "testAddUniqueNonCoveringTableIndexRejected1.jar");
// shrink the pkey index
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL, PRIMARY KEY(C1, C2));");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testAddUniqueNonCoveringTableIndexRejected2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "testAddUniqueNonCoveringTableIndexRejected2.jar");
verifyDiff(catOriginal, catUpdated);
}
public void testAddNonUniqueTableIndex() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// start with a table
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL, PRIMARY KEY(C1));");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testAddNonUniqueTableIndex1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "testAddNonUniqueTableIndex1.jar");
// add an index
builder.addLiteralSchema("\nCREATE INDEX IDX ON A(C1,C2);");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testAddNonUniqueTableIndex2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "testAddNonUniqueTableIndex2.jar");
verifyDiff(catOriginal, catUpdated);
}
public void renameUniqueIndexes() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// start with a table
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL, PRIMARY KEY(C1));");
builder.addLiteralSchema("\nCREATE UNIQUE INDEX IDX ON A(C1,C2);");
builder.addLiteralSchema("\nCREATE INDEX IDX2 ON A(C2);");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "renameUniqueIndexes1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "renameUniqueIndexes1.jar");
// rename an index
VoltProjectBuilder builder2 = new VoltProjectBuilder();
builder2.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL, PRIMARY KEY(C1));");
builder2.addLiteralSchema("\nCREATE UNIQUE INDEX RYANLIKETHEYANKEES ON A(C1,C2);");
builder2.addLiteralSchema("\nCREATE INDEX GAGNAMSTYLE ON A(C2);");
builder2.addPartitionInfo("A", "C1");
builder2.addProcedures(org.voltdb.catalog.ProcedureA.class);
builder2.compile(testDir + File.separator + "renameUniqueIndexes2.jar");
Catalog catUpdated = catalogForJar(testDir + File.separator + "renameUniqueIndexes2.jar");
verifyDiff(catOriginal, catUpdated);
}
public void testRemoveUniqueIndex() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// start with a table with an index
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL, PRIMARY KEY(C1));");
builder.addLiteralSchema("\nCREATE UNIQUE INDEX IDX ON A(C1,C2);");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testRemoveUniqueIndex1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "testRemoveUniqueIndex1.jar");
// remove the index
Catalog catUpdated = get2ColumnCatalogForTable("A", "testRemoveUniqueIndex2");
verifyDiff(catOriginal, catUpdated);
}
public void testRemoveNonUniqueIndex() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// start with a table with an index
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL, PRIMARY KEY(C1));");
builder.addLiteralSchema("\nCREATE INDEX IDX ON A(C1,C2);");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testRemoveNonUniqueIndex1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "testRemoveNonUniqueIndex1.jar");
// remove the index
Catalog catUpdated = get2ColumnCatalogForTable("A", "testRemoveNonUniqueIndex2");
verifyDiff(catOriginal, catUpdated);
}
public void testAddTableConstraintRejectedIfNotEmpty() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// start with a table without a PKEY
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "testAddTableConstraintRejected1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "testAddTableConstraintRejected1.jar");
// add a constraint (this function creates a primary key)
Catalog catUpdated = getCatalogForTable("A", "testAddTableConstraintRejected2");
verifyDiffIfEmptyTable(catOriginal, catUpdated);
}
public void testRemoveTableConstraint() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// with the primary key
Catalog catOriginal = getCatalogForTable("A", "dropconstraint1");
// without the primary key
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT DEFAULT 0 NOT NULL);");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "dropconstraint2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "dropconstraint2.jar");
verifyDiff(catOriginal, catUpdated);
}
public void testAddMaterializedView() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "addmatview1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "addmatview1.jar");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C1, NUM) AS " +
"\n SELECT C1, COUNT(*) FROM A GROUP BY C1;");
builder.addLiteralSchema("\nCREATE VIEW MATVIEWJOIN(C1, NUM) AS " +
"\n SELECT A.C1, COUNT(*) FROM A JOIN B ON A.C1=B.C2 GROUP BY A.C1;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "addmatview2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "addmatview2.jar");
verifyDiff(catOriginal, catUpdated);
}
public void testRemoveMaterializedView() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// with a view
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C1, NUM) AS " +
"\n SELECT C1, COUNT(*) FROM A GROUP BY C1;");
builder.addLiteralSchema("\nCREATE VIEW MATVIEWJOIN(C1, NUM) AS " +
"\n SELECT A.C1, COUNT(*) FROM A JOIN B ON A.C1=B.C2 GROUP BY A.C1;");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "remmatview1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "remmatview1.jar");
// without a view
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "remmatview2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "remmatview2.jar");
verifyDiff(catOriginal, catUpdated);
}
public void testModifyMaterializedViewColumnRejected() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// with a view
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL, C3 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C, NUM) AS " +
"\n SELECT C3, COUNT(*) FROM A GROUP BY C3;");
builder.addLiteralSchema("\nCREATE VIEW MATVIEWJOIN(C1, NUM) AS " +
"\n SELECT A.C1, COUNT(*) FROM A JOIN B ON A.C1=B.C2 GROUP BY A.C1;");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "modmatview1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "modmatview1.jar");
// with a slightly different view
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL, C3 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C, NUM) AS " +
"\n SELECT C2, COUNT(*) FROM A GROUP BY C2;");
builder.addLiteralSchema("\nCREATE VIEW MATVIEWJOIN(C1, NUM) AS " +
"\n SELECT A.C2, COUNT(*) FROM A JOIN B ON A.C1=B.C1 GROUP BY A.C2;");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "modmatview2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "modmatview2.jar");
verifyDiffRejected(catOriginal, catUpdated);
}
public void testModifyMaterializedViewStructureRejectedIfEmpty() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// with a view
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C1, NUM) AS " +
"\n SELECT C1, COUNT(*) FROM A GROUP BY C1;");
builder.addLiteralSchema("\nCREATE VIEW MATVIEWJOIN(C1, NUM) AS " +
"\n SELECT A.C1, COUNT(*) FROM A JOIN B ON A.C1=B.C2 GROUP BY A.C1;");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "modmatview1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "modmatview1.jar");
// with a quite different view
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C2, C1, NUM) AS " +
"\n SELECT C2, C1, COUNT(*) FROM A GROUP BY C2, C1;");
builder.addLiteralSchema("\nCREATE VIEW MATVIEWJOIN(C1, NUM) AS " +
"\n SELECT A.C2, COUNT(*) FROM A JOIN B ON A.C1=B.C1 GROUP BY A.C2;");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "modmatview2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "modmatview2.jar");
verifyDiffIfEmptyTable(catOriginal, catUpdated);
}
public void testModifyMaterializedViewAddPredicateRejected() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// with a view
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C1, NUM) AS " +
"\n SELECT C1, COUNT(*) FROM A GROUP BY C1;");
builder.addLiteralSchema("\nCREATE VIEW MATVIEWJOIN(C1, NUM) AS " +
"\n SELECT A.C1, COUNT(*) FROM A JOIN B ON A.C1=B.C2 GROUP BY A.C1;");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "addpredmatview1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "addpredmatview1.jar");
// without a view
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C1, NUM) AS " +
"\n SELECT C1, COUNT(*) FROM A WHERE C1 > 0 GROUP BY C1;");
builder.addLiteralSchema("\nCREATE VIEW MATVIEWJOIN(C1, NUM) AS " +
"\n SELECT A.C1, COUNT(*) FROM A JOIN B ON A.C1=B.C2 WHERE A.C1 > 0 GROUP BY A.C1;");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "addpredmatview2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "addpredmatview2.jar");
verifyDiffRejected(catOriginal, catUpdated);
}
public void testModifyMaterializedViewDropPredicateRejected() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// with a view
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C1, NUM) AS " +
"\n SELECT C1, COUNT(*) FROM A WHERE C1 > 0 GROUP BY C1;");
builder.addLiteralSchema("\nCREATE VIEW MATVIEWJOIN(C1, NUM) AS " +
"\n SELECT A.C1, COUNT(*) FROM A JOIN B ON A.C1=B.C2 WHERE A.C1 > 0 GROUP BY A.C1;");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "droppredmatview1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "droppredmatview1.jar");
// without a view
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C1, NUM) AS " +
"\n SELECT C1, COUNT(*) FROM A GROUP BY C1;");
builder.addLiteralSchema("\nCREATE VIEW MATVIEWJOIN(C1, NUM) AS " +
"\n SELECT A.C1, COUNT(*) FROM A JOIN B ON A.C1=B.C2 GROUP BY A.C1;");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "droppredmatview2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "droppredmatview2.jar");
verifyDiffRejected(catOriginal, catUpdated);
}
public void testModifyMaterializedViewPredicateRejected() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// with a view
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C1, NUM) AS " +
"\n SELECT C1, COUNT(*) FROM A WHERE C1 < 0 GROUP BY C1;");
builder.addLiteralSchema("\nCREATE VIEW MATVIEWJOIN(C1, NUM) AS " +
"\n SELECT A.C1, COUNT(*) FROM A JOIN B ON A.C1=B.C2 WHERE A.C1 > 0 GROUP BY A.C1;");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "modpredmatview1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "modpredmatview1.jar");
// without a view
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C1, NUM) AS " +
"\n SELECT C1, COUNT(*) FROM A WHERE C1 > 0 GROUP BY C1;");
builder.addLiteralSchema("\nCREATE VIEW MATVIEWJOIN(C1, NUM) AS " +
"\n SELECT A.C1, COUNT(*) FROM A JOIN B ON A.C1=B.C2 WHERE A.C2 <= 0 GROUP BY A.C1;");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "modpredmatview2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "modpredmatview2.jar");
verifyDiffRejected(catOriginal, catUpdated);
}
public void testModifyMaterializedViewSourceRejectedIfEmpty() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// with a view
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C1, NUM) AS " +
"\n SELECT C1, COUNT(*) FROM A GROUP BY C1;");
builder.addLiteralSchema("\nCREATE VIEW MATVIEWJOIN(C1, NUM) AS " +
"\n SELECT A.C1, COUNT(*) FROM A JOIN B ON A.C1=B.C2 GROUP BY A.C1;");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "resrcmatview1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "resrcmatview1.jar");
// without an added column (should work with empty table)
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL, C3 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C1, NUM) AS " +
"\n SELECT C1, COUNT(*) FROM A GROUP BY C1;");
builder.addLiteralSchema("\nCREATE VIEW MATVIEWJOIN(C1, NUM) AS " +
"\n SELECT A.C1, COUNT(*) FROM A JOIN B ON A.C1=B.C2 GROUP BY A.C1;");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "resrcmatview2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "resrcmatview2.jar");
verifyDiffIfEmptyTable(catOriginal, catUpdated);
}
public void testRemoveTableAndMaterializedView() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
// with a view
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE TABLE B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addLiteralSchema("\nCREATE VIEW MATVIEW(C1, NUM) AS " +
"\n SELECT C1, COUNT(*) FROM A GROUP BY C1;");
builder.addLiteralSchema("\nCREATE VIEW MATVIEWJOIN(C1, NUM) AS " +
"\n SELECT A.C1, COUNT(*) FROM A JOIN B ON A.C1=B.C2 GROUP BY A.C1;");
builder.addPartitionInfo("A", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureA.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "remtablematview1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "remtablematview1.jar");
// without a view
builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE C (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addPartitionInfo("C", "C1");
builder.addProcedures(org.voltdb.catalog.ProcedureC.class);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "remtablematview2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "remtablematview2.jar");
verifyDiff(catOriginal, catUpdated);
}
public void testChangeTableReplicationSetting() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addStmtProcedure("the_requisite_procedure", "select * from A;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "addpart1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "addpart1.jar");
builder.addPartitionInfo("A", "C1");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "addpart2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "addpart2.jar");
verifyDiffIfEmptyTable(catOriginal, catUpdated);
}
public void testDRRoleChange() throws Exception {
final String ddl = "CREATE TABLE A (C1 BIGINT NOT NULL); DR TABLE A;";
String noneDepXml =
"<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
+ "<deployment>"
+ "<cluster hostcount='3' kfactor='1' sitesperhost='2'/>"
+ " <dr id=\"1\" listen=\"false\"></dr>"
+ "</deployment>";
String defaultDepXml =
"<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
+ "<deployment>"
+ "<cluster hostcount='3' kfactor='1' sitesperhost='2'/>"
+ " <dr id=\"1\"></dr>"
+ "</deployment>";
String masterDepXml =
"<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
+ "<deployment>"
+ "<cluster hostcount='3' kfactor='1' sitesperhost='2'/>"
+ " <dr id=\"1\" role=\"master\"></dr>"
+ "</deployment>";
String replicaDepXml =
"<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
+ "<deployment>"
+ "<cluster hostcount='3' kfactor='1' sitesperhost='2'/>"
+ " <dr id=\"1\" role=\"replica\"></dr>"
+ "</deployment>";
Catalog noneCatalog = generateCatalogWithDeployment(ddl, noneDepXml);
Catalog defaultCatalog = generateCatalogWithDeployment(ddl, defaultDepXml);
Catalog masterCatalog = generateCatalogWithDeployment(ddl, masterDepXml);
Catalog replicaCatalog = generateCatalogWithDeployment(ddl, replicaDepXml);
// Making a deep copy to the original catalog so that it doesn't apply
// the changes to the catalogs.
verifyDiff(noneCatalog.deepCopy(), defaultCatalog);
assertTrue(verifyDiff(defaultCatalog.deepCopy(), masterCatalog, false).contains("No changes detected"));
verifyDiff(replicaCatalog.deepCopy(), masterCatalog);
verifyDiff(replicaCatalog.deepCopy(), defaultCatalog);
assertTrue(verifyDiff(masterCatalog.deepCopy(), defaultCatalog, false).contains("No changes detected"));
verifyDiffRejected(defaultCatalog.deepCopy(), replicaCatalog);
verifyDiffRejected(masterCatalog.deepCopy(), replicaCatalog);
}
private static Catalog generateCatalogWithDeployment(String ddl, String defaultDepXml) throws IOException {
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema(ddl);
final File jarPath = VoltFile.createTempFile("drrole", "jar");
builder.compile(jarPath.getAbsolutePath());
Catalog catalog = catalogForJar(jarPath.getAbsolutePath());
File file = VoltProjectBuilder.writeStringToTempFile(defaultDepXml);
DeploymentType deployment = CatalogUtil.getDeployment(new FileInputStream(file));
CatalogUtil.compileDeployment(catalog, deployment, false);
jarPath.delete();
return catalog;
}
public void testChangeCompatibleWithElasticNoChange() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addStmtProcedure("the_requisite_procedure", "select * from A;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "elastic1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "elastic1.jar");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "elastic2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "elastic2.jar");
verifyDiff(catOriginal, catUpdated, null, true, false, false, true);
}
public void testChangeNotCompatibleWithElasticAddProcedure() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addStmtProcedure("the_requisite_procedure", "select * from A;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "elastic1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "elastic1.jar");
builder.addStmtProcedure("another_procedure", "select * from A;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "elastic2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "elastic2.jar");
verifyDiff(catOriginal, catUpdated, null, false, false, false, true);
}
public void testChangeNotCompatibleWithElasticAddTable() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
builder.addStmtProcedure("the_requisite_procedure", "select * from A;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "elastic1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "elastic1.jar");
builder.addLiteralSchema("\nCREATE TABLE another_table (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "elastic2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "elastic2.jar");
verifyDiff(catOriginal, catUpdated, null, false, true, false, true);
}
public void testEnableDROnEmptyTable() throws IOException {
if (!MiscUtils.isPro()) { return; } // not supported in community
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);" +
"\nPARTITION TABLE A ON COLUMN C1;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "dr1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "dr1.jar");
builder.addLiteralSchema("\nDR TABLE A;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "dr2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "dr2.jar");
verifyDiffIfEmptyTable(catOriginal, catUpdated);
}
public void testDisableDROnTable() throws IOException {
if (!MiscUtils.isPro()) { return; } // not supported in community
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);" +
"\nPARTITION TABLE A ON COLUMN C1;" +
"\nDR TABLE A;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "dr1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "dr1.jar");
builder.addLiteralSchema("\nDR TABLE A DISABLE;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "dr2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "dr2.jar");
verifyDiff(catOriginal, catUpdated);
}
public void testAddDRTableColumn() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);" +
"\nPARTITION TABLE A ON COLUMN C1;" +
"\nDR TABLE A;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "dr1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "dr1.jar");
builder.addLiteralSchema("\nALTER TABLE A ADD COLUMN C3 INTEGER;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "dr2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "dr2.jar");
verifyDiff(catOriginal, catUpdated);
}
public void testRemoveDRTableColumn() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);" +
"\nPARTITION TABLE A ON COLUMN C1;" +
"\nDR TABLE A;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "dr1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "dr1.jar");
builder.addLiteralSchema("\nALTER TABLE A DROP COLUMN C2;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "dr2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "dr2.jar");
verifyDiff(catOriginal, catUpdated);
}
public void testModifyDRTableColumn() throws IOException {
String originalSchema = "\nCREATE TABLE A (C1 BIGINT NOT NULL, C2 INTEGER NOT NULL);" +
"\nPARTITION TABLE A ON COLUMN C1;" +
"\nDR TABLE A;";
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema(originalSchema);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "dr1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "dr1.jar");
builder.addLiteralSchema("\nALTER TABLE A ALTER COLUMN C2 BIGINT;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "dr2.jar"));
Catalog catUpdated = catalogForJar(testDir + File.separator + "dr2.jar");
// Does not require empty table as C2 is made wider
verifyDiff(catOriginal, catUpdated);
builder = new VoltProjectBuilder();
builder.addLiteralSchema(originalSchema);
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "dr3.jar"));
catOriginal = catalogForJar(testDir + File.separator + "dr3.jar");
builder.addLiteralSchema("\nALTER TABLE A ALTER COLUMN C2 TINYINT;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "dr4.jar"));
catUpdated = catalogForJar(testDir + File.separator + "dr4.jar");
// Requires empty table as C2 is made narrower
verifyDiffIfEmptyTable(catOriginal, catUpdated);
}
public void testExportConfigStreamTargetAttribute() throws Exception {
if (!MiscUtils.isPro()) { return; } // not supported in community
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
final String ddl =
"CREATE STREAM export_data ( id BIGINT default 0 , value BIGINT DEFAULT 0 );";
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema(ddl);
String depXml =
"<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
+ "<deployment>"
+ "<cluster hostcount='3' kfactor='1' sitesperhost='2'/>"
+ " <export>"
+ " <configuration target='default' enabled='true' type='file'>"
+ " <property name=\"type\">CSV</property>"
+ " <property name=\"with-schema\">false</property>"
+ " <property name=\"nonce\">pre-fix</property>"
+ " <property name=\"outdir\">"+m_dir+"</property>"
+ " </configuration>"
+ " </export>"
+ "</deployment>";
builder.compile(testDir + File.separator + "exporttarget1.jar");
Catalog cat = catalogForJar(testDir + File.separator + "exporttarget1.jar");
File file = VoltProjectBuilder.writeStringToTempFile(depXml);
DeploymentType deployment = CatalogUtil.getDeployment(new FileInputStream(file));
String msg = CatalogUtil.compileDeployment(cat, deployment, false);
assertTrue("Deployment file failed to parse: " + msg, msg == null);
}
public void testConnectorPropertiesChanges() throws Exception {
if (!MiscUtils.isPro()) { return; } // not supported in community
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
final String ddl =
"CREATE STREAM export_data export to target default ( id BIGINT default 0 , value BIGINT DEFAULT 0 );";
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema(ddl);
final String origXml =
"<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
+ "<deployment>"
+ "<cluster hostcount='3' kfactor='1' sitesperhost='2'/>"
+ " <export>"
+ " <configuration target='default' enabled='true' type='file'>"
+ " <property name=\"type\">CSV</property>"
+ " <property name=\"with-schema\">false</property>"
+ " <property name=\"nonce\">pre-fix</property>"
+ " <property name=\"outdir\">"+m_dir+"</property>"
+ " </configuration>"
+ " </export>"
+ "</deployment>";
builder.compile(testDir + File.separator + "propexport1.jar");
Catalog origCat = catalogForJar(testDir + File.separator + "propexport1.jar");
final File origFile = VoltProjectBuilder.writeStringToTempFile(origXml);
DeploymentType origDepl = CatalogUtil.getDeployment(new FileInputStream(origFile));
String msg = CatalogUtil.compileDeployment(origCat, origDepl, false);
assertTrue("Deployment file failed to parse: " + msg, msg == null);
final String newPropXml =
"<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
+ "<deployment>"
+ "<cluster hostcount='3' kfactor='1' sitesperhost='2'/>"
+ " <export>"
+ " <configuration target='default' enabled='true' type='file'>"
+ " <property name=\"type\">CSV</property>"
+ " <property name=\"with-schema\">false</property>"
+ " <property name=\"nonce\">pre-fix</property>"
+ " <property name=\"outdir\">"+m_dir+"</property>"
+ " <property name=\"iamnew\">see_me_roar</property>"
+ " </configuration>"
+ " </export>"
+ "</deployment>";
builder.compile(testDir + File.separator + "propexport2.jar");
Catalog newPropCat = catalogForJar(testDir + File.separator + "propexport2.jar");
final File newPropFile = VoltProjectBuilder.writeStringToTempFile(newPropXml);
DeploymentType newPropDepl = CatalogUtil.getDeployment(new FileInputStream(newPropFile));
msg = CatalogUtil.compileDeployment(newPropCat, newPropDepl, false);
assertTrue("Deployment file failed to parse: " + msg, msg == null);
final String modPropXml =
"<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
+ "<deployment>"
+ "<cluster hostcount='3' kfactor='1' sitesperhost='2'/>"
+ " <export>"
+ " <configuration target='default' enabled='true' type='file'>"
+ " <property name=\"type\">TSV</property>"
+ " <property name=\"with-schema\">true</property>"
+ " <property name=\"nonce\">pre-fix-other</property>"
+ " <property name=\"outdir\">"+m_dir+"</property>"
+ " </configuration>"
+ " </export>"
+ "</deployment>";
builder.compile(testDir + File.separator + "propexport3.jar");
Catalog modPropCat = catalogForJar(testDir + File.separator + "propexport3.jar");
final File modPropFile = VoltProjectBuilder.writeStringToTempFile(modPropXml);
DeploymentType modPropDepl = CatalogUtil.getDeployment(new FileInputStream(modPropFile));
msg = CatalogUtil.compileDeployment(modPropCat, modPropDepl, false);
assertTrue("Deployment file failed to parse: " + msg, msg == null);
final String modTypeXml =
"<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
+ "<deployment>"
+ "<cluster hostcount='3' kfactor='1' sitesperhost='2'/>"
+ " <export>"
+ " <configuration target='default' enabled='false' type='custom' exportconnectorclass=\"org.voltdb.exportclient.NoOpTestExportClient\" >"
+ " <property name=\"foo\">false</property>"
+ " <property name=\"type\">CSV</property>"
+ " <property name=\"with-schema\">false</property>"
+ " </configuration>"
+ " </export>"
+ "</deployment>";
builder.compile(testDir + File.separator + "propexport4.jar");
Catalog modTypeCat = catalogForJar(testDir + File.separator + "propexport4.jar");
final File modTypeFile = VoltProjectBuilder.writeStringToTempFile(modTypeXml);
DeploymentType modTypeDepl = CatalogUtil.getDeployment(new FileInputStream(modTypeFile));
msg = CatalogUtil.compileDeployment(modTypeCat, modTypeDepl, false);
assertTrue("Deployment file failed to parse: " + msg, msg == null);
verifyDiff(newPropCat, origCat, null, null, true, true, false); // test delete
verifyDiff(origCat, newPropCat, null, null, true, true, false); // test add
verifyDiff(origCat, modPropCat, null, null, true, true, false); // test modification
verifyDiff(modPropCat, modTypeCat, null, null, true, true, false); // test modification
}
public void testAddStreamRollGeneration() throws IOException {
String testDir = BuildDirectoryUtils.getBuildDirectoryPath();
VoltProjectBuilder builder = new VoltProjectBuilder();
builder.addLiteralSchema("CREATE STREAM A PARTITION ON COLUMN C1 (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);"
+ "\nCREATE TABLE tableToDrop (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);"
+ "\nCREATE STREAM B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "exp1.jar"));
Catalog catOriginal = catalogForJar(testDir + File.separator + "exp1.jar");
builder = new VoltProjectBuilder();
builder.addLiteralSchema("CREATE STREAM A PARTITION ON COLUMN C1 (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);"
+ "\nCREATE TABLE tableToDrop (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "exp2.jar"));
Catalog catUpdatedWithDropStream = catalogForJar(testDir + File.separator + "exp2.jar");
builder = new VoltProjectBuilder();
builder.addLiteralSchema("CREATE STREAM A PARTITION ON COLUMN C1 (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);"
+ "\nCREATE TABLE tableToDrop (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);"
+ "\nCREATE STREAM B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);"
+ "\nCREATE TABLE foo (i integer);");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "exp3.jar"));
Catalog catUpdatedWithNewTable = catalogForJar(testDir + File.separator + "exp3.jar");
builder = new VoltProjectBuilder();
builder.addLiteralSchema("CREATE STREAM A PARTITION ON COLUMN C1 (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);"
+ "\nCREATE STREAM B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "exp4.jar"));
Catalog catUpdatedWithDroppedTable = catalogForJar(testDir + File.separator + "exp4.jar");
builder = new VoltProjectBuilder();
builder.addLiteralSchema("CREATE STREAM A PARTITION ON COLUMN C1 (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);"
+ "\nCREATE TABLE tableToDrop (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);"
+ "\nCREATE STREAM B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);"
+ "\nCREATE STREAM C (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "exp5.jar"));
Catalog catUpdatedWithNewStream = catalogForJar(testDir + File.separator + "exp5.jar");
verifyDiff(catOriginal, catUpdatedWithNewStream, null, null, true, true, false); // add stream and roll
verifyDiff(catOriginal, catUpdatedWithDropStream, null, null, true, true, false); // drop stream and roll
verifyDiff(catOriginal, catUpdatedWithNewTable, null, null, true, false, false); // add table and dont roll
verifyDiff(catOriginal, catUpdatedWithDroppedTable, null, null, true, false, false); // drop table and dont roll
builder = new VoltProjectBuilder();
builder.addLiteralSchema("CREATE STREAM A PARTITION ON COLUMN C1 (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);"
+ "\nCREATE TABLE tableToDrop (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);"
+ "\nCREATE STREAM B (C1 BIGINT NOT NULL, C2 BIGINT NOT NULL);"
+ "\nCREATE VIEW V_A (C1 , NUM_A) AS SELECT C1, COUNT(*) FROM A GROUP BY C1;");
assertTrue("Failed to compile schema", builder.compile(testDir + File.separator + "exp6.jar"));
Catalog catUpdatedWithStreamView = catalogForJar(testDir + File.separator + "exp6.jar");
verifyDiff(catOriginal, catUpdatedWithStreamView, null, null, true, false, false); // create view on stream and roll
verifyDiff(catUpdatedWithStreamView, catOriginal, null, null, true, false, false); // drop view on stream and roll
}
}