@@ -131,6 +131,10 @@ func (p *Parser) parseStatement() ast.Statement {
131131 if p .peek .Token == token .IDENT && strings .ToUpper (p .peek .Value ) == "PROFILE" {
132132 return p .parseDropSettingsProfile ()
133133 }
134+ // Check for DROP ROW POLICY or DROP POLICY
135+ if p .peek .Token == token .IDENT && (strings .ToUpper (p .peek .Value ) == "ROW" || strings .ToUpper (p .peek .Value ) == "POLICY" ) {
136+ return p .parseDropRowPolicy ()
137+ }
134138 return p .parseDrop ()
135139 case token .ALTER :
136140 // Check for ALTER USER
@@ -145,6 +149,10 @@ func (p *Parser) parseStatement() ast.Statement {
145149 if p .peek .Token == token .IDENT && strings .ToUpper (p .peek .Value ) == "PROFILE" {
146150 return p .parseAlterSettingsProfile ()
147151 }
152+ // Check for ALTER ROW POLICY or ALTER POLICY
153+ if p .peek .Token == token .IDENT && (strings .ToUpper (p .peek .Value ) == "ROW" || strings .ToUpper (p .peek .Value ) == "POLICY" ) {
154+ return p .parseAlterRowPolicy ()
155+ }
148156 return p .parseAlter ()
149157 case token .TRUNCATE :
150158 return p .parseTruncate ()
@@ -1352,7 +1360,13 @@ func (p *Parser) parseCreate() ast.Statement {
13521360 case "PROFILE" :
13531361 // CREATE PROFILE (without SETTINGS keyword)
13541362 return p .parseCreateSettingsProfile (pos )
1355- case "RESOURCE" , "WORKLOAD" , "POLICY" , "ROLE" , "QUOTA" :
1363+ case "ROW" :
1364+ // CREATE ROW POLICY
1365+ return p .parseCreateRowPolicy (pos )
1366+ case "POLICY" :
1367+ // CREATE POLICY (without ROW keyword)
1368+ return p .parseCreateRowPolicy (pos )
1369+ case "RESOURCE" , "WORKLOAD" , "ROLE" , "QUOTA" :
13561370 // Skip these statements - just consume tokens until semicolon
13571371 p .parseCreateGeneric (create )
13581372 default :
@@ -2064,6 +2078,112 @@ func (p *Parser) parseShowCreateSettingsProfile(pos token.Position) *ast.ShowCre
20642078 return query
20652079}
20662080
2081+ func (p * Parser ) parseCreateRowPolicy (pos token.Position ) * ast.CreateRowPolicyQuery {
2082+ query := & ast.CreateRowPolicyQuery {
2083+ Position : pos ,
2084+ }
2085+
2086+ // Skip ROW if present (CREATE ROW POLICY vs CREATE POLICY)
2087+ if p .currentIs (token .IDENT ) && strings .ToUpper (p .current .Value ) == "ROW" {
2088+ p .nextToken ()
2089+ }
2090+
2091+ // Skip POLICY
2092+ if p .currentIs (token .IDENT ) && strings .ToUpper (p .current .Value ) == "POLICY" {
2093+ p .nextToken ()
2094+ }
2095+
2096+ // Skip the rest of the statement (policy names, ON table, etc.)
2097+ for ! p .currentIs (token .EOF ) && ! p .currentIs (token .SEMICOLON ) {
2098+ p .nextToken ()
2099+ }
2100+
2101+ return query
2102+ }
2103+
2104+ func (p * Parser ) parseDropRowPolicy () * ast.DropRowPolicyQuery {
2105+ query := & ast.DropRowPolicyQuery {
2106+ Position : p .current .Pos ,
2107+ }
2108+
2109+ p .nextToken () // skip DROP
2110+
2111+ // Skip ROW if present (DROP ROW POLICY vs DROP POLICY)
2112+ if p .currentIs (token .IDENT ) && strings .ToUpper (p .current .Value ) == "ROW" {
2113+ p .nextToken ()
2114+ }
2115+
2116+ // Skip POLICY
2117+ if p .currentIs (token .IDENT ) && strings .ToUpper (p .current .Value ) == "POLICY" {
2118+ p .nextToken ()
2119+ }
2120+
2121+ // Handle IF EXISTS
2122+ if p .currentIs (token .IF ) {
2123+ p .nextToken ()
2124+ if p .currentIs (token .EXISTS ) {
2125+ query .IfExists = true
2126+ p .nextToken ()
2127+ }
2128+ }
2129+
2130+ // Skip the rest of the statement (policy names, ON table, etc.)
2131+ for ! p .currentIs (token .EOF ) && ! p .currentIs (token .SEMICOLON ) {
2132+ p .nextToken ()
2133+ }
2134+
2135+ return query
2136+ }
2137+
2138+ func (p * Parser ) parseAlterRowPolicy () * ast.CreateRowPolicyQuery {
2139+ query := & ast.CreateRowPolicyQuery {
2140+ Position : p .current .Pos ,
2141+ IsAlter : true ,
2142+ }
2143+
2144+ p .nextToken () // skip ALTER
2145+
2146+ // Skip ROW if present (ALTER ROW POLICY vs ALTER POLICY)
2147+ if p .currentIs (token .IDENT ) && strings .ToUpper (p .current .Value ) == "ROW" {
2148+ p .nextToken ()
2149+ }
2150+
2151+ // Skip POLICY
2152+ if p .currentIs (token .IDENT ) && strings .ToUpper (p .current .Value ) == "POLICY" {
2153+ p .nextToken ()
2154+ }
2155+
2156+ // Skip the rest of the statement (policy names, ON table, etc.)
2157+ for ! p .currentIs (token .EOF ) && ! p .currentIs (token .SEMICOLON ) {
2158+ p .nextToken ()
2159+ }
2160+
2161+ return query
2162+ }
2163+
2164+ func (p * Parser ) parseShowCreateRowPolicy (pos token.Position ) * ast.ShowCreateRowPolicyQuery {
2165+ query := & ast.ShowCreateRowPolicyQuery {
2166+ Position : pos ,
2167+ }
2168+
2169+ // Skip ROW if present (SHOW CREATE ROW POLICY vs SHOW CREATE POLICY)
2170+ if p .currentIs (token .IDENT ) && strings .ToUpper (p .current .Value ) == "ROW" {
2171+ p .nextToken ()
2172+ }
2173+
2174+ // Skip POLICY
2175+ if p .currentIs (token .IDENT ) && strings .ToUpper (p .current .Value ) == "POLICY" {
2176+ p .nextToken ()
2177+ }
2178+
2179+ // Skip the rest of the statement (policy names, ON table, etc.)
2180+ for ! p .currentIs (token .EOF ) && ! p .currentIs (token .SEMICOLON ) {
2181+ p .nextToken ()
2182+ }
2183+
2184+ return query
2185+ }
2186+
20672187func (p * Parser ) parseCreateDictionary (create * ast.CreateQuery ) {
20682188 // Handle IF NOT EXISTS
20692189 if p .currentIs (token .IF ) {
@@ -3717,6 +3837,9 @@ func (p *Parser) parseShow() ast.Statement {
37173837 } else if p .currentIs (token .SETTINGS ) || (p .currentIs (token .IDENT ) && strings .ToUpper (p .current .Value ) == "PROFILE" ) {
37183838 // SHOW CREATE SETTINGS PROFILE or SHOW CREATE PROFILE
37193839 return p .parseShowCreateSettingsProfile (pos )
3840+ } else if p .currentIs (token .IDENT ) && (strings .ToUpper (p .current .Value ) == "ROW" || strings .ToUpper (p .current .Value ) == "POLICY" ) {
3841+ // SHOW CREATE ROW POLICY or SHOW CREATE POLICY
3842+ return p .parseShowCreateRowPolicy (pos )
37203843 } else if p .currentIs (token .IDENT ) && strings .ToUpper (p .current .Value ) == "DICTIONARY" {
37213844 show .ShowType = ast .ShowCreateDictionary
37223845 p .nextToken ()
0 commit comments