@@ -2115,6 +2115,11 @@ func checkTableInfoValidWithStmt(ctx sessionctx.Context, tbInfo *model.TableInfo
2115
2115
}
2116
2116
}
2117
2117
}
2118
+ if tbInfo .TTLInfo != nil {
2119
+ if err := checkTTLInfoValid (ctx , tbInfo ); err != nil {
2120
+ return errors .Trace (err )
2121
+ }
2122
+ }
2118
2123
2119
2124
return nil
2120
2125
}
@@ -2193,6 +2198,10 @@ func BuildTableInfoWithLike(ctx sessionctx.Context, ident ast.Ident, referTblInf
2193
2198
copy (pi .Definitions , referTblInfo .Partition .Definitions )
2194
2199
tblInfo .Partition = & pi
2195
2200
}
2201
+
2202
+ if referTblInfo .TTLInfo != nil {
2203
+ tblInfo .TTLInfo = referTblInfo .TTLInfo .Clone ()
2204
+ }
2196
2205
return & tblInfo , nil
2197
2206
}
2198
2207
@@ -3000,6 +3009,8 @@ func SetDirectPlacementOpt(placementSettings *model.PlacementSettings, placement
3000
3009
3001
3010
// handleTableOptions updates tableInfo according to table options.
3002
3011
func handleTableOptions (options []* ast.TableOption , tbInfo * model.TableInfo ) error {
3012
+ var handledTTLOrTTLEnable bool
3013
+
3003
3014
for _ , op := range options {
3004
3015
switch op .Tp {
3005
3016
case ast .TableOptionAutoIncrement :
@@ -3036,6 +3047,23 @@ func handleTableOptions(options []*ast.TableOption, tbInfo *model.TableInfo) err
3036
3047
tbInfo .PlacementPolicyRef = & model.PolicyRefInfo {
3037
3048
Name : model .NewCIStr (op .StrValue ),
3038
3049
}
3050
+ case ast .TableOptionTTL , ast .TableOptionTTLEnable :
3051
+ if handledTTLOrTTLEnable {
3052
+ continue
3053
+ }
3054
+
3055
+ ttlInfo , ttlEnable , err := getTTLInfoInOptions (options )
3056
+ if err != nil {
3057
+ return err
3058
+ }
3059
+ // It's impossible that `ttlInfo` and `ttlEnable` are all nil, because we have met this option.
3060
+ // After exclude the situation `ttlInfo == nil && ttlEnable != nil`, we could say `ttlInfo != nil`
3061
+ if ttlInfo == nil && ttlEnable != nil {
3062
+ return errors .Trace (dbterror .ErrSetTTLEnableForNonTTLTable )
3063
+ }
3064
+
3065
+ tbInfo .TTLInfo = ttlInfo
3066
+ handledTTLOrTTLEnable = true
3039
3067
}
3040
3068
}
3041
3069
shardingBits := shardingBits (tbInfo )
@@ -3227,6 +3255,7 @@ func (d *ddl) AlterTable(ctx context.Context, sctx sessionctx.Context, stmt *ast
3227
3255
}
3228
3256
for _ , spec := range validSpecs {
3229
3257
var handledCharsetOrCollate bool
3258
+ var handledTTLOrTTLEnable bool
3230
3259
switch spec .Tp {
3231
3260
case ast .AlterTableAddColumns :
3232
3261
err = d .AddColumn (sctx , ident , spec )
@@ -3363,6 +3392,20 @@ func (d *ddl) AlterTable(ctx context.Context, sctx sessionctx.Context, stmt *ast
3363
3392
Name : model .NewCIStr (opt .StrValue ),
3364
3393
}
3365
3394
case ast .TableOptionEngine :
3395
+ case ast .TableOptionTTL , ast .TableOptionTTLEnable :
3396
+ var ttlInfo * model.TTLInfo
3397
+ var ttlEnable * bool
3398
+
3399
+ if handledTTLOrTTLEnable {
3400
+ continue
3401
+ }
3402
+ ttlInfo , ttlEnable , err = getTTLInfoInOptions (spec .Options )
3403
+ if err != nil {
3404
+ return err
3405
+ }
3406
+ err = d .AlterTableTTLInfoOrEnable (sctx , ident , ttlInfo , ttlEnable )
3407
+
3408
+ handledTTLOrTTLEnable = true
3366
3409
default :
3367
3410
err = dbterror .ErrUnsupportedAlterTableOption
3368
3411
}
@@ -3406,6 +3449,9 @@ func (d *ddl) AlterTable(ctx context.Context, sctx sessionctx.Context, stmt *ast
3406
3449
case ast .AlterTableDisableKeys , ast .AlterTableEnableKeys :
3407
3450
// Nothing to do now, see https://github.com/pingcap/tidb/issues/1051
3408
3451
// MyISAM specific
3452
+ case ast .AlterTableRemoveTTL :
3453
+ // the parser makes sure we have only one `ast.AlterTableRemoveTTL` in an alter statement
3454
+ err = d .AlterTableRemoveTTL (sctx , ident )
3409
3455
default :
3410
3456
err = errors .Trace (dbterror .ErrUnsupportedAlterTableSpec )
3411
3457
}
@@ -4238,6 +4284,11 @@ func checkIsDroppableColumn(ctx sessionctx.Context, is infoschema.InfoSchema, sc
4238
4284
if err != nil {
4239
4285
return false , errors .Trace (err )
4240
4286
}
4287
+ // Check the column with TTL config
4288
+ err = checkDropColumnWithTTLConfig (tblInfo , colName .L )
4289
+ if err != nil {
4290
+ return false , errors .Trace (err )
4291
+ }
4241
4292
// We don't support dropping column with PK handle covered now.
4242
4293
if col .IsPKHandleColumn (tblInfo ) {
4243
4294
return false , dbterror .ErrUnsupportedPKHandle
@@ -4724,6 +4775,13 @@ func GetModifiableColumnJob(
4724
4775
return nil , errors .Trace (err )
4725
4776
}
4726
4777
4778
+ if t .Meta ().TTLInfo != nil {
4779
+ // the column referenced by TTL should be a time type
4780
+ if t .Meta ().TTLInfo .ColumnName .L == originalColName .L && ! types .IsTypeTime (newCol .ColumnInfo .FieldType .GetType ()) {
4781
+ return nil , errors .Trace (dbterror .ErrUnsupportedColumnInTTLConfig .GenWithStackByArgs (newCol .ColumnInfo .Name .O ))
4782
+ }
4783
+ }
4784
+
4727
4785
var newAutoRandBits uint64
4728
4786
if newAutoRandBits , err = checkAutoRandom (t .Meta (), col , specNewColumn ); err != nil {
4729
4787
return nil , errors .Trace (err )
@@ -5262,6 +5320,98 @@ func (d *ddl) AlterTableSetTiFlashReplica(ctx sessionctx.Context, ident ast.Iden
5262
5320
return errors .Trace (err )
5263
5321
}
5264
5322
5323
+ // AlterTableTTLInfoOrEnable submit ddl job to change table info according to the ttlInfo, or ttlEnable
5324
+ // at least one of the `ttlInfo` or `ttlEnable` should be not nil.
5325
+ // When `ttlInfo` is nil, and `ttlEnable` is not, it will use the original `.TTLInfo` in the table info and modify the
5326
+ // `.Enable`. If the `.TTLInfo` in the table info is empty, this function will return an error.
5327
+ // When `ttlInfo` is not nil, it simply submits the job with the `ttlInfo` and ignore the `ttlEnable`.
5328
+ func (d * ddl ) AlterTableTTLInfoOrEnable (ctx sessionctx.Context , ident ast.Ident , ttlInfo * model.TTLInfo , ttlEnable * bool ) error {
5329
+ is := d .infoCache .GetLatest ()
5330
+ schema , ok := is .SchemaByName (ident .Schema )
5331
+ if ! ok {
5332
+ return infoschema .ErrDatabaseNotExists .GenWithStackByArgs (ident .Schema )
5333
+ }
5334
+
5335
+ tb , err := is .TableByName (ident .Schema , ident .Name )
5336
+ if err != nil {
5337
+ return errors .Trace (infoschema .ErrTableNotExists .GenWithStackByArgs (ident .Schema , ident .Name ))
5338
+ }
5339
+
5340
+ tblInfo := tb .Meta ().Clone ()
5341
+ tableID := tblInfo .ID
5342
+ tableName := tblInfo .Name .L
5343
+
5344
+ var job * model.Job
5345
+ if ttlInfo != nil {
5346
+ tblInfo .TTLInfo = ttlInfo
5347
+ err = checkTTLInfoValid (ctx , tblInfo )
5348
+ if err != nil {
5349
+ return err
5350
+ }
5351
+ job = & model.Job {
5352
+ SchemaID : schema .ID ,
5353
+ TableID : tableID ,
5354
+ SchemaName : schema .Name .L ,
5355
+ TableName : tableName ,
5356
+ Type : model .ActionAlterTTLInfo ,
5357
+ BinlogInfo : & model.HistoryInfo {},
5358
+ Args : []interface {}{ttlInfo , ttlEnable },
5359
+ }
5360
+ } else {
5361
+ if tblInfo .TTLInfo == nil {
5362
+ return errors .Trace (dbterror .ErrSetTTLEnableForNonTTLTable )
5363
+ }
5364
+
5365
+ job = & model.Job {
5366
+ SchemaID : schema .ID ,
5367
+ TableID : tableID ,
5368
+ SchemaName : schema .Name .L ,
5369
+ TableName : tableName ,
5370
+ Type : model .ActionAlterTTLInfo ,
5371
+ BinlogInfo : & model.HistoryInfo {},
5372
+ Args : []interface {}{ttlInfo , ttlEnable },
5373
+ }
5374
+ }
5375
+
5376
+ err = d .DoDDLJob (ctx , job )
5377
+ err = d .callHookOnChanged (job , err )
5378
+ return errors .Trace (err )
5379
+ }
5380
+
5381
+ func (d * ddl ) AlterTableRemoveTTL (ctx sessionctx.Context , ident ast.Ident ) error {
5382
+ is := d .infoCache .GetLatest ()
5383
+
5384
+ schema , ok := is .SchemaByName (ident .Schema )
5385
+ if ! ok {
5386
+ return infoschema .ErrDatabaseNotExists .GenWithStackByArgs (ident .Schema )
5387
+ }
5388
+
5389
+ tb , err := is .TableByName (ident .Schema , ident .Name )
5390
+ if err != nil {
5391
+ return errors .Trace (infoschema .ErrTableNotExists .GenWithStackByArgs (ident .Schema , ident .Name ))
5392
+ }
5393
+
5394
+ tblInfo := tb .Meta ().Clone ()
5395
+ tableID := tblInfo .ID
5396
+ tableName := tblInfo .Name .L
5397
+
5398
+ if tblInfo .TTLInfo != nil {
5399
+ job := & model.Job {
5400
+ SchemaID : schema .ID ,
5401
+ TableID : tableID ,
5402
+ SchemaName : schema .Name .L ,
5403
+ TableName : tableName ,
5404
+ Type : model .ActionAlterTTLRemove ,
5405
+ BinlogInfo : & model.HistoryInfo {},
5406
+ }
5407
+ err = d .DoDDLJob (ctx , job )
5408
+ err = d .callHookOnChanged (job , err )
5409
+ return errors .Trace (err )
5410
+ }
5411
+
5412
+ return nil
5413
+ }
5414
+
5265
5415
func isTableTiFlashSupported (schema * model.DBInfo , tb table.Table ) error {
5266
5416
// Memory tables and system tables are not supported by TiFlash
5267
5417
if util .IsMemOrSysDB (schema .Name .L ) {
0 commit comments