From 1dfd21067edb9fc15804f47d7f64ed1e392efa3c Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Thu, 30 Apr 2026 03:24:49 +0900 Subject: [PATCH] Implement ALL object_type IN SCHEMA in GRANT/REVOKE --- ast/ast.go | 48 ++++++- ast/pos.go | 24 ++++ ast/sql.go | 12 ++ ast/walk_internal.go | 10 ++ parser.go | 130 ++++++++++++++++++ .../grant_on_all_change_streams_in_schema.sql | 1 + .../ddl/grant_on_all_tables_in_schema.sql | 1 + .../ddl/grant_on_all_views_in_schema.sql | 1 + ...revoke_on_all_change_streams_in_schema.sql | 1 + .../ddl/revoke_on_all_tables_in_schema.sql | 1 + .../ddl/revoke_on_all_views_in_schema.sql | 1 + ...nt_on_all_change_streams_in_schema.sql.txt | 30 ++++ .../ddl/grant_on_all_tables_in_schema.sql.txt | 47 +++++++ .../ddl/grant_on_all_views_in_schema.sql.txt | 30 ++++ ...ke_on_all_change_streams_in_schema.sql.txt | 39 ++++++ .../revoke_on_all_tables_in_schema.sql.txt | 44 ++++++ .../ddl/revoke_on_all_views_in_schema.sql.txt | 35 +++++ ...nt_on_all_change_streams_in_schema.sql.txt | 30 ++++ .../grant_on_all_tables_in_schema.sql.txt | 47 +++++++ .../grant_on_all_views_in_schema.sql.txt | 30 ++++ ...ke_on_all_change_streams_in_schema.sql.txt | 39 ++++++ .../revoke_on_all_tables_in_schema.sql.txt | 44 ++++++ .../revoke_on_all_views_in_schema.sql.txt | 35 +++++ 23 files changed, 675 insertions(+), 5 deletions(-) create mode 100644 testdata/input/ddl/grant_on_all_change_streams_in_schema.sql create mode 100644 testdata/input/ddl/grant_on_all_tables_in_schema.sql create mode 100644 testdata/input/ddl/grant_on_all_views_in_schema.sql create mode 100644 testdata/input/ddl/revoke_on_all_change_streams_in_schema.sql create mode 100644 testdata/input/ddl/revoke_on_all_tables_in_schema.sql create mode 100644 testdata/input/ddl/revoke_on_all_views_in_schema.sql create mode 100644 testdata/result/ddl/grant_on_all_change_streams_in_schema.sql.txt create mode 100644 testdata/result/ddl/grant_on_all_tables_in_schema.sql.txt create mode 100644 testdata/result/ddl/grant_on_all_views_in_schema.sql.txt create mode 100644 testdata/result/ddl/revoke_on_all_change_streams_in_schema.sql.txt create mode 100644 testdata/result/ddl/revoke_on_all_tables_in_schema.sql.txt create mode 100644 testdata/result/ddl/revoke_on_all_views_in_schema.sql.txt create mode 100644 testdata/result/statement/grant_on_all_change_streams_in_schema.sql.txt create mode 100644 testdata/result/statement/grant_on_all_tables_in_schema.sql.txt create mode 100644 testdata/result/statement/grant_on_all_views_in_schema.sql.txt create mode 100644 testdata/result/statement/revoke_on_all_change_streams_in_schema.sql.txt create mode 100644 testdata/result/statement/revoke_on_all_tables_in_schema.sql.txt create mode 100644 testdata/result/statement/revoke_on_all_views_in_schema.sql.txt diff --git a/ast/ast.go b/ast/ast.go index e4d774b3..5f048a7b 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -499,11 +499,14 @@ type Privilege interface { isPrivilege() } -func (PrivilegeOnTable) isPrivilege() {} -func (SelectPrivilegeOnChangeStream) isPrivilege() {} -func (SelectPrivilegeOnView) isPrivilege() {} -func (ExecutePrivilegeOnTableFunction) isPrivilege() {} -func (RolePrivilege) isPrivilege() {} +func (PrivilegeOnTable) isPrivilege() {} +func (PrivilegeOnAllTablesInSchema) isPrivilege() {} +func (SelectPrivilegeOnChangeStream) isPrivilege() {} +func (SelectPrivilegeOnAllChangeStreamsInSchema) isPrivilege() {} +func (SelectPrivilegeOnView) isPrivilege() {} +func (SelectPrivilegeOnAllViewsInSchema) isPrivilege() {} +func (ExecutePrivilegeOnTableFunction) isPrivilege() {} +func (RolePrivilege) isPrivilege() {} // TablePrivilege represents privileges on table. type TablePrivilege interface { @@ -3513,6 +3516,17 @@ type PrivilegeOnTable struct { Names []*Path // len(Names) > 0 } +// PrivilegeOnAllTablesInSchema is ON ALL TABLES IN SCHEMA privilege node in GRANT and REVOKE. +// +// {{.Privileges | sqlJoin ","}} ON ALL TABLES IN SCHEMA {{.Schemas | sqlJoin ", "}} +type PrivilegeOnAllTablesInSchema struct { + // pos = Privileges[0].pos + // end = Schemas[$].end + + Privileges []TablePrivilege // len(Privileges) > 0 + Schemas []*Path // len(Schemas) > 0 +} + // SelectPrivilege is SELECT ON TABLE privilege node in GRANT and REVOKE. // // SELECT{{if .Columns}}({{.Columns | sqlJoin ","}}){{end}} @@ -3574,6 +3588,18 @@ type SelectPrivilegeOnChangeStream struct { Names []*Path // len(Names) > 0 } +// SelectPrivilegeOnAllChangeStreamsInSchema is SELECT ON ALL CHANGE STREAMS IN SCHEMA privilege node in GRANT and REVOKE. +// +// SELECT ON ALL CHANGE STREAMS IN SCHEMA {{.Schemas | sqlJoin ", "}} +type SelectPrivilegeOnAllChangeStreamsInSchema struct { + // pos = Select + // end = Schemas[$].end + + Select token.Pos + + Schemas []*Path // len(Schemas) > 0 +} + // SelectPrivilegeOnView is SELECT ON VIEW privilege node in GRANT and REVOKE. // // SELECT ON VIEW {{.Names | sqlJoin ","}} @@ -3586,6 +3612,18 @@ type SelectPrivilegeOnView struct { Names []*Path // len(Names) > 0 } +// SelectPrivilegeOnAllViewsInSchema is SELECT ON ALL VIEWS IN SCHEMA privilege node in GRANT and REVOKE. +// +// SELECT ON ALL VIEWS IN SCHEMA {{.Schemas | sqlJoin ", "}} +type SelectPrivilegeOnAllViewsInSchema struct { + // pos = Select + // end = Schemas[$].end + + Select token.Pos + + Schemas []*Path // len(Schemas) > 0 +} + // ExecutePrivilegeOnTableFunction is EXECUTE ON TABLE FUNCTION privilege node in GRANT and REVOKE. // // EXECUTE ON TABLE FUNCTION {{.Names | sqlJoin ","}} diff --git a/ast/pos.go b/ast/pos.go index 12609ea7..a7105380 100644 --- a/ast/pos.go +++ b/ast/pos.go @@ -1726,6 +1726,14 @@ func (p *PrivilegeOnTable) End() token.Pos { return nodeEnd(nodeSliceLast(p.Names)) } +func (p *PrivilegeOnAllTablesInSchema) Pos() token.Pos { + return nodePos(nodeSliceIndex(p.Privileges, 0)) +} + +func (p *PrivilegeOnAllTablesInSchema) End() token.Pos { + return nodeEnd(nodeSliceLast(p.Schemas)) +} + func (s *SelectPrivilege) Pos() token.Pos { return s.Select } @@ -1766,6 +1774,14 @@ func (s *SelectPrivilegeOnChangeStream) End() token.Pos { return nodeEnd(nodeSliceLast(s.Names)) } +func (s *SelectPrivilegeOnAllChangeStreamsInSchema) Pos() token.Pos { + return s.Select +} + +func (s *SelectPrivilegeOnAllChangeStreamsInSchema) End() token.Pos { + return nodeEnd(nodeSliceLast(s.Schemas)) +} + func (s *SelectPrivilegeOnView) Pos() token.Pos { return s.Select } @@ -1774,6 +1790,14 @@ func (s *SelectPrivilegeOnView) End() token.Pos { return nodeEnd(nodeSliceLast(s.Names)) } +func (s *SelectPrivilegeOnAllViewsInSchema) Pos() token.Pos { + return s.Select +} + +func (s *SelectPrivilegeOnAllViewsInSchema) End() token.Pos { + return nodeEnd(nodeSliceLast(s.Schemas)) +} + func (e *ExecutePrivilegeOnTableFunction) Pos() token.Pos { return e.Execute } diff --git a/ast/sql.go b/ast/sql.go index 93260ae4..ef0a02eb 100644 --- a/ast/sql.go +++ b/ast/sql.go @@ -1126,6 +1126,10 @@ func (p *PrivilegeOnTable) SQL() string { return sqlJoin(p.Privileges, ", ") + " ON TABLE " + sqlJoin(p.Names, ", ") } +func (p *PrivilegeOnAllTablesInSchema) SQL() string { + return sqlJoin(p.Privileges, ", ") + " ON ALL TABLES IN SCHEMA " + sqlJoin(p.Schemas, ", ") +} + func (s *SelectPrivilege) SQL() string { return "SELECT" + strOpt(len(s.Columns) > 0, "("+sqlJoin(s.Columns, ", ")+")") @@ -1149,10 +1153,18 @@ func (p *SelectPrivilegeOnChangeStream) SQL() string { return "SELECT ON CHANGE STREAM " + sqlJoin(p.Names, ", ") } +func (p *SelectPrivilegeOnAllChangeStreamsInSchema) SQL() string { + return "SELECT ON ALL CHANGE STREAMS IN SCHEMA " + sqlJoin(p.Schemas, ", ") +} + func (s *SelectPrivilegeOnView) SQL() string { return "SELECT ON VIEW " + sqlJoin(s.Names, ", ") } +func (s *SelectPrivilegeOnAllViewsInSchema) SQL() string { + return "SELECT ON ALL VIEWS IN SCHEMA " + sqlJoin(s.Schemas, ", ") +} + func (e *ExecutePrivilegeOnTableFunction) SQL() string { return "EXECUTE ON TABLE FUNCTION " + sqlJoin(e.Names, ", ") } diff --git a/ast/walk_internal.go b/ast/walk_internal.go index 7a801297..c37d42fb 100644 --- a/ast/walk_internal.go +++ b/ast/walk_internal.go @@ -783,6 +783,10 @@ func walkInternal(node Node, v Visitor, stack []*stackItem) []*stackItem { stack = append(stack, &stackItem{nodes: wrapNodes(n.Names), visitor: v.Field("Names")}) stack = append(stack, &stackItem{nodes: wrapNodes(n.Privileges), visitor: v.Field("Privileges")}) + case *PrivilegeOnAllTablesInSchema: + stack = append(stack, &stackItem{nodes: wrapNodes(n.Schemas), visitor: v.Field("Schemas")}) + stack = append(stack, &stackItem{nodes: wrapNodes(n.Privileges), visitor: v.Field("Privileges")}) + case *SelectPrivilege: stack = append(stack, &stackItem{nodes: wrapNodes(n.Columns), visitor: v.Field("Columns")}) @@ -798,9 +802,15 @@ func walkInternal(node Node, v Visitor, stack []*stackItem) []*stackItem { case *SelectPrivilegeOnChangeStream: stack = append(stack, &stackItem{nodes: wrapNodes(n.Names), visitor: v.Field("Names")}) + case *SelectPrivilegeOnAllChangeStreamsInSchema: + stack = append(stack, &stackItem{nodes: wrapNodes(n.Schemas), visitor: v.Field("Schemas")}) + case *SelectPrivilegeOnView: stack = append(stack, &stackItem{nodes: wrapNodes(n.Names), visitor: v.Field("Names")}) + case *SelectPrivilegeOnAllViewsInSchema: + stack = append(stack, &stackItem{nodes: wrapNodes(n.Schemas), visitor: v.Field("Schemas")}) + case *ExecutePrivilegeOnTableFunction: stack = append(stack, &stackItem{nodes: wrapNodes(n.Names), visitor: v.Field("Names")}) diff --git a/parser.go b/parser.go index 416b4411..a923dc79 100644 --- a/parser.go +++ b/parser.go @@ -4846,6 +4846,9 @@ func (p *Parser) parseRevoke(pos token.Pos) *ast.Revoke { } func (p *Parser) parsePrivilege() ast.Privilege { + if s := p.tryParseSelectPrivilegeOnAllViewsInSchema(); s != nil { + return s + } if s := p.tryParseSelectPrivilegeOnView(); s != nil { return s } @@ -4855,12 +4858,48 @@ func (p *Parser) parsePrivilege() ast.Privilege { if r := p.tryParseRolePrivilege(); r != nil { return r } + if c := p.tryParseSelectPrivilegeOnAllChangeStreamsInSchema(); c != nil { + return c + } if c := p.tryParseSelectPrivilegeOnChangeStream(); c != nil { return c } + if t := p.tryParsePrivilegeOnAllTablesInSchema(); t != nil { + return t + } return p.parsePrivilegeOnTable() } +func (p *Parser) tryParseSelectPrivilegeOnAllViewsInSchema() *ast.SelectPrivilegeOnAllViewsInSchema { + if p.Token.Kind != "SELECT" { + return nil + } + lexer := p.Clone() + pos := p.expect("SELECT").Pos + if p.Token.Kind != "ON" { + p.Lexer = lexer + return nil + } + p.expect("ON") + if p.Token.Kind != "ALL" { + p.Lexer = lexer + return nil + } + p.expect("ALL") + if !p.Token.IsKeywordLike("VIEWS") { + p.Lexer = lexer + return nil + } + p.expectKeywordLike("VIEWS") + p.expect("IN") + p.expectKeywordLike("SCHEMA") + schemas := parseCommaSeparatedList(p, p.parsePath) + return &ast.SelectPrivilegeOnAllViewsInSchema{ + Select: pos, + Schemas: schemas, + } +} + func (p *Parser) tryParseSelectPrivilegeOnView() *ast.SelectPrivilegeOnView { if p.Token.Kind != "SELECT" { return nil @@ -4911,6 +4950,38 @@ func (p *Parser) tryParseRolePrivilege() *ast.RolePrivilege { } } +func (p *Parser) tryParseSelectPrivilegeOnAllChangeStreamsInSchema() *ast.SelectPrivilegeOnAllChangeStreamsInSchema { + if p.Token.Kind != "SELECT" { + return nil + } + lexer := p.Clone() + pos := p.expect("SELECT").Pos + if p.Token.Kind != "ON" { + p.Lexer = lexer + return nil + } + p.expect("ON") + if p.Token.Kind != "ALL" { + p.Lexer = lexer + return nil + } + p.expect("ALL") + if !p.Token.IsKeywordLike("CHANGE") { + p.Lexer = lexer + return nil + } + p.expectKeywordLike("CHANGE") + p.expectKeywordLike("STREAMS") + p.expect("IN") + p.expectKeywordLike("SCHEMA") + schemas := parseCommaSeparatedList(p, p.parsePath) + + return &ast.SelectPrivilegeOnAllChangeStreamsInSchema{ + Select: pos, + Schemas: schemas, + } +} + func (p *Parser) tryParseSelectPrivilegeOnChangeStream() *ast.SelectPrivilegeOnChangeStream { if p.Token.Kind != "SELECT" { return nil @@ -4936,6 +5007,33 @@ func (p *Parser) tryParseSelectPrivilegeOnChangeStream() *ast.SelectPrivilegeOnC } } +func (p *Parser) tryParsePrivilegeOnAllTablesInSchema() *ast.PrivilegeOnAllTablesInSchema { + lexer := p.Clone() + privileges := parseCommaSeparatedList(p, p.parseSchemaTablePrivilege) + if p.Token.Kind != "ON" { + p.Lexer = lexer + return nil + } + p.expect("ON") + if p.Token.Kind != "ALL" { + p.Lexer = lexer + return nil + } + p.expect("ALL") + if !p.Token.IsKeywordLike("TABLES") { + p.Lexer = lexer + return nil + } + p.expectKeywordLike("TABLES") + p.expect("IN") + p.expectKeywordLike("SCHEMA") + schemas := parseCommaSeparatedList(p, p.parsePath) + return &ast.PrivilegeOnAllTablesInSchema{ + Privileges: privileges, + Schemas: schemas, + } +} + func (p *Parser) parsePrivilegeOnTable() *ast.PrivilegeOnTable { privileges := parseCommaSeparatedList(p, p.parseTablePrivilege) p.expect("ON") @@ -4947,6 +5045,38 @@ func (p *Parser) parsePrivilegeOnTable() *ast.PrivilegeOnTable { } } +func (p *Parser) parseSchemaTablePrivilege() ast.TablePrivilege { + pos := p.Token.Pos + switch { + case p.Token.Kind == "SELECT": + p.nextToken() + return &ast.SelectPrivilege{ + Select: pos, + Rparen: token.InvalidPos, + } + case p.Token.IsKeywordLike("INSERT"): + p.nextToken() + return &ast.InsertPrivilege{ + Insert: pos, + Rparen: token.InvalidPos, + } + case p.Token.IsKeywordLike("UPDATE"): + p.nextToken() + return &ast.UpdatePrivilege{ + Update: pos, + Rparen: token.InvalidPos, + } + case p.Token.IsKeywordLike("DELETE"): + p.nextToken() + return &ast.DeletePrivilege{ + Delete: pos, + } + default: + p.panicfAtToken(&p.Token, "expected privilege token: SELECT, INSERT, UPDATE, DELETE, but: %s", p.Token.AsString) + return nil + } +} + func (p *Parser) parseTablePrivilege() ast.TablePrivilege { pos := p.Token.Pos switch { diff --git a/testdata/input/ddl/grant_on_all_change_streams_in_schema.sql b/testdata/input/ddl/grant_on_all_change_streams_in_schema.sql new file mode 100644 index 00000000..0f224a4d --- /dev/null +++ b/testdata/input/ddl/grant_on_all_change_streams_in_schema.sql @@ -0,0 +1 @@ +GRANT SELECT ON ALL CHANGE STREAMS IN SCHEMA sch TO ROLE r diff --git a/testdata/input/ddl/grant_on_all_tables_in_schema.sql b/testdata/input/ddl/grant_on_all_tables_in_schema.sql new file mode 100644 index 00000000..4dd0c43f --- /dev/null +++ b/testdata/input/ddl/grant_on_all_tables_in_schema.sql @@ -0,0 +1 @@ +GRANT SELECT, DELETE ON ALL TABLES IN SCHEMA sch1, sch2 TO ROLE r diff --git a/testdata/input/ddl/grant_on_all_views_in_schema.sql b/testdata/input/ddl/grant_on_all_views_in_schema.sql new file mode 100644 index 00000000..8d8bb251 --- /dev/null +++ b/testdata/input/ddl/grant_on_all_views_in_schema.sql @@ -0,0 +1 @@ +GRANT SELECT ON ALL VIEWS IN SCHEMA sch TO ROLE r diff --git a/testdata/input/ddl/revoke_on_all_change_streams_in_schema.sql b/testdata/input/ddl/revoke_on_all_change_streams_in_schema.sql new file mode 100644 index 00000000..0cbb625f --- /dev/null +++ b/testdata/input/ddl/revoke_on_all_change_streams_in_schema.sql @@ -0,0 +1 @@ +REVOKE SELECT ON ALL CHANGE STREAMS IN SCHEMA sch1, sch2 FROM ROLE r diff --git a/testdata/input/ddl/revoke_on_all_tables_in_schema.sql b/testdata/input/ddl/revoke_on_all_tables_in_schema.sql new file mode 100644 index 00000000..18b00e0f --- /dev/null +++ b/testdata/input/ddl/revoke_on_all_tables_in_schema.sql @@ -0,0 +1 @@ +REVOKE INSERT, UPDATE ON ALL TABLES IN SCHEMA db.sch FROM ROLE r diff --git a/testdata/input/ddl/revoke_on_all_views_in_schema.sql b/testdata/input/ddl/revoke_on_all_views_in_schema.sql new file mode 100644 index 00000000..0dd3a0d7 --- /dev/null +++ b/testdata/input/ddl/revoke_on_all_views_in_schema.sql @@ -0,0 +1 @@ +REVOKE SELECT ON ALL VIEWS IN SCHEMA db.sch FROM ROLE r diff --git a/testdata/result/ddl/grant_on_all_change_streams_in_schema.sql.txt b/testdata/result/ddl/grant_on_all_change_streams_in_schema.sql.txt new file mode 100644 index 00000000..7863f2c1 --- /dev/null +++ b/testdata/result/ddl/grant_on_all_change_streams_in_schema.sql.txt @@ -0,0 +1,30 @@ +--- grant_on_all_change_streams_in_schema.sql +GRANT SELECT ON ALL CHANGE STREAMS IN SCHEMA sch TO ROLE r + +--- AST +&ast.Grant{ + Privilege: &ast.SelectPrivilegeOnAllChangeStreamsInSchema{ + Select: 6, + Schemas: []*ast.Path{ + &ast.Path{ + Idents: []*ast.Ident{ + &ast.Ident{ + NamePos: 45, + NameEnd: 48, + Name: "sch", + }, + }, + }, + }, + }, + Roles: []*ast.Ident{ + &ast.Ident{ + NamePos: 57, + NameEnd: 58, + Name: "r", + }, + }, +} + +--- SQL +GRANT SELECT ON ALL CHANGE STREAMS IN SCHEMA sch TO ROLE r diff --git a/testdata/result/ddl/grant_on_all_tables_in_schema.sql.txt b/testdata/result/ddl/grant_on_all_tables_in_schema.sql.txt new file mode 100644 index 00000000..17e2b1e7 --- /dev/null +++ b/testdata/result/ddl/grant_on_all_tables_in_schema.sql.txt @@ -0,0 +1,47 @@ +--- grant_on_all_tables_in_schema.sql +GRANT SELECT, DELETE ON ALL TABLES IN SCHEMA sch1, sch2 TO ROLE r + +--- AST +&ast.Grant{ + Privilege: &ast.PrivilegeOnAllTablesInSchema{ + Privileges: []ast.TablePrivilege{ + &ast.SelectPrivilege{ + Select: 6, + Rparen: -1, + }, + &ast.DeletePrivilege{ + Delete: 14, + }, + }, + Schemas: []*ast.Path{ + &ast.Path{ + Idents: []*ast.Ident{ + &ast.Ident{ + NamePos: 45, + NameEnd: 49, + Name: "sch1", + }, + }, + }, + &ast.Path{ + Idents: []*ast.Ident{ + &ast.Ident{ + NamePos: 51, + NameEnd: 55, + Name: "sch2", + }, + }, + }, + }, + }, + Roles: []*ast.Ident{ + &ast.Ident{ + NamePos: 64, + NameEnd: 65, + Name: "r", + }, + }, +} + +--- SQL +GRANT SELECT, DELETE ON ALL TABLES IN SCHEMA sch1, sch2 TO ROLE r diff --git a/testdata/result/ddl/grant_on_all_views_in_schema.sql.txt b/testdata/result/ddl/grant_on_all_views_in_schema.sql.txt new file mode 100644 index 00000000..909329ea --- /dev/null +++ b/testdata/result/ddl/grant_on_all_views_in_schema.sql.txt @@ -0,0 +1,30 @@ +--- grant_on_all_views_in_schema.sql +GRANT SELECT ON ALL VIEWS IN SCHEMA sch TO ROLE r + +--- AST +&ast.Grant{ + Privilege: &ast.SelectPrivilegeOnAllViewsInSchema{ + Select: 6, + Schemas: []*ast.Path{ + &ast.Path{ + Idents: []*ast.Ident{ + &ast.Ident{ + NamePos: 36, + NameEnd: 39, + Name: "sch", + }, + }, + }, + }, + }, + Roles: []*ast.Ident{ + &ast.Ident{ + NamePos: 48, + NameEnd: 49, + Name: "r", + }, + }, +} + +--- SQL +GRANT SELECT ON ALL VIEWS IN SCHEMA sch TO ROLE r diff --git a/testdata/result/ddl/revoke_on_all_change_streams_in_schema.sql.txt b/testdata/result/ddl/revoke_on_all_change_streams_in_schema.sql.txt new file mode 100644 index 00000000..3c268154 --- /dev/null +++ b/testdata/result/ddl/revoke_on_all_change_streams_in_schema.sql.txt @@ -0,0 +1,39 @@ +--- revoke_on_all_change_streams_in_schema.sql +REVOKE SELECT ON ALL CHANGE STREAMS IN SCHEMA sch1, sch2 FROM ROLE r + +--- AST +&ast.Revoke{ + Privilege: &ast.SelectPrivilegeOnAllChangeStreamsInSchema{ + Select: 7, + Schemas: []*ast.Path{ + &ast.Path{ + Idents: []*ast.Ident{ + &ast.Ident{ + NamePos: 46, + NameEnd: 50, + Name: "sch1", + }, + }, + }, + &ast.Path{ + Idents: []*ast.Ident{ + &ast.Ident{ + NamePos: 52, + NameEnd: 56, + Name: "sch2", + }, + }, + }, + }, + }, + Roles: []*ast.Ident{ + &ast.Ident{ + NamePos: 67, + NameEnd: 68, + Name: "r", + }, + }, +} + +--- SQL +REVOKE SELECT ON ALL CHANGE STREAMS IN SCHEMA sch1, sch2 FROM ROLE r diff --git a/testdata/result/ddl/revoke_on_all_tables_in_schema.sql.txt b/testdata/result/ddl/revoke_on_all_tables_in_schema.sql.txt new file mode 100644 index 00000000..0d1f8024 --- /dev/null +++ b/testdata/result/ddl/revoke_on_all_tables_in_schema.sql.txt @@ -0,0 +1,44 @@ +--- revoke_on_all_tables_in_schema.sql +REVOKE INSERT, UPDATE ON ALL TABLES IN SCHEMA db.sch FROM ROLE r + +--- AST +&ast.Revoke{ + Privilege: &ast.PrivilegeOnAllTablesInSchema{ + Privileges: []ast.TablePrivilege{ + &ast.InsertPrivilege{ + Insert: 7, + Rparen: -1, + }, + &ast.UpdatePrivilege{ + Update: 15, + Rparen: -1, + }, + }, + Schemas: []*ast.Path{ + &ast.Path{ + Idents: []*ast.Ident{ + &ast.Ident{ + NamePos: 46, + NameEnd: 48, + Name: "db", + }, + &ast.Ident{ + NamePos: 49, + NameEnd: 52, + Name: "sch", + }, + }, + }, + }, + }, + Roles: []*ast.Ident{ + &ast.Ident{ + NamePos: 63, + NameEnd: 64, + Name: "r", + }, + }, +} + +--- SQL +REVOKE INSERT, UPDATE ON ALL TABLES IN SCHEMA db.sch FROM ROLE r diff --git a/testdata/result/ddl/revoke_on_all_views_in_schema.sql.txt b/testdata/result/ddl/revoke_on_all_views_in_schema.sql.txt new file mode 100644 index 00000000..cee7f7f0 --- /dev/null +++ b/testdata/result/ddl/revoke_on_all_views_in_schema.sql.txt @@ -0,0 +1,35 @@ +--- revoke_on_all_views_in_schema.sql +REVOKE SELECT ON ALL VIEWS IN SCHEMA db.sch FROM ROLE r + +--- AST +&ast.Revoke{ + Privilege: &ast.SelectPrivilegeOnAllViewsInSchema{ + Select: 7, + Schemas: []*ast.Path{ + &ast.Path{ + Idents: []*ast.Ident{ + &ast.Ident{ + NamePos: 37, + NameEnd: 39, + Name: "db", + }, + &ast.Ident{ + NamePos: 40, + NameEnd: 43, + Name: "sch", + }, + }, + }, + }, + }, + Roles: []*ast.Ident{ + &ast.Ident{ + NamePos: 54, + NameEnd: 55, + Name: "r", + }, + }, +} + +--- SQL +REVOKE SELECT ON ALL VIEWS IN SCHEMA db.sch FROM ROLE r diff --git a/testdata/result/statement/grant_on_all_change_streams_in_schema.sql.txt b/testdata/result/statement/grant_on_all_change_streams_in_schema.sql.txt new file mode 100644 index 00000000..7863f2c1 --- /dev/null +++ b/testdata/result/statement/grant_on_all_change_streams_in_schema.sql.txt @@ -0,0 +1,30 @@ +--- grant_on_all_change_streams_in_schema.sql +GRANT SELECT ON ALL CHANGE STREAMS IN SCHEMA sch TO ROLE r + +--- AST +&ast.Grant{ + Privilege: &ast.SelectPrivilegeOnAllChangeStreamsInSchema{ + Select: 6, + Schemas: []*ast.Path{ + &ast.Path{ + Idents: []*ast.Ident{ + &ast.Ident{ + NamePos: 45, + NameEnd: 48, + Name: "sch", + }, + }, + }, + }, + }, + Roles: []*ast.Ident{ + &ast.Ident{ + NamePos: 57, + NameEnd: 58, + Name: "r", + }, + }, +} + +--- SQL +GRANT SELECT ON ALL CHANGE STREAMS IN SCHEMA sch TO ROLE r diff --git a/testdata/result/statement/grant_on_all_tables_in_schema.sql.txt b/testdata/result/statement/grant_on_all_tables_in_schema.sql.txt new file mode 100644 index 00000000..17e2b1e7 --- /dev/null +++ b/testdata/result/statement/grant_on_all_tables_in_schema.sql.txt @@ -0,0 +1,47 @@ +--- grant_on_all_tables_in_schema.sql +GRANT SELECT, DELETE ON ALL TABLES IN SCHEMA sch1, sch2 TO ROLE r + +--- AST +&ast.Grant{ + Privilege: &ast.PrivilegeOnAllTablesInSchema{ + Privileges: []ast.TablePrivilege{ + &ast.SelectPrivilege{ + Select: 6, + Rparen: -1, + }, + &ast.DeletePrivilege{ + Delete: 14, + }, + }, + Schemas: []*ast.Path{ + &ast.Path{ + Idents: []*ast.Ident{ + &ast.Ident{ + NamePos: 45, + NameEnd: 49, + Name: "sch1", + }, + }, + }, + &ast.Path{ + Idents: []*ast.Ident{ + &ast.Ident{ + NamePos: 51, + NameEnd: 55, + Name: "sch2", + }, + }, + }, + }, + }, + Roles: []*ast.Ident{ + &ast.Ident{ + NamePos: 64, + NameEnd: 65, + Name: "r", + }, + }, +} + +--- SQL +GRANT SELECT, DELETE ON ALL TABLES IN SCHEMA sch1, sch2 TO ROLE r diff --git a/testdata/result/statement/grant_on_all_views_in_schema.sql.txt b/testdata/result/statement/grant_on_all_views_in_schema.sql.txt new file mode 100644 index 00000000..909329ea --- /dev/null +++ b/testdata/result/statement/grant_on_all_views_in_schema.sql.txt @@ -0,0 +1,30 @@ +--- grant_on_all_views_in_schema.sql +GRANT SELECT ON ALL VIEWS IN SCHEMA sch TO ROLE r + +--- AST +&ast.Grant{ + Privilege: &ast.SelectPrivilegeOnAllViewsInSchema{ + Select: 6, + Schemas: []*ast.Path{ + &ast.Path{ + Idents: []*ast.Ident{ + &ast.Ident{ + NamePos: 36, + NameEnd: 39, + Name: "sch", + }, + }, + }, + }, + }, + Roles: []*ast.Ident{ + &ast.Ident{ + NamePos: 48, + NameEnd: 49, + Name: "r", + }, + }, +} + +--- SQL +GRANT SELECT ON ALL VIEWS IN SCHEMA sch TO ROLE r diff --git a/testdata/result/statement/revoke_on_all_change_streams_in_schema.sql.txt b/testdata/result/statement/revoke_on_all_change_streams_in_schema.sql.txt new file mode 100644 index 00000000..3c268154 --- /dev/null +++ b/testdata/result/statement/revoke_on_all_change_streams_in_schema.sql.txt @@ -0,0 +1,39 @@ +--- revoke_on_all_change_streams_in_schema.sql +REVOKE SELECT ON ALL CHANGE STREAMS IN SCHEMA sch1, sch2 FROM ROLE r + +--- AST +&ast.Revoke{ + Privilege: &ast.SelectPrivilegeOnAllChangeStreamsInSchema{ + Select: 7, + Schemas: []*ast.Path{ + &ast.Path{ + Idents: []*ast.Ident{ + &ast.Ident{ + NamePos: 46, + NameEnd: 50, + Name: "sch1", + }, + }, + }, + &ast.Path{ + Idents: []*ast.Ident{ + &ast.Ident{ + NamePos: 52, + NameEnd: 56, + Name: "sch2", + }, + }, + }, + }, + }, + Roles: []*ast.Ident{ + &ast.Ident{ + NamePos: 67, + NameEnd: 68, + Name: "r", + }, + }, +} + +--- SQL +REVOKE SELECT ON ALL CHANGE STREAMS IN SCHEMA sch1, sch2 FROM ROLE r diff --git a/testdata/result/statement/revoke_on_all_tables_in_schema.sql.txt b/testdata/result/statement/revoke_on_all_tables_in_schema.sql.txt new file mode 100644 index 00000000..0d1f8024 --- /dev/null +++ b/testdata/result/statement/revoke_on_all_tables_in_schema.sql.txt @@ -0,0 +1,44 @@ +--- revoke_on_all_tables_in_schema.sql +REVOKE INSERT, UPDATE ON ALL TABLES IN SCHEMA db.sch FROM ROLE r + +--- AST +&ast.Revoke{ + Privilege: &ast.PrivilegeOnAllTablesInSchema{ + Privileges: []ast.TablePrivilege{ + &ast.InsertPrivilege{ + Insert: 7, + Rparen: -1, + }, + &ast.UpdatePrivilege{ + Update: 15, + Rparen: -1, + }, + }, + Schemas: []*ast.Path{ + &ast.Path{ + Idents: []*ast.Ident{ + &ast.Ident{ + NamePos: 46, + NameEnd: 48, + Name: "db", + }, + &ast.Ident{ + NamePos: 49, + NameEnd: 52, + Name: "sch", + }, + }, + }, + }, + }, + Roles: []*ast.Ident{ + &ast.Ident{ + NamePos: 63, + NameEnd: 64, + Name: "r", + }, + }, +} + +--- SQL +REVOKE INSERT, UPDATE ON ALL TABLES IN SCHEMA db.sch FROM ROLE r diff --git a/testdata/result/statement/revoke_on_all_views_in_schema.sql.txt b/testdata/result/statement/revoke_on_all_views_in_schema.sql.txt new file mode 100644 index 00000000..cee7f7f0 --- /dev/null +++ b/testdata/result/statement/revoke_on_all_views_in_schema.sql.txt @@ -0,0 +1,35 @@ +--- revoke_on_all_views_in_schema.sql +REVOKE SELECT ON ALL VIEWS IN SCHEMA db.sch FROM ROLE r + +--- AST +&ast.Revoke{ + Privilege: &ast.SelectPrivilegeOnAllViewsInSchema{ + Select: 7, + Schemas: []*ast.Path{ + &ast.Path{ + Idents: []*ast.Ident{ + &ast.Ident{ + NamePos: 37, + NameEnd: 39, + Name: "db", + }, + &ast.Ident{ + NamePos: 40, + NameEnd: 43, + Name: "sch", + }, + }, + }, + }, + }, + Roles: []*ast.Ident{ + &ast.Ident{ + NamePos: 54, + NameEnd: 55, + Name: "r", + }, + }, +} + +--- SQL +REVOKE SELECT ON ALL VIEWS IN SCHEMA db.sch FROM ROLE r