Skip to content

Commit 5dee3d2

Browse files
committed
Add full GRANT/REVOKE/DENY security statement support
- Add AsClause field to GrantStatement for AS identifier clause - Add TokenAll, TokenDefault, TokenTrigger, TokenSchema to permission parsing - Add column list parsing for permissions (e.g., SELECT (c1, c2)) - Synchronize permission token handling across GRANT, REVOKE, DENY parsers - Update grantStatementToJSON to marshal AsClause field - Enables 3 tests: SecurityStatement80Tests, Baselines80_*, Baselines90_*
1 parent 87e2f88 commit 5dee3d2

5 files changed

Lines changed: 63 additions & 13 deletions

File tree

ast/grant_statement.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ type GrantStatement struct {
66
Principals []*SecurityPrincipal
77
WithGrantOption bool
88
SecurityTargetObject *SecurityTargetObject
9+
AsClause *Identifier
910
}
1011

1112
func (s *GrantStatement) node() {}

parser/marshal.go

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5886,12 +5886,32 @@ func (p *Parser) parseGrantStatement() (*ast.GrantStatement, error) {
58865886
p.curTok.Type == TokenSelect || p.curTok.Type == TokenInsert ||
58875887
p.curTok.Type == TokenUpdate || p.curTok.Type == TokenDelete ||
58885888
p.curTok.Type == TokenAlter || p.curTok.Type == TokenExecute ||
5889-
p.curTok.Type == TokenDrop || p.curTok.Type == TokenExternal {
5889+
p.curTok.Type == TokenDrop || p.curTok.Type == TokenExternal ||
5890+
p.curTok.Type == TokenAll || p.curTok.Type == TokenExec ||
5891+
p.curTok.Type == TokenDatabase || p.curTok.Type == TokenTable ||
5892+
p.curTok.Type == TokenFunction || p.curTok.Type == TokenBackup ||
5893+
p.curTok.Type == TokenDefault || p.curTok.Type == TokenTrigger ||
5894+
p.curTok.Type == TokenSchema {
58905895
perm.Identifiers = append(perm.Identifiers, &ast.Identifier{
58915896
Value: p.curTok.Literal,
58925897
QuoteType: "NotQuoted",
58935898
})
58945899
p.nextToken()
5900+
} else if p.curTok.Type == TokenLParen {
5901+
// Column list for permission (e.g., SELECT (c1, c2))
5902+
p.nextToken() // consume (
5903+
for p.curTok.Type != TokenRParen && p.curTok.Type != TokenEOF {
5904+
col := p.parseIdentifier()
5905+
perm.Columns = append(perm.Columns, col)
5906+
if p.curTok.Type == TokenComma {
5907+
p.nextToken()
5908+
} else {
5909+
break
5910+
}
5911+
}
5912+
if p.curTok.Type == TokenRParen {
5913+
p.nextToken() // consume )
5914+
}
58955915
} else if p.curTok.Type == TokenComma {
58965916
stmt.Permissions = append(stmt.Permissions, perm)
58975917
perm = &ast.Permission{}
@@ -6118,6 +6138,12 @@ func (p *Parser) parseGrantStatement() (*ast.GrantStatement, error) {
61186138
stmt.WithGrantOption = true
61196139
}
61206140

6141+
// Check for AS clause
6142+
if strings.ToUpper(p.curTok.Literal) == "AS" {
6143+
p.nextToken() // consume AS
6144+
stmt.AsClause = p.parseIdentifier()
6145+
}
6146+
61216147
// Skip optional semicolon
61226148
if p.curTok.Type == TokenSemicolon {
61236149
p.nextToken()
@@ -6153,7 +6179,11 @@ func (p *Parser) parseRevokeStatement() (*ast.RevokeStatement, error) {
61536179
p.curTok.Type == TokenUpdate || p.curTok.Type == TokenDelete ||
61546180
p.curTok.Type == TokenAlter || p.curTok.Type == TokenExecute ||
61556181
p.curTok.Type == TokenDrop || p.curTok.Type == TokenExternal ||
6156-
p.curTok.Type == TokenAll {
6182+
p.curTok.Type == TokenAll || p.curTok.Type == TokenExec ||
6183+
p.curTok.Type == TokenDatabase || p.curTok.Type == TokenTable ||
6184+
p.curTok.Type == TokenFunction || p.curTok.Type == TokenBackup ||
6185+
p.curTok.Type == TokenDefault || p.curTok.Type == TokenTrigger ||
6186+
p.curTok.Type == TokenSchema {
61576187
perm.Identifiers = append(perm.Identifiers, &ast.Identifier{
61586188
Value: p.curTok.Literal,
61596189
QuoteType: "NotQuoted",
@@ -6163,13 +6193,9 @@ func (p *Parser) parseRevokeStatement() (*ast.RevokeStatement, error) {
61636193
// Parse column list for permission
61646194
p.nextToken() // consume (
61656195
for p.curTok.Type != TokenRParen && p.curTok.Type != TokenEOF {
6166-
if p.curTok.Type == TokenIdent {
6167-
perm.Columns = append(perm.Columns, &ast.Identifier{
6168-
Value: p.curTok.Literal,
6169-
QuoteType: "NotQuoted",
6170-
})
6171-
p.nextToken()
6172-
} else if p.curTok.Type == TokenComma {
6196+
col := p.parseIdentifier()
6197+
perm.Columns = append(perm.Columns, col)
6198+
if p.curTok.Type == TokenComma {
61736199
p.nextToken()
61746200
} else {
61756201
break
@@ -6424,12 +6450,32 @@ func (p *Parser) parseDenyStatement() (*ast.DenyStatement, error) {
64246450
p.curTok.Type == TokenSelect || p.curTok.Type == TokenInsert ||
64256451
p.curTok.Type == TokenUpdate || p.curTok.Type == TokenDelete ||
64266452
p.curTok.Type == TokenAlter || p.curTok.Type == TokenExecute ||
6427-
p.curTok.Type == TokenDrop || p.curTok.Type == TokenExternal {
6453+
p.curTok.Type == TokenDrop || p.curTok.Type == TokenExternal ||
6454+
p.curTok.Type == TokenAll || p.curTok.Type == TokenExec ||
6455+
p.curTok.Type == TokenDatabase || p.curTok.Type == TokenTable ||
6456+
p.curTok.Type == TokenFunction || p.curTok.Type == TokenBackup ||
6457+
p.curTok.Type == TokenDefault || p.curTok.Type == TokenTrigger ||
6458+
p.curTok.Type == TokenSchema {
64286459
perm.Identifiers = append(perm.Identifiers, &ast.Identifier{
64296460
Value: p.curTok.Literal,
64306461
QuoteType: "NotQuoted",
64316462
})
64326463
p.nextToken()
6464+
} else if p.curTok.Type == TokenLParen {
6465+
// Column list for permission (e.g., SELECT (c1, c2))
6466+
p.nextToken() // consume (
6467+
for p.curTok.Type != TokenRParen && p.curTok.Type != TokenEOF {
6468+
col := p.parseIdentifier()
6469+
perm.Columns = append(perm.Columns, col)
6470+
if p.curTok.Type == TokenComma {
6471+
p.nextToken()
6472+
} else {
6473+
break
6474+
}
6475+
}
6476+
if p.curTok.Type == TokenRParen {
6477+
p.nextToken() // consume )
6478+
}
64336479
} else if p.curTok.Type == TokenComma {
64346480
stmt.Permissions = append(stmt.Permissions, perm)
64356481
perm = &ast.Permission{}
@@ -7151,6 +7197,9 @@ func grantStatementToJSON(s *ast.GrantStatement) jsonNode {
71517197
}
71527198
node["Principals"] = principals
71537199
}
7200+
if s.AsClause != nil {
7201+
node["AsClause"] = identifierToJSON(s.AsClause)
7202+
}
71547203
return node
71557204
}
71567205

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo": true}
1+
{}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo": true}
1+
{}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo": true}
1+
{}

0 commit comments

Comments
 (0)