Search in sources :

Example 1 with ForeignKeyIndex

use of net.sf.jsqlparser.statement.create.table.ForeignKeyIndex in project herddb by diennea.

the class JSQLParserPlanner method buildCreateTableStatement.

private Statement buildCreateTableStatement(String defaultTableSpace, CreateTable s) throws StatementExecutionException {
    String tableSpace = fixMySqlBackTicks(s.getTable().getSchemaName());
    String tableName = fixMySqlBackTicks(s.getTable().getName());
    if (tableSpace == null) {
        tableSpace = defaultTableSpace;
    }
    if (s.getColumnDefinitions() == null) {
        throw new StatementExecutionException("A table must have at least 1 column");
    }
    final boolean isNotExsists = s.isIfNotExists();
    try {
        boolean foundPk = false;
        Table.Builder tablebuilder = Table.builder().uuid(UUID.randomUUID().toString()).name(tableName).tablespace(tableSpace);
        Set<String> primaryKey = new HashSet<>();
        Set<String> simpleUniqueFields = new HashSet<>();
        if (s.getIndexes() != null) {
            for (Index index : s.getIndexes()) {
                if (index.getType().equalsIgnoreCase("PRIMARY KEY")) {
                    for (String n : index.getColumnsNames()) {
                        n = fixMySqlBackTicks(n.toLowerCase());
                        tablebuilder.primaryKey(n);
                        primaryKey.add(n);
                        foundPk = true;
                    }
                }
            }
        }
        int position = 0;
        for (ColumnDefinition cf : s.getColumnDefinitions()) {
            String columnName = fixMySqlBackTicks(cf.getColumnName().toLowerCase());
            int type;
            String dataType = cf.getColDataType().getDataType();
            List<String> columnSpecs = decodeColumnSpecs(cf.getColumnSpecs());
            type = sqlDataTypeToColumnType(dataType, cf.getColDataType().getArgumentsStringList(), columnSpecs);
            Bytes defaultValue = decodeDefaultValue(cf, type);
            if (!columnSpecs.isEmpty()) {
                boolean auto_increment = decodeAutoIncrement(columnSpecs);
                if (columnSpecs.contains("PRIMARY")) {
                    foundPk = true;
                    tablebuilder.primaryKey(columnName, auto_increment);
                }
                if (auto_increment && primaryKey.contains(columnName)) {
                    tablebuilder.primaryKey(columnName, auto_increment);
                }
                boolean isUnique = columnSpecs.contains("UNIQUE");
                if (isUnique) {
                    simpleUniqueFields.add(columnName);
                }
            }
            tablebuilder.column(columnName, type, position++, defaultValue);
        }
        if (!foundPk) {
            tablebuilder.column("_pk", ColumnTypes.LONG, position++, null);
            tablebuilder.primaryKey("_pk", true);
        }
        Table table = tablebuilder.build();
        List<herddb.model.Index> otherIndexes = new ArrayList<>();
        List<herddb.model.ForeignKeyDef> foreignKeys = new ArrayList<>();
        if (s.getIndexes() != null) {
            for (Index index : s.getIndexes()) {
                if (index.getType().equalsIgnoreCase("PRIMARY KEY")) {
                } else if (index.getType().equalsIgnoreCase("INDEX") || index.getType().equalsIgnoreCase("KEY") || index.getType().equalsIgnoreCase("UNIQUE KEY")) {
                    String indexName = fixMySqlBackTicks(index.getName().toLowerCase());
                    String indexType = convertIndexType(null);
                    boolean unique = index.getType().equalsIgnoreCase("UNIQUE KEY");
                    herddb.model.Index.Builder builder = herddb.model.Index.builder().onTable(table).name(indexName).unique(unique).type(indexType).uuid(UUID.randomUUID().toString());
                    for (String columnName : index.getColumnsNames()) {
                        columnName = fixMySqlBackTicks(columnName.toLowerCase());
                        Column column = table.getColumn(columnName);
                        if (column == null) {
                            throw new StatementExecutionException("no such column " + columnName + " on table " + tableName + " in tablespace " + tableSpace);
                        }
                        builder.column(column.name, column.type);
                    }
                    otherIndexes.add(builder.build());
                } else if (index.getType().equals("FOREIGN KEY")) {
                    ForeignKeyIndex fk = (ForeignKeyIndex) index;
                    ForeignKeyDef fkDef = parseForeignKeyIndex(fk, table, tableName, tableSpace);
                    foreignKeys.add(fkDef);
                } else {
                    throw new StatementExecutionException("Unsupported index type " + index.getType());
                }
            }
        }
        for (String col : simpleUniqueFields) {
            herddb.model.Index.Builder builder = herddb.model.Index.builder().onTable(table).name(table.name + "_unique_" + col).unique(true).type(herddb.model.Index.TYPE_BRIN).uuid(UUID.randomUUID().toString()).column(col, table.getColumn(col).type);
            otherIndexes.add(builder.build());
        }
        if (!foreignKeys.isEmpty()) {
            table = table.withForeignKeys(foreignKeys.toArray(new ForeignKeyDef[0]));
        }
        CreateTableStatement statement = new CreateTableStatement(table, otherIndexes, isNotExsists);
        return statement;
    } catch (IllegalArgumentException err) {
        throw new StatementExecutionException("bad table definition: " + err.getMessage(), err);
    }
}
Also used : Table(herddb.model.Table) ShowCreateTableCalculator.calculateShowCreateTable(herddb.sql.functions.ShowCreateTableCalculator.calculateShowCreateTable) CreateTable(net.sf.jsqlparser.statement.create.table.CreateTable) CreateTableStatement(herddb.model.commands.CreateTableStatement) ArrayList(java.util.ArrayList) CreateIndex(net.sf.jsqlparser.statement.create.index.CreateIndex) ForeignKeyIndex(net.sf.jsqlparser.statement.create.table.ForeignKeyIndex) Index(net.sf.jsqlparser.statement.create.table.Index) StatementExecutionException(herddb.model.StatementExecutionException) ColumnDefinition(net.sf.jsqlparser.statement.create.table.ColumnDefinition) Bytes(herddb.utils.Bytes) Column(herddb.model.Column) ForeignKeyDef(herddb.model.ForeignKeyDef) ForeignKeyIndex(net.sf.jsqlparser.statement.create.table.ForeignKeyIndex) HashSet(java.util.HashSet)

