Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: support for "admin show next_row_id" #8268

Merged
merged 3 commits into from
Nov 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ast/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,7 @@ const (
AdminShowDDLJobQueries
AdminChecksumTable
AdminShowSlow
AdminShowNextRowID
)

// HandleRange represents a range where handle value >= Begin and < End.
Expand Down
43 changes: 43 additions & 0 deletions executor/admin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (

. "github.com/pingcap/check"
"github.com/pingcap/tidb/executor"
"github.com/pingcap/tidb/meta/autoid"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/table/tables"
"github.com/pingcap/tidb/types"
Expand Down Expand Up @@ -515,3 +516,45 @@ func (s *testSuite) TestAdminCheckPrimaryIndex(c *C) {
tk.MustExec("insert into t values(1, 1, 1), (9223372036854775807, 2, 2);")
tk.MustExec("admin check index t idx;")
}

func (s *testSuite) TestAdminShowNextID(c *C) {
step := int64(10)
autoIDStep := autoid.GetStep()
autoid.SetStep(step)
defer autoid.SetStep(autoIDStep)
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("create table t(id int, c int)")
// Start handle is 1.
r := tk.MustQuery("admin show t next_row_id")
r.Check(testkit.Rows("test t _tidb_rowid 1"))
// Row ID is step + 1.
tk.MustExec("insert into t values(1, 1)")
r = tk.MustQuery("admin show t next_row_id")
r.Check(testkit.Rows("test t _tidb_rowid 11"))
// Row ID is original + step.
for i := 0; i < int(step); i++ {
tk.MustExec("insert into t values(10000, 1)")
}
r = tk.MustQuery("admin show t next_row_id")
r.Check(testkit.Rows("test t _tidb_rowid 21"))

// test for a table with the primary key
tk.MustExec("create table tt(id int primary key auto_increment, c int)")
// Start handle is 1.
r = tk.MustQuery("admin show tt next_row_id")
r.Check(testkit.Rows("test tt id 1"))
// After rebasing auto ID, row ID is 20 + step + 1.
tk.MustExec("insert into tt values(20, 1)")
r = tk.MustQuery("admin show tt next_row_id")
r.Check(testkit.Rows("test tt id 31"))
// test for renaming the table
tk.MustExec("create database test1")
tk.MustExec("rename table test.tt to test1.tt")
tk.MustExec("use test1")
r = tk.MustQuery("admin show tt next_row_id")
r.Check(testkit.Rows("test1 tt id 31"))
tk.MustExec("insert test1.tt values ()")
r = tk.MustQuery("admin show tt next_row_id")
r.Check(testkit.Rows("test1 tt id 41"))
}
2 changes: 1 addition & 1 deletion executor/aggregate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ func (s *testSuite) TestAggregation(c *C) {

result = tk.MustQuery("select count(*) from information_schema.columns")
// When adding new memory columns in information_schema, please update this variable.
columnCountOfAllInformationSchemaTables := "757"
columnCountOfAllInformationSchemaTables := "759"
result.Check(testkit.Rows(columnCountOfAllInformationSchemaTables))

tk.MustExec("drop table if exists t1")
Expand Down
10 changes: 10 additions & 0 deletions executor/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ func (b *executorBuilder) build(p plannercore.Plan) Executor {
return b.buildSelectLock(v)
case *plannercore.CancelDDLJobs:
return b.buildCancelDDLJobs(v)
case *plannercore.ShowNextRowID:
return b.buildShowNextRowID(v)
case *plannercore.ShowDDL:
return b.buildShowDDL(v)
case *plannercore.ShowDDLJobs:
Expand Down Expand Up @@ -185,6 +187,14 @@ func (b *executorBuilder) buildCancelDDLJobs(v *plannercore.CancelDDLJobs) Execu
return e
}

func (b *executorBuilder) buildShowNextRowID(v *plannercore.ShowNextRowID) Executor {
e := &ShowNextRowIDExec{
baseExecutor: newBaseExecutor(b.ctx, v.Schema(), v.ExplainID()),
tblName: v.TableName,
}
return e
}

func (b *executorBuilder) buildShowDDL(v *plannercore.ShowDDL) Executor {
// We get DDLInfo here because for Executors that returns result set,
// next will be called after transaction has been committed.
Expand Down
38 changes: 38 additions & 0 deletions executor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ var (
_ Executor = &ProjectionExec{}
_ Executor = &SelectionExec{}
_ Executor = &SelectLockExec{}
_ Executor = &ShowNextRowIDExec{}
_ Executor = &ShowDDLExec{}
_ Executor = &ShowDDLJobsExec{}
_ Executor = &ShowDDLJobQueriesExec{}
Expand Down Expand Up @@ -200,6 +201,43 @@ func (e *CancelDDLJobsExec) Next(ctx context.Context, chk *chunk.Chunk) error {
return nil
}

// ShowNextRowIDExec represents a show the next row ID executor.
type ShowNextRowIDExec struct {
baseExecutor
tblName *ast.TableName
done bool
}

// Next implements the Executor Next interface.
func (e *ShowNextRowIDExec) Next(ctx context.Context, chk *chunk.Chunk) error {
chk.Reset()
if e.done {
return nil
}
is := domain.GetDomain(e.ctx).InfoSchema()
tbl, err := is.TableByName(e.tblName.Schema, e.tblName.Name)
if err != nil {
return errors.Trace(err)
}
colName := model.ExtraHandleName
for _, col := range tbl.Meta().Columns {
if mysql.HasAutoIncrementFlag(col.Flag) {
colName = col.Name
break
}
}
nextGlobalID, err := tbl.Allocator(e.ctx).NextGlobalAutoID(tbl.Meta().ID)
if err != nil {
return errors.Trace(err)
}
chk.AppendString(0, e.tblName.Schema.O)
chk.AppendString(1, e.tblName.Name.O)
chk.AppendString(2, colName.O)
chk.AppendInt64(3, nextGlobalID)
e.done = true
return nil
}

// ShowDDLExec represents a show DDL executor.
type ShowDDLExec struct {
baseExecutor
Expand Down
1 change: 1 addition & 0 deletions parser/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ var tokenMap = map[string]int{
"NAMES": names,
"NATIONAL": national,
"NATURAL": natural,
"NEXT_ROW_ID": nextRowID,
"NO": no,
"NO_WRITE_TO_BINLOG": noWriteToBinLog,
"NONE": none,
Expand Down
10 changes: 9 additions & 1 deletion parser/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@ import (
extract "EXTRACT"
getFormat "GET_FORMAT"
groupConcat "GROUP_CONCAT"
nextRowID "NEXT_ROW_ID"
inplace "INPLACE"
internal "INTERNAL"
min "MIN"
Expand Down Expand Up @@ -2838,7 +2839,7 @@ TiDBKeyword:

NotKeywordToken:
"ADDDATE" | "BIT_AND" | "BIT_OR" | "BIT_XOR" | "CAST" | "COPY" | "COUNT" | "CURTIME" | "DATE_ADD" | "DATE_SUB" | "EXTRACT" | "GET_FORMAT" | "GROUP_CONCAT" | "INPLACE" | "INTERNAL"
|"MIN" | "MAX" | "MAX_EXECUTION_TIME" | "NOW" | "RECENT" | "POSITION" | "SUBDATE" | "SUBSTRING" | "SUM" | "TIMESTAMPADD" | "TIMESTAMPDIFF" | "TOP" | "TRIM"
|"MIN" | "MAX" | "MAX_EXECUTION_TIME" | "NOW" | "RECENT" | "POSITION" | "SUBDATE" | "SUBSTRING" | "SUM" | "TIMESTAMPADD" | "TIMESTAMPDIFF" | "TOP" | "TRIM" | "NEXT_ROW_ID"

/************************************************************************************
*
Expand Down Expand Up @@ -5173,6 +5174,13 @@ AdminStmt:
JobNumber: $5.(int64),
}
}
| "ADMIN" "SHOW" TableName "NEXT_ROW_ID"
{
$$ = &ast.AdminStmt{
Tp: ast.AdminShowNextRowID,
Tables: []*ast.TableName{$3.(*ast.TableName)},
}
}
| "ADMIN" "CHECK" "TABLE" TableNameList
{
$$ = &ast.AdminStmt{
Expand Down
1 change: 1 addition & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ func (s *testParserSuite) TestDMLStmt(c *C) {
{"admin checksum table t1, t2;", true},
{"admin cancel ddl jobs 1", true},
{"admin cancel ddl jobs 1, 2", true},
{"admin show t1 next_row_id", true},
{"admin recover index t1 idx_a", true},
{"admin cleanup index t1 idx_a", true},
{"admin show slow top 3", true},
Expand Down
6 changes: 6 additions & 0 deletions planner/core/common_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ type ShowDDLJobQueries struct {
JobIDs []int64
}

// ShowNextRowID is for showing the next global row ID.
type ShowNextRowID struct {
baseSchemaProducer
TableName *ast.TableName
}

// CheckTable is used for checking table data, built from the 'admin check table' statement.
type CheckTable struct {
baseSchemaProducer
Expand Down
13 changes: 13 additions & 0 deletions planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,10 @@ func (b *planBuilder) buildAdmin(as *ast.AdminStmt) (Plan, error) {
p := &ChecksumTable{Tables: as.Tables}
p.SetSchema(buildChecksumTableSchema())
ret = p
case ast.AdminShowNextRowID:
p := &ShowNextRowID{TableName: as.Tables[0]}
p.SetSchema(buildShowNextRowID())
ret = p
case ast.AdminShowDDL:
p := &ShowDDL{}
p.SetSchema(buildShowDDLFields())
Expand Down Expand Up @@ -706,6 +710,15 @@ func (b *planBuilder) buildAnalyze(as *ast.AnalyzeTableStmt) (Plan, error) {
return b.buildAnalyzeTable(as), nil
}

func buildShowNextRowID() *expression.Schema {
schema := expression.NewSchema(make([]*expression.Column, 0, 4)...)
schema.Append(buildColumn("", "DB_NAME", mysql.TypeVarchar, mysql.MaxDatabaseNameLength))
schema.Append(buildColumn("", "TABLE_NAME", mysql.TypeVarchar, mysql.MaxTableNameLength))
schema.Append(buildColumn("", "COLUMN_NAME", mysql.TypeVarchar, mysql.MaxColumnNameLength))
schema.Append(buildColumn("", "NEXT_GLOBAL_ROW_ID", mysql.TypeLonglong, 4))
return schema
}

func buildShowDDLFields() *expression.Schema {
schema := expression.NewSchema(make([]*expression.Column, 0, 4)...)
schema.Append(buildColumn("", "SCHEMA_VER", mysql.TypeLonglong, 4))
Expand Down