Package org.voltdb.compiler

Source Code of org.voltdb.compiler.TestVoltCompiler

/* 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);
    }
}
TOP

Related Classes of org.voltdb.compiler.TestVoltCompiler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.