diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go index 048b4e7ce62..b497be9d283 100644 --- a/go/vt/vttablet/onlineddl/executor.go +++ b/go/vt/vttablet/onlineddl/executor.go @@ -4693,6 +4693,31 @@ func (e *Executor) SubmitMigration( return result, nil } +// ShowMigrations shows migrations, optionally filtered by a condition +func (e *Executor) ShowMigrations(ctx context.Context, show *sqlparser.Show) (result *sqltypes.Result, err error) { + if atomic.LoadInt64(&e.isOpen) == 0 { + return nil, vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, "online ddl is disabled") + } + showBasic, ok := show.Internal.(*sqlparser.ShowBasic) + if !ok { + return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] ShowMigrations expects a ShowBasic statement. Got: %s", sqlparser.String(show)) + } + if showBasic.Command != sqlparser.VitessMigrations { + return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] ShowMigrations expects a VitessMigrations command, got %v. Statement: %s", sqlparser.VitessMigrations, sqlparser.String(show)) + } + whereExpr := "" + if showBasic.Filter != nil { + if showBasic.Filter.Filter != nil { + whereExpr = fmt.Sprintf(" where %s", sqlparser.String(showBasic.Filter.Filter)) + } else if showBasic.Filter.Like != "" { + lit := sqlparser.String(sqlparser.NewStrLiteral(showBasic.Filter.Like)) + whereExpr = fmt.Sprintf(" where migration_uuid LIKE %s OR migration_context LIKE %s OR migration_status LIKE %s", lit, lit, lit) + } + } + query := sqlparser.BuildParsedQuery(sqlShowMigrationsWhere, whereExpr).Query + return e.execQuery(ctx, query) +} + // ShowMigrationLogs reads the migration log for a given migration func (e *Executor) ShowMigrationLogs(ctx context.Context, stmt *sqlparser.ShowMigrationLogs) (result *sqltypes.Result, err error) { if atomic.LoadInt64(&e.isOpen) == 0 { diff --git a/go/vt/vttablet/onlineddl/schema.go b/go/vt/vttablet/onlineddl/schema.go index 90babe05b20..c35591fd5a9 100644 --- a/go/vt/vttablet/onlineddl/schema.go +++ b/go/vt/vttablet/onlineddl/schema.go @@ -359,6 +359,10 @@ const ( AND cleanup_timestamp IS NULL AND completed_timestamp IS NULL ` + sqlShowMigrationsWhere = `SELECT * + FROM _vt.schema_migrations + %s + ` sqlSelectMigration = `SELECT id, migration_uuid, diff --git a/go/vt/vttablet/tabletserver/planbuilder/builder.go b/go/vt/vttablet/tabletserver/planbuilder/builder.go index 980adf3efb5..89388812d70 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/builder.go +++ b/go/vt/vttablet/tabletserver/planbuilder/builder.go @@ -135,7 +135,10 @@ func analyzeInsert(ins *sqlparser.Insert, tables map[string]*schema.Table) (plan func analyzeShow(show *sqlparser.Show, dbName string) (plan *Plan, err error) { switch showInternal := show.Internal.(type) { case *sqlparser.ShowBasic: - if showInternal.Command == sqlparser.Table { + switch showInternal.Command { + case sqlparser.VitessMigrations: + return &Plan{PlanID: PlanShowMigrations, FullStmt: show}, nil + case sqlparser.Table: // rewrite WHERE clause if it exists // `where Tables_in_Keyspace` => `where Tables_in_DbName` if showInternal.Filter != nil { diff --git a/go/vt/vttablet/tabletserver/planbuilder/plan.go b/go/vt/vttablet/tabletserver/planbuilder/plan.go index 603ea455ac7..842f6349665 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/plan.go +++ b/go/vt/vttablet/tabletserver/planbuilder/plan.go @@ -76,6 +76,7 @@ const ( PlanCallProc PlanAlterMigration PlanRevertMigration + PlanShowMigrations PlanShowMigrationLogs PlanShowThrottledApps PlanShowThrottlerStatus @@ -112,6 +113,7 @@ var planName = []string{ "CallProcedure", "AlterMigration", "RevertMigration", + "ShowMigrations", "ShowMigrationLogs", "ShowThrottledApps", "ShowThrottlerStatus", diff --git a/go/vt/vttablet/tabletserver/query_executor.go b/go/vt/vttablet/tabletserver/query_executor.go index e342b2b6b18..eb8ef76dcd0 100644 --- a/go/vt/vttablet/tabletserver/query_executor.go +++ b/go/vt/vttablet/tabletserver/query_executor.go @@ -204,6 +204,8 @@ func (qre *QueryExecutor) Execute() (reply *sqltypes.Result, err error) { return qre.execAlterMigration() case p.PlanRevertMigration: return qre.execRevertMigration() + case p.PlanShowMigrations: + return qre.execShowMigrations() case p.PlanShowMigrationLogs: return qre.execShowMigrationLogs() case p.PlanShowThrottledApps: @@ -1057,6 +1059,13 @@ func (qre *QueryExecutor) execRevertMigration() (*sqltypes.Result, error) { return qre.tsv.onlineDDLExecutor.SubmitMigration(qre.ctx, qre.plan.FullStmt) } +func (qre *QueryExecutor) execShowMigrations() (*sqltypes.Result, error) { + if showStmt, ok := qre.plan.FullStmt.(*sqlparser.Show); ok { + return qre.tsv.onlineDDLExecutor.ShowMigrations(qre.ctx, showStmt) + } + return nil, vterrors.New(vtrpcpb.Code_INTERNAL, "Expecting SHOW VITESS_MIGRATIONS plan") +} + func (qre *QueryExecutor) execShowMigrationLogs() (*sqltypes.Result, error) { if showMigrationLogsStmt, ok := qre.plan.FullStmt.(*sqlparser.ShowMigrationLogs); ok { return qre.tsv.onlineDDLExecutor.ShowMigrationLogs(qre.ctx, showMigrationLogsStmt)