TableDDL { public static void createTable(DDLFunctions ddlFunctions, Session session, String defaultSchemaName, CreateTableNode createTable, QueryContext context) { if (createTable.getQueryExpression() != null) throw new UnsupportedCreateSelectException(); TableName fullName = convertName(defaultSchemaName, createTable.getObjectName()); String schemaName = fullName.getSchemaName(); String tableName = fullName.getTableName(); AkibanInformationSchema ais = ddlFunctions.getAIS(session); Table curTable = ais.getTable(fullName); if((curTable != null) && skipOrThrow(context, createTable.getExistenceCheck(), curTable, new DuplicateTableNameException(fullName))) { return; } TypesTranslator typesTranslator = ddlFunctions.getTypesTranslator(); AISBuilder builder = new AISBuilder(); builder.getNameGenerator().mergeAIS(ais); builder.table(schemaName, tableName); Table table = builder.akibanInformationSchema().getTable(schemaName, tableName); IndexNameGenerator namer = DefaultIndexNameGenerator.forTable(table); cloneReferencedTables(defaultSchemaName, ddlFunctions.getAISCloner(), ais, builder.akibanInformationSchema(), createTable.getTableElementList()); int colpos = 0; for (TableElementNode tableElement : createTable.getTableElementList()) { if (tableElement instanceof ColumnDefinitionNode) { addColumn (builder, typesTranslator, (ColumnDefinitionNode)tableElement, schemaName, tableName, colpos++); } } for (TableElementNode tableElement : createTable.getTableElementList()) { if (tableElement instanceof FKConstraintDefinitionNode) { FKConstraintDefinitionNode fkdn = (FKConstraintDefinitionNode)tableElement; if (fkdn.isGrouping()) { addJoin (builder, fkdn, defaultSchemaName, schemaName, tableName); } } else if (tableElement instanceof ConstraintDefinitionNode) { addIndex (namer, builder, (ConstraintDefinitionNode)tableElement, schemaName, tableName, context); } else if (tableElement instanceof IndexDefinitionNode) { addIndex (namer, builder, (IndexDefinitionNode)tableElement, schemaName, tableName, context, ddlFunctions); } else if (!(tableElement instanceof ColumnDefinitionNode)) { throw new UnsupportedSQLException("Unexpected TableElement", tableElement); } } for (TableElementNode tableElement : createTable.getTableElementList()) { if (tableElement instanceof FKConstraintDefinitionNode) { FKConstraintDefinitionNode fkdn = (FKConstraintDefinitionNode)tableElement; if (!fkdn.isGrouping()) { addForeignKey(builder, ddlFunctions.getAIS(session), fkdn, defaultSchemaName, schemaName, tableName); } } } setTableStorage(ddlFunctions, createTable, builder, tableName, table, schemaName); builder.basicSchemaIsComplete(); builder.groupingIsComplete(); ddlFunctions.createTable(session, table); } private  TableDDL(); static void dropTable(DDLFunctions ddlFunctions,
                                  Session session, 
                                  String defaultSchemaName,
                                  DropTableNode dropTable,
                                  QueryContext context); static void dropGroup(DDLFunctions ddlFunctions,
                                    Session session,
                                    String defaultSchemaName,
                                    DropGroupNode dropGroup,
                                    QueryContext context); static void renameTable(DDLFunctions ddlFunctions,
                                    Session session,
                                    String defaultSchemaName,
                                    RenameNode renameTable); static void createTable(DDLFunctions ddlFunctions,
                                   Session session,
                                   String defaultSchemaName,
                                   CreateTableNode createTable,
                                   QueryContext context); static void createTable(DDLFunctions ddlFunctions,
                                   Session session,
                                   String defaultSchemaName,
                                   CreateTableNode createTable,
                                   QueryContext context,
                                   List<DataTypeDescriptor>  descriptors,
                                   List<String> columnNames,
                                   ServerSession server); static void setStorage(DDLFunctions ddlFunctions,
                                  HasStorage object, 
                                  StorageFormatNode storage); static void setAutoIncrement(AISBuilder builder, String schema, String table, ColumnDefinitionNode cdn); static void setAutoIncrement(AISBuilder builder, String schemaName, String tableName, String columnName,
                                        boolean defaultIdentity, long start, long increment); static String addIndex(IndexNameGenerator namer, AISBuilder builder, ConstraintDefinitionNode cdn,
                                  String schemaName, String tableName, QueryContext context); static String addIndex(IndexNameGenerator namer,
                                  AISBuilder builder,
                                  IndexDefinitionNode idn,
                                  String schemaName,
                                  String tableName,
                                  QueryContext context,
                                  DDLFunctions ddl); static TableName getReferencedName(String schemaName, FKConstraintDefinitionNode fkdn); static void addJoin(final AISBuilder builder, final FKConstraintDefinitionNode fkdn,
                               final String defaultSchemaName, final String schemaName, final String tableName);  }
@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); }
@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); }
@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(); StatementNode createNode = parser.parseStatement(sql); assertTrue(createNode instanceof CreateTableNode); TableDDL.createTable(ddlFunctions, null, DEFAULT_SCHEMA, (CreateTableNode) createNode, 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); }