Package com.foundationdb.sql.aisddl

Source Code of com.foundationdb.sql.aisddl.TableDDLTest

/**
* Copyright (C) 2009-2013 FoundationDB, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.foundationdb.sql.aisddl;

import com.foundationdb.server.api.ddl.DDLFunctionsMockBase;
import com.foundationdb.server.error.*;
import com.foundationdb.sql.StandardException;

import com.foundationdb.sql.types.DataTypeDescriptor;
import com.foundationdb.sql.types.TypeId;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import com.foundationdb.ais.model.AkibanInformationSchema;
import com.foundationdb.ais.model.Column;
import com.foundationdb.ais.model.Index;
import com.foundationdb.ais.model.IndexColumn;
import com.foundationdb.ais.model.Join;
import com.foundationdb.ais.model.JoinColumn;
import com.foundationdb.ais.model.Table;
import com.foundationdb.ais.model.TableName;
import com.foundationdb.ais.model.TestAISBuilder;
import com.foundationdb.server.service.session.Session;
import com.foundationdb.sql.parser.SQLParser;
import com.foundationdb.sql.parser.StatementNode;
import com.foundationdb.sql.parser.DropTableNode;
import com.foundationdb.sql.parser.CreateTableNode;
import com.foundationdb.server.types.service.TestTypesRegistry;
import com.foundationdb.server.types.service.TypesRegistry;

import java.util.List;
import java.util.Arrays;

public class TableDDLTest {

    private static TableName dropTable;
    private static final String    DEFAULT_SCHEMA = "test";
    private static final String    DEFAULT_TABLE  = "t1";
    private static final String    JOIN_TABLE = "t2";
    private static final String    JOIN_NAME = "test/t1/c1/test/test.t2/c2";
    protected SQLParser parser;
    private DDLFunctionsMock ddlFunctions;
    private TypesRegistry typesRegistry;
    private TestAISBuilder builder;

    @Before
    public void before() throws Exception {
        parser = new SQLParser();
        typesRegistry = TestTypesRegistry.MCOMPAT;
        builder = new TestAISBuilder(typesRegistry);
        ddlFunctions = new DDLFunctionsMock(builder.akibanInformationSchema());
    }
   
    @Test
    public void createNewTableWithIfNotExists() throws StandardException
    {
        String sql = "CREATE TABLE IF NOT EXISTS t1 (c1 INT)";
        createTableSimpleGenerateAIS();
        StatementNode createNode = parser.parseStatement(sql);
        assertTrue(createNode instanceof CreateTableNode);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode) createNode, null);
    }

    @Test
    public void createDuplicateTableWithIfNotExists() throws StandardException
    {
        String sql = "CREATE TABLE IF NOT EXISTS " + DEFAULT_TABLE + "(c1 INT)";
        createTableSimpleGenerateAIS(); // creates DEFAULT_SCHEMA.DEFAULT_TABLE
        StatementNode createNode = parser.parseStatement(sql);
        assertTrue(createNode instanceof CreateTableNode);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode) createNode, null);
    }

    @Test
    public void dropExistingTableWithIfExists() throws StandardException
    {
        String sql = "DROP TABLE IF EXISTS " + DEFAULT_TABLE;
        createTableSimpleGenerateAIS();
        StatementNode node = parser.parseStatement(sql);
        assertTrue(node instanceof DropTableNode);
        TableDDL.dropTable(ddlFunctions, null, DEFAULT_SCHEMA, (DropTableNode)node, null);
    }
   
    @Test
    public void dropNonExistingTableWithIfExists() throws StandardException
    {
        String sql = "DROP TABLE IF EXISTS chair";
        createTableSimpleGenerateAIS();
        StatementNode node = parser.parseStatement(sql);
        assertTrue(node instanceof DropTableNode);
        TableDDL.dropTable(ddlFunctions, null, DEFAULT_SCHEMA, (DropTableNode)node, null);
    }
   
    @Test
    public void dropTableSimple() throws Exception {
        String sql = "DROP TABLE t1";
        dropTable = TableName.create(DEFAULT_SCHEMA, DEFAULT_TABLE);
        createTableSimpleGenerateAIS ();
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof DropTableNode);
       
        TableDDL.dropTable(ddlFunctions, null, DEFAULT_SCHEMA, (DropTableNode)stmt, null);
    }

    @Test
    public void dropTableSchemaTrue() throws Exception {
        String sql = "DROP TABLE test.t1";
        dropTable = TableName.create(DEFAULT_SCHEMA, DEFAULT_TABLE);
        createTableSimpleGenerateAIS ();
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof DropTableNode);
       
        TableDDL.dropTable(ddlFunctions, null, DEFAULT_SCHEMA, (DropTableNode)stmt, null);
    }

    @Test (expected=NoSuchTableException.class)
    public void dropTableSchema() throws Exception {
        String sql = "DROP TABLE foo.t1";

        createTableSimpleGenerateAIS ();

        dropTable = TableName.create("foo", DEFAULT_TABLE);

        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof DropTableNode);
        TableDDL.dropTable(ddlFunctions, null, DEFAULT_SCHEMA, (DropTableNode)stmt, null);
    }
   
    @Test (expected=NoSuchTableException.class)
    public void dropTableQuoted() throws Exception {
        String sql = "DROP TABLE \"T1\"";

        dropTable = TableName.create(DEFAULT_SCHEMA, "T1");

        createTableSimpleGenerateAIS ();

        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof DropTableNode);
        TableDDL.dropTable(ddlFunctions, null, DEFAULT_SCHEMA, (DropTableNode)stmt, null);
    }

    @Test
    public void createTableSimple() throws Exception {
        makeSeparateAIS();
        String sql = "CREATE TABLE t1 (c1 INT)";
        createTableSimpleGenerateAIS();
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof CreateTableNode);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null);

    }
   
    @Test
    public void createTablePK() throws Exception {
        makeSeparateAIS();
        String sql = "CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY)";
        createTablePKGenerateAIS();
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof CreateTableNode);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null);
    }
   
    @Test
    public void createTableUniqueKey() throws Exception {
        makeSeparateAIS();
        String sql = "CREATE TABLE t1 (C1 int NOT NULL UNIQUE)";
        createTableUniqueKeyGenerateAIS();
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof CreateTableNode);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null);
    }

    @Test (expected=DuplicateIndexException.class)
    public void createTable2PKs() throws Exception {
        String sql = "CREATE TABLE test.t1 (c1 int primary key, c2 int NOT NULL, primary key (c2))";
       
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof CreateTableNode);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null);
    }
   
    @Test
    public void createTableFKSimple() throws Exception {
        makeSeparateAIS();
        String sql = "CREATE TABLE t2 (c1 int not null primary key, c2 int not null, grouping foreign key (c2) references t1)";
        createTableFKSimpleGenerateAIS();
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof CreateTableNode);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null);
    }

    @Test
    public void createTableAs1() throws Exception {
        makeSeparateAIS();
        String sql = "CREATE TABLE t1 (column1, column2, column3) AS (SELECT c1, c2, c3 FROM t2) WITH NO DATA";
        createTableAsColumnGenerateAIS();
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof CreateTableNode);
        List<String> columnNames = Arrays.asList("c1", "c2", "c3");
        DataTypeDescriptor d = new DataTypeDescriptor(TypeId.INTEGER_ID, false);
        List<DataTypeDescriptor> descriptors = Arrays.asList(d,d,d);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null, descriptors ,columnNames, null);
    }

    @Test
    public void createTableAs2() throws Exception {
        makeSeparateAIS();
        String sql = "CREATE TABLE t1 (column1, column2, column3) AS (SELECT * FROM t2) WITH NO DATA";
        createTableAsColumnGenerateAIS();
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof CreateTableNode);
        List<String> columnNames = Arrays.asList("c1", "c2", "c3");
        DataTypeDescriptor d = new DataTypeDescriptor(TypeId.INTEGER_ID, false);
        List<DataTypeDescriptor> descriptors = Arrays.asList(d,d,d);

        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null, descriptors ,columnNames, null);
    }

    @Test
    public void createTableAs3() throws Exception {
        makeSeparateAIS();
        String sql = "CREATE TABLE t1 AS (SELECT c1, c2, c3 FROM t2) WITH NO DATA";
        createTableAsCGenerateAIS();
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof CreateTableNode);
        List<String> columnNames = Arrays.asList("c1", "c2", "c3");
        DataTypeDescriptor d = new DataTypeDescriptor(TypeId.INTEGER_ID, false);
        List<DataTypeDescriptor> descriptors = Arrays.asList(d,d,d);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null, descriptors ,columnNames, null);
    }

    @Test
    public void createTableAs4() throws Exception {
        makeSeparateAIS();
        String sql = "CREATE TABLE t1 AS (SELECT * FROM t2) WITH  NO DATA";
        createTableAsCGenerateAIS();
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof CreateTableNode);
        List<String> columnNames = Arrays.asList("c1", "c2", "c3");
        DataTypeDescriptor d = new DataTypeDescriptor(TypeId.INTEGER_ID, false);
        List<DataTypeDescriptor> descriptors = Arrays.asList(d,d,d);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null, descriptors ,columnNames, null);
    }

    @Test
    public void createTableAs5() throws Exception {
        makeSeparateAIS();
        String sql = "CREATE TABLE t1 (c1, c2) AS (SELECT column1, column2, column3 FROM t2) WITH NO DATA";
        createTableAsMixGenerateAIS();
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof CreateTableNode);
        List<String> columnNames = Arrays.asList("column1", "column2", "column3");
        DataTypeDescriptor d = new DataTypeDescriptor(TypeId.INTEGER_ID, false);
        List<DataTypeDescriptor> descriptors = Arrays.asList(d,d,d);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null, descriptors ,columnNames, null);
    }

    @Test (expected=InvalidCreateAsException.class)
    public void createTableAs6() throws Exception {
        makeSeparateAIS();
        String sql = "CREATE TABLE t1 (c1, c2, c3) AS (SELECT column1, column2 FROM t2) WITH NO DATA";
        createTableAsMixGenerateAIS();
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof CreateTableNode);
        List<String> columnNames = Arrays.asList("column1", "column2");
        DataTypeDescriptor d = new DataTypeDescriptor(TypeId.INTEGER_ID, false);
        List<DataTypeDescriptor> descriptors = Arrays.asList(d,d);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null, descriptors ,columnNames, null);
    }

    @Test
    public void columnDefaultsArePreserved() throws StandardException {
        final String DEFAULT_C1 = "50";
        final String DEFAULT_C2 = "ban ana";
        makeSeparateAIS();
        dropTable = TableName.create(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.table(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", 0, "MCOMPAT", "int", null, null, true, DEFAULT_C1, null);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c2", 1, "MCOMPAT", "varchar", 32L, null, true, DEFAULT_C2, null);
        builder.basicSchemaIsComplete();
        builder.groupingIsComplete();

        String sql = String.format("CREATE TABLE t1 (c1 INT DEFAULT %s, c2 VARCHAR(32) DEFAULT '%s')",
                                   DEFAULT_C1, DEFAULT_C2);
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof CreateTableNode);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null);
    }

    @Test
    public void columnGeneratedByDefaultHasNoDefaultValue() throws StandardException {
        makeSeparateAIS();
        dropTable = TableName.create(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.table(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", 0, "MCOMPAT", "int", false);
        builder.sequence(DEFAULT_SCHEMA, "sequence_c1", 1, 1, 0, 1000, false);
        builder.columnAsIdentity(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", "sequence_c1", true);
        builder.basicSchemaIsComplete();
        builder.groupingIsComplete();

        String sql = "CREATE TABLE t1 (c1 INT GENERATED BY DEFAULT AS IDENTITY)";
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof CreateTableNode);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null);
    }

    @Test
    public void columnGeneratedAlwaysHasNoDefaultValue() throws StandardException {
        makeSeparateAIS();
        dropTable = TableName.create(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.table(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", 0, "MCOMPAT", "int", false);
        builder.sequence(DEFAULT_SCHEMA, "sequence_c1", 1, 1, 0, 1000, false);
        builder.columnAsIdentity(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", "sequence_c1", false);
        builder.basicSchemaIsComplete();
        builder.groupingIsComplete();

        String sql = "CREATE TABLE t1 (c1 INT GENERATED ALWAYS AS IDENTITY)";
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof CreateTableNode);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null);
    }
   
    @Test
    public void columnSerial() throws StandardException {
        makeSeparateAIS();
        dropTable = TableName.create(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.table(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", 0, "MCOMPAT", "int", false, true);
        builder.sequence(DEFAULT_SCHEMA, "sequence_c1", 1, 1, 0, 1000, false);
        builder.columnAsIdentity(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", "sequence_c1", true);
        builder.basicSchemaIsComplete();
        builder.groupingIsComplete();

        String sql = "Create Table " + DEFAULT_TABLE + " (c1 SERIAL)";
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof CreateTableNode);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null);
    }

    @Test
    public void columnBigSerial() throws StandardException {
        makeSeparateAIS();
        dropTable = TableName.create(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.table(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", 0, "MCOMPAT", "bigint", false, true);
        builder.sequence(DEFAULT_SCHEMA, "sequence_c1", 1, 1, 0, 1000, false);
        builder.columnAsIdentity(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", "sequence_c1", true);
        builder.basicSchemaIsComplete();
        builder.groupingIsComplete();

        String sql = "Create Table " + DEFAULT_TABLE + " (c1 BIGSERIAL)";
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue (stmt instanceof CreateTableNode);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null);
    }
   
    //bug1047037
    @Test (expected=DuplicateIndexException.class)
    public void namedPKConstraint() throws StandardException {
        String sql = "CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY, CONSTRAINT co1 PRIMARY KEY (c1))";
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue(stmt instanceof CreateTableNode);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null);
    }

    @Test
    public void contraintPKAdjustedNotNull() throws StandardException {
        String sql = "CREATE TABLE t1 (c1 int PRIMARY KEY)";

        makeSeparateAIS();
        dropTable = TableName.create(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.table(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", 0, "MCOMPAT", "int", false, true);
        builder.pk(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.indexColumn(DEFAULT_SCHEMA, DEFAULT_TABLE, "PRIMARY", "c1", 0, true, 0);

        builder.basicSchemaIsComplete();
        builder.groupingIsComplete();
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue(stmt instanceof CreateTableNode);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null);
    }
   
    @Test
    public void contraintPKAdjustedNotNullSeparate() throws StandardException {
        String sql = "CREATE TABLE t1 (c1 int, PRIMARY KEY(c1))";

        makeSeparateAIS();
        dropTable = TableName.create(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.table(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", 0, "MCOMPAT", "int", false, true);
        builder.pk(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.indexColumn(DEFAULT_SCHEMA, DEFAULT_TABLE, "PRIMARY", "c1", 0, true, 0);

        builder.basicSchemaIsComplete();
        builder.groupingIsComplete();
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue(stmt instanceof CreateTableNode);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null);
    }
   
    @Test
    public void contraintPKAdjustedNotNullFirst() throws StandardException {
        String sql = "CREATE TABLE t1 (c1 int, c2 varchar(32) not null, PRIMARY KEY(c1,c2))";

        makeSeparateAIS();
        dropTable = TableName.create(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.table(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", 0, "MCOMPAT", "int", false, false);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c2", 1, "MCOMPAT", "varchar", 32L, 0L, false);
        builder.pk(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.indexColumn(DEFAULT_SCHEMA, DEFAULT_TABLE, "PRIMARY", "c1", 0, true, 0);
        builder.indexColumn(DEFAULT_SCHEMA, DEFAULT_TABLE, "PRIMARY", "c2", 1, true, 0);

        builder.basicSchemaIsComplete();
        builder.groupingIsComplete();
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue(stmt instanceof CreateTableNode);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null);
    }

    @Test
    public void contraintPKAdjustedNotNullSecond() throws StandardException {
        String sql = "CREATE TABLE t1 (c1 int NOT NULL, c2 varchar(32), PRIMARY KEY(c1,c2))";

        makeSeparateAIS();
        dropTable = TableName.create(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.table(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", 0, "MCOMPAT", "int", false, false);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c2", 1, "MCOMPAT", "varchar", 32L, 0L, false);
        builder.pk(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.indexColumn(DEFAULT_SCHEMA, DEFAULT_TABLE, "PRIMARY", "c1", 0, true, 0);
        builder.indexColumn(DEFAULT_SCHEMA, DEFAULT_TABLE, "PRIMARY", "c2", 1, true, 0);

        builder.basicSchemaIsComplete();
        builder.groupingIsComplete();
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue(stmt instanceof CreateTableNode);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null);
    }

    @Test
    public void contraintPKAdjustedNotNullBoth() throws StandardException {
        String sql = "CREATE TABLE t1 (c1 int, c2 varchar(32), PRIMARY KEY(c1,c2))";

        makeSeparateAIS();
        dropTable = TableName.create(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.table(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", 0, "MCOMPAT", "int", false, false);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c2", 1, "MCOMPAT", "varchar", 32L, 0L, false);
        builder.pk(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.indexColumn(DEFAULT_SCHEMA, DEFAULT_TABLE, "PRIMARY", "c1", 0, true, 0);
        builder.indexColumn(DEFAULT_SCHEMA, DEFAULT_TABLE, "PRIMARY", "c2", 1, true, 0);

        builder.basicSchemaIsComplete();
        builder.groupingIsComplete();
        StatementNode stmt = parser.parseStatement(sql);
        assertTrue(stmt instanceof CreateTableNode);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null);
    }

    @Test(expected=JoinToSelfException.class)
    public void joinToSelf() throws StandardException {
        String sql = "CREATE TABLE t(id1 INT PRIMARY KEY, id2 INT, GROUPING FOREIGN KEY(id2) REFERENCES t(id1))";
        StatementNode stmt = parser.parseStatement(sql);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null);
    }

    @Test(expected=JoinToUnknownTableException.class)
    public void joinToUnknown() throws StandardException {
        String sql = "CREATE TABLE t(id1 INT PRIMARY KEY, xid INT, GROUPING FOREIGN KEY(xid) REFERENCES x(id))";
        StatementNode stmt = parser.parseStatement(sql);
        TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode)stmt, null);
    }


    public static class DDLFunctionsMock extends DDLFunctionsMockBase {
        private final AkibanInformationSchema internalAIS;
        private final AkibanInformationSchema externalAIS;

        public DDLFunctionsMock(AkibanInformationSchema ais) {
            this.internalAIS = ais;
            this.externalAIS = ais;
        }

        public DDLFunctionsMock(AkibanInformationSchema internal, AkibanInformationSchema external) {
            this.internalAIS = internal;
            this.externalAIS = external;
        }

        private static void checkColumn(Column expected, Column actual) {
            assertNotNull("actual column name", actual.getName());
            assertNotNull("expected column", expected);
            assertEquals("type", expected.getType().typeClass(), actual.getType().typeClass());
            assertEquals("is nullable", expected.getNullable(), actual.getNullable());
            assertEquals("default value", expected.getDefaultValue(), actual.getDefaultValue());
            assertEquals("identity", expected.getIdentityGenerator() != null, actual.getIdentityGenerator() != null);
        }

        @Override
        public void createTable(Session session, Table table) {

            assertEquals(table.getName(), dropTable);

            final Table dropAisTable = internalAIS.getTable(dropTable);
            assertNotNull("expected table", dropAisTable);
            for (Column col : table.getColumnsIncludingInternal()) {
                checkColumn(dropAisTable.getColumn(col.getName()), col);
            }
            for (Column col : internalAIS.getTable(dropTable).getColumnsIncludingInternal()) {
                checkColumn(dropAisTable.getColumn(col.getName()), col);
            }
           
            checkIndexes (table, dropAisTable);
            checkIndexes (dropAisTable, table);
           
            if (table.getParentJoin() != null) {
                checkJoin (table.getParentJoin(), internalAIS.getJoin(JOIN_NAME));
            }
        }

        private void checkIndexes(Table sourceTable, Table checkTable) {
            for (Index index : sourceTable.getIndexesIncludingInternal()) {
                assertNotNull(checkTable.getIndexIncludingInternal(index.getIndexName().getName()));
                Index checkIndex = checkTable.getIndexIncludingInternal(index.getIndexName().getName());
                for (IndexColumn col : index.getKeyColumns()) {
                    checkIndex.getKeyColumns().get(col.getPosition());
                }
            }
        }

        private void checkJoin (Join sourceJoin, Join checkJoin) {
            assertEquals (sourceJoin.getName(), checkJoin.getName());
            assertEquals (sourceJoin.getJoinColumns().size(), checkJoin.getJoinColumns().size());
            for (int i = 0; i < sourceJoin.getJoinColumns().size(); i++) {
                JoinColumn sourceColumn = sourceJoin.getJoinColumns().get(i);
                JoinColumn checkColumn = checkJoin.getJoinColumns().get(i);
               
                assertEquals (sourceColumn.getChild().getName(), checkColumn.getChild().getName());
                assertEquals (sourceColumn.getParent().getName(), checkColumn.getParent().getName());
            }
        }

        @Override
        public void dropTable(Session session, TableName tableName) {
            assertEquals(tableName, dropTable);
        }

        @Override
        public AkibanInformationSchema getAIS(Session session) {
            return externalAIS;
        }
    } // END class DDLFunctionsMock

    private void makeSeparateAIS() {
        AkibanInformationSchema external = new AkibanInformationSchema();
        ddlFunctions = new DDLFunctionsMock(builder.akibanInformationSchema(), external);
    }

    /*"CREATE TABLE t1 (c1 INT)";*/
    private void createTableSimpleGenerateAIS () {
        dropTable = TableName.create(DEFAULT_SCHEMA, DEFAULT_TABLE);
       
        builder.table(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", 0, "MCOMPAT", "int", true);
        builder.basicSchemaIsComplete();
        builder.groupingIsComplete();
    }
   
    /*CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY)*/
    private void createTablePKGenerateAIS() {
        dropTable = TableName.create(DEFAULT_SCHEMA, DEFAULT_TABLE);
       
        builder.table(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", 0, "MCOMPAT", "int", false);
        builder.pk(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.indexColumn(DEFAULT_SCHEMA, DEFAULT_TABLE, "PRIMARY", "c1", 0, true, 0);
        builder.basicSchemaIsComplete();
    }

    /*CREATE TABLE t1 (C1 int NOT NULL UNIQUE) */
    private void createTableUniqueKeyGenerateAIS() {
        dropTable = TableName.create(DEFAULT_SCHEMA, DEFAULT_TABLE);
       
        builder.table(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", 0, "MCOMPAT", "int", false);
        builder.unique(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1");
        builder.indexColumn(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", "c1", 0, true, 0);
        builder.basicSchemaIsComplete();
        builder.groupingIsComplete();
    }

    /* CREATE TABLE t1 (c1 int not null primary key) */
    /* CREATE TABLE t2 (c1 int not null primary key, c2 int not null, grouping foreign key (c2) references t1) */
    private void createTableFKSimpleGenerateAIS() {
        dropTable = TableName.create(DEFAULT_SCHEMA, JOIN_TABLE);

        TestAISBuilder builders[] = { builder, new TestAISBuilder(ddlFunctions.externalAIS, typesRegistry) };

        // Re-gen the DDLFunctions to have the AIS for internal references.
        ddlFunctions = new DDLFunctionsMock(builder.akibanInformationSchema(), ddlFunctions.externalAIS);
        // Need t1 in both internal and external
        for(TestAISBuilder b : builders) {
            // table t1:
            b.table(DEFAULT_SCHEMA, DEFAULT_TABLE);
            b.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", 0, "MCOMPAT", "int", false);
            b.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c2", 1, "MCOMPAT", "int", false);
            b.pk(DEFAULT_SCHEMA, DEFAULT_TABLE);
            b.indexColumn(DEFAULT_SCHEMA, DEFAULT_TABLE, Index.PRIMARY, "c1", 0, true, 0);
            b.basicSchemaIsComplete();
            b.createGroup("t1", DEFAULT_SCHEMA);
            b.addTableToGroup("t1", DEFAULT_SCHEMA, DEFAULT_TABLE);
            b.groupingIsComplete();
        }
       
        // table t2:
        builder.table(DEFAULT_SCHEMA, JOIN_TABLE);
        builder.column(DEFAULT_SCHEMA, JOIN_TABLE, "c1", 0, "MCOMPAT", "int", false);
        builder.column(DEFAULT_SCHEMA, JOIN_TABLE, "c2", 1, "MCOMPAT", "int", false);
        builder.pk(DEFAULT_SCHEMA, JOIN_TABLE);
        builder.indexColumn(DEFAULT_SCHEMA, JOIN_TABLE, "PRIMARY", "c1", 0, true, 0);
        builder.basicSchemaIsComplete();
        // do the join
        builder.joinTables(JOIN_NAME, DEFAULT_SCHEMA, DEFAULT_TABLE, DEFAULT_SCHEMA, JOIN_TABLE);
        builder.joinColumns(JOIN_NAME, DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", DEFAULT_SCHEMA, JOIN_TABLE, "c2");
       
        builder.addJoinToGroup("t1", JOIN_NAME, 0);
        builder.groupingIsComplete();
    }

    private void createTableAsCGenerateAIS () {
        dropTable = TableName.create(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.table(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", 0, "MCOMPAT", "int", false);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c2", 1, "MCOMPAT", "int", false);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c3", 2, "MCOMPAT", "int", false);
        builder.basicSchemaIsComplete();
        builder.groupingIsComplete();
    }

    private void createTableAsColumnGenerateAIS () {
        dropTable = TableName.create(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.table(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "column1", 0, "MCOMPAT", "int", false);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "column2", 1, "MCOMPAT", "int", false);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "column3", 2, "MCOMPAT", "int", false);
        builder.basicSchemaIsComplete();
        builder.groupingIsComplete();
    }

    private void createTableAsMixGenerateAIS () {
        dropTable = TableName.create(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.table(DEFAULT_SCHEMA, DEFAULT_TABLE);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c1", 0, "MCOMPAT", "int", false);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "c2", 1, "MCOMPAT", "int", false);
        builder.column(DEFAULT_SCHEMA, DEFAULT_TABLE, "column3", 2, "MCOMPAT", "int", false);
        builder.basicSchemaIsComplete();
        builder.groupingIsComplete();
    }
}
TOP

Related Classes of com.foundationdb.sql.aisddl.TableDDLTest

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.