@@ -44,7 +44,8 @@ func validateCreateTable(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.
4444 if err != nil {
4545 return nil , transform .SameTree , err
4646 }
47- err = validateIndexes (ctx , sch , idxs , strictMySQLCompat )
47+ validatePrefixLengths := a .DatabaseType == sql .EngineType_MySql
48+ err = validateIndexes (ctx , sch , idxs , strictMySQLCompat , validatePrefixLengths )
4849 if err != nil {
4950 return nil , transform .SameTree , err
5051 }
@@ -226,6 +227,7 @@ func resolveAlterColumn(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.S
226227 initialSch := sch
227228
228229 addedColumn := false
230+ validatePrefixLengths := a .DatabaseType == sql .EngineType_MySql
229231
230232 // Need a TransformUp here because multiple of these statement types can be nested under a Block node.
231233 // It doesn't look it, but this is actually an iterative loop over all the independent clauses in an ALTER statement
@@ -237,7 +239,7 @@ func resolveAlterColumn(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.S
237239 return nil , transform .SameTree , err
238240 }
239241
240- sch , err = validateModifyColumn (ctx , initialSch , sch , n .(* plan.ModifyColumn ), keyedColumns )
242+ sch , err = validateModifyColumn (ctx , initialSch , sch , n .(* plan.ModifyColumn ), keyedColumns , validatePrefixLengths )
241243 if err != nil {
242244 return nil , transform .SameTree , err
243245 }
@@ -282,7 +284,7 @@ func resolveAlterColumn(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.S
282284 if err != nil {
283285 return nil , transform .SameTree , err
284286 }
285- indexes , err = validateAlterIndex (ctx , initialSch , sch , n .(* plan.AlterIndex ), indexes )
287+ indexes , err = validateAlterIndex (ctx , sch , n .(* plan.AlterIndex ), indexes , validatePrefixLengths )
286288 if err != nil {
287289 return nil , transform .SameTree , err
288290 }
@@ -294,7 +296,7 @@ func resolveAlterColumn(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.S
294296 if err != nil {
295297 return nil , transform .SameTree , err
296298 }
297- sch , err = validatePrimaryKey (ctx , initialSch , sch , n .(* plan.AlterPK ))
299+ sch , err = validatePrimaryKey (ctx , sch , n .(* plan.AlterPK ), validatePrefixLengths )
298300 if err != nil {
299301 return nil , transform .SameTree , err
300302 }
@@ -446,7 +448,9 @@ func isStrictMysqlCompatibilityEnabled(ctx *sql.Context) (bool, error) {
446448 return i == 1 , nil
447449}
448450
449- func validateModifyColumn (ctx * sql.Context , initialSch sql.Schema , schema sql.Schema , mc * plan.ModifyColumn , keyedColumns map [string ]bool ) (sql.Schema , error ) {
451+ // validateModifyColumn validates the |mc| ModifyColumn node and returns the updated schema. If
452+ // |validatePrefixLengths| is true, then prefix lengths on TEXT/BLOB columns will also be validated.
453+ func validateModifyColumn (ctx * sql.Context , initialSch sql.Schema , schema sql.Schema , mc * plan.ModifyColumn , keyedColumns map [string ]bool , validatePrefixLengths bool ) (sql.Schema , error ) {
450454 table := mc .Table
451455 tableName := table .(sql.Nameable ).Name ()
452456
@@ -496,7 +500,6 @@ func validateModifyColumn(ctx *sql.Context, initialSch sql.Schema, schema sql.Sc
496500 if index .IsFullText () {
497501 continue
498502 }
499- prefixLengths := index .PrefixLengths ()
500503 for i , expr := range index .Expressions () {
501504 col := plan .GetColumnFromIndexExpr (expr , tbl )
502505 if ! strings .EqualFold (col .Name , oldColName ) {
@@ -505,13 +508,16 @@ func validateModifyColumn(ctx *sql.Context, initialSch sql.Schema, schema sql.Sc
505508 if types .IsJSON (newCol .Type ) {
506509 return nil , sql .ErrJSONIndex .New (col .Name )
507510 }
508- var prefixLen int64
509- if i < len (prefixLengths ) {
510- prefixLen = int64 (prefixLengths [i ])
511- }
512- err = validatePrefixLength (ctx , oldColName , prefixLen , newCol .Type , strictMySQLCompat , index .IsUnique ())
513- if err != nil {
514- return nil , err
511+
512+ if validatePrefixLengths {
513+ var prefixLen int64
514+ if i < len (index .PrefixLengths ()) {
515+ prefixLen = int64 (index .PrefixLengths ()[i ])
516+ }
517+ err = validatePrefixLength (ctx , oldColName , prefixLen , newCol .Type , strictMySQLCompat , index .IsUnique ())
518+ if err != nil {
519+ return nil , err
520+ }
515521 }
516522 }
517523 }
@@ -619,8 +625,9 @@ func validateColumnSafeToDropWithCheckConstraint(columnName string, checks sql.C
619625}
620626
621627// validateAlterIndex validates the specified column can have an index added, dropped, or renamed. Returns an updated
622- // list of index name given the add, drop, or rename operations.
623- func validateAlterIndex (ctx * sql.Context , initialSch , sch sql.Schema , ai * plan.AlterIndex , indexes []string ) ([]string , error ) {
628+ // list of index name given the add, drop, or rename operations. If |validatePrefixLengths| is true, then index prefix
629+ // lengths on TEXT and BLOB columns will also be validated.
630+ func validateAlterIndex (ctx * sql.Context , sch sql.Schema , ai * plan.AlterIndex , indexes []string , validatePrefixLengths bool ) ([]string , error ) {
624631 switch ai .Action {
625632 case plan .IndexAction_Create :
626633 err := validateIdentifier (ai .IndexName )
@@ -640,7 +647,7 @@ func validateAlterIndex(ctx *sql.Context, initialSch, sch sql.Schema, ai *plan.A
640647 Storage : ai .Using ,
641648 Comment : ai .Comment ,
642649 }
643- err = validateIndex (ctx , colMap , indexDef , strictMySQLCompat )
650+ err = validateIndex (ctx , colMap , indexDef , strictMySQLCompat , validatePrefixLengths )
644651 if err != nil {
645652 return nil , err
646653 }
@@ -839,14 +846,14 @@ func schToColMap(sch sql.Schema) map[string]*sql.Column {
839846}
840847
841848// validateIndexes prevents creating tables with blob/text primary keys and indexes without a specified length
842- func validateIndexes (ctx * sql.Context , sch sql.Schema , idxDefs sql.IndexDefs , strictMySQLCompat bool ) error {
849+ func validateIndexes (ctx * sql.Context , sch sql.Schema , idxDefs sql.IndexDefs , strictMySQLCompat bool , validatePrefixLengths bool ) error {
843850 colMap := schToColMap (sch )
844851 var hasPkIndexDef bool
845852 for _ , idxDef := range idxDefs {
846853 if idxDef .IsPrimary () {
847854 hasPkIndexDef = true
848855 }
849- if err := validateIndex (ctx , colMap , idxDef , strictMySQLCompat ); err != nil {
856+ if err := validateIndex (ctx , colMap , idxDef , strictMySQLCompat , validatePrefixLengths ); err != nil {
850857 return err
851858 }
852859 }
@@ -865,13 +872,14 @@ func validateIndexes(ctx *sql.Context, sch sql.Schema, idxDefs sql.IndexDefs, st
865872}
866873
867874// validateIndex ensures that the Index Definition is valid for the table schema.
868- // This function will throw errors and warnings as needed.
869- // All columns in the index must be:
875+ // This function will throw errors and warnings as needed. If |validatePrefixLengths| is
876+ // true, then TEXT and BLOB columns included in the index will also be checked to ensure
877+ // they include a valid prefix length. All columns in the index must be:
870878// - in the schema
871879// - not duplicated
872880// - not JSON Type
873881// - have the proper prefix length
874- func validateIndex (ctx * sql.Context , colMap map [string ]* sql.Column , idxDef * sql.IndexDef , strictMySQLCompat bool ) error {
882+ func validateIndex (ctx * sql.Context , colMap map [string ]* sql.Column , idxDef * sql.IndexDef , strictMySQLCompat , validatePrefixLengths bool ) error {
875883 seenCols := make (map [string ]struct {})
876884 for _ , idxCol := range idxDef .Columns {
877885 schCol , exists := colMap [strings .ToLower (idxCol .Name )]
@@ -890,9 +898,11 @@ func validateIndex(ctx *sql.Context, colMap map[string]*sql.Column, idxDef *sql.
890898 continue
891899 }
892900
893- err := validatePrefixLength (ctx , idxCol .Name , idxCol .Length , schCol .Type , strictMySQLCompat , idxDef .IsUnique ())
894- if err != nil {
895- return err
901+ if validatePrefixLengths {
902+ err := validatePrefixLength (ctx , idxCol .Name , idxCol .Length , schCol .Type , strictMySQLCompat , idxDef .IsUnique ())
903+ if err != nil {
904+ return err
905+ }
896906 }
897907 }
898908
@@ -957,8 +967,9 @@ func getTableIndexNames(ctx *sql.Context, _ *Analyzer, table sql.Node) ([]string
957967 return names , nil
958968}
959969
960- // validatePrimaryKey validates a primary key add or drop operation.
961- func validatePrimaryKey (ctx * sql.Context , initialSch , sch sql.Schema , ai * plan.AlterPK ) (sql.Schema , error ) {
970+ // validatePrimaryKey validates a primary key add or drop operation. If |validatePrefixLengths| is true, then
971+ // TEXT and BLOB columns will be checked for a valid prefix length.
972+ func validatePrimaryKey (ctx * sql.Context , sch sql.Schema , ai * plan.AlterPK , validatePrefixLengths bool ) (sql.Schema , error ) {
962973 tableName := getTableName (ai .Table )
963974 switch ai .Action {
964975 case plan .PrimaryKeyAction_Create :
@@ -976,7 +987,7 @@ func validatePrimaryKey(ctx *sql.Context, initialSch, sch sql.Schema, ai *plan.A
976987 if err != nil {
977988 return nil , err
978989 }
979- err = validateIndex (ctx , colMap , idxDef , strictMySQLCompat )
990+ err = validateIndex (ctx , colMap , idxDef , strictMySQLCompat , validatePrefixLengths )
980991 if err != nil {
981992 return nil , err
982993 }
0 commit comments