Example 2 with ForeignKeyIndex

use of net.sf.jsqlparser.statement.create.table.ForeignKeyIndex in project herddb by diennea.

the class JSQLParserPlanner method buildAlterStatement.

private Statement buildAlterStatement(String defaultTableSpace, Alter alter) throws StatementExecutionException {
    if (alter.getTable() == null) {
        throw new StatementExecutionException("missing table name");
    }
    String tableSpace = alter.getTable().getSchemaName();
    if (tableSpace == null) {
        tableSpace = defaultTableSpace;
    }
    tableSpace = fixMySqlBackTicks(tableSpace);
    List<Column> addColumns = new ArrayList<>();
    List<Column> modifyColumns = new ArrayList<>();
    List<String> dropColumns = new ArrayList<>();
    List<String> dropForeignKeys = new ArrayList<>();
    List<ForeignKeyDef> addForeignKeys = new ArrayList<>();
    String tableName = fixMySqlBackTicks(alter.getTable().getName().toLowerCase());
    if (alter.getAlterExpressions() == null || alter.getAlterExpressions().size() != 1) {
        throw new StatementExecutionException("supported multi-alter operation '" + alter + "'");
    }
    AlterExpression alterExpression = alter.getAlterExpressions().get(0);
    AlterOperation operation = alterExpression.getOperation();
    Boolean changeAutoIncrement = null;
    TableSpaceManager tableSpaceManager = manager.getTableSpaceManager(tableSpace);
    if (tableSpaceManager == null) {
        throw new StatementExecutionException("bad tablespace '" + tableSpace + "'");
    }
    Table table = getTable(defaultTableSpace, alter.getTable());
    switch(operation) {
        case ADD:
            {
                if (alterExpression.getColDataTypeList() != null) {
                    List<AlterExpression.ColumnDataType> cols = alterExpression.getColDataTypeList();
                    for (AlterExpression.ColumnDataType cl : cols) {
                        List<String> columnSpecs = decodeColumnSpecs(cl.getColumnSpecs());
                        int type = sqlDataTypeToColumnType(cl.getColDataType().getDataType(), cl.getColDataType().getArgumentsStringList(), columnSpecs);
                        Column newColumn = Column.column(fixMySqlBackTicks(cl.getColumnName()), type, decodeDefaultValue(cl, type));
                        addColumns.add(newColumn);
                    }
                } else if (alterExpression.getIndex() != null && alterExpression.getIndex() instanceof ForeignKeyIndex) {
                    ForeignKeyDef fkIndex = parseForeignKeyIndex((ForeignKeyIndex) alterExpression.getIndex(), table, tableName, tableSpace);
                    addForeignKeys.add(fkIndex);
                } else {
                    throw new StatementExecutionException("Unrecognized ALTER TABLE ADD ... statement");
                }
            }
            break;
        case DROP:
            if (alterExpression.getColumnName() != null) {
                dropColumns.add(fixMySqlBackTicks(alterExpression.getColumnName()));
            } else if (alterExpression.getConstraintName() != null) {
                dropForeignKeys.add(fixMySqlBackTicks(alterExpression.getConstraintName()));
            } else {
                throw new StatementExecutionException("Unrecognized ALTER TABLE DROP ... statement");
            }
            break;
        case MODIFY:
            {
                List<AlterExpression.ColumnDataType> cols = alterExpression.getColDataTypeList();
                for (AlterExpression.ColumnDataType cl : cols) {
                    String columnName = fixMySqlBackTicks(cl.getColumnName().toLowerCase());
                    Column oldColumn = table.getColumn(columnName);
                    if (oldColumn == null) {
                        throw new StatementExecutionException("bad column " + columnName + " in table " + tableName + " in tablespace '" + tableSpace + "'");
                    }
                    Map<String, AbstractIndexManager> indexes = tableSpaceManager.getIndexesOnTable(tableName);
                    if (indexes != null) {
                        for (AbstractIndexManager am : indexes.values()) {
                            for (String indexedColumn : am.getColumnNames()) {
                                indexedColumn = fixMySqlBackTicks(indexedColumn);
                                if (indexedColumn.equalsIgnoreCase(oldColumn.name)) {
                                    throw new StatementExecutionException("cannot alter indexed " + columnName + " in table " + tableName + " in tablespace '" + tableSpace + "'," + "index name is " + am.getIndexName());
                                }
                            }
                        }
                    }
                    List<String> columnSpecs = decodeColumnSpecs(cl.getColumnSpecs());
                    int newType = sqlDataTypeToColumnType(cl.getColDataType().getDataType(), cl.getColDataType().getArgumentsStringList(), columnSpecs);
                    if (oldColumn.type != newType) {
                        if (ColumnTypes.isNotNullToNullConversion(oldColumn.type, newType)) {
                        // allow change from "STRING NOT NULL" to "STRING NULL"
                        } else if (ColumnTypes.isNullToNotNullConversion(oldColumn.type, newType)) {
                        // allow change from "STRING NULL" to "STRING NOT NULL"
                        // it will require a check on table at execution time
                        } else {
                            throw new StatementExecutionException("cannot change datatype to " + ColumnTypes.typeToString(newType) + " for column " + columnName + " (" + ColumnTypes.typeToString(oldColumn.type) + ") in table " + tableName + " in tablespace '" + tableSpace + "'");
                        }
                    }
                    if (table.isPrimaryKeyColumn(columnName)) {
                        boolean new_auto_increment = decodeAutoIncrement(columnSpecs);
                        if (new_auto_increment && table.primaryKey.length > 1) {
                            throw new StatementExecutionException("cannot add auto_increment flag to " + cl.getColDataType().getDataType() + " for column " + columnName + " in table " + tableName + " in tablespace '" + tableSpace + "'");
                        }
                        if (table.auto_increment != new_auto_increment) {
                            changeAutoIncrement = new_auto_increment;
                        }
                    }
                    Bytes newDefault = oldColumn.defaultValue;
                    if (containsDefaultClause(cl)) {
                        newDefault = decodeDefaultValue(cl, newType);
                    }
                    Column newColumnDef = Column.column(columnName, newType, oldColumn.serialPosition, newDefault);
                    modifyColumns.add(newColumnDef);
                }
            }
            break;
        case CHANGE:
            {
                String columnName = alterExpression.getColOldName();
                List<AlterExpression.ColumnDataType> cols = alterExpression.getColDataTypeList();
                if (cols.size() != 1) {
                    throw new StatementExecutionException("bad CHANGE column " + columnName + " in table " + tableName + " in tablespace '" + tableSpace + "'");
                }
                AlterExpression.ColumnDataType cl = cols.get(0);
                Column oldColumn = table.getColumn(columnName);
                if (oldColumn == null) {
                    throw new StatementExecutionException("bad column " + columnName + " in table " + tableName + " in tablespace '" + tableSpace + "'");
                }
                Map<String, AbstractIndexManager> indexes = tableSpaceManager.getIndexesOnTable(tableName);
                if (indexes != null) {
                    for (AbstractIndexManager am : indexes.values()) {
                        for (String indexedColumn : am.getColumnNames()) {
                            indexedColumn = fixMySqlBackTicks(indexedColumn);
                            if (indexedColumn.equalsIgnoreCase(oldColumn.name)) {
                                throw new StatementExecutionException("cannot alter indexed " + columnName + " in table " + tableName + " in tablespace '" + tableSpace + "'," + "index name is " + am.getIndexName());
                            }
                        }
                    }
                }
                List<String> columnSpecs = decodeColumnSpecs(cl.getColumnSpecs());
                int newType = sqlDataTypeToColumnType(cl.getColDataType().getDataType(), cl.getColDataType().getArgumentsStringList(), columnSpecs);
                if (oldColumn.type != newType) {
                    throw new StatementExecutionException("cannot change datatype to " + ColumnTypes.typeToString(newType) + " for column " + columnName + " (" + ColumnTypes.typeToString(oldColumn.type) + ") in table " + tableName + " in tablespace '" + tableSpace + "'");
                }
                if (table.isPrimaryKeyColumn(columnName)) {
                    boolean new_auto_increment = decodeAutoIncrement(columnSpecs);
                    if (new_auto_increment && table.primaryKey.length > 1) {
                        throw new StatementExecutionException("cannot add auto_increment flag to " + cl.getColDataType().getDataType() + " for column " + columnName + " in table " + tableName + " in tablespace '" + tableSpace + "'");
                    }
                    if (table.auto_increment != new_auto_increment) {
                        changeAutoIncrement = new_auto_increment;
                    }
                }
                String renameTo = fixMySqlBackTicks(cl.getColumnName().toLowerCase());
                if (renameTo != null) {
                    columnName = renameTo;
                }
                Column newColumnDef = Column.column(columnName, newType, oldColumn.serialPosition, oldColumn.defaultValue);
                modifyColumns.add(newColumnDef);
            }
            break;
        default:
            throw new StatementExecutionException("supported alter operation '" + alter + "'");
    }
    return new AlterTableStatement(addColumns, modifyColumns, dropColumns, changeAutoIncrement, tableName.toLowerCase(), tableSpace, null, dropForeignKeys, addForeignKeys);
}
Also used : AlterOperation(net.sf.jsqlparser.statement.alter.AlterOperation) Table(herddb.model.Table) ShowCreateTableCalculator.calculateShowCreateTable(herddb.sql.functions.ShowCreateTableCalculator.calculateShowCreateTable) CreateTable(net.sf.jsqlparser.statement.create.table.CreateTable) AbstractIndexManager(herddb.core.AbstractIndexManager) AlterTableStatement(herddb.model.commands.AlterTableStatement) ArrayList(java.util.ArrayList) StatementExecutionException(herddb.model.StatementExecutionException) AlterExpression(net.sf.jsqlparser.statement.alter.AlterExpression) Bytes(herddb.utils.Bytes) Column(herddb.model.Column) TableSpaceManager(herddb.core.TableSpaceManager) ItemsList(net.sf.jsqlparser.expression.operators.relational.ItemsList) ArrayList(java.util.ArrayList) ExpressionList(net.sf.jsqlparser.expression.operators.relational.ExpressionList) MultiExpressionList(net.sf.jsqlparser.expression.operators.relational.MultiExpressionList) List(java.util.List) SetOperationList(net.sf.jsqlparser.statement.select.SetOperationList) ForeignKeyDef(herddb.model.ForeignKeyDef) ForeignKeyIndex(net.sf.jsqlparser.statement.create.table.ForeignKeyIndex) Map(java.util.Map)

