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

privilege: remove any string concat #22523

Merged
merged 9 commits into from
Feb 3, 2021
38 changes: 25 additions & 13 deletions privilege/privileges/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,23 @@ var (

const globalDBVisible = mysql.CreatePriv | mysql.SelectPriv | mysql.InsertPriv | mysql.UpdatePriv | mysql.DeletePriv | mysql.ShowDBPriv | mysql.DropPriv | mysql.AlterPriv | mysql.IndexPriv | mysql.CreateViewPriv | mysql.ShowViewPriv | mysql.GrantPriv | mysql.TriggerPriv | mysql.ReferencesPriv | mysql.ExecutePriv

const (
sqlLoadRoleGraph = "SELECT HIGH_PRIORITY FROM_USER, FROM_HOST, TO_USER, TO_HOST FROM mysql.role_edges"
sqlLoadGlobalPrivTable = "SELECT HIGH_PRIORITY Host,User,Priv FROM mysql.global_priv"
sqlLoadDBTable = "SELECT HIGH_PRIORITY Host,DB,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Grant_priv,Index_priv,Alter_priv,Execute_priv,Create_view_priv,Show_view_priv FROM mysql.db ORDER BY host, db, user"
sqlLoadTablePrivTable = "SELECT HIGH_PRIORITY Host,DB,User,Table_name,Grantor,Timestamp,Table_priv,Column_priv FROM mysql.tables_priv"
sqlLoadColumnsPrivTable = "SELECT HIGH_PRIORITY Host,DB,User,Table_name,Column_name,Timestamp,Column_priv FROM mysql.columns_priv"
sqlLoadDefaultRoles = "SELECT HIGH_PRIORITY HOST, USER, DEFAULT_ROLE_HOST, DEFAULT_ROLE_USER FROM mysql.default_roles"
// list of privileges from mysql.Priv2UserCol
sqlLoadUserTable = `SELECT HIGH_PRIORITY Host,User,authentication_string,
Create_priv, Select_priv, Insert_priv, Update_priv, Delete_priv, Show_db_priv, Super_priv,
Create_user_priv,Create_tablespace_priv,Trigger_priv,Drop_priv,Process_priv,Grant_priv,
References_priv,Alter_priv,Execute_priv,Index_priv,Create_view_priv,Show_view_priv,
Create_role_priv,Drop_role_priv,Create_tmp_table_priv,Lock_tables_priv,Create_routine_priv,
Alter_routine_priv,Event_priv,Shutdown_priv,Reload_priv,File_priv,Config_priv,Repl_client_priv,Repl_slave_priv,
account_locked FROM mysql.user`
)

func computePrivMask(privs []mysql.PrivilegeType) mysql.PrivilegeType {
var mask mysql.PrivilegeType
for _, p := range privs {
Expand Down Expand Up @@ -348,7 +365,7 @@ func noSuchTable(err error) bool {
// LoadRoleGraph loads the mysql.role_edges table from database.
func (p *MySQLPrivilege) LoadRoleGraph(ctx sessionctx.Context) error {
p.RoleGraph = make(map[string]roleGraphEdgesTable)
err := p.loadTable(ctx, "select FROM_USER, FROM_HOST, TO_USER, TO_HOST from mysql.role_edges;", p.decodeRoleEdgesTable)
err := p.loadTable(ctx, sqlLoadRoleGraph, p.decodeRoleEdgesTable)
if err != nil {
return errors.Trace(err)
}
Expand All @@ -357,12 +374,7 @@ func (p *MySQLPrivilege) LoadRoleGraph(ctx sessionctx.Context) error {

// LoadUserTable loads the mysql.user table from database.
func (p *MySQLPrivilege) LoadUserTable(ctx sessionctx.Context) error {
userPrivCols := make([]string, 0, len(mysql.Priv2UserCol))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to keep this dynamic array. Won't we add more privUserCol in the future?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory actually it should become rare. The new privileges added to MySQL are usually added with something called DYNAMIC privileges. We have a spec for adding it here: #22486

We have already extended the privileges table prior to add ad-hoc DYNAMIC privileges. I don't think we need to migrate these yet, but it does actually break MySQL compatibility since a mysqldump becomes non-restorable.

Copy link
Contributor

@xhebox xhebox Jan 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense to me, though. I wonder that there should be a comment at the mysql.Priv2UserCol to remind the update of tidb.

It is also rare that internal column names will cause problems, even if they are using string concat. The new API could handle the problem, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets see what @tiancaiamao thinks. I am happy to take either approach, but prefer the comment if he is okay with that.

for _, v := range mysql.Priv2UserCol {
userPrivCols = append(userPrivCols, v)
}
query := fmt.Sprintf("select HIGH_PRIORITY Host,User,authentication_string,%s,account_locked from mysql.user;", strings.Join(userPrivCols, ", "))
err := p.loadTable(ctx, query, p.decodeUserTableRow)
err := p.loadTable(ctx, sqlLoadUserTable, p.decodeUserTableRow)
if err != nil {
return errors.Trace(err)
}
Expand Down Expand Up @@ -468,12 +480,12 @@ func (p MySQLPrivilege) SortUserTable() {

// LoadGlobalPrivTable loads the mysql.global_priv table from database.
func (p *MySQLPrivilege) LoadGlobalPrivTable(ctx sessionctx.Context) error {
return p.loadTable(ctx, "select HIGH_PRIORITY Host,User,Priv from mysql.global_priv", p.decodeGlobalPrivTableRow)
return p.loadTable(ctx, sqlLoadGlobalPrivTable, p.decodeGlobalPrivTableRow)
}

// LoadDBTable loads the mysql.db table from database.
func (p *MySQLPrivilege) LoadDBTable(ctx sessionctx.Context) error {
err := p.loadTable(ctx, "select HIGH_PRIORITY Host,DB,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Grant_priv,Index_priv,Alter_priv,Execute_priv,Create_view_priv,Show_view_priv from mysql.db order by host, db, user;", p.decodeDBTableRow)
err := p.loadTable(ctx, sqlLoadDBTable, p.decodeDBTableRow)
if err != nil {
return err
}
Expand All @@ -491,7 +503,7 @@ func (p *MySQLPrivilege) buildDBMap() {

// LoadTablesPrivTable loads the mysql.tables_priv table from database.
func (p *MySQLPrivilege) LoadTablesPrivTable(ctx sessionctx.Context) error {
err := p.loadTable(ctx, "select HIGH_PRIORITY Host,DB,User,Table_name,Grantor,Timestamp,Table_priv,Column_priv from mysql.tables_priv", p.decodeTablesPrivTableRow)
err := p.loadTable(ctx, sqlLoadTablePrivTable, p.decodeTablesPrivTableRow)
if err != nil {
return err
}
Expand All @@ -509,18 +521,18 @@ func (p *MySQLPrivilege) buildTablesPrivMap() {

// LoadColumnsPrivTable loads the mysql.columns_priv table from database.
func (p *MySQLPrivilege) LoadColumnsPrivTable(ctx sessionctx.Context) error {
return p.loadTable(ctx, "select HIGH_PRIORITY Host,DB,User,Table_name,Column_name,Timestamp,Column_priv from mysql.columns_priv", p.decodeColumnsPrivTableRow)
return p.loadTable(ctx, sqlLoadColumnsPrivTable, p.decodeColumnsPrivTableRow)
}

// LoadDefaultRoles loads the mysql.columns_priv table from database.
func (p *MySQLPrivilege) LoadDefaultRoles(ctx sessionctx.Context) error {
return p.loadTable(ctx, "select HOST, USER, DEFAULT_ROLE_HOST, DEFAULT_ROLE_USER from mysql.default_roles", p.decodeDefaultRoleTableRow)
return p.loadTable(ctx, sqlLoadDefaultRoles, p.decodeDefaultRoleTableRow)
}

func (p *MySQLPrivilege) loadTable(sctx sessionctx.Context, sql string,
decodeTableRow func(chunk.Row, []*ast.ResultField) error) error {
ctx := context.Background()
tmp, err := sctx.(sqlexec.SQLExecutor).Execute(ctx, sql)
tmp, err := sctx.(sqlexec.SQLExecutor).ExecuteInternal(ctx, sql)
if err != nil {
return errors.Trace(err)
}
Expand Down