github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/plan/build_alter_add_primarykey.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 ) 23 24 // AddPrimaryKey will add a new column to the table. 25 func AddPrimaryKey(ctx CompilerContext, alterPlan *plan.AlterTable, spec *tree.PrimaryKeyIndex, alterCtx *AlterTableContext) error { 26 tableDef := alterPlan.CopyTableDef 27 if tableDef.Pkey != nil && tableDef.Pkey.PkeyColName != catalog.FakePrimaryKeyColName { 28 return moerr.NewErrMultiplePriKey(ctx.GetContext()) 29 } 30 if tableDef.ClusterBy != nil && tableDef.ClusterBy.Name != "" { 31 return moerr.NewNotSupported(ctx.GetContext(), "cluster by with primary key is not support") 32 } 33 34 primaryKeys := make([]string, 0) 35 pksMap := map[string]bool{} 36 for _, key := range spec.KeyParts { 37 colName := key.ColName.Parts[0] // name of primary key column 38 col := FindColumn(tableDef.Cols, colName) 39 if col == nil { 40 return moerr.NewErrKeyColumnDoesNotExist(ctx.GetContext(), colName) 41 } 42 if err := CheckColumnNameValid(ctx.GetContext(), colName); err != nil { 43 return err 44 } 45 if err := checkPrimaryKeyPartType(ctx.GetContext(), col.Typ, colName); err != nil { 46 return err 47 } 48 49 if _, ok := pksMap[colName]; ok { 50 return moerr.NewInvalidInput(ctx.GetContext(), "duplicate column name '%s' in primary key", colName) 51 } 52 53 primaryKeys = append(primaryKeys, colName) 54 pksMap[colName] = true 55 } 56 57 pkeyName := "" 58 if len(primaryKeys) == 1 { 59 pkeyName = primaryKeys[0] 60 for _, col := range tableDef.Cols { 61 if col.Name == pkeyName { 62 col.Primary = true 63 col.NotNull = true 64 col.Default.NullAbility = false 65 tableDef.Pkey = &PrimaryKeyDef{ 66 Names: primaryKeys, 67 PkeyColName: pkeyName, 68 } 69 break 70 } 71 } 72 } else { 73 for _, coldef := range tableDef.Cols { 74 if coldef.Hidden { 75 continue 76 } 77 78 for _, primaryKey := range primaryKeys { 79 if coldef.Name == primaryKey { 80 coldef.NotNull = true 81 coldef.Default.NullAbility = true 82 } 83 } 84 } 85 pkeyName = catalog.CPrimaryKeyColName 86 colDef := MakeHiddenColDefByName(pkeyName) 87 colDef.Primary = true 88 tableDef.Cols = append(tableDef.Cols, colDef) 89 90 pkeyDef := &PrimaryKeyDef{ 91 Names: primaryKeys, 92 PkeyColName: pkeyName, 93 CompPkeyCol: colDef, 94 } 95 tableDef.Pkey = pkeyDef 96 } 97 return nil 98 } 99 100 func DropPrimaryKey(ctx CompilerContext, alterPlan *plan.AlterTable, alterCtx *AlterTableContext) error { 101 tableDef := alterPlan.CopyTableDef 102 if tableDef.Pkey.PkeyColName == catalog.FakePrimaryKeyColName { 103 return moerr.NewErrCantDropFieldOrKey(ctx.GetContext(), "PRIMARY") 104 } 105 pkey := tableDef.Pkey 106 if len(pkey.Names) == 1 { 107 for _, coldef := range tableDef.Cols { 108 if pkey.PkeyColName == coldef.Name { 109 coldef.Primary = false 110 } 111 } 112 } else { 113 for idx, coldef := range tableDef.Cols { 114 if coldef.Hidden && pkey.PkeyColName == coldef.Name { 115 tableDef.Cols = append(tableDef.Cols[:idx], tableDef.Cols[idx+1:]...) 116 break 117 } 118 } 119 } 120 tableDef.Pkey = nil 121 return nil 122 }