Example 3 with ForeignKeyIndex

use of net.sf.jsqlparser.statement.create.table.ForeignKeyIndex in project JSqlParser by JSQLParser.

the class AlterTest method assertReferentialActionOnConstraint.

private void assertReferentialActionOnConstraint(Alter parsed, Action onUpdate, Action onDelete) {
    AlterExpression alterExpression = parsed.getAlterExpressions().get(0);
    ForeignKeyIndex index = (ForeignKeyIndex) alterExpression.getIndex();
    // remove line if deprecated methods are removed.
    index.setOnDeleteReferenceOption(index.getOnDeleteReferenceOption());
    if (onDelete != null) {
        assertEquals(new ReferentialAction(Type.DELETE, onDelete), index.getReferentialAction(Type.DELETE));
    } else {
        assertNull(index.getReferentialAction(Type.DELETE));
    }
    // remove line if deprecated methods are removed.
    index.setOnUpdateReferenceOption(index.getOnUpdateReferenceOption());
    if (onUpdate != null) {
        assertEquals(new ReferentialAction(Type.UPDATE, onUpdate), index.getReferentialAction(Type.UPDATE));
    } else {
        assertNull(index.getReferentialAction(Type.UPDATE));
    }
}
Also used : ReferentialAction(net.sf.jsqlparser.statement.ReferentialAction) ForeignKeyIndex(net.sf.jsqlparser.statement.create.table.ForeignKeyIndex)

Aggregations

ForeignKeyIndex (net.sf.jsqlparser.statement.create.table.ForeignKeyIndex)3 Column (herddb.model.Column)2 ForeignKeyDef (herddb.model.ForeignKeyDef)2 StatementExecutionException (herddb.model.StatementExecutionException)2 Table (herddb.model.Table)2 ShowCreateTableCalculator.calculateShowCreateTable (herddb.sql.functions.ShowCreateTableCalculator.calculateShowCreateTable)2 Bytes (herddb.utils.Bytes)2 ArrayList (java.util.ArrayList)2 CreateTable (net.sf.jsqlparser.statement.create.table.CreateTable)2 AbstractIndexManager (herddb.core.AbstractIndexManager)1 TableSpaceManager (herddb.core.TableSpaceManager)1 AlterTableStatement (herddb.model.commands.AlterTableStatement)1 CreateTableStatement (herddb.model.commands.CreateTableStatement)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Map (java.util.Map)1 ExpressionList (net.sf.jsqlparser.expression.operators.relational.ExpressionList)1 ItemsList (net.sf.jsqlparser.expression.operators.relational.ItemsList)1 MultiExpressionList (net.sf.jsqlparser.expression.operators.relational.MultiExpressionList)1 ReferentialAction (net.sf.jsqlparser.statement.ReferentialAction)1