Skip to content

Commit ec3fb7b

Browse files
bb7133winoros
authored andcommitted
planner/core: fix a wrong privilege check for CTE & UPDATE statement (#57430)
close #53490
1 parent 6c41ea2 commit ec3fb7b

File tree

4 files changed

+53
-5
lines changed

4 files changed

+53
-5
lines changed

pkg/planner/core/logical_plan_builder.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5502,7 +5502,10 @@ func (b *PlanBuilder) buildUpdate(ctx context.Context, update *ast.UpdateStmt) (
55025502
if dbName == "" {
55035503
dbName = b.ctx.GetSessionVars().CurrentDB
55045504
}
5505-
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SelectPriv, dbName, t.Name.L, "", nil)
5505+
// Avoid adding CTE table to the SELECT privilege list, maybe we have better way to do this?
5506+
if _, ok := b.nameMapCTE[t.Name.L]; !ok {
5507+
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SelectPriv, dbName, t.Name.L, "", nil)
5508+
}
55065509
}
55075510

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

74077410
func (b *PlanBuilder) buildWith(ctx context.Context, w *ast.WithClause) ([]*cteInfo, error) {
74087411
// Check CTE name must be unique.
7409-
nameMap := make(map[string]struct{})
7412+
b.nameMapCTE = make(map[string]struct{})
74107413
for _, cte := range w.CTEs {
7411-
if _, ok := nameMap[cte.Name.L]; ok {
7414+
if _, ok := b.nameMapCTE[cte.Name.L]; ok {
74127415
return nil, plannererrors.ErrNonUniqTable
74137416
}
7414-
nameMap[cte.Name.L] = struct{}{}
7417+
b.nameMapCTE[cte.Name.L] = struct{}{}
74157418
}
74167419
ctes := make([]*cteInfo, 0, len(w.CTEs))
74177420
for _, cte := range w.CTEs {

pkg/planner/core/planbuilder.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,10 @@ type PlanBuilder struct {
269269
allocIDForCTEStorage int
270270
buildingRecursivePartForCTE bool
271271
buildingCTE bool
272-
//Check whether the current building query is a CTE
272+
// Check whether the current building query is a CTE
273273
isCTE bool
274+
// CTE table name in lower case, it can be nil
275+
nameMapCTE map[string]struct{}
274276

275277
// subQueryCtx and subQueryHintFlags are for handling subquery related hints.
276278
// Note: "subquery" here only contains subqueries that are handled by the expression rewriter, i.e., [NOT] IN,

tests/integrationtest/r/privilege/privileges.result

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,3 +647,19 @@ ADMIN SHOW SLOW TOP ALL 3;
647647
Error 8121 (HY000): privilege check for 'Super' fail
648648
ADMIN ALTER DDL JOBS 10 THREAD = 3, BATCH_SIZE = 100, MAX_WRITE_SPEED = '10MiB';
649649
Error 8121 (HY000): privilege check for 'Super' fail
650+
create table privilege__privileges.tt1 (id bigint,pid bigint,name varchar(20),fullname varchar(20));
651+
insert into privilege__privileges.tt1 values (1,null,'a',''),(2,1,'b',''),(3,2,'c','');
652+
CREATE USER u53490;
653+
GRANT USAGE ON *.* TO 'u53490';
654+
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,CREATE ROUTINE,ALTER ROUTINE,ALTER,EXECUTE,INDEX,CREATE VIEW,SHOW VIEW ON privilege__privileges.* TO 'u53490';
655+
with t_f as (
656+
select id,pid,name,'AAA' fullname from privilege__privileges.tt1 )
657+
update privilege__privileges.tt1 inner join t_f
658+
set tt1.fullname=t_f.fullname
659+
where tt1.id=t_f.id;
660+
with t_f as (
661+
select id,pid,name,'AAA' fullname from privilege__privileges.tt1 )
662+
update privilege__privileges.tt1 inner join t_f
663+
set t_f.fullname=t_f.fullname
664+
where tt1.id=t_f.id;
665+
Error 1288 (HY000): The target table t_f of the UPDATE is not updatable

tests/integrationtest/t/privilege/privileges.test

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,3 +871,30 @@ ADMIN ALTER DDL JOBS 10 THREAD = 3, BATCH_SIZE = 100, MAX_WRITE_SPEED = '10MiB';
871871

872872
disconnect without_super;
873873
connection default;
874+
875+
# TestIssue53490
876+
create table privilege__privileges.tt1 (id bigint,pid bigint,name varchar(20),fullname varchar(20));
877+
insert into privilege__privileges.tt1 values (1,null,'a',''),(2,1,'b',''),(3,2,'c','');
878+
879+
CREATE USER u53490;
880+
GRANT USAGE ON *.* TO 'u53490';
881+
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,CREATE ROUTINE,ALTER ROUTINE,ALTER,EXECUTE,INDEX,CREATE VIEW,SHOW VIEW ON privilege__privileges.* TO 'u53490';
882+
883+
connect (u53490,localhost,u53490,,);
884+
connection u53490;
885+
886+
with t_f as (
887+
select id,pid,name,'AAA' fullname from privilege__privileges.tt1 )
888+
update privilege__privileges.tt1 inner join t_f
889+
set tt1.fullname=t_f.fullname
890+
where tt1.id=t_f.id;
891+
892+
-- error 1288
893+
with t_f as (
894+
select id,pid,name,'AAA' fullname from privilege__privileges.tt1 )
895+
update privilege__privileges.tt1 inner join t_f
896+
set t_f.fullname=t_f.fullname
897+
where tt1.id=t_f.id;
898+
899+
disconnect u53490;
900+
connection default;

0 commit comments

Comments
 (0)