Commit df26f836 authored by terrymanu's avatar terrymanu
Browse files

move alter metadata from parser to jdbc layer

parent de3e1037
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -56,6 +56,15 @@ public final class ShardingTableMetaData {
        tableMetaDataMap.put(logicTableName, tableMetaData);
    }
    
    /**
     * Remove table meta data.
     *
     * @param logicTableName logic table name
     */
    public void remove(final String logicTableName) {
        tableMetaDataMap.remove(logicTableName);
    }
    
    /**
     * Judge contains table from table meta data or not.
     *
+0 −92
Original line number Diff line number Diff line
/*
 * Copyright 2016-2018 shardingsphere.io.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * </p>
 */

package io.shardingsphere.core.parsing.antlr.optimizer.impl.ddl;

import io.shardingsphere.core.metadata.table.ColumnMetaData;
import io.shardingsphere.core.metadata.table.ShardingTableMetaData;
import io.shardingsphere.core.metadata.table.TableMetaData;
import io.shardingsphere.core.parsing.antlr.optimizer.SQLStatementOptimizer;
import io.shardingsphere.core.parsing.antlr.sql.segment.definition.column.ColumnDefinitionSegment;
import io.shardingsphere.core.parsing.antlr.sql.statement.ddl.AlterTableStatement;
import io.shardingsphere.core.parsing.parser.sql.SQLStatement;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * Alter table optimizer.
 * 
 * @author duhongjun
 */
public class AlterTableOptimizer implements SQLStatementOptimizer {
    
    @Override
    public final void optimize(final SQLStatement sqlStatement, final ShardingTableMetaData shardingTableMetaData) {
        AlterTableStatement alterTableStatement = (AlterTableStatement) sqlStatement;
        TableMetaData oldTableMetaData = shardingTableMetaData.get(alterTableStatement.getTables().getSingleTableName());
        if (null == oldTableMetaData) {
            return;
        }
        List<ColumnMetaData> newColumnMetaData = getModifiedColumnMetaDataList(alterTableStatement, oldTableMetaData);
        fillColumnDefinition(alterTableStatement, newColumnMetaData);
        adjustColumnDefinition(alterTableStatement, newColumnMetaData);
        dropColumnDefinition(alterTableStatement, newColumnMetaData);
        alterTableStatement.setTableMetaData(new TableMetaData(newColumnMetaData));
    }
    
    private List<ColumnMetaData> getModifiedColumnMetaDataList(final AlterTableStatement alterTableStatement, final TableMetaData oldTableMetaData) {
        List<ColumnMetaData> result = new LinkedList<>();
        for (ColumnMetaData each : oldTableMetaData.getColumnMetaDataList()) {
            ColumnDefinitionSegment modifiedColumnDefinition = alterTableStatement.getModifiedColumnDefinitions().get(each.getColumnName());
            String columnName;
            String columnType;
            boolean primaryKey;
            if (null == modifiedColumnDefinition) {
                columnName = each.getColumnName();
                columnType = each.getDataType();
                primaryKey = !alterTableStatement.isDropPrimaryKey() && each.isPrimaryKey();
            } else {
                columnName = modifiedColumnDefinition.getColumnName();
                columnType = modifiedColumnDefinition.getDataType();
                primaryKey = !alterTableStatement.isDropPrimaryKey() && modifiedColumnDefinition.isPrimaryKey();
            }
            result.add(new ColumnMetaData(columnName, columnType, primaryKey));
        }
        return result;
    }
    
    private void fillColumnDefinition(final AlterTableStatement alterTableStatement, final List<ColumnMetaData> newColumnMetaData) {
        for (ColumnDefinitionSegment each : alterTableStatement.getAddedColumnDefinitions()) {
            newColumnMetaData.add(new ColumnMetaData(each.getColumnName(), each.getDataType(), each.isPrimaryKey()));
        }
    }
    
    protected void adjustColumnDefinition(final AlterTableStatement alterTableStatement, final List<ColumnMetaData> newColumnMetaData) {
    }
    
    private void dropColumnDefinition(final AlterTableStatement alterTableStatement, final List<ColumnMetaData> newColumnMetaData) {
        Iterator<ColumnMetaData> iterator = newColumnMetaData.iterator();
        while (iterator.hasNext()) {
            ColumnMetaData each = iterator.next();
            if (alterTableStatement.getDropColumnNames().contains(each.getColumnName())) {
                iterator.remove();
            }
        }
    }
}
+0 −86
Original line number Diff line number Diff line
/*
 * Copyright 2016-2018 shardingsphere.io.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * </p>
 */

package io.shardingsphere.core.parsing.antlr.optimizer.impl.ddl.dialect.mysql;

import io.shardingsphere.core.metadata.table.ColumnMetaData;
import io.shardingsphere.core.parsing.antlr.optimizer.impl.ddl.AlterTableOptimizer;
import io.shardingsphere.core.parsing.antlr.sql.segment.definition.column.position.ColumnAfterPositionSegment;
import io.shardingsphere.core.parsing.antlr.sql.segment.definition.column.position.ColumnFirstPositionSegment;
import io.shardingsphere.core.parsing.antlr.sql.segment.definition.column.position.ColumnPositionSegment;
import io.shardingsphere.core.parsing.antlr.sql.statement.ddl.AlterTableStatement;

