From ab0248cdb16d5f801b0234426497a030541d45dc Mon Sep 17 00:00:00 2001 From: robll-v1 <3922295484@qq.com> Date: Thu, 26 Feb 2026 15:43:03 +0800 Subject: [PATCH 1/9] fix(show): make tenant SHOW TABLE STATUS rows consistent for system statement_info --- pkg/frontend/mysql_cmd_executor.go | 53 +++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/pkg/frontend/mysql_cmd_executor.go b/pkg/frontend/mysql_cmd_executor.go index d08d154a27e0d..129bdc862ad1c 100644 --- a/pkg/frontend/mysql_cmd_executor.go +++ b/pkg/frontend/mysql_cmd_executor.go @@ -485,6 +485,49 @@ func handleShowTableStatus(ses *Session, execCtx *ExecCtx, stmt *tree.ShowTableS return sizes, nil } + // For some system tables (for example `system.statement_info`), tenant queries + // are rewritten to sys account with account-level filtering. mo_table_rows/size + // does not reflect that rewritten visibility in all cases, so fallback to + // count(*) for Rows to keep SHOW TABLE STATUS consistent with SELECT semantics. + getSpecialTableRows := func(tblNames []string) (map[string]int64, error) { + rows := make(map[string]int64) + if len(tblNames) == 0 { + return rows, nil + } + accountId, err := defines.GetAccountId(ctx) + if err != nil { + return nil, err + } + if accountId == sysAccountID { + return rows, nil + } + + escapeIdent := func(name string) string { + return strings.ReplaceAll(name, "`", "``") + } + + for _, tblName := range tblNames { + if !ShouldSwitchToSysAccount(dbName, tblName) { + continue + } + sql := fmt.Sprintf("select count(*) from `%s`.`%s`", escapeIdent(dbName), escapeIdent(tblName)) + rets, err := executeSQLInBackgroundSession(ctx, bh, sql) + if err != nil { + return nil, err + } + if !execResultArrayHasData(rets) { + continue + } + cnt, err := rets[0].GetInt64(ctx, 0, 0) + if err != nil { + return nil, err + } + rows[tblName] = cnt + } + + return rows, nil + } + var tblNames []string var tblIdxes []int // baseTable -> index table names (secondary/unique only), for Index_length @@ -544,6 +587,10 @@ func handleShowTableStatus(ses *Session, execCtx *ExecCtx, stmt *tree.ShowTableS if err != nil { return err } + specialRows, err := getSpecialTableRows(tblNames) + if err != nil { + return err + } indexLengths := make(map[string]int64, len(tblNames)) if len(indexTableSet) > 0 { @@ -562,7 +609,11 @@ func handleShowTableStatus(ses *Session, execCtx *ExecCtx, stmt *tree.ShowTableS for i, tblName := range tblNames { idx := tblIdxes[i] - ses.data[idx][3] = rows[tblName] + if cnt, ok := specialRows[tblName]; ok { + ses.data[idx][3] = cnt + } else { + ses.data[idx][3] = rows[tblName] + } if rows[tblName] > 0 { ses.data[idx][4] = sizes[tblName] / rows[tblName] } else { From 541d883ff50c3421e90fde8f18eaca9be5f252ea Mon Sep 17 00:00:00 2001 From: robll-v1 <3922295484@qq.com> Date: Thu, 26 Feb 2026 16:11:07 +0800 Subject: [PATCH 2/9] add bvt case and ut test --- pkg/frontend/mysql_cmd_executor.go | 6 +- pkg/frontend/mysql_cmd_executor_test.go | 92 ++++++++++++++++++++ test/distributed/cases/dml/show/show7.result | 10 +++ test/distributed/cases/dml/show/show7.sql | 14 +++ 4 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 test/distributed/cases/dml/show/show7.result create mode 100644 test/distributed/cases/dml/show/show7.sql diff --git a/pkg/frontend/mysql_cmd_executor.go b/pkg/frontend/mysql_cmd_executor.go index 129bdc862ad1c..1709cb4ec648b 100644 --- a/pkg/frontend/mysql_cmd_executor.go +++ b/pkg/frontend/mysql_cmd_executor.go @@ -430,7 +430,7 @@ func handleShowTableStatus(ses *Session, execCtx *ExecCtx, stmt *tree.ShowTableS // get table stats var rets []ExecResult - if rets, err = executeSQLInBackgroundSession(ctx, bh, sqlBuilder.String()); err != nil { + if rets, err = ExeSqlInBgSes(ctx, bh, sqlBuilder.String()); err != nil { return } @@ -466,7 +466,7 @@ func handleShowTableStatus(ses *Session, execCtx *ExecCtx, stmt *tree.ShowTableS sqlBuilder.WriteString(fmt.Sprintf("row('%s', '%s')", dbName, tblName)) } sqlBuilder.WriteString(") as tmp(db, tbl)") - rets, err := executeSQLInBackgroundSession(ctx, bh, sqlBuilder.String()) + rets, err := ExeSqlInBgSes(ctx, bh, sqlBuilder.String()) if err != nil { return nil, err } @@ -511,7 +511,7 @@ func handleShowTableStatus(ses *Session, execCtx *ExecCtx, stmt *tree.ShowTableS continue } sql := fmt.Sprintf("select count(*) from `%s`.`%s`", escapeIdent(dbName), escapeIdent(tblName)) - rets, err := executeSQLInBackgroundSession(ctx, bh, sql) + rets, err := ExeSqlInBgSes(ctx, bh, sql) if err != nil { return nil, err } diff --git a/pkg/frontend/mysql_cmd_executor_test.go b/pkg/frontend/mysql_cmd_executor_test.go index b4193c06f0a84..50f18b723a893 100644 --- a/pkg/frontend/mysql_cmd_executor_test.go +++ b/pkg/frontend/mysql_cmd_executor_test.go @@ -19,6 +19,7 @@ import ( "encoding/binary" "fmt" "io" + "strings" "sync/atomic" "testing" "time" @@ -1834,6 +1835,97 @@ func Test_handleShowTableStatus(t *testing.T) { ec = newTestExecCtx(context.Background(), ctrl) convey.So(handleShowTableStatus(ses, ec, shv), convey.ShouldNotBeNil) }) + + convey.Convey("handleShowTableStatus statement_info fallback rows", t, func() { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + relation := mock_frontend.NewMockRelation(ctrl) + relation.EXPECT().GetTableDef(gomock.Any()).Return(&plan.TableDef{ + TableType: catalog.SystemOrdinaryRel, + }).AnyTimes() + + database := mock_frontend.NewMockDatabase(ctrl) + database.EXPECT().IsSubscription(gomock.Any()).Return(false).AnyTimes() + database.EXPECT().Relation(gomock.Any(), gomock.Any(), nil).Return(relation, nil).AnyTimes() + + eng := mock_frontend.NewMockEngine(ctrl) + eng.EXPECT().New(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() + eng.EXPECT().Database(gomock.Any(), gomock.Any(), nil).Return(database, nil).AnyTimes() + + txnOperator := mock_frontend.NewMockTxnOperator(ctrl) + txnOperator.EXPECT().Commit(gomock.Any()).Return(nil).AnyTimes() + txnOperator.EXPECT().Rollback(gomock.Any()).Return(nil).AnyTimes() + txnOperator.EXPECT().Status().Return(txn.TxnStatus_Active).AnyTimes() + txnOperator.EXPECT().EnterRunSqlWithTokenAndSQL(gomock.Any(), gomock.Any()).Return(uint64(0)).AnyTimes() + txnOperator.EXPECT().ExitRunSqlWithToken(gomock.Any()).Return().AnyTimes() + + txnClient := mock_frontend.NewMockTxnClient(ctrl) + txnClient.EXPECT().New(gomock.Any(), gomock.Any()).Return(txnOperator, nil).AnyTimes() + + sv, err := getSystemVariables("test/system_vars_config.toml") + if err != nil { + t.Error(err) + } + pu := config.NewParameterUnit(sv, eng, txnClient, nil) + pu.SV.SkipCheckUser = true + setPu("", pu) + setSessionAlloc("", NewLeakCheckAllocator()) + ioses, err := NewIOSession(&testConn{}, pu, "") + convey.So(err, convey.ShouldBeNil) + pu.StorageEngine = eng + pu.TxnClient = txnClient + proto := NewMysqlClientProtocol("", 0, ioses, 1024, pu.SV) + + ses := NewSession(ctx, "", proto, nil) + tenant := &TenantInfo{ + Tenant: "acc_fallback", + TenantID: 1, + User: "admin", + DefaultRole: accountAdminRoleName, + DefaultRoleID: moAdminRoleID, + } + ses.SetTenantInfo(tenant) + ses.mrs = &MysqlResultSet{} + ses.SetDatabaseName(catalog.MO_SYSTEM) + ses.data = [][]interface{}{{ + []byte(catalog.MO_STATEMENT), nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, uint32(moAdminRoleID), nil, + }} + + statsRet := mock_frontend.NewMockExecResult(ctrl) + statsRet.EXPECT().GetRowCount().Return(uint64(1)).AnyTimes() + statsRet.EXPECT().GetString(gomock.Any(), uint64(0), uint64(0)).Return(catalog.MO_STATEMENT, nil).AnyTimes() + statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(1)).Return(int64(0), nil).AnyTimes() + statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(2)).Return(int64(128), nil).AnyTimes() + + countRet := mock_frontend.NewMockExecResult(ctrl) + countRet.EXPECT().GetRowCount().Return(uint64(1)).AnyTimes() + countRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(0)).Return(int64(7), nil).AnyTimes() + + calls := 0 + execStub := gostub.StubFunc(&ExeSqlInBgSes, func(reqCtx context.Context, bh BackgroundExec, sql string) ([]ExecResult, error) { + calls++ + switch { + case strings.Contains(sql, "mo_table_rows(db, tbl)"): + return []ExecResult{statsRet}, nil + case strings.Contains(sql, "select count(*) from `system`.`statement_info`"): + return []ExecResult{countRet}, nil + default: + return nil, moerr.NewInternalErrorf(reqCtx, "unexpected sql in test: %s", sql) + } + }) + defer execStub.Reset() + + proto.SetSession(ses) + ec := newTestExecCtx(ctx, ctrl) + shv := &tree.ShowTableStatus{DbName: catalog.MO_SYSTEM} + convey.So(handleShowTableStatus(ses, ec, shv), convey.ShouldBeNil) + convey.So(calls, convey.ShouldEqual, 2) + convey.So(ses.data[0][3], convey.ShouldEqual, int64(7)) + convey.So(ses.data[0][4], convey.ShouldEqual, int64(0)) + convey.So(ses.data[0][5], convey.ShouldEqual, int64(128)) + }) } func Test_checkModify(t *testing.T) { diff --git a/test/distributed/cases/dml/show/show7.result b/test/distributed/cases/dml/show/show7.result new file mode 100644 index 0000000000000..02b7e3433ed86 --- /dev/null +++ b/test/distributed/cases/dml/show/show7.result @@ -0,0 +1,10 @@ +drop account if exists show_table_status_acc_10163; +create account show_table_status_acc_10163 admin_name = 'admin' identified by '111'; +select 1; +1 +1 +show table status from system like 'statement_info'; +-- @regex("(?m)^statement_info\\s+Tae\\s+Dynamic\\s+[1-9][0-9]*\\s+",true) +Name Engine Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Role_id Role_name +statement_info Tae Dynamic 116 0 102892 0 0 NULL 0 2024-08-29 16:04:58 NULL NULL utf8mb4_bin NULL record each statement and stats info[mo_no_del_hint] 0 moadmin +drop account show_table_status_acc_10163; diff --git a/test/distributed/cases/dml/show/show7.sql b/test/distributed/cases/dml/show/show7.sql new file mode 100644 index 0000000000000..0c116be6e5347 --- /dev/null +++ b/test/distributed/cases/dml/show/show7.sql @@ -0,0 +1,14 @@ +drop account if exists show_table_status_acc_10163; +create account show_table_status_acc_10163 admin_name = 'admin' identified by '111'; + +-- @session:id=1&user=show_table_status_acc_10163:admin&password=111 +select 1; + +-- @bvt:issue#10163 +-- @ignore:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 +-- @regex("(?m)^statement_info\\s+Tae\\s+Dynamic\\s+[1-9][0-9]*\\s+",true) +show table status from system like 'statement_info'; +-- @bvt:issue + +-- @session +drop account show_table_status_acc_10163; From 69a13e4ecccad6e5a5964fcd5e1a675042bb2733 Mon Sep 17 00:00:00 2001 From: robll-v1 <3922295484@qq.com> Date: Thu, 26 Feb 2026 16:51:50 +0800 Subject: [PATCH 3/9] add ut and bvt case --- pkg/frontend/mysql_cmd_executor_test.go | 276 ++++++++++++++++++- test/distributed/cases/dml/show/show7.result | 14 +- test/distributed/cases/dml/show/show7.sql | 4 + 3 files changed, 292 insertions(+), 2 deletions(-) diff --git a/pkg/frontend/mysql_cmd_executor_test.go b/pkg/frontend/mysql_cmd_executor_test.go index 50f18b723a893..268cd9e59ca6f 100644 --- a/pkg/frontend/mysql_cmd_executor_test.go +++ b/pkg/frontend/mysql_cmd_executor_test.go @@ -1776,6 +1776,61 @@ func Test_run_panic(t *testing.T) { func Test_handleShowTableStatus(t *testing.T) { ctx := defines.AttachAccountId(context.TODO(), 1) + newShowTableStatusFixture := func( + reqCtx context.Context, + ctrl *gomock.Controller, + tableType, tableName string, + roleID uint32, + tenant *TenantInfo, + dbName string, + ) (*Session, *ExecCtx, *tree.ShowTableStatus) { + relation := mock_frontend.NewMockRelation(ctrl) + relation.EXPECT().GetTableDef(gomock.Any()).Return(&plan.TableDef{TableType: tableType}).AnyTimes() + + database := mock_frontend.NewMockDatabase(ctrl) + database.EXPECT().IsSubscription(gomock.Any()).Return(false).AnyTimes() + database.EXPECT().Relation(gomock.Any(), gomock.Any(), nil).Return(relation, nil).AnyTimes() + + eng := mock_frontend.NewMockEngine(ctrl) + eng.EXPECT().New(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() + eng.EXPECT().Database(gomock.Any(), gomock.Any(), nil).Return(database, nil).AnyTimes() + + txnOperator := mock_frontend.NewMockTxnOperator(ctrl) + txnOperator.EXPECT().Commit(gomock.Any()).Return(nil).AnyTimes() + txnOperator.EXPECT().Rollback(gomock.Any()).Return(nil).AnyTimes() + txnOperator.EXPECT().Status().Return(txn.TxnStatus_Active).AnyTimes() + txnOperator.EXPECT().EnterRunSqlWithTokenAndSQL(gomock.Any(), gomock.Any()).Return(uint64(0)).AnyTimes() + txnOperator.EXPECT().ExitRunSqlWithToken(gomock.Any()).Return().AnyTimes() + + txnClient := mock_frontend.NewMockTxnClient(ctrl) + txnClient.EXPECT().New(gomock.Any(), gomock.Any()).Return(txnOperator, nil).AnyTimes() + + sv, err := getSystemVariables("test/system_vars_config.toml") + if err != nil { + t.Error(err) + } + pu := config.NewParameterUnit(sv, eng, txnClient, nil) + pu.SV.SkipCheckUser = true + setPu("", pu) + setSessionAlloc("", NewLeakCheckAllocator()) + ioses, err := NewIOSession(&testConn{}, pu, "") + convey.So(err, convey.ShouldBeNil) + pu.StorageEngine = eng + pu.TxnClient = txnClient + proto := NewMysqlClientProtocol("", 0, ioses, 1024, pu.SV) + + ses := NewSession(reqCtx, "", proto, nil) + ses.SetTenantInfo(tenant) + ses.mrs = &MysqlResultSet{} + ses.SetDatabaseName(dbName) + ses.data = [][]interface{}{{ + []byte(tableName), nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, roleID, nil, + }} + proto.SetSession(ses) + return ses, newTestExecCtx(reqCtx, ctrl), &tree.ShowTableStatus{DbName: dbName} + } + convey.Convey("handleShowTableStatus succ", t, func() { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -1904,7 +1959,7 @@ func Test_handleShowTableStatus(t *testing.T) { countRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(0)).Return(int64(7), nil).AnyTimes() calls := 0 - execStub := gostub.StubFunc(&ExeSqlInBgSes, func(reqCtx context.Context, bh BackgroundExec, sql string) ([]ExecResult, error) { + execStub := gostub.Stub(&ExeSqlInBgSes, func(reqCtx context.Context, bh BackgroundExec, sql string) ([]ExecResult, error) { calls++ switch { case strings.Contains(sql, "mo_table_rows(db, tbl)"): @@ -1926,6 +1981,225 @@ func Test_handleShowTableStatus(t *testing.T) { convey.So(ses.data[0][4], convey.ShouldEqual, int64(0)) convey.So(ses.data[0][5], convey.ShouldEqual, int64(128)) }) + + convey.Convey("handleShowTableStatus non-special table should not fallback", t, func() { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + ses, ec, shv := newShowTableStatusFixture( + ctx, ctrl, + catalog.SystemOrdinaryRel, "not_special", + uint32(moAdminRoleID), + &TenantInfo{ + Tenant: "acc_fallback", + TenantID: 1, + User: "admin", + DefaultRole: accountAdminRoleName, + DefaultRoleID: moAdminRoleID, + }, + catalog.MO_SYSTEM, + ) + + statsRet := mock_frontend.NewMockExecResult(ctrl) + statsRet.EXPECT().GetRowCount().Return(uint64(1)).AnyTimes() + statsRet.EXPECT().GetString(gomock.Any(), uint64(0), uint64(0)).Return("not_special", nil).AnyTimes() + statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(1)).Return(int64(5), nil).AnyTimes() + statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(2)).Return(int64(100), nil).AnyTimes() + + countCalls := 0 + execStub := gostub.Stub(&ExeSqlInBgSes, func(reqCtx context.Context, bh BackgroundExec, sql string) ([]ExecResult, error) { + switch { + case strings.Contains(sql, "mo_table_rows(db, tbl)"): + return []ExecResult{statsRet}, nil + case strings.Contains(sql, "select count(*)"): + countCalls++ + return nil, moerr.NewInternalErrorf(reqCtx, "count query should not be called, sql: %s", sql) + default: + return nil, moerr.NewInternalErrorf(reqCtx, "unexpected sql in test: %s", sql) + } + }) + defer execStub.Reset() + + convey.So(handleShowTableStatus(ses, ec, shv), convey.ShouldBeNil) + convey.So(countCalls, convey.ShouldEqual, 0) + convey.So(ses.data[0][3], convey.ShouldEqual, int64(5)) + convey.So(ses.data[0][4], convey.ShouldEqual, int64(20)) + convey.So(ses.data[0][5], convey.ShouldEqual, int64(100)) + }) + + convey.Convey("handleShowTableStatus statement_info fallback empty result should keep mo_table_rows", t, func() { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + ses, ec, shv := newShowTableStatusFixture( + ctx, ctrl, + catalog.SystemOrdinaryRel, catalog.MO_STATEMENT, + uint32(moAdminRoleID), + &TenantInfo{ + Tenant: "acc_fallback", + TenantID: 1, + User: "admin", + DefaultRole: accountAdminRoleName, + DefaultRoleID: moAdminRoleID, + }, + catalog.MO_SYSTEM, + ) + + statsRet := mock_frontend.NewMockExecResult(ctrl) + statsRet.EXPECT().GetRowCount().Return(uint64(1)).AnyTimes() + statsRet.EXPECT().GetString(gomock.Any(), uint64(0), uint64(0)).Return(catalog.MO_STATEMENT, nil).AnyTimes() + statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(1)).Return(int64(3), nil).AnyTimes() + statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(2)).Return(int64(90), nil).AnyTimes() + + countRet := mock_frontend.NewMockExecResult(ctrl) + countRet.EXPECT().GetRowCount().Return(uint64(0)).AnyTimes() + + calls := 0 + execStub := gostub.Stub(&ExeSqlInBgSes, func(reqCtx context.Context, bh BackgroundExec, sql string) ([]ExecResult, error) { + calls++ + switch { + case strings.Contains(sql, "mo_table_rows(db, tbl)"): + return []ExecResult{statsRet}, nil + case strings.Contains(sql, "select count(*) from `system`.`statement_info`"): + return []ExecResult{countRet}, nil + default: + return nil, moerr.NewInternalErrorf(reqCtx, "unexpected sql in test: %s", sql) + } + }) + defer execStub.Reset() + + convey.So(handleShowTableStatus(ses, ec, shv), convey.ShouldBeNil) + convey.So(calls, convey.ShouldEqual, 2) + convey.So(ses.data[0][3], convey.ShouldEqual, int64(3)) + convey.So(ses.data[0][4], convey.ShouldEqual, int64(30)) + convey.So(ses.data[0][5], convey.ShouldEqual, int64(90)) + }) + + convey.Convey("handleShowTableStatus statement_info fallback count query error", t, func() { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + ses, ec, shv := newShowTableStatusFixture( + ctx, ctrl, + catalog.SystemOrdinaryRel, catalog.MO_STATEMENT, + uint32(moAdminRoleID), + &TenantInfo{ + Tenant: "acc_fallback", + TenantID: 1, + User: "admin", + DefaultRole: accountAdminRoleName, + DefaultRoleID: moAdminRoleID, + }, + catalog.MO_SYSTEM, + ) + + statsRet := mock_frontend.NewMockExecResult(ctrl) + statsRet.EXPECT().GetRowCount().Return(uint64(1)).AnyTimes() + statsRet.EXPECT().GetString(gomock.Any(), uint64(0), uint64(0)).Return(catalog.MO_STATEMENT, nil).AnyTimes() + statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(1)).Return(int64(3), nil).AnyTimes() + statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(2)).Return(int64(90), nil).AnyTimes() + + execStub := gostub.Stub(&ExeSqlInBgSes, func(reqCtx context.Context, bh BackgroundExec, sql string) ([]ExecResult, error) { + switch { + case strings.Contains(sql, "mo_table_rows(db, tbl)"): + return []ExecResult{statsRet}, nil + case strings.Contains(sql, "select count(*) from `system`.`statement_info`"): + return nil, moerr.NewInternalErrorf(reqCtx, "mock count query error") + default: + return nil, moerr.NewInternalErrorf(reqCtx, "unexpected sql in test: %s", sql) + } + }) + defer execStub.Reset() + + convey.So(handleShowTableStatus(ses, ec, shv), convey.ShouldNotBeNil) + }) + + convey.Convey("handleShowTableStatus statement_info fallback count decode error", t, func() { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + ses, ec, shv := newShowTableStatusFixture( + ctx, ctrl, + catalog.SystemOrdinaryRel, catalog.MO_STATEMENT, + uint32(moAdminRoleID), + &TenantInfo{ + Tenant: "acc_fallback", + TenantID: 1, + User: "admin", + DefaultRole: accountAdminRoleName, + DefaultRoleID: moAdminRoleID, + }, + catalog.MO_SYSTEM, + ) + + statsRet := mock_frontend.NewMockExecResult(ctrl) + statsRet.EXPECT().GetRowCount().Return(uint64(1)).AnyTimes() + statsRet.EXPECT().GetString(gomock.Any(), uint64(0), uint64(0)).Return(catalog.MO_STATEMENT, nil).AnyTimes() + statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(1)).Return(int64(3), nil).AnyTimes() + statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(2)).Return(int64(90), nil).AnyTimes() + + countRet := mock_frontend.NewMockExecResult(ctrl) + countRet.EXPECT().GetRowCount().Return(uint64(1)).AnyTimes() + countRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(0)).Return(int64(0), moerr.NewInternalErrorNoCtx("mock decode error")).AnyTimes() + + execStub := gostub.Stub(&ExeSqlInBgSes, func(reqCtx context.Context, bh BackgroundExec, sql string) ([]ExecResult, error) { + switch { + case strings.Contains(sql, "mo_table_rows(db, tbl)"): + return []ExecResult{statsRet}, nil + case strings.Contains(sql, "select count(*) from `system`.`statement_info`"): + return []ExecResult{countRet}, nil + default: + return nil, moerr.NewInternalErrorf(reqCtx, "unexpected sql in test: %s", sql) + } + }) + defer execStub.Reset() + + convey.So(handleShowTableStatus(ses, ec, shv), convey.ShouldNotBeNil) + }) + + convey.Convey("handleShowTableStatus sys account should skip special rows fallback", t, func() { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + sysCtx := defines.AttachAccountId(context.TODO(), sysAccountID) + ses, ec, shv := newShowTableStatusFixture( + sysCtx, ctrl, + catalog.SystemOrdinaryRel, catalog.MO_DATABASE, + uint32(moAdminRoleID), + &TenantInfo{ + Tenant: "sys", + TenantID: 0, + User: DefaultTenantMoAdmin, + }, + catalog.MO_SYSTEM, + ) + + statsRet := mock_frontend.NewMockExecResult(ctrl) + statsRet.EXPECT().GetRowCount().Return(uint64(1)).AnyTimes() + statsRet.EXPECT().GetString(gomock.Any(), uint64(0), uint64(0)).Return(catalog.MO_DATABASE, nil).AnyTimes() + statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(1)).Return(int64(11), nil).AnyTimes() + statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(2)).Return(int64(121), nil).AnyTimes() + + countCalls := 0 + execStub := gostub.Stub(&ExeSqlInBgSes, func(reqCtx context.Context, bh BackgroundExec, sql string) ([]ExecResult, error) { + switch { + case strings.Contains(sql, "mo_table_rows(db, tbl)"): + return []ExecResult{statsRet}, nil + case strings.Contains(sql, "select count(*)"): + countCalls++ + return nil, moerr.NewInternalErrorf(reqCtx, "count query should not be called, sql: %s", sql) + default: + return nil, moerr.NewInternalErrorf(reqCtx, "unexpected sql in test: %s", sql) + } + }) + defer execStub.Reset() + + convey.So(handleShowTableStatus(ses, ec, shv), convey.ShouldBeNil) + convey.So(countCalls, convey.ShouldEqual, 0) + convey.So(ses.data[0][3], convey.ShouldEqual, int64(11)) + convey.So(ses.data[0][4], convey.ShouldEqual, int64(11)) + convey.So(ses.data[0][5], convey.ShouldEqual, int64(121)) + }) } func Test_checkModify(t *testing.T) { diff --git a/test/distributed/cases/dml/show/show7.result b/test/distributed/cases/dml/show/show7.result index 02b7e3433ed86..5f6f0d8288880 100644 --- a/test/distributed/cases/dml/show/show7.result +++ b/test/distributed/cases/dml/show/show7.result @@ -3,8 +3,20 @@ create account show_table_status_acc_10163 admin_name = 'admin' identified by '1 select 1; 1 1 +select 2; +2 +2 +select 3; +3 +3 +select sleep(15); +sleep(15) +0 +select count(*) > 0 as has_data from system.statement_info; +has_data +1 show table status from system like 'statement_info'; -- @regex("(?m)^statement_info\\s+Tae\\s+Dynamic\\s+[1-9][0-9]*\\s+",true) Name Engine Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Role_id Role_name -statement_info Tae Dynamic 116 0 102892 0 0 NULL 0 2024-08-29 16:04:58 NULL NULL utf8mb4_bin NULL record each statement and stats info[mo_no_del_hint] 0 moadmin +statement_info Tae Dynamic 2 0 0 0 0 NULL 1 2026-02-26 16:36:09 NULL NULL utf8mb4_bin NULL record each statement and stats info[mo_no_del_hint] 2 accountadmin drop account show_table_status_acc_10163; diff --git a/test/distributed/cases/dml/show/show7.sql b/test/distributed/cases/dml/show/show7.sql index 0c116be6e5347..669a6143a9c6c 100644 --- a/test/distributed/cases/dml/show/show7.sql +++ b/test/distributed/cases/dml/show/show7.sql @@ -3,8 +3,12 @@ create account show_table_status_acc_10163 admin_name = 'admin' identified by '1 -- @session:id=1&user=show_table_status_acc_10163:admin&password=111 select 1; +select 2; +select 3; +select sleep(15); -- @bvt:issue#10163 +select count(*) > 0 as has_data from system.statement_info; -- @ignore:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 -- @regex("(?m)^statement_info\\s+Tae\\s+Dynamic\\s+[1-9][0-9]*\\s+",true) show table status from system like 'statement_info'; From 4031eb77e417131c080a4bd7b04e65d09b7aa79b Mon Sep 17 00:00:00 2001 From: robll-v1 <3922295484@qq.com> Date: Sat, 28 Feb 2026 15:37:34 +0800 Subject: [PATCH 4/9] remove issue tag --- test/distributed/cases/dml/show/show7.sql | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/distributed/cases/dml/show/show7.sql b/test/distributed/cases/dml/show/show7.sql index 669a6143a9c6c..0e3bd21729e44 100644 --- a/test/distributed/cases/dml/show/show7.sql +++ b/test/distributed/cases/dml/show/show7.sql @@ -7,12 +7,10 @@ select 2; select 3; select sleep(15); --- @bvt:issue#10163 select count(*) > 0 as has_data from system.statement_info; -- @ignore:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 -- @regex("(?m)^statement_info\\s+Tae\\s+Dynamic\\s+[1-9][0-9]*\\s+",true) show table status from system like 'statement_info'; --- @bvt:issue -- @session drop account show_table_status_acc_10163; From 9b9418e4b310cb331229a7a88560a76c981998ac Mon Sep 17 00:00:00 2001 From: robll-v1 <3922295484@qq.com> Date: Sat, 28 Feb 2026 16:11:28 +0800 Subject: [PATCH 5/9] fix bvt case --- test/distributed/cases/dml/show/show7.result | 4 ++-- test/distributed/cases/dml/show/show7.sql | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/distributed/cases/dml/show/show7.result b/test/distributed/cases/dml/show/show7.result index 5f6f0d8288880..504b3f85df30e 100644 --- a/test/distributed/cases/dml/show/show7.result +++ b/test/distributed/cases/dml/show/show7.result @@ -16,7 +16,7 @@ select count(*) > 0 as has_data from system.statement_info; has_data 1 show table status from system like 'statement_info'; --- @regex("(?m)^statement_info\\s+Tae\\s+Dynamic\\s+[1-9][0-9]*\\s+",true) +-- @regex("(?m)^statement_info\\b.*\\bTae\\b.*\\bDynamic\\b.*\\b[1-9][0-9]*\\b",true) Name Engine Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Role_id Role_name -statement_info Tae Dynamic 2 0 0 0 0 NULL 1 2026-02-26 16:36:09 NULL NULL utf8mb4_bin NULL record each statement and stats info[mo_no_del_hint] 2 accountadmin +statement_info Tae Dynamic 1 0 0 0 0 NULL 1 2026-02-28 16:08:26 NULL NULL utf8mb4_bin NULL record each statement and stats info[mo_no_del_hint] 2 accountadmin drop account show_table_status_acc_10163; diff --git a/test/distributed/cases/dml/show/show7.sql b/test/distributed/cases/dml/show/show7.sql index 0e3bd21729e44..4f9a54e78e06b 100644 --- a/test/distributed/cases/dml/show/show7.sql +++ b/test/distributed/cases/dml/show/show7.sql @@ -9,7 +9,7 @@ select sleep(15); select count(*) > 0 as has_data from system.statement_info; -- @ignore:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 --- @regex("(?m)^statement_info\\s+Tae\\s+Dynamic\\s+[1-9][0-9]*\\s+",true) +-- @regex("(?m)^statement_info\\b.*\\bTae\\b.*\\bDynamic\\b.*\\b[1-9][0-9]*\\b",true) show table status from system like 'statement_info'; -- @session From a362c2723f3895e7496b1d567c0bd47f738a1fce Mon Sep 17 00:00:00 2001 From: robll-v1 <3922295484@qq.com> Date: Sat, 28 Feb 2026 16:40:06 +0800 Subject: [PATCH 6/9] fix bvt case --- test/distributed/cases/dml/show/show7.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/distributed/cases/dml/show/show7.sql b/test/distributed/cases/dml/show/show7.sql index 4f9a54e78e06b..e55c2abae7a10 100644 --- a/test/distributed/cases/dml/show/show7.sql +++ b/test/distributed/cases/dml/show/show7.sql @@ -8,7 +8,7 @@ select 3; select sleep(15); select count(*) > 0 as has_data from system.statement_info; --- @ignore:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 +-- @ignore:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 -- @regex("(?m)^statement_info\\b.*\\bTae\\b.*\\bDynamic\\b.*\\b[1-9][0-9]*\\b",true) show table status from system like 'statement_info'; From 8edc32ad36941c8eebd71cd6989be5b8e3053f8f Mon Sep 17 00:00:00 2001 From: robll-v1 <3922295484@qq.com> Date: Sat, 28 Feb 2026 17:10:04 +0800 Subject: [PATCH 7/9] fix bvt case --- test/distributed/cases/dml/show/show7.result | 2 +- test/distributed/cases/dml/show/show7.sql | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/distributed/cases/dml/show/show7.result b/test/distributed/cases/dml/show/show7.result index 504b3f85df30e..c2a2a38c6aafc 100644 --- a/test/distributed/cases/dml/show/show7.result +++ b/test/distributed/cases/dml/show/show7.result @@ -17,6 +17,6 @@ has_data 1 show table status from system like 'statement_info'; -- @regex("(?m)^statement_info\\b.*\\bTae\\b.*\\bDynamic\\b.*\\b[1-9][0-9]*\\b",true) -Name Engine Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Role_id Role_name +➤ Name[12,-1,0] ¦ Engine[12,-1,0] ¦ Row_format[12,-1,0] ¦ Rows[-5,64,0] ¦ Avg_row_length[-5,64,0] ¦ Data_length[-5,64,0] ¦ Max_data_length[-5,64,0] ¦ Index_length[-5,64,0] ¦ Data_free[12,-1,0] ¦ Auto_increment[-5,64,0] ¦ Create_time[93,64,0] ¦ Update_time[12,-1,0] ¦ Check_time[12,-1,0] ¦ Collation[12,-1,0] ¦ Checksum[12,-1,0] ¦ Create_options[1,0,0] ¦ Comment[12,-1,0] ¦ Role_id[4,32,0] ¦ Role_name[12,-1,0] 𝄀 statement_info Tae Dynamic 1 0 0 0 0 NULL 1 2026-02-28 16:08:26 NULL NULL utf8mb4_bin NULL record each statement and stats info[mo_no_del_hint] 2 accountadmin drop account show_table_status_acc_10163; diff --git a/test/distributed/cases/dml/show/show7.sql b/test/distributed/cases/dml/show/show7.sql index e55c2abae7a10..c14cf403cc28b 100644 --- a/test/distributed/cases/dml/show/show7.sql +++ b/test/distributed/cases/dml/show/show7.sql @@ -9,6 +9,7 @@ select sleep(15); select count(*) > 0 as has_data from system.statement_info; -- @ignore:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 +-- @metacmp(false) -- @regex("(?m)^statement_info\\b.*\\bTae\\b.*\\bDynamic\\b.*\\b[1-9][0-9]*\\b",true) show table status from system like 'statement_info'; From f3ac271c4c4c2983257fa1a92f77c731bab603e7 Mon Sep 17 00:00:00 2001 From: robll-v1 <3922295484@qq.com> Date: Sat, 28 Feb 2026 17:28:54 +0800 Subject: [PATCH 8/9] fix bvt --- test/distributed/cases/dml/show/show7.result | 4 ++-- test/distributed/cases/dml/show/show7.sql | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/distributed/cases/dml/show/show7.result b/test/distributed/cases/dml/show/show7.result index c2a2a38c6aafc..ee4a3a70ed836 100644 --- a/test/distributed/cases/dml/show/show7.result +++ b/test/distributed/cases/dml/show/show7.result @@ -16,7 +16,7 @@ select count(*) > 0 as has_data from system.statement_info; has_data 1 show table status from system like 'statement_info'; --- @regex("(?m)^statement_info\\b.*\\bTae\\b.*\\bDynamic\\b.*\\b[1-9][0-9]*\\b",true) +-- @regex("(?m)^statement_info.*Tae.*Dynamic.*[1-9][0-9]*.*$",true) ➤ Name[12,-1,0] ¦ Engine[12,-1,0] ¦ Row_format[12,-1,0] ¦ Rows[-5,64,0] ¦ Avg_row_length[-5,64,0] ¦ Data_length[-5,64,0] ¦ Max_data_length[-5,64,0] ¦ Index_length[-5,64,0] ¦ Data_free[12,-1,0] ¦ Auto_increment[-5,64,0] ¦ Create_time[93,64,0] ¦ Update_time[12,-1,0] ¦ Check_time[12,-1,0] ¦ Collation[12,-1,0] ¦ Checksum[12,-1,0] ¦ Create_options[1,0,0] ¦ Comment[12,-1,0] ¦ Role_id[4,32,0] ¦ Role_name[12,-1,0] 𝄀 -statement_info Tae Dynamic 1 0 0 0 0 NULL 1 2026-02-28 16:08:26 NULL NULL utf8mb4_bin NULL record each statement and stats info[mo_no_del_hint] 2 accountadmin +statement_info ¦ Tae ¦ Dynamic ¦ 1 ¦ 0 ¦ 0 ¦ 0 ¦ 0 ¦ NULL ¦ 1 ¦ 2026-02-28 16:08:26 ¦ NULL ¦ NULL ¦ utf8mb4_bin ¦ NULL ¦ ¦ record each statement and stats info[mo_no_del_hint] ¦ 2 ¦ accountadmin drop account show_table_status_acc_10163; diff --git a/test/distributed/cases/dml/show/show7.sql b/test/distributed/cases/dml/show/show7.sql index c14cf403cc28b..923327f0b72b4 100644 --- a/test/distributed/cases/dml/show/show7.sql +++ b/test/distributed/cases/dml/show/show7.sql @@ -10,7 +10,7 @@ select sleep(15); select count(*) > 0 as has_data from system.statement_info; -- @ignore:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 -- @metacmp(false) --- @regex("(?m)^statement_info\\b.*\\bTae\\b.*\\bDynamic\\b.*\\b[1-9][0-9]*\\b",true) +-- @regex("(?m)^statement_info.*Tae.*Dynamic.*[1-9][0-9]*.*$",true) show table status from system like 'statement_info'; -- @session From c5559df8bc3d099cb01af98389316ac7a05643cb Mon Sep 17 00:00:00 2001 From: robll-v1 <3922295484@qq.com> Date: Mon, 9 Mar 2026 15:28:16 +0800 Subject: [PATCH 9/9] fix some question --- pkg/frontend/mysql_cmd_executor.go | 11 ++-- pkg/frontend/mysql_cmd_executor_test.go | 55 ++++++++++++++++++-- test/distributed/cases/dml/show/show7.result | 4 +- test/distributed/cases/dml/show/show7.sql | 2 +- 4 files changed, 61 insertions(+), 11 deletions(-) diff --git a/pkg/frontend/mysql_cmd_executor.go b/pkg/frontend/mysql_cmd_executor.go index 1709cb4ec648b..70d932255cf81 100644 --- a/pkg/frontend/mysql_cmd_executor.go +++ b/pkg/frontend/mysql_cmd_executor.go @@ -488,8 +488,10 @@ func handleShowTableStatus(ses *Session, execCtx *ExecCtx, stmt *tree.ShowTableS // For some system tables (for example `system.statement_info`), tenant queries // are rewritten to sys account with account-level filtering. mo_table_rows/size // does not reflect that rewritten visibility in all cases, so fallback to - // count(*) for Rows to keep SHOW TABLE STATUS consistent with SELECT semantics. - getSpecialTableRows := func(tblNames []string) (map[string]int64, error) { + // count(*) for Rows when mo_table_rows is empty/zero to keep SHOW TABLE STATUS + // consistent with SELECT semantics without paying the extra cost when stats are + // already populated. + getSpecialTableRows := func(tblNames []string, tableRows map[string]int64) (map[string]int64, error) { rows := make(map[string]int64) if len(tblNames) == 0 { return rows, nil @@ -510,6 +512,9 @@ func handleShowTableStatus(ses *Session, execCtx *ExecCtx, stmt *tree.ShowTableS if !ShouldSwitchToSysAccount(dbName, tblName) { continue } + if currentRows, ok := tableRows[tblName]; ok && currentRows > 0 { + continue + } sql := fmt.Sprintf("select count(*) from `%s`.`%s`", escapeIdent(dbName), escapeIdent(tblName)) rets, err := ExeSqlInBgSes(ctx, bh, sql) if err != nil { @@ -587,7 +592,7 @@ func handleShowTableStatus(ses *Session, execCtx *ExecCtx, stmt *tree.ShowTableS if err != nil { return err } - specialRows, err := getSpecialTableRows(tblNames) + specialRows, err := getSpecialTableRows(tblNames, rows) if err != nil { return err } diff --git a/pkg/frontend/mysql_cmd_executor_test.go b/pkg/frontend/mysql_cmd_executor_test.go index 268cd9e59ca6f..e8943b6380486 100644 --- a/pkg/frontend/mysql_cmd_executor_test.go +++ b/pkg/frontend/mysql_cmd_executor_test.go @@ -1982,6 +1982,51 @@ func Test_handleShowTableStatus(t *testing.T) { convey.So(ses.data[0][5], convey.ShouldEqual, int64(128)) }) + convey.Convey("handleShowTableStatus statement_info with rows should skip fallback", t, func() { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + ses, ec, shv := newShowTableStatusFixture( + ctx, ctrl, + catalog.SystemOrdinaryRel, catalog.MO_STATEMENT, + uint32(moAdminRoleID), + &TenantInfo{ + Tenant: "acc_fallback", + TenantID: 1, + User: "admin", + DefaultRole: accountAdminRoleName, + DefaultRoleID: moAdminRoleID, + }, + catalog.MO_SYSTEM, + ) + + statsRet := mock_frontend.NewMockExecResult(ctrl) + statsRet.EXPECT().GetRowCount().Return(uint64(1)).AnyTimes() + statsRet.EXPECT().GetString(gomock.Any(), uint64(0), uint64(0)).Return(catalog.MO_STATEMENT, nil).AnyTimes() + statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(1)).Return(int64(3), nil).AnyTimes() + statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(2)).Return(int64(90), nil).AnyTimes() + + countCalls := 0 + execStub := gostub.Stub(&ExeSqlInBgSes, func(reqCtx context.Context, bh BackgroundExec, sql string) ([]ExecResult, error) { + switch { + case strings.Contains(sql, "mo_table_rows(db, tbl)"): + return []ExecResult{statsRet}, nil + case strings.Contains(sql, "select count(*) from `system`.`statement_info`"): + countCalls++ + return nil, moerr.NewInternalErrorf(reqCtx, "count query should not be called, sql: %s", sql) + default: + return nil, moerr.NewInternalErrorf(reqCtx, "unexpected sql in test: %s", sql) + } + }) + defer execStub.Reset() + + convey.So(handleShowTableStatus(ses, ec, shv), convey.ShouldBeNil) + convey.So(countCalls, convey.ShouldEqual, 0) + convey.So(ses.data[0][3], convey.ShouldEqual, int64(3)) + convey.So(ses.data[0][4], convey.ShouldEqual, int64(30)) + convey.So(ses.data[0][5], convey.ShouldEqual, int64(90)) + }) + convey.Convey("handleShowTableStatus non-special table should not fallback", t, func() { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -2048,7 +2093,7 @@ func Test_handleShowTableStatus(t *testing.T) { statsRet := mock_frontend.NewMockExecResult(ctrl) statsRet.EXPECT().GetRowCount().Return(uint64(1)).AnyTimes() statsRet.EXPECT().GetString(gomock.Any(), uint64(0), uint64(0)).Return(catalog.MO_STATEMENT, nil).AnyTimes() - statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(1)).Return(int64(3), nil).AnyTimes() + statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(1)).Return(int64(0), nil).AnyTimes() statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(2)).Return(int64(90), nil).AnyTimes() countRet := mock_frontend.NewMockExecResult(ctrl) @@ -2070,8 +2115,8 @@ func Test_handleShowTableStatus(t *testing.T) { convey.So(handleShowTableStatus(ses, ec, shv), convey.ShouldBeNil) convey.So(calls, convey.ShouldEqual, 2) - convey.So(ses.data[0][3], convey.ShouldEqual, int64(3)) - convey.So(ses.data[0][4], convey.ShouldEqual, int64(30)) + convey.So(ses.data[0][3], convey.ShouldEqual, int64(0)) + convey.So(ses.data[0][4], convey.ShouldEqual, int64(0)) convey.So(ses.data[0][5], convey.ShouldEqual, int64(90)) }) @@ -2096,7 +2141,7 @@ func Test_handleShowTableStatus(t *testing.T) { statsRet := mock_frontend.NewMockExecResult(ctrl) statsRet.EXPECT().GetRowCount().Return(uint64(1)).AnyTimes() statsRet.EXPECT().GetString(gomock.Any(), uint64(0), uint64(0)).Return(catalog.MO_STATEMENT, nil).AnyTimes() - statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(1)).Return(int64(3), nil).AnyTimes() + statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(1)).Return(int64(0), nil).AnyTimes() statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(2)).Return(int64(90), nil).AnyTimes() execStub := gostub.Stub(&ExeSqlInBgSes, func(reqCtx context.Context, bh BackgroundExec, sql string) ([]ExecResult, error) { @@ -2135,7 +2180,7 @@ func Test_handleShowTableStatus(t *testing.T) { statsRet := mock_frontend.NewMockExecResult(ctrl) statsRet.EXPECT().GetRowCount().Return(uint64(1)).AnyTimes() statsRet.EXPECT().GetString(gomock.Any(), uint64(0), uint64(0)).Return(catalog.MO_STATEMENT, nil).AnyTimes() - statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(1)).Return(int64(3), nil).AnyTimes() + statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(1)).Return(int64(0), nil).AnyTimes() statsRet.EXPECT().GetInt64(gomock.Any(), uint64(0), uint64(2)).Return(int64(90), nil).AnyTimes() countRet := mock_frontend.NewMockExecResult(ctrl) diff --git a/test/distributed/cases/dml/show/show7.result b/test/distributed/cases/dml/show/show7.result index ee4a3a70ed836..551ad760c843b 100644 --- a/test/distributed/cases/dml/show/show7.result +++ b/test/distributed/cases/dml/show/show7.result @@ -9,8 +9,8 @@ select 2; select 3; 3 3 -select sleep(15); -sleep(15) +select case when count(*) > 0 then 0 else sleep(15) end as wait_for_statement_info_ready from system.statement_info; +wait_for_statement_info_ready 0 select count(*) > 0 as has_data from system.statement_info; has_data diff --git a/test/distributed/cases/dml/show/show7.sql b/test/distributed/cases/dml/show/show7.sql index 923327f0b72b4..a19876912917a 100644 --- a/test/distributed/cases/dml/show/show7.sql +++ b/test/distributed/cases/dml/show/show7.sql @@ -5,7 +5,7 @@ create account show_table_status_acc_10163 admin_name = 'admin' identified by '1 select 1; select 2; select 3; -select sleep(15); +select case when count(*) > 0 then 0 else sleep(15) end as wait_for_statement_info_ready from system.statement_info; select count(*) > 0 as has_data from system.statement_info; -- @ignore:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18