/* This file is part of VoltDB.
* Copyright (C) 2008-2010 VoltDB L.L.C.
*
* 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.compiler;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.voltdb.ProcInfoData;
import org.voltdb.benchmark.tpcc.TPCCClient;
import org.voltdb.benchmark.tpcc.TPCCProjectBuilder;
import org.voltdb.catalog.*;
import org.voltdb.regressionsuites.TestSQLTypesSuite;
import org.voltdb.types.ConstraintType;
import org.voltdb.utils.BuildDirectoryUtils;
import org.voltdb.utils.JarReader;
import edu.brown.BaseTestCase;
import edu.brown.catalog.CatalogUtil;
public class TestVoltCompiler extends BaseTestCase {
String nothing_jar;
String testout_jar;
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
@Override
public void setUp() {
nothing_jar = BuildDirectoryUtils.getBuildDirectoryPath() + File.pathSeparator + "nothing.jar";
testout_jar = BuildDirectoryUtils.getBuildDirectoryPath() + File.pathSeparator + "testout.jar";
}
@Override
public void tearDown() {
File njar = new File(nothing_jar);
njar.delete();
File tjar = new File(testout_jar);
tjar.delete();
}
public void testSnapshotSettings() throws IOException {
String schemaPath = "";
try {
final URL url = TPCCClient.class.getResource("tpcc-ddl.sql");
schemaPath = URLDecoder.decode(url.getPath(), "UTF-8");
} catch (final UnsupportedEncodingException e) {
e.printStackTrace();
System.exit(-1);
}
VoltProjectBuilder builder = new VoltProjectBuilder("testvoltcompiler");
builder.addProcedures(org.voltdb.compiler.procedures.TPCCTestProc.class);
builder.setSnapshotSettings("32m", 5, "/tmp", "woobar");
builder.addSchema(schemaPath);
try {
assertTrue(builder.compile("/tmp/snapshot_settings_test.jar"));
final String catalogContents =
JarReader.readFileFromJarfile("/tmp/snapshot_settings_test.jar", "catalog.txt");
final Catalog cat = new Catalog();
cat.execute(catalogContents);
SnapshotSchedule schedule =
cat.getClusters().get("cluster").getDatabases().
get("database").getSnapshotschedule().get("default");
assertEquals(32, schedule.getFrequencyvalue());
assertEquals("m", schedule.getFrequencyunit());
assertEquals("/tmp", schedule.getPath());
assertEquals("woobar", schedule.getPrefix());
} finally {
final File jar = new File("/tmp/snapshot_settings_test.jar");
jar.delete();
}
}
// TestELTSuite tests most of these options end-to-end; however need to test
// that a disabled connector is really disabled and that auth data is correct.
public void testELTSetting() throws IOException {
final VoltProjectBuilder project = new VoltProjectBuilder("sqltypessuite");
project.addSchema(TestSQLTypesSuite.class.getResource("sqltypessuite-ddl.sql"));
project.addProcedures(org.voltdb.regressionsuites.sqltypesprocs.Insert.class);
project.addTablePartitionInfo("NO_NULLS", "PKEY");
project.addTablePartitionInfo("ALLOW_NULLS", "PKEY");
project.addTablePartitionInfo("WITH_DEFAULTS", "PKEY");
project.addTablePartitionInfo("WITH_NULL_DEFAULTS", "PKEY");
project.addTablePartitionInfo("EXPRESSIONS_WITH_NULLS", "PKEY");
project.addTablePartitionInfo("EXPRESSIONS_NO_NULLS", "PKEY");
project.addTablePartitionInfo("JUMBO_ROW", "PKEY");
project.addELT("org.voltdb.elt.processors.RawProcessor", false, null, null);
project.addELTTable("ALLOW_NULLS", false); // persistent table
project.addELTTable("WITH_DEFAULTS", true); // streamed table
try {
assertTrue(project.compile("/tmp/eltsettingstest.jar"));
final String catalogContents =
JarReader.readFileFromJarfile("/tmp/eltsettingstest.jar", "catalog.txt");
final Catalog cat = new Catalog();
cat.execute(catalogContents);
Connector connector = cat.getClusters().get("cluster").getDatabases().
get("database").getConnectors().get("0");
assertFalse(connector.getEnabled());
} finally {
final File jar = new File("/tmp/eltsettingstest.jar");
jar.delete();
}
}
public void testBadPath() {
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final boolean success = compiler.compile("invalidnonsense",
cluster_config,
"nothing", System.out, null);
assertFalse(success);
}
public void testInvalidXMLFile() {
final String simpleXML =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<database name='database'>" +
"<schemas><schema path='my schema file.sql' /></schemas>" +
"<procedures><procedure class='procedures/procs.jar' /></procedures>" +
"</database>" +
"</project>";
final File xmlFile = VoltProjectBuilder.writeStringToTempFile(simpleXML);
final String path = xmlFile.getPath();
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final boolean success = compiler.compile(path, cluster_config,
"nothing", System.out, null);
assertFalse(success);
}
public void testXMLFileWithSchemaError() {
final String simpleXML =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<database name='database'>" +
"<schemas><schema path='my schema file.sql' /></schemas>" +
"<procedures><procedure class='procedures/procs.jar'/></procedures>" +
"</database>" +
"</project>";
final File xmlFile = VoltProjectBuilder.writeStringToTempFile(simpleXML);
final String path = xmlFile.getPath();
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final boolean success = compiler.compile(path, cluster_config,
"nothing", System.out, null);
assertFalse(success);
}
public void testXMLFileWithWrongDBName() {
final String simpleXML =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<database name='mydb1'>" +
"<schemas>" +
"<schema path='my schema file.sql' />" +
"</schemas>" +
"<procedures>" +
"<procedure class='procedures/procs.jar' />" +
"</procedures>" +
"</database>" +
"</project>";
final File xmlFile = VoltProjectBuilder.writeStringToTempFile(simpleXML);
final String path = xmlFile.getPath();
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final boolean success = compiler.compile(path, cluster_config,
"nothing", System.out, null);
assertFalse(success);
}
public void testBadClusterConfig() throws IOException {
String simpleSchema =
"create table books (cash integer default 23, title varchar default 'foo', PRIMARY KEY(cash));";
File schemaFile = VoltProjectBuilder.writeStringToTempFile(simpleSchema);
String schemaPath = schemaFile.getPath();
String simpleProject =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<!-- xml comment check -->" +
"<database name='database'>" +
"<!-- xml comment check -->" +
"<schema path='" + schemaPath + "' />" +
"<!-- xml comment check -->" +
"<procedure class='org.voltdb.compiler.procedures.AddBook' />" +
"<!-- xml comment check -->" +
"</database>" +
"<!-- xml comment check -->" +
"</project>";
File projectFile = VoltProjectBuilder.writeStringToTempFile(simpleProject);
String projectPath = projectFile.getPath();
VoltCompiler compiler = new VoltCompiler();
// check no hosts
ClusterConfig cluster_config = new ClusterConfig(0, 1, 0, "localhost");
boolean success = compiler.compile(projectPath, cluster_config,
"testout.jar", System.out, null);
assertFalse(success);
// check no sites-per-hosts
cluster_config = new ClusterConfig(1, 0, 0, "localhost");
success = compiler.compile(projectPath, cluster_config,
"testout.jar", System.out, null);
assertFalse(success);
File jar = new File("testout.jar");
jar.delete();
}
public void testXMLFileWithDDL() throws IOException {
final String simpleSchema1 =
"create table books (cash integer default 23, title varchar(3) default 'foo', PRIMARY KEY(cash));";
// newline inserted to test catalog friendliness
final String simpleSchema2 =
"create table books2\n (cash integer default 23, title varchar(3) default 'foo', PRIMARY KEY(cash));";
final File schemaFile1 = VoltProjectBuilder.writeStringToTempFile(simpleSchema1);
final String schemaPath1 = schemaFile1.getPath();
final File schemaFile2 = VoltProjectBuilder.writeStringToTempFile(simpleSchema2);
final String schemaPath2 = schemaFile2.getPath();
final String simpleProject =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<!-- xml comment check -->" +
"<database name='database'>" +
"<!-- xml comment check -->" +
"<schemas>" +
"<!-- xml comment check -->" +
"<schema path='" + schemaPath1 + "' />" +
"<schema path='" + schemaPath2 + "' />" +
"<!-- xml comment check -->" +
"</schemas>" +
"<!-- xml comment check -->" +
"<procedures>" +
"<!-- xml comment check -->" +
"<procedure class='org.voltdb.compiler.procedures.AddBook' />" +
"<procedure class='Foo'>" +
"<sql>select * from books;</sql>" +
"</procedure>" +
"</procedures>" +
"<!-- xml comment check -->" +
"</database>" +
"<!-- xml comment check -->" +
"</project>";
final File projectFile = VoltProjectBuilder.writeStringToTempFile(simpleProject);
final String projectPath = projectFile.getPath();
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final boolean success = compiler.compile(projectPath, cluster_config,
"testout.jar", System.out, null);
assertTrue(success);
final Catalog c1 = compiler.getCatalog();
final String catalogContents = JarReader.readFileFromJarfile("testout.jar", "catalog.txt");
final Catalog c2 = new Catalog();
c2.execute(catalogContents);
assertTrue(c2.serialize().equals(c1.serialize()));
final File jar = new File("testout.jar");
jar.delete();
}
public void testDDLWithNoLengthString() throws IOException {
final String simpleSchema1 =
"create table books (cash integer default 23, title varchar default 'foo', PRIMARY KEY(cash));";
final File schemaFile = VoltProjectBuilder.writeStringToTempFile(simpleSchema1);
final String schemaPath = schemaFile.getPath();
final String simpleProject =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<database name='database'>" +
"<schemas>" +
"<schema path='" + schemaPath + "' />" +
"</schemas>" +
"<procedures>" +
"<procedure class='org.voltdb.compiler.procedures.AddBook' />" +
"<procedure class='Foo'>" +
"<sql>select * from books;</sql>" +
"</procedure>" +
"</procedures>" +
"</database>" +
"</project>";
final File projectFile = VoltProjectBuilder.writeStringToTempFile(simpleProject);
final String projectPath = projectFile.getPath();
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final boolean success = compiler.compile(projectPath, cluster_config,
"testout.jar", System.out, null);
assertFalse(success);
}
public void testNullablePartitionColumn() throws IOException {
final String simpleSchema =
"create table books (cash integer default 23, title varchar(3) default 'foo', PRIMARY KEY(cash));";
final File schemaFile = VoltProjectBuilder.writeStringToTempFile(simpleSchema);
final String schemaPath = schemaFile.getPath();
final String simpleProject =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<database name='database'>" +
"<schemas><schema path='" + schemaPath + "' /></schemas>" +
"<procedures><procedure class='org.voltdb.compiler.procedures.AddBook'/></procedures>" +
"<partitions><partition table='BOOKS' column='CASH' /></partitions>" +
"</database>" +
"</project>";
final File projectFile = VoltProjectBuilder.writeStringToTempFile(simpleProject);
final String projectPath = projectFile.getPath();
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final boolean success = compiler.compile(projectPath, cluster_config,
"testout.jar", System.out, null);
assertFalse(success);
boolean found = false;
for (final VoltCompiler.Feedback fb : compiler.m_errors) {
if (fb.message.indexOf("Partition column") > 0)
found = true;
}
assertTrue(found);
}
public void testXMLFileWithBadDDL() throws IOException {
final String simpleSchema =
"create table books (id integer default 0, strval varchar(33000) default '', PRIMARY KEY(id));";
final File schemaFile = VoltProjectBuilder.writeStringToTempFile(simpleSchema);
final String schemaPath = schemaFile.getPath();
final String simpleProject =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<database name='database'>" +
"<schemas><schema path='" + schemaPath + "' /></schemas>" +
"<procedures><procedure class='org.voltdb.compiler.procedures.AddBook' /></procedures>" +
"</database>" +
"</project>";
final File projectFile = VoltProjectBuilder.writeStringToTempFile(simpleProject);
final String projectPath = projectFile.getPath();
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final boolean success = compiler.compile(projectPath, cluster_config,
"testout.jar", System.out, null);
assertFalse(success);
}
// NOTE: TPCCTest proc also tests whitespaces regressions in SQL literals
public void testWithTPCCDDL() {
String schemaPath = "";
try {
final URL url = TPCCClient.class.getResource("tpcc-ddl.sql");
schemaPath = URLDecoder.decode(url.getPath(), "UTF-8");
} catch (final UnsupportedEncodingException e) {
e.printStackTrace();
System.exit(-1);
}
final String simpleProject =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<database name='database'>" +
"<schemas><schema path='" + schemaPath + "' /></schemas>" +
"<procedures><procedure class='org.voltdb.compiler.procedures.TPCCTestProc' /></procedures>" +
"</database>" +
"</project>";
//System.out.println(simpleProject);
final File projectFile = VoltProjectBuilder.writeStringToTempFile(simpleProject);
final String projectPath = projectFile.getPath();
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final boolean success = compiler.compile(projectPath, cluster_config,
"testout.jar", System.out, null);
assertTrue(success);
final File jar = new File("testout.jar");
jar.delete();
}
public void testSeparateCatalogCompilation() throws IOException {
String schemaPath = "";
try {
final URL url = TPCCClient.class.getResource("tpcc-ddl.sql");
schemaPath = URLDecoder.decode(url.getPath(), "UTF-8");
} catch (final UnsupportedEncodingException e) {
e.printStackTrace();
System.exit(-1);
}
final String simpleProject =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<database name='database'>" +
"<schemas><schema path='" + schemaPath + "' /></schemas>" +
"<procedures><procedure class='org.voltdb.compiler.procedures.TPCCTestProc' /></procedures>" +
"</database>" +
"</project>";
//System.out.println(simpleProject);
final File projectFile = VoltProjectBuilder.writeStringToTempFile(simpleProject);
final String projectPath = projectFile.getPath();
final VoltCompiler compiler1 = new VoltCompiler();
final VoltCompiler compiler2 = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final Catalog catalog = compiler1.compileCatalog(projectPath, cluster_config);
final String cat1 = catalog.serialize();
final boolean success = compiler2.compile(projectPath, cluster_config,
"testout.jar", System.out, null);
final String cat2 = JarReader.readFileFromJarfile("testout.jar", "catalog.txt");
assertTrue(success);
assertTrue(cat1.compareTo(cat2) == 0);
final File jar = new File("testout.jar");
jar.delete();
}
public void testDDLTableTooManyColumns() throws IOException {
String schemaPath = "";
try {
final URL url = TestVoltCompiler.class.getResource("toowidetable-ddl.sql");
schemaPath = URLDecoder.decode(url.getPath(), "UTF-8");
} catch (final UnsupportedEncodingException e) {
e.printStackTrace();
System.exit(-1);
}
final String simpleProject =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<database name='database'>" +
"<schemas><schema path='" + schemaPath + "' /></schemas>" +
"<procedures><procedure class='org.voltdb.compiler.procedures.TPCCTestProc' /></procedures>" +
"</database>" +
"</project>";
//System.out.println(simpleProject);
final File projectFile = VoltProjectBuilder.writeStringToTempFile(simpleProject);
final String projectPath = projectFile.getPath();
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final boolean success = compiler.compile(projectPath, cluster_config,
"testout.jar", System.out, null);
assertFalse(success);
boolean found = false;
for (final VoltCompiler.Feedback fb : compiler.m_errors) {
if (fb.message.startsWith("Table MANY_COLUMNS has"))
found = true;
}
assertTrue(found);
}
public void testExtraFilesExist() throws IOException {
String schemaPath = "";
try {
final URL url = TPCCClient.class.getResource("tpcc-ddl.sql");
schemaPath = URLDecoder.decode(url.getPath(), "UTF-8");
} catch (final UnsupportedEncodingException e) {
e.printStackTrace();
System.exit(-1);
}
final String simpleProject =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<database name='database'>" +
"<schemas><schema path='" + schemaPath + "' /></schemas>" +
"<procedures><procedure class='org.voltdb.compiler.procedures.TPCCTestProc' /></procedures>" +
"</database>" +
"</project>";
//System.out.println(simpleProject);
final File projectFile = VoltProjectBuilder.writeStringToTempFile(simpleProject);
final String projectPath = projectFile.getPath();
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final boolean success = compiler.compile(projectPath, cluster_config,
"testout.jar", System.out, null);
assertTrue(success);
final String sql = JarReader.readFileFromJarfile("testout.jar", "tpcc-ddl.sql");
assertNotNull(sql);
final File jar = new File("testout.jar");
jar.delete();
}
public void testXMLFileWithELEnabled() throws IOException {
final String simpleSchema =
"create table books (cash integer default 23, title varchar(3) default 'foo', PRIMARY KEY(cash));";
final File schemaFile = VoltProjectBuilder.writeStringToTempFile(simpleSchema);
final String schemaPath = schemaFile.getPath();
final String simpleProject =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
" <database name='database'>" +
" <schemas><schema path='" + schemaPath + "' /></schemas>" +
" <procedures><procedure class='org.voltdb.compiler.procedures.AddBook' /></procedures>" +
" <exports><connector class='org.voltdb.VerticaLoader'> " +
" <tables><table name='foo' exportonly='true'/></tables>" +
" </connector>" +
" </exports>" +
" </database>" +
"</project>";
final File projectFile = VoltProjectBuilder.writeStringToTempFile(simpleProject);
final String projectPath = projectFile.getPath();
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final boolean success = compiler.compile(projectPath, cluster_config,
"testout.jar", System.out, null);
assertTrue(success);
final Catalog c1 = compiler.getCatalog();
//System.out.println("PRINTING Catalog 1");
//System.out.println(c1.serialize());
final String catalogContents = JarReader.readFileFromJarfile("testout.jar", "catalog.txt");
final Catalog c2 = new Catalog();
c2.execute(catalogContents);
assertTrue(c2.serialize().equals(c1.serialize()));
final File jar = new File("testout.jar");
jar.delete();
}
public void testOverrideProcInfo() throws IOException {
final String simpleSchema =
"create table books (cash integer default 23 not null, title varchar(3) default 'foo', PRIMARY KEY(cash));";
final File schemaFile = VoltProjectBuilder.writeStringToTempFile(simpleSchema);
final String schemaPath = schemaFile.getPath();
final String simpleProject =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<database name='database'>" +
"<schemas><schema path='" + schemaPath + "' /></schemas>" +
"<procedures><procedure class='org.voltdb.compiler.procedures.AddBook' /></procedures>" +
"<partitions><partition table='BOOKS' column='CASH' /></partitions>" +
"</database>" +
"</project>";
final File projectFile = VoltProjectBuilder.writeStringToTempFile(simpleProject);
final String projectPath = projectFile.getPath();
final ProcInfoData info = new ProcInfoData();
info.singlePartition = true;
info.partitionInfo = "BOOKS.CASH: 0";
final Map<String, ProcInfoData> overrideMap = new HashMap<String, ProcInfoData>();
overrideMap.put("AddBook", info);
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final boolean success = compiler.compile(projectPath, cluster_config,
"testout.jar", System.out,
overrideMap);
assertTrue(success);
final String catalogContents = JarReader.readFileFromJarfile("testout.jar", "catalog.txt");
final Catalog c2 = new Catalog();
c2.execute(catalogContents);
final Database db = c2.getClusters().get("cluster").getDatabases().get("database");
final Procedure addBook = db.getProcedures().get("AddBook");
assertEquals(true, addBook.getSinglepartition());
final File jar = new File("testout.jar");
jar.delete();
}
public void testBadStmtProcName() throws IOException {
final String simpleSchema =
"create table books (cash integer default 23 not null, title varchar default 'foo', PRIMARY KEY(cash));";
final File schemaFile = VoltProjectBuilder.writeStringToTempFile(simpleSchema);
final String schemaPath = schemaFile.getPath();
final String simpleProject =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<database name='database'>" +
"<schemas><schema path='" + schemaPath + "' /></schemas>" +
"<procedures><procedure class='@Foo'><sql>select * from books;</sql></procedure></procedures>" +
"<partitions><partition table='BOOKS' column='CASH' /></partitions>" +
"</database>" +
"</project>";
final File projectFile = VoltProjectBuilder.writeStringToTempFile(simpleProject);
final String projectPath = projectFile.getPath();
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final boolean success = compiler.compile(projectPath, cluster_config,
"testout.jar", System.out,
null);
assertFalse(success);
}
public void testGoodStmtProcName() throws IOException {
final String simpleSchema =
"create table books (cash integer default 23 not null, title varchar(3) default 'foo', PRIMARY KEY(cash));";
final File schemaFile = VoltProjectBuilder.writeStringToTempFile(simpleSchema);
final String schemaPath = schemaFile.getPath();
final String simpleProject =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<database name='database'>" +
"<schemas><schema path='" + schemaPath + "' /></schemas>" +
"<procedures><procedure class='Foo'><sql>select * from books;</sql></procedure></procedures>" +
"<partitions><partition table='BOOKS' column='CASH' /></partitions>" +
"</database>" +
"</project>";
final File projectFile = VoltProjectBuilder.writeStringToTempFile(simpleProject);
final String projectPath = projectFile.getPath();
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final boolean success = compiler.compile(projectPath, cluster_config,
"testout.jar", System.out,
null);
assertTrue(success);
final File jar = new File("testout.jar");
jar.delete();
}
public void testMaterializedView() throws IOException {
final String simpleSchema =
"create table books (cash integer default 23, title varchar(32) default 'foo', PRIMARY KEY(cash));\n" +
"create view matt (title, num, foo) as select title, count(*), sum(cash) from books group by title;";
final File schemaFile = VoltProjectBuilder.writeStringToTempFile(simpleSchema);
final String schemaPath = schemaFile.getPath();
final String simpleProject =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<database name='database'>" +
"<schemas><schema path='" + schemaPath + "' /></schemas>" +
"<procedures><procedure class='org.voltdb.compiler.procedures.AddBook' /></procedures>" +
"</database>" +
"</project>";
final File projectFile = VoltProjectBuilder.writeStringToTempFile(simpleProject);
final String projectPath = projectFile.getPath();
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final boolean success = compiler.compile(projectPath, cluster_config,
"testout.jar", System.out, null);
assertTrue(success);
final Catalog c1 = compiler.getCatalog();
final String catalogContents = JarReader.readFileFromJarfile("testout.jar", "catalog.txt");
final Catalog c2 = new Catalog();
c2.execute(catalogContents);
assertTrue(c2.serialize().equals(c1.serialize()));
final File jar = new File("testout.jar");
jar.delete();
}
public void testForeignKeys() {
String schemaPath = "";
try {
final URL url = new TPCCProjectBuilder().getDDLURL(true);
schemaPath = URLDecoder.decode(url.getPath(), "UTF-8");
} catch (final UnsupportedEncodingException e) {
e.printStackTrace();
System.exit(-1);
}
final String simpleProject =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<database name='database'>" +
"<schemas><schema path='" + schemaPath + "' /></schemas>" +
"<procedures><procedure class='org.voltdb.compiler.procedures.TPCCTestProc' /></procedures>" +
"</database>" +
"</project>";
//System.out.println(simpleProject);
final File projectFile = VoltProjectBuilder.writeStringToTempFile(simpleProject);
final String projectPath = projectFile.getPath();
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final Catalog catalog = compiler.compileCatalog(projectPath, cluster_config);
assertNotNull(catalog);
// Now check that CUSTOMER correctly references DISTRICT
// (1) Make sure CUSTOMER has a fkey constraint
// (2) Make sure that each source column in CUSTOMER points to the constraint
// (3) Make sure that the fkey constraint points to DISTRICT
final Database catalog_db = catalog.getClusters().get("cluster").getDatabases().get("database");
assertNotNull(catalog_db);
final Table cust_table = catalog_db.getTables().get("CUSTOMER");
assertNotNull(cust_table);
final Table dist_table = catalog_db.getTables().get("DISTRICT");
assertNotNull(dist_table);
// In the code below, we will refer to the column that is pointed to by another column
// in the dependency as the parent, and the column with the fkey constraint as the child
boolean found = false;
for (final Constraint catalog_const : cust_table.getConstraints()) {
final ConstraintType const_type = ConstraintType.get(catalog_const.getType());
if (const_type == ConstraintType.FOREIGN_KEY) {
found = true;
assertEquals(dist_table, catalog_const.getForeignkeytable());
assertEquals(catalog_const.getForeignkeycols().size(), 2);
for (final ColumnRef catalog_parent_colref : catalog_const.getForeignkeycols()) {
// We store the name of the child column in the name of the ColumnRef catalog
// object to the parent
final Column catalog_child_col = cust_table.getColumns().get(catalog_parent_colref.getTypeName());
assertNotNull(catalog_child_col);
// Lame
boolean found_const_for_child = false;
for (final ConstraintRef catalog_constref : catalog_child_col.getConstraints()) {
if (catalog_constref.getConstraint().equals(catalog_const)) {
found_const_for_child = true;
break;
}
}
assertTrue(found_const_for_child);
final Column catalog_parent_col = catalog_parent_colref.getColumn();
assertEquals(dist_table, catalog_parent_col.getParent());
}
break;
}
}
assertTrue(found);
}
public void testVerticalPartition() {
String schemaPath = "";
try {
final URL url = new TPCCProjectBuilder().getDDLURL(true);
schemaPath = URLDecoder.decode(url.getPath(), "UTF-8");
} catch (final UnsupportedEncodingException e) {
e.printStackTrace();
System.exit(-1);
}
String targetTable = "CUSTOMER";
String targetColumns[] = { "C_ID", "C_FIRST", "C_LAST" };
String columns = "";
for (String col : targetColumns)
columns += String.format("<column>%s</column>", col);
final String simpleProject =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<database name='database'>" +
"<schemas><schema path='" + schemaPath + "' /></schemas>" +
"<procedures><procedure class='org.voltdb.compiler.procedures.TPCCTestProc' /></procedures>" +
"<partitions><partition table='" + targetTable + "' column='" + targetColumns[0] + "' /></partitions>" +
"<verticalpartitions><verticalpartition table='" + targetTable + "'>" + columns + "</verticalpartition></verticalpartitions>" +
"</database>" +
"</project>";
//System.out.println(simpleProject);
final File projectFile = VoltProjectBuilder.writeStringToTempFile(simpleProject);
final String projectPath = projectFile.getPath();
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final Catalog catalog = compiler.compileCatalog(projectPath, cluster_config);
assertNotNull(catalog);
// Make sure that our target table has the columns that we specified
final Database catalog_db = catalog.getClusters().get("cluster").getDatabases().get("database");
assertNotNull(catalog_db);
final Table catalog_tbl = catalog_db.getTables().get(targetTable);
assertNotNull(catalog_tbl);
boolean found = false;
for (MaterializedViewInfo catalog_view : catalog_tbl.getViews()) {
assertFalse(found);
if (catalog_view.getVerticalpartition() == false) continue;
found = true;
Collection<Column> catalog_cols = CatalogUtil.getColumns(catalog_view.getGroupbycols());
assertNotNull(catalog_cols);
assertEquals(targetColumns.length, catalog_cols.size());
for (String columnName : targetColumns) {
Column catalog_col = catalog_tbl.getColumns().get(columnName);
assertNotNull(catalog_col);
assert(catalog_cols.contains(catalog_col)) : "Missing " + catalog_col.fullName();
} // FOR (cols)
// Make sure the sys table for this vertical partition has an index
Table view_tbl = catalog_view.getDest();
assertNotNull(view_tbl);
assert(view_tbl.getSystable());
assertEquals(1, view_tbl.getIndexes().size());
} // FOR (views)
assertTrue(found);
}
public void testInvalidVerticalPartition() {
String schemaPath = "";
try {
final URL url = new TPCCProjectBuilder().getDDLURL(true);
schemaPath = URLDecoder.decode(url.getPath(), "UTF-8");
} catch (final UnsupportedEncodingException e) {
e.printStackTrace();
System.exit(-1);
}
String targetTable = "CUSTOMER";
String targetColumns[] = { "C_ID", "C_FIRST", "C_LAST", "C_FIRST" };
String columns = "";
for (String col : targetColumns)
columns += String.format("<column>%s</column>", col);
final String simpleProject =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<database name='database'>" +
"<schemas><schema path='" + schemaPath + "' /></schemas>" +
"<procedures><procedure class='org.voltdb.compiler.procedures.TPCCTestProc' /></procedures>" +
"<verticalpartitions><verticalpartition table=\"" + targetTable + "\">" + columns + "</verticalpartition></verticalpartitions>" +
"</database>" +
"</project>";
//System.out.println(simpleProject);
final File projectFile = VoltProjectBuilder.writeStringToTempFile(simpleProject);
final String projectPath = projectFile.getPath();
final VoltCompiler compiler = new VoltCompiler();
final ClusterConfig cluster_config = new ClusterConfig(1, 1, 0, "localhost");
final Catalog catalog = compiler.compileCatalog(projectPath, cluster_config);
assert(catalog == null);
}
public void testUniqueProcedureStatementIds() {
final File schemaFile = VoltProjectBuilder.writeStringToTempFile("create table T(ID INTEGER);");
int expected = 5;
String simpleXML =
"<?xml version=\"1.0\"?>\n" +
"<project>" +
"<database name='database'>" +
"<schemas>" +
"<schema path='" + schemaFile.getAbsolutePath() + "'/>" +
"</schemas>" +
"<procedures>";
for (int i = 0; i < expected; i++) {
simpleXML += "<procedure class='proc" + i + "'><sql>select * from T</sql></procedure>";
}
simpleXML += "</procedures>" +
"</database>" +
"</project>";
final File projectFile = VoltProjectBuilder.writeStringToTempFile(simpleXML);
final String projectPath = projectFile.getPath();
final VoltCompiler compiler = new VoltCompiler();
final Catalog catalog = compiler.compileCatalog(projectPath, cluster_config);
assertNotNull(catalog);
Set<Integer> proc_ids = new HashSet<Integer>();
Set<Integer> stmt_ids = new HashSet<Integer>();
Database catalog_db = CatalogUtil.getDatabase(catalog);
int actual_procs = 0;
int actual_stmts = 0;
for (Procedure catalog_proc : catalog_db.getProcedures()) {
assertFalse(proc_ids.contains(catalog_proc.getId()));
for (Statement catalog_stmt : catalog_proc.getStatements()) {
assertFalse(stmt_ids.contains(catalog_stmt.getId()));
stmt_ids.add(catalog_stmt.getId());
if (catalog_proc.getSystemproc() == false) actual_stmts++;
} // FOR
proc_ids.add(catalog_proc.getId());
if (catalog_proc.getSystemproc() == false) actual_procs++;
} // FOR
assertEquals(expected, actual_procs);
assertEquals(expected, actual_stmts);
}
}