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