Skip to content
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
3 changes: 1 addition & 2 deletions pkg/ddl/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -1086,8 +1086,7 @@ func (e *executor) CreateMaterializedViewLog(ctx sessionctx.Context, s *ast.Crea
return dbterror.ErrWrongObject.GenWithStackByArgs(schemaName, s.Table.Name, "BASE TABLE")
}

mlogName := "$mlog$" + baseTable.Meta().Name.O
mlogNameCIStr := pmodel.NewCIStr(mlogName)
mlogNameCIStr := model.MaterializedViewLogTableName(baseTable.Meta().Name)
if err := checkTooLongTable(mlogNameCIStr); err != nil {
return err
}
Expand Down
9 changes: 6 additions & 3 deletions pkg/ddl/materialized_view.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ func (e *executor) CreateMaterializedView(ctx sessionctx.Context, s *ast.CreateM
}
baseTableID := baseTable.Meta().ID

mlogName := pmodel.NewCIStr("$mlog$" + baseTable.Meta().Name.O)
mlogName := model.MaterializedViewLogTableName(baseTable.Meta().Name)
mlogTable, err := is.TableByName(e.ctx, baseTableName.Schema, mlogName)
if err != nil {
if infoschema.ErrTableNotExists.Equal(err) {
Expand Down Expand Up @@ -435,7 +435,7 @@ func (e *executor) DropMaterializedViewLog(ctx sessionctx.Context, s *ast.DropMa
}
baseTableID := baseTable.Meta().ID

mlogName := pmodel.NewCIStr("$mlog$" + baseTable.Meta().Name.O)
mlogName := model.MaterializedViewLogTableName(baseTable.Meta().Name)
mlogTable, err := is.TableByName(e.ctx, schemaName, mlogName)
if err != nil {
return err
Expand Down Expand Up @@ -563,7 +563,7 @@ func (e *executor) AlterMaterializedViewLog(ctx sessionctx.Context, s *ast.Alter
}
baseTableID := baseTable.Meta().ID

mlogName := pmodel.NewCIStr("$mlog$" + baseTable.Meta().Name.O)
mlogName := model.MaterializedViewLogTableName(baseTable.Meta().Name)
mlogTable, err := is.TableByName(e.ctx, schemaName, mlogName)
if err != nil {
return err
Expand All @@ -572,6 +572,9 @@ func (e *executor) AlterMaterializedViewLog(ctx sessionctx.Context, s *ast.Alter
return dbterror.ErrWrongObject.GenWithStackByArgs(schemaName.O, mlogName, "MATERIALIZED VIEW LOG")
}

// TODO: split ALTER MATERIALIZED VIEW LOG into per-action handlers and
// dedicated DDL job args when schema-changing actions (for example column
// add/drop) are supported.
for _, action := range s.Actions {
switch action.Tp {
case ast.AlterMaterializedViewLogActionPurge:
Expand Down
2 changes: 1 addition & 1 deletion pkg/ddl/schematracker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ func (d *Checker) CreateMaterializedViewLog(ctx sessionctx.Context, stmt *ast.Cr
if schemaName.O == "" {
schemaName = pmodel.NewCIStr(ctx.GetSessionVars().CurrentDB)
}
d.checkTableInfo(ctx, schemaName, pmodel.NewCIStr("$mlog$"+stmt.Table.Name.O))
d.checkTableInfo(ctx, schemaName, model.MaterializedViewLogTableName(stmt.Table.Name))
d.checkTableInfo(ctx, schemaName, stmt.Table.Name)
return nil
}
Expand Down
3 changes: 1 addition & 2 deletions pkg/ddl/schematracker/dm_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,7 @@ func (d *SchemaTracker) CreateMaterializedViewLog(ctx sessionctx.Context, s *ast
return dbterror.ErrWrongObject.GenWithStackByArgs(schemaName, s.Table.Name, "BASE TABLE")
}

mlogName := "$mlog$" + baseTable.Name.O
mlogNameCIStr := pmodel.NewCIStr(mlogName)
mlogNameCIStr := model.MaterializedViewLogTableName(baseTable.Name)
if utf8.RuneCountInString(mlogNameCIStr.L) > mysql.MaxTableNameLength {
return dbterror.ErrTooLongIdent.GenWithStackByArgs(mlogNameCIStr)
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/executor/grant.go
Original file line number Diff line number Diff line change
Expand Up @@ -614,10 +614,10 @@ func isSafeMViewTableGrantPriv(priv mysql.PrivilegeType) bool {

func isSafeMLogTableGrantPriv(priv mysql.PrivilegeType) bool {
switch priv {
case mysql.AllPriv, mysql.UsagePriv, mysql.GrantPriv, mysql.SelectPriv:
case mysql.AllPriv, mysql.UsagePriv, mysql.GrantPriv:
return true
default:
return false
return materializedViewTablePrivs.Has(priv)
}
}

Expand Down Expand Up @@ -736,7 +736,7 @@ func tablePrivsForGrantTarget(ctx sessionctx.Context, db string, tbl string) (my
case meta.MaterializedView != nil:
return materializedViewTablePrivs, nil
case meta.MaterializedViewLog != nil:
return mysql.Privileges{mysql.SelectPriv}, nil
return materializedViewTablePrivs, nil
case meta.MaterializedViewShadow != nil:
return nil, nil
default:
Expand Down
64 changes: 17 additions & 47 deletions pkg/executor/materialized_view.go
Original file line number Diff line number Diff line change
Expand Up @@ -559,57 +559,30 @@ func checkCancelMaterializedViewJobPrivilege(
if !found {
return cancelMaterializedViewJobNotRunningUserError(stmt)
}
baseTable, err := is.TableByName(kctx, pmodel.NewCIStr(dbName), pmodel.NewCIStr(tableName))
if err != nil {
return errors.Trace(err)
}
if err := checkOperateViewOnAnyDependentMView(ctx, is, baseTable.Meta()); err != nil {
return cancelMaterializedViewJobPrecheckUserError(stmt, err)
if pm.RequestVerification(ctx.GetSessionVars().ActiveRoles, dbName, tableName, "", mysql.OperateViewPriv) {
return nil
}
return nil
return cancelMaterializedViewJobPrecheckUserError(stmt,
plannererrors.ErrTableaccessDenied.GenWithStackByArgs("OPERATE VIEW", user.AuthUsername, user.AuthHostname, tableName))
default:
return errors.Errorf("invalid materialized view job cancel type: %d", stmt.Tp)
}
}

func checkOperateViewOnAnyDependentMView(
func checkOperateViewOnMLog(
ctx sessionctx.Context,
is infoschema.InfoSchema,
baseTableMeta *model.TableInfo,
schemaName pmodel.CIStr,
mlogName pmodel.CIStr,
) error {
pm := privilege.GetPrivilegeManager(ctx)
user := ctx.GetSessionVars().User
if pm == nil || user == nil {
return nil
}

var lastTableName string
if baseTableMeta != nil {
lastTableName = baseTableMeta.Name.L
}
if baseTableMeta == nil || baseTableMeta.MaterializedViewBase == nil || len(baseTableMeta.MaterializedViewBase.MViewIDs) == 0 {
return errors.NewNoStackErrorf(
"no dependent materialized view found for materialized view log on table %s",
lastTableName,
)
}

for _, id := range baseTableMeta.MaterializedViewBase.MViewIDs {
mvTable, ok := is.TableByID(context.Background(), id)
if !ok || mvTable.Meta().MaterializedView == nil {
continue
}
dbInfo, ok := infoschema.SchemaByTable(is, mvTable.Meta())
if !ok {
continue
}
mvName := mvTable.Meta().Name.L
lastTableName = mvName
if pm.RequestVerification(ctx.GetSessionVars().ActiveRoles, dbInfo.Name.L, mvName, "", mysql.OperateViewPriv) {
return nil
}
if pm.RequestVerification(ctx.GetSessionVars().ActiveRoles, schemaName.L, mlogName.L, "", mysql.OperateViewPriv) {
return nil
}
return plannererrors.ErrTableaccessDenied.GenWithStackByArgs("OPERATE VIEW", user.AuthUsername, user.AuthHostname, lastTableName)
return plannererrors.ErrTableaccessDenied.GenWithStackByArgs("OPERATE VIEW", user.AuthUsername, user.AuthHostname, mlogName.L)
}

func checkRefreshMaterializedViewBaseTableSelect(
Expand Down Expand Up @@ -717,19 +690,16 @@ WHERE PURGE_JOB_ID = %?
if !ok {
return "", "", false, errors.Errorf("cannot resolve materialized view log %d for cancel job %d", mlogID, purgeJobID)
}
mlogInfo := mlogTable.Meta().MaterializedViewLog
mlogMeta := mlogTable.Meta()
mlogInfo := mlogMeta.MaterializedViewLog
if mlogInfo == nil {
return "", "", false, errors.Errorf("table %d is not a materialized view log", mlogID)
}
baseTable, ok := is.TableByID(context.Background(), mlogInfo.BaseTableID)
if !ok {
return "", "", false, errors.Errorf("cannot resolve base table %d for materialized view log %d", mlogInfo.BaseTableID, mlogID)
}
dbInfo, ok := infoschema.SchemaByTable(is, baseTable.Meta())
dbInfo, ok := infoschema.SchemaByTable(is, mlogMeta)
if !ok {
return "", "", false, errors.Errorf("cannot resolve schema for base table %d", mlogInfo.BaseTableID)
return "", "", false, errors.Errorf("cannot resolve schema for materialized view log %d", mlogID)
}
return dbInfo.Name.L, baseTable.Meta().Name.L, true, nil
return dbInfo.Name.L, mlogMeta.Name.L, true, nil
}

// MVCompleteDeltaApplyExec applies COMPLETE DELTA APPLY diff rows to the target MV table.
Expand Down Expand Up @@ -1787,7 +1757,7 @@ func (e *PurgeMaterializedViewLogExec) executePurgeMaterializedViewLog(
if err != nil {
return err
}
if err := checkOperateViewOnAnyDependentMView(e.Ctx(), domain.GetDomain(e.Ctx()).InfoSchema(), baseTableMeta); err != nil {
if err := checkOperateViewOnMLog(e.Ctx(), schemaName, mlogName); err != nil {
return err
}
releaseCtx := kctx
Expand Down Expand Up @@ -2297,7 +2267,7 @@ func (e *PurgeMaterializedViewLogExec) resolvePurgeMaterializedViewLogMeta(
baseTableMeta = baseTable.Meta()
baseTableID := baseTableMeta.ID

mlogName = pmodel.NewCIStr("$mlog$" + baseTableMeta.Name.O)
mlogName = model.MaterializedViewLogTableName(baseTableMeta.Name)
mlogTable, err := is.TableByName(context.Background(), schemaName, mlogName)
if err != nil {
if infoschema.ErrTableNotExists.Equal(err) {
Expand Down
6 changes: 1 addition & 5 deletions pkg/executor/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -723,13 +723,9 @@ func (e *ShowExec) fetchShowMaterializedViewLogs(ctx context.Context) error {
}
baseID := tbl.MaterializedViewLog.BaseTableID
baseName := ""
baseDB := e.DBName.O
if baseID != 0 {
if baseTbl, ok := e.is.TableByID(ctx, baseID); ok {
baseName = baseTbl.Meta().Name.O
if dbInfo, ok := infoschema.SchemaByTable(e.is, baseTbl.Meta()); ok {
baseDB = dbInfo.Name.O
}
}
}
if baseName == "" {
Expand All @@ -742,7 +738,7 @@ func (e *ShowExec) fetchShowMaterializedViewLogs(ctx context.Context) error {
if fieldPatternsLike != nil && !fieldPatternsLike.DoMatch(lowerMLogName) {
continue
}
if checker != nil && !checker.RequestVerification(activeRoles, baseDB, baseName, "", mysql.SelectPriv) {
if checker != nil && !hasAnyMaterializedViewVisiblePriv(checker, activeRoles, e.DBName.O, tbl.Name.O) {
continue
}
rows = append(rows, mlogRow{
Expand Down
11 changes: 10 additions & 1 deletion pkg/executor/test/ddl/materialized_view_ddl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,15 @@ func TestShowMaterializedViewLogs(t *testing.T) {
Check(testkit.Rows(otherExpected))
tk.MustQuery("show materialized view logs in test_show_mlog_other like 'test_show_mlog_other.$mlog$%'").
Check(testkit.Rows())

tk.MustExec("create user 'show_mlog_u'@'%' identified by ''")
defer tk.MustExec("drop user 'show_mlog_u'@'%'")
tk.MustExec("grant select on test.t to 'show_mlog_u'@'%'")
tkUser := testkit.NewTestKit(t, store)
require.NoError(t, tkUser.Session().Auth(&auth.UserIdentity{Username: "show_mlog_u", Hostname: "%"}, nil, nil, nil))
tkUser.MustQuery("show materialized view logs from test").Check(testkit.Rows())
tk.MustExec("grant alter on test.`$mlog$t` to 'show_mlog_u'@'%'")
tkUser.MustQuery("show materialized view logs from test").Check(testkit.Rows(expected))
}

func TestShowMaterializedViewStatusPrivilege(t *testing.T) {
Expand Down Expand Up @@ -624,7 +633,7 @@ func TestShowMaterializedViewStatusPrivilege(t *testing.T) {
err = tkUser.ExecToErr("show materialized view log on test.t_show_mv_status wait_purge")
require.ErrorContains(t, err, "SHOW VIEW command denied")

tk.MustExec("grant show view on test.t_show_mv_status to 'show_mv_status_u'@'%'")
tk.MustExec("grant show view on test.`$mlog$t_show_mv_status` to 'show_mv_status_u'@'%'")
tkUser.MustQuery("show materialized view log on test.t_show_mv_status wait_purge").Check(testkit.Rows(mlogExpected(2)))
}

Expand Down
Loading