GetModifiableColumnJob returns a DDL job of model.ActionModifyColumn.
( ctx context.Context, sctx sessionctx.Context, is infoschema.InfoSchema, // WARN: is maybe nil here. ident ast.Ident, originalColName pmodel.CIStr, schema *model.DBInfo, t table.Table, spec *ast.AlterTableSpec, )
| 1448 | |
| 1449 | // GetModifiableColumnJob returns a DDL job of model.ActionModifyColumn. |
| 1450 | func GetModifiableColumnJob( |
| 1451 | ctx context.Context, |
| 1452 | sctx sessionctx.Context, |
| 1453 | is infoschema.InfoSchema, // WARN: is maybe nil here. |
| 1454 | ident ast.Ident, |
| 1455 | originalColName pmodel.CIStr, |
| 1456 | schema *model.DBInfo, |
| 1457 | t table.Table, |
| 1458 | spec *ast.AlterTableSpec, |
| 1459 | ) (*JobWrapper, error) { |
| 1460 | var err error |
| 1461 | specNewColumn := spec.NewColumns[0] |
| 1462 | |
| 1463 | col := table.FindCol(t.Cols(), originalColName.L) |
| 1464 | if col == nil { |
| 1465 | return nil, infoschema.ErrColumnNotExists.GenWithStackByArgs(originalColName, ident.Name) |
| 1466 | } |
| 1467 | newColName := specNewColumn.Name.Name |
| 1468 | if newColName.L == model.ExtraHandleName.L { |
| 1469 | return nil, dbterror.ErrWrongColumnName.GenWithStackByArgs(newColName.L) |
| 1470 | } |
| 1471 | errG := checkModifyColumnWithGeneratedColumnsConstraint(t.Cols(), originalColName) |
| 1472 | |
| 1473 | // If we want to rename the column name, we need to check whether it already exists. |
| 1474 | if newColName.L != originalColName.L { |
| 1475 | c := table.FindCol(t.Cols(), newColName.L) |
| 1476 | if c != nil { |
| 1477 | return nil, infoschema.ErrColumnExists.GenWithStackByArgs(newColName) |
| 1478 | } |
| 1479 | |
| 1480 | // And also check the generated columns dependency, if some generated columns |
| 1481 | // depend on this column, we can't rename the column name. |
| 1482 | if errG != nil { |
| 1483 | return nil, errors.Trace(errG) |
| 1484 | } |
| 1485 | } |
| 1486 | |
| 1487 | // Constraints in the new column means adding new constraints. Errors should thrown, |
| 1488 | // which will be done by `processColumnOptions` later. |
| 1489 | if specNewColumn.Tp == nil { |
| 1490 | // Make sure the column definition is simple field type. |
| 1491 | return nil, errors.Trace(dbterror.ErrUnsupportedModifyColumn) |
| 1492 | } |
| 1493 | |
| 1494 | if err = checkColumnAttributes(specNewColumn.Name.OrigColName(), specNewColumn.Tp); err != nil { |
| 1495 | return nil, errors.Trace(err) |
| 1496 | } |
| 1497 | |
| 1498 | newCol := table.ToColumn(&model.ColumnInfo{ |
| 1499 | ID: col.ID, |
| 1500 | // We use this PR(https://github.com/pingcap/tidb/pull/6274) as the dividing line to define whether it is a new version or an old version TiDB. |
| 1501 | // The old version TiDB initializes the column's offset and state here. |
| 1502 | // The new version TiDB doesn't initialize the column's offset and state, and it will do the initialization in run DDL function. |
| 1503 | // When we do the rolling upgrade the following may happen: |
| 1504 | // a new version TiDB builds the DDL job that doesn't be set the column's offset and state, |
| 1505 | // and the old version TiDB is the DDL owner, it doesn't get offset and state from the store. Then it will encounter errors. |
| 1506 | // So here we set offset and state to support the rolling upgrade. |
| 1507 | Offset: col.Offset, |
no test coverage detected