github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/plan/build_alter_rename_column.go (about) 1 // Copyright 2023 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 "github.com/matrixorigin/matrixone/pkg/common/moerr" 20 "github.com/matrixorigin/matrixone/pkg/pb/plan" 21 "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" 22 "strings" 23 ) 24 25 // RenameColumn Can change a column name but not its definition. 26 // More convenient than CHANGE to rename a column without changing its definition. 27 func RenameColumn(ctx CompilerContext, alterPlan *plan.AlterTable, spec *tree.AlterTableRenameColumnClause, alterCtx *AlterTableContext) error { 28 tableDef := alterPlan.CopyTableDef 29 30 // get the original column name 31 originalColName := spec.OldColumnName.Parts[0] 32 33 // get the new column name 34 newColName := spec.NewColumnName.Parts[0] 35 36 // Check whether original column has existed. 37 originalCol := FindColumn(tableDef.Cols, originalColName) 38 if originalCol == nil || originalCol.Hidden { 39 return moerr.NewBadFieldError(ctx.GetContext(), originalColName, alterPlan.TableDef.Name) 40 } 41 42 if originalColName == newColName { 43 return nil 44 } 45 46 // Check if the new column name is valid and conflicts with internal hidden columns 47 if err := CheckColumnNameValid(ctx.GetContext(), newColName); err != nil { 48 return err 49 } 50 51 if isColumnWithPartition(originalCol.Name, tableDef.Partition) { 52 return moerr.NewNotSupported(ctx.GetContext(), "unsupport alter partition part column currently") 53 } 54 55 // If you want to rename the original column name to new name, you need to first check if the new name already exists. 56 if newColName != originalColName { 57 newcol := FindColumn(tableDef.Cols, newColName) 58 if newcol != nil { 59 return moerr.NewErrDupFieldName(ctx.GetContext(), newColName) 60 } 61 62 // If the column name of the table changes, it is necessary to check if it is associated 63 // with the index key. If it is an index key column, column name replacement is required. 64 for _, indexInfo := range alterPlan.CopyTableDef.Indexes { 65 for j, partCol := range indexInfo.Parts { 66 partCol = catalog.ResolveAlias(partCol) 67 if partCol == originalCol.Name { 68 indexInfo.Parts[j] = newColName 69 break 70 } 71 } 72 } 73 74 primaryKeyDef := alterPlan.CopyTableDef.Pkey 75 for j, partCol := range primaryKeyDef.Names { 76 if partCol == originalCol.Name { 77 primaryKeyDef.Names[j] = newColName 78 break 79 } 80 } 81 // handle cluster by key in modify column 82 handleClusterByKey(ctx.GetContext(), alterPlan, newColName, originalCol.Name) 83 } 84 85 for i, col := range tableDef.Cols { 86 if strings.EqualFold(col.Name, originalCol.Name) { 87 colDef := DeepCopyColDef(col) 88 colDef.Name = newColName 89 tableDef.Cols[i] = colDef 90 break 91 } 92 } 93 94 delete(alterCtx.alterColMap, originalCol.Name) 95 alterCtx.alterColMap[newColName] = selectExpr{ 96 sexprType: columnName, 97 sexprStr: originalCol.Name, 98 } 99 100 if tmpCol, ok := alterCtx.changColDefMap[originalCol.ColId]; ok { 101 tmpCol.Name = newColName 102 } 103 104 alterCtx.UpdateSqls = append(alterCtx.UpdateSqls, 105 getSqlForRenameColumn(alterPlan.Database, 106 alterPlan.TableDef.Name, 107 originalColName, 108 newColName)...) 109 110 return nil 111 } 112 113 // AlterColumn ALTER ... SET DEFAULT or ALTER ... DROP DEFAULT specify a new default value for a column or remove the old default value, respectively. 114 // If the old default is removed and the column can be NULL, the new default is NULL. If the column cannot be NULL, MySQL assigns a default value 115 func AlterColumn(ctx CompilerContext, alterPlan *plan.AlterTable, spec *tree.AlterTableAlterColumnClause, alterCtx *AlterTableContext) error { 116 tableDef := alterPlan.CopyTableDef 117 118 // get the original column name 119 originalColName := spec.ColumnName.Parts[0] 120 121 // Check whether original column has existed. 122 originalCol := FindColumn(tableDef.Cols, originalColName) 123 if originalCol == nil || originalCol.Hidden { 124 return moerr.NewBadFieldError(ctx.GetContext(), originalColName, alterPlan.TableDef.Name) 125 } 126 127 for i, col := range tableDef.Cols { 128 if strings.EqualFold(col.Name, originalCol.Name) { 129 colDef := DeepCopyColDef(col) 130 if spec.OptionType == tree.AlterColumnOptionSetDefault { 131 tmpColumnDef := tree.NewColumnTableDef(spec.ColumnName, nil, []tree.ColumnAttribute{spec.DefalutExpr}) 132 defer func() { 133 tmpColumnDef.Free() 134 }() 135 defaultValue, err := buildDefaultExpr(tmpColumnDef, colDef.Typ, ctx.GetProcess()) 136 if err != nil { 137 return err 138 } 139 defaultValue.NullAbility = colDef.Default.NullAbility 140 colDef.Default = defaultValue 141 } else if spec.OptionType == tree.AlterColumnOptionDropDefault { 142 colDef.Default.Expr = nil 143 colDef.Default.OriginString = "" 144 } 145 tableDef.Cols[i] = colDef 146 break 147 } 148 } 149 return nil 150 } 151 152 // OrderByColumn Currently, Mo only performs semantic checks on alter table order by 153 // and does not implement the function of changing the physical storage order of data in the table 154 func OrderByColumn(ctx CompilerContext, alterPlan *plan.AlterTable, spec *tree.AlterTableOrderByColumnClause, alterCtx *AlterTableContext) error { 155 tableDef := alterPlan.CopyTableDef 156 for _, order := range spec.AlterOrderByList { 157 // get the original column name 158 originalColName := order.Column.Parts[0] 159 // Check whether original column has existed. 160 originalCol := FindColumn(tableDef.Cols, originalColName) 161 if originalCol == nil || originalCol.Hidden { 162 return moerr.NewBadFieldError(ctx.GetContext(), originalColName, alterPlan.TableDef.Name) 163 } 164 } 165 return nil 166 }