Skip to content

Commit e725593

Browse files
kyleconroyclaude
andcommitted
Add CREATE/ALTER SECURITY POLICY statement support
- Add SecurityPolicyStatement, SecurityPolicyOption, SecurityPredicateAction AST types - Implement parseCreateSecurityPolicyStatement and parseAlterSecurityPolicyStatement - Add marshaling functions with correct ActionType handling (AlterState, AlterReplication, AlterPredicates) - Handle comma-separated predicate actions and NOT FOR REPLICATION clauses - Enable CreateAlterSecurityPolicyStatementTests130 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent a5c42aa commit e725593

6 files changed

Lines changed: 510 additions & 2 deletions

File tree

ast/security_policy_statement.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package ast
2+
3+
// CreateSecurityPolicyStatement represents CREATE SECURITY POLICY
4+
type CreateSecurityPolicyStatement struct {
5+
Name *SchemaObjectName
6+
NotForReplication bool
7+
SecurityPolicyOptions []*SecurityPolicyOption
8+
SecurityPredicateActions []*SecurityPredicateAction
9+
ActionType string // "Create"
10+
}
11+
12+
func (s *CreateSecurityPolicyStatement) node() {}
13+
func (s *CreateSecurityPolicyStatement) statement() {}
14+
15+
// AlterSecurityPolicyStatement represents ALTER SECURITY POLICY
16+
type AlterSecurityPolicyStatement struct {
17+
Name *SchemaObjectName
18+
NotForReplication bool
19+
NotForReplicationModified bool // tracks if NOT FOR REPLICATION was changed
20+
SecurityPolicyOptions []*SecurityPolicyOption
21+
SecurityPredicateActions []*SecurityPredicateAction
22+
ActionType string // "Alter"
23+
}
24+
25+
func (s *AlterSecurityPolicyStatement) node() {}
26+
func (s *AlterSecurityPolicyStatement) statement() {}
27+
28+
// SecurityPolicyOption represents an option like STATE=ON, SCHEMABINDING=OFF
29+
type SecurityPolicyOption struct {
30+
OptionKind string // "State" or "SchemaBinding"
31+
OptionState string // "On" or "Off"
32+
}
33+
34+
func (o *SecurityPolicyOption) node() {}
35+
36+
// SecurityPredicateAction represents ADD/DROP/ALTER FILTER/BLOCK PREDICATE
37+
type SecurityPredicateAction struct {
38+
ActionType string // "Create", "Drop", "Alter"
39+
SecurityPredicateType string // "Filter" or "Block"
40+
FunctionCall *FunctionCall
41+
TargetObjectName *SchemaObjectName
42+
SecurityPredicateOperation string // "All", "AfterInsert", "AfterUpdate", "BeforeUpdate", "BeforeDelete"
43+
}
44+
45+
func (a *SecurityPredicateAction) node() {}

parser/marshal.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,10 @@ func statementToJSON(stmt ast.Statement) jsonNode {
521521
return createPartitionFunctionStatementToJSON(s)
522522
case *ast.CreateEventNotificationStatement:
523523
return createEventNotificationStatementToJSON(s)
524+
case *ast.CreateSecurityPolicyStatement:
525+
return createSecurityPolicyStatementToJSON(s)
526+
case *ast.AlterSecurityPolicyStatement:
527+
return alterSecurityPolicyStatementToJSON(s)
524528
case *ast.AlterIndexStatement:
525529
return alterIndexStatementToJSON(s)
526530
case *ast.DropDatabaseStatement:
@@ -20324,3 +20328,89 @@ func openRowsetColumnDefinitionToJSON(col *ast.OpenRowsetColumnDefinition) jsonN
2032420328
}
2032520329
return node
2032620330
}
20331+
20332+
func createSecurityPolicyStatementToJSON(s *ast.CreateSecurityPolicyStatement) jsonNode {
20333+
node := jsonNode{
20334+
"$type": "CreateSecurityPolicyStatement",
20335+
"NotForReplication": s.NotForReplication,
20336+
"ActionType": s.ActionType,
20337+
}
20338+
if s.Name != nil {
20339+
node["Name"] = schemaObjectNameToJSON(s.Name)
20340+
}
20341+
if len(s.SecurityPolicyOptions) > 0 {
20342+
opts := make([]jsonNode, len(s.SecurityPolicyOptions))
20343+
for i, opt := range s.SecurityPolicyOptions {
20344+
opts[i] = securityPolicyOptionToJSON(opt)
20345+
}
20346+
node["SecurityPolicyOptions"] = opts
20347+
}
20348+
if len(s.SecurityPredicateActions) > 0 {
20349+
actions := make([]jsonNode, len(s.SecurityPredicateActions))
20350+
for i, action := range s.SecurityPredicateActions {
20351+
actions[i] = securityPredicateActionToJSON(action)
20352+
}
20353+
node["SecurityPredicateActions"] = actions
20354+
}
20355+
return node
20356+
}
20357+
20358+
func alterSecurityPolicyStatementToJSON(s *ast.AlterSecurityPolicyStatement) jsonNode {
20359+
// Determine ActionType based on statement contents
20360+
actionType := "Alter"
20361+
if len(s.SecurityPredicateActions) > 0 {
20362+
actionType = "AlterPredicates"
20363+
} else if len(s.SecurityPolicyOptions) > 0 {
20364+
actionType = "AlterState"
20365+
} else if s.NotForReplicationModified {
20366+
actionType = "AlterReplication"
20367+
}
20368+
20369+
node := jsonNode{
20370+
"$type": "AlterSecurityPolicyStatement",
20371+
"NotForReplication": s.NotForReplication,
20372+
"ActionType": actionType,
20373+
}
20374+
if s.Name != nil {
20375+
node["Name"] = schemaObjectNameToJSON(s.Name)
20376+
}
20377+
if len(s.SecurityPolicyOptions) > 0 {
20378+
opts := make([]jsonNode, len(s.SecurityPolicyOptions))
20379+
for i, opt := range s.SecurityPolicyOptions {
20380+
opts[i] = securityPolicyOptionToJSON(opt)
20381+
}
20382+
node["SecurityPolicyOptions"] = opts
20383+
}
20384+
if len(s.SecurityPredicateActions) > 0 {
20385+
actions := make([]jsonNode, len(s.SecurityPredicateActions))
20386+
for i, action := range s.SecurityPredicateActions {
20387+
actions[i] = securityPredicateActionToJSON(action)
20388+
}
20389+
node["SecurityPredicateActions"] = actions
20390+
}
20391+
return node
20392+
}
20393+
20394+
func securityPolicyOptionToJSON(opt *ast.SecurityPolicyOption) jsonNode {
20395+
return jsonNode{
20396+
"$type": "SecurityPolicyOption",
20397+
"OptionKind": opt.OptionKind,
20398+
"OptionState": opt.OptionState,
20399+
}
20400+
}
20401+
20402+
func securityPredicateActionToJSON(action *ast.SecurityPredicateAction) jsonNode {
20403+
node := jsonNode{
20404+
"$type": "SecurityPredicateAction",
20405+
"ActionType": action.ActionType,
20406+
"SecurityPredicateType": action.SecurityPredicateType,
20407+
"SecurityPredicateOperation": action.SecurityPredicateOperation,
20408+
}
20409+
if action.FunctionCall != nil {
20410+
node["FunctionCall"] = scalarExpressionToJSON(action.FunctionCall)
20411+
}
20412+
if action.TargetObjectName != nil {
20413+
node["TargetObjectName"] = schemaObjectNameToJSON(action.TargetObjectName)
20414+
}
20415+
return node
20416+
}

0 commit comments

Comments
 (0)