github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/plan/alter_util.go (about)

     1  // Copyright 2022 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package plan
    16  
    17  import (
    18  	"github.com/matrixorigin/matrixone/pkg/catalog"
    19  	"strings"
    20  
    21  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    22  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    23  )
    24  
    25  func checkDropColumnWithPrimaryKey(colName string, pkey *plan.PrimaryKeyDef, ctx CompilerContext) error {
    26  	for _, column := range pkey.Names {
    27  		if column == colName {
    28  			return moerr.NewInvalidInput(ctx.GetContext(), "can't drop column %s with primary key covered now", colName)
    29  		}
    30  	}
    31  	return nil
    32  }
    33  
    34  func checkDropColumnWithIndex(colName string, indexes []*plan.IndexDef, ctx CompilerContext) error {
    35  	for _, indexInfo := range indexes {
    36  		if indexInfo.TableExist {
    37  			for _, column := range indexInfo.Parts {
    38  				column = catalog.ResolveAlias(column)
    39  				if column == colName {
    40  					return moerr.NewInvalidInput(ctx.GetContext(), "can't drop column %s with index covered now", colName)
    41  				}
    42  			}
    43  		}
    44  	}
    45  	return nil
    46  }
    47  
    48  func checkAlterColumnWithForeignKey(colName string, RefChildTbls []uint64, Fkeys []*ForeignKeyDef, ctx CompilerContext) error {
    49  	if len(RefChildTbls) > 0 || len(Fkeys) > 0 {
    50  		// We do not support drop column that dependent foreign keys constraints
    51  		return moerr.NewInvalidInput(ctx.GetContext(), "can't add/drop column for foreign key table now")
    52  	}
    53  	return nil
    54  }
    55  
    56  func checkAlterColumnWithPartitionKeys(colName string, tblInfo *TableDef, ctx CompilerContext) error {
    57  	if tblInfo.Partition != nil {
    58  		return moerr.NewInvalidInput(ctx.GetContext(), "can't add/drop column for partition table now")
    59  	}
    60  	return nil
    61  }
    62  
    63  func checkDropColumnWithCluster(colName string, tblInfo *TableDef, ctx CompilerContext) error {
    64  	//if tblInfo.ClusterBy != nil {
    65  	//	// We do not support drop column that dependent foreign keys constraints
    66  	//	return moerr.NewInvalidInput(ctx.GetContext(), "can't add/drop column for cluster table now")
    67  	//}
    68  	return nil
    69  }
    70  
    71  func checkIsDroppableColumn(tableDef *TableDef, colName string, ctx CompilerContext) error {
    72  	// Check whether dropped column has existed.
    73  	col := FindColumn(tableDef.Cols, colName)
    74  	if col == nil {
    75  		return moerr.NewInvalidInput(ctx.GetContext(), "can't DROP '%-.192s'; check that column/key exists", colName)
    76  	}
    77  
    78  	var colCnt int
    79  	for _, col := range tableDef.Cols {
    80  		if !col.Hidden {
    81  			colCnt++
    82  		}
    83  	}
    84  	if colCnt == 1 {
    85  		return moerr.NewInvalidInput(ctx.GetContext(), "can't drop only column %s in table %s", colName, tableDef.Name)
    86  	}
    87  
    88  	// We don not support drop auto_incr col
    89  	if col.Typ.AutoIncr {
    90  		return moerr.NewInvalidInput(ctx.GetContext(), "can' t drop auto_incr col")
    91  	}
    92  
    93  	// We do not support drop column that contain primary key columns now.
    94  	err := checkDropColumnWithPrimaryKey(colName, tableDef.Pkey, ctx)
    95  	if err != nil {
    96  		return err
    97  	}
    98  	// We do not support drop column that contain index columns now.
    99  	err = checkDropColumnWithIndex(colName, tableDef.Indexes, ctx)
   100  	if err != nil {
   101  		return err
   102  	}
   103  	// We do not support drop column that contain foreign key columns now.
   104  	err = checkAlterColumnWithForeignKey(colName, tableDef.RefChildTbls, tableDef.Fkeys, ctx)
   105  	if err != nil {
   106  		return err
   107  	}
   108  
   109  	// We do not support drop column for partitioned table now
   110  	err = checkAlterColumnWithPartitionKeys(colName, tableDef, ctx)
   111  	if err != nil {
   112  		return err
   113  	}
   114  
   115  	// We do not support drop column for cluster table now
   116  	err = checkDropColumnWithCluster(colName, tableDef, ctx)
   117  	if err != nil {
   118  		return err
   119  	}
   120  	return nil
   121  }
   122  
   123  func checkIsAddableColumn(tableDef *TableDef, colName string, colType *plan.Type, ctx CompilerContext) error {
   124  	// Check whether added column has existed.
   125  	col := FindColumn(tableDef.Cols, colName)
   126  	if col != nil {
   127  		return moerr.NewInvalidInput(ctx.GetContext(), "can't add '%-.192s'; check that column/key exists", colName)
   128  	}
   129  
   130  	// We don not support add auto_incr col
   131  	if colType.AutoIncr {
   132  		return moerr.NewInvalidInput(ctx.GetContext(), "can' t add auto_incr col")
   133  	}
   134  
   135  	// We do not support add column that contain foreign key columns now.
   136  	err := checkAlterColumnWithForeignKey(colName, tableDef.RefChildTbls, tableDef.Fkeys, ctx)
   137  	if err != nil {
   138  		return err
   139  	}
   140  
   141  	// We do not support add column for partitioned table now
   142  	err = checkAlterColumnWithPartitionKeys(colName, tableDef, ctx)
   143  	if err != nil {
   144  		return err
   145  	}
   146  
   147  	// We do not support add column for cluster table now
   148  	err = checkDropColumnWithCluster(colName, tableDef, ctx)
   149  	if err != nil {
   150  		return err
   151  	}
   152  	return nil
   153  }
   154  
   155  // FindColumn finds column in cols by name.
   156  func FindColumn(cols []*ColDef, name string) *ColDef {
   157  	for _, col := range cols {
   158  		if strings.EqualFold(col.Name, name) {
   159  			return col
   160  		}
   161  	}
   162  	return nil
   163  }
   164  
   165  // FindColumn finds column in cols by colId
   166  func FindColumnByColId(cols []*ColDef, colId uint64) *ColDef {
   167  	for _, col := range cols {
   168  		if col.ColId == colId {
   169  			return col
   170  		}
   171  	}
   172  	return nil
   173  }