import java.util.Iterator;
import java.util.List;

/**
 * Alter table statement optimizer for MySQL.
 * 
 * @author duhongjun
 */
public final class MySQLAlterTableOptimizer extends AlterTableOptimizer {
    
    @Override
    protected void adjustColumnDefinition(final AlterTableStatement alterTableStatement, final List<ColumnMetaData> newColumnMetaData) {
        for (ColumnPositionSegment each : alterTableStatement.getChangedPositionColumns()) {
            if (each instanceof ColumnFirstPositionSegment) {
                adjustFirst(newColumnMetaData, (ColumnFirstPositionSegment) each);
            } else {
                adjustAfter(newColumnMetaData, (ColumnAfterPositionSegment) each);
            }
        }
    }
    
    private void adjustFirst(final List<ColumnMetaData> newColumnMetaData, final ColumnFirstPositionSegment columnFirstPositionSegment) {
        ColumnMetaData firstMetaData = null;
        Iterator<ColumnMetaData> iterator = newColumnMetaData.iterator();
        while (iterator.hasNext()) {
            ColumnMetaData each = iterator.next();
            if (each.getColumnName().equals(columnFirstPositionSegment.getColumnName())) {
                firstMetaData = each;
                iterator.remove();
                break;
            }
        }
        if (null != firstMetaData) {
            newColumnMetaData.add(0, firstMetaData);
        }
    }
    
    private void adjustAfter(final List<ColumnMetaData> newColumnMetaData, final ColumnAfterPositionSegment columnAfterPositionSegment) {
        int afterIndex = -1;
        int adjustColumnIndex = -1;
        for (int i = 0; i < newColumnMetaData.size(); i++) {
            if (newColumnMetaData.get(i).getColumnName().equals(columnAfterPositionSegment.getColumnName())) {
                adjustColumnIndex = i;
            }
            if (newColumnMetaData.get(i).getColumnName().equals(columnAfterPositionSegment.getAfterColumnName())) {
                afterIndex = i;
            }
            if (adjustColumnIndex >= 0 && afterIndex >= 0) {
                break;
            }
        }
        if (adjustColumnIndex >= 0 && afterIndex >= 0 && adjustColumnIndex != afterIndex + 1) {
            ColumnMetaData adjustColumnMetaData = newColumnMetaData.remove(adjustColumnIndex);
            if (afterIndex < adjustColumnIndex) {
                afterIndex = afterIndex + 1;
            }
            newColumnMetaData.add(afterIndex, adjustColumnMetaData);
        }
    }
}
+8 −2
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ package io.shardingsphere.core.parsing.antlr.sql.statement.ddl;
import com.google.common.base.Optional;
import io.shardingsphere.core.metadata.table.ColumnMetaData;
import io.shardingsphere.core.metadata.table.ShardingTableMetaData;
import io.shardingsphere.core.metadata.table.TableMetaData;
import io.shardingsphere.core.parsing.antlr.sql.segment.definition.column.ColumnDefinitionSegment;
import io.shardingsphere.core.parsing.antlr.sql.segment.definition.column.position.ColumnPositionSegment;
import lombok.Getter;
@@ -53,7 +52,14 @@ public final class AlterTableStatement extends DDLStatement {
    
    private String newTableName;
    
    private TableMetaData tableMetaData;
    /**
     * Get new table name.
     * 
     * @return new table name
     */
    public Optional<String> getNewTableName() {
        return Optional.fromNullable(newTableName);
    }
    
    /**
     * Find column definition.
+1 −2
Original line number Diff line number Diff line
@@ -3,8 +3,7 @@
    <sql-statement-rule context="createTable" sql-statement-class="io.shardingsphere.core.parsing.antlr.sql.statement.ddl.CreateTableStatement" 
                        extractor-rule-refs="tableNames, indexNames, columnDefinitions, outlinePrimaryKey" />
    <sql-statement-rule context="alterTable" sql-statement-class="io.shardingsphere.core.parsing.antlr.sql.statement.ddl.AlterTableStatement" 
                        extractor-rule-refs="tableNames, indexNames, addColumnDefinition, modifyColumnDefinition, changeColumnDefinition, dropColumnDefinition, outlinePrimaryKey, dropPrimaryKey, renameTable" 
                        optimizer-class="ddl.dialect.mysql.MySQLAlterTableOptimizer" />
                        extractor-rule-refs="tableNames, indexNames, addColumnDefinition, modifyColumnDefinition, changeColumnDefinition, dropColumnDefinition, outlinePrimaryKey, dropPrimaryKey, renameTable" />
    <sql-statement-rule context="dropTable" sql-statement-class="io.shardingsphere.core.parsing.antlr.sql.statement.ddl.DDLStatement" extractor-rule-refs="tableNames" />
    <sql-statement-rule context="truncateTable" sql-statement-class="io.shardingsphere.core.parsing.antlr.sql.statement.ddl.DDLStatement" extractor-rule-refs="tableName" />
    <sql-statement-rule context="createIndex" sql-statement-class="io.shardingsphere.core.parsing.antlr.sql.statement.ddl.DDLStatement" extractor-rule-refs="tableName, indexName" />
Loading