Skip to content

Commit

Permalink
planner/core: fix a wrong privilege check for CTE & UPDATE statement (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ti-chi-bot authored Nov 25, 2024
1 parent 3da59f7 commit 0468b8e
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 5 deletions.
11 changes: 7 additions & 4 deletions pkg/planner/core/logical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -5502,7 +5502,10 @@ func (b *PlanBuilder) buildUpdate(ctx context.Context, update *ast.UpdateStmt) (
if dbName == "" {
dbName = b.ctx.GetSessionVars().CurrentDB
}
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SelectPriv, dbName, t.Name.L, "", nil)
// Avoid adding CTE table to the SELECT privilege list, maybe we have better way to do this?
if _, ok := b.nameMapCTE[t.Name.L]; !ok {
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SelectPriv, dbName, t.Name.L, "", nil)
}
}

oldSchemaLen := p.Schema().Len()
Expand Down Expand Up @@ -7406,12 +7409,12 @@ func (b *PlanBuilder) genCTETableNameForError() string {

func (b *PlanBuilder) buildWith(ctx context.Context, w *ast.WithClause) ([]*cteInfo, error) {
// Check CTE name must be unique.
nameMap := make(map[string]struct{})
b.nameMapCTE = make(map[string]struct{})
for _, cte := range w.CTEs {
if _, ok := nameMap[cte.Name.L]; ok {
if _, ok := b.nameMapCTE[cte.Name.L]; ok {
return nil, plannererrors.ErrNonUniqTable
}
nameMap[cte.Name.L] = struct{}{}
b.nameMapCTE[cte.Name.L] = struct{}{}
}
ctes := make([]*cteInfo, 0, len(w.CTEs))
for _, cte := range w.CTEs {
Expand Down
4 changes: 3 additions & 1 deletion pkg/planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,10 @@ type PlanBuilder struct {
allocIDForCTEStorage int
buildingRecursivePartForCTE bool
buildingCTE bool
//Check whether the current building query is a CTE
// Check whether the current building query is a CTE
isCTE bool
// CTE table name in lower case, it can be nil
nameMapCTE map[string]struct{}

// subQueryCtx and subQueryHintFlags are for handling subquery related hints.
// Note: "subquery" here only contains subqueries that are handled by the expression rewriter, i.e., [NOT] IN,
Expand Down
16 changes: 16 additions & 0 deletions tests/integrationtest/r/privilege/privileges.result
Original file line number Diff line number Diff line change
Expand Up @@ -647,3 +647,19 @@ ADMIN SHOW SLOW TOP ALL 3;
Error 8121 (HY000): privilege check for 'Super' fail
ADMIN ALTER DDL JOBS 10 THREAD = 3, BATCH_SIZE = 100, MAX_WRITE_SPEED = '10MiB';
Error 8121 (HY000): privilege check for 'Super' fail
create table privilege__privileges.tt1 (id bigint,pid bigint,name varchar(20),fullname varchar(20));
insert into privilege__privileges.tt1 values (1,null,'a',''),(2,1,'b',''),(3,2,'c','');
CREATE USER u53490;
GRANT USAGE ON *.* TO 'u53490';
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,CREATE ROUTINE,ALTER ROUTINE,ALTER,EXECUTE,INDEX,CREATE VIEW,SHOW VIEW ON privilege__privileges.* TO 'u53490';
with t_f as (
select id,pid,name,'AAA' fullname from privilege__privileges.tt1 )
update privilege__privileges.tt1 inner join t_f
set tt1.fullname=t_f.fullname
where tt1.id=t_f.id;
with t_f as (
select id,pid,name,'AAA' fullname from privilege__privileges.tt1 )
update privilege__privileges.tt1 inner join t_f
set t_f.fullname=t_f.fullname
where tt1.id=t_f.id;
Error 1288 (HY000): The target table t_f of the UPDATE is not updatable
27 changes: 27 additions & 0 deletions tests/integrationtest/t/privilege/privileges.test
Original file line number Diff line number Diff line change
Expand Up @@ -871,3 +871,30 @@ ADMIN ALTER DDL JOBS 10 THREAD = 3, BATCH_SIZE = 100, MAX_WRITE_SPEED = '10MiB';

disconnect without_super;
connection default;

# TestIssue53490
create table privilege__privileges.tt1 (id bigint,pid bigint,name varchar(20),fullname varchar(20));
insert into privilege__privileges.tt1 values (1,null,'a',''),(2,1,'b',''),(3,2,'c','');

CREATE USER u53490;
GRANT USAGE ON *.* TO 'u53490';
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,CREATE ROUTINE,ALTER ROUTINE,ALTER,EXECUTE,INDEX,CREATE VIEW,SHOW VIEW ON privilege__privileges.* TO 'u53490';

connect (u53490,localhost,u53490,,);
connection u53490;

with t_f as (
select id,pid,name,'AAA' fullname from privilege__privileges.tt1 )
update privilege__privileges.tt1 inner join t_f
set tt1.fullname=t_f.fullname
where tt1.id=t_f.id;

-- error 1288
with t_f as (
select id,pid,name,'AAA' fullname from privilege__privileges.tt1 )
update privilege__privileges.tt1 inner join t_f
set t_f.fullname=t_f.fullname
where tt1.id=t_f.id;

disconnect u53490;
connection default;

0 comments on commit 0468b8e

Please sign in to comment.