@@ -996,6 +996,9 @@ func (p *parser) parseDDLStmt() (DDLStmt, *parseError) {
996996 } else if p .sniff ("CREATE" , "VIEW" ) || p .sniff ("CREATE" , "OR" , "REPLACE" , "VIEW" ) {
997997 cv , err := p .parseCreateView ()
998998 return cv , err
999+ } else if p .sniff ("CREATE" , "ROLE" ) {
1000+ cr , err := p .parseCreateRole ()
1001+ return cr , err
9991002 } else if p .sniff ("ALTER" , "TABLE" ) {
10001003 a , err := p .parseAlterTable ()
10011004 return a , err
@@ -1005,6 +1008,7 @@ func (p *parser) parseDDLStmt() (DDLStmt, *parseError) {
10051008 // DROP TABLE table_name
10061009 // DROP INDEX index_name
10071010 // DROP VIEW view_name
1011+ // DROP ROLE role_name
10081012 // DROP CHANGE STREAM change_stream_name
10091013 tok := p .next ()
10101014 if tok .err != nil {
@@ -1031,6 +1035,12 @@ func (p *parser) parseDDLStmt() (DDLStmt, *parseError) {
10311035 return nil , err
10321036 }
10331037 return & DropView {Name : name , Position : pos }, nil
1038+ case tok .caseEqual ("ROLE" ):
1039+ name , err := p .parseTableOrIndexOrColumnName ()
1040+ if err != nil {
1041+ return nil , err
1042+ }
1043+ return & DropRole {Name : name , Position : pos }, nil
10341044 case tok .caseEqual ("CHANGE" ):
10351045 if err := p .expect ("STREAM" ); err != nil {
10361046 return nil , err
@@ -1044,6 +1054,12 @@ func (p *parser) parseDDLStmt() (DDLStmt, *parseError) {
10441054 } else if p .sniff ("ALTER" , "DATABASE" ) {
10451055 a , err := p .parseAlterDatabase ()
10461056 return a , err
1057+ } else if p .eat ("GRANT" ) {
1058+ a , err := p .parseGrantRole ()
1059+ return a , err
1060+ } else if p .eat ("REVOKE" ) {
1061+ a , err := p .parseRevokeRole ()
1062+ return a , err
10471063 } else if p .sniff ("CREATE" , "CHANGE" , "STREAM" ) {
10481064 cs , err := p .parseCreateChangeStream ()
10491065 return cs , err
@@ -1297,6 +1313,176 @@ func (p *parser) parseCreateView() (*CreateView, *parseError) {
12971313 }, nil
12981314}
12991315
1316+ func (p * parser ) parseCreateRole () (* CreateRole , * parseError ) {
1317+ debugf ("parseCreateRole: %v" , p )
1318+
1319+ /*
1320+ CREATE ROLE database_role_name
1321+ */
1322+
1323+ if err := p .expect ("CREATE" ); err != nil {
1324+ return nil , err
1325+ }
1326+ pos := p .Pos ()
1327+ if err := p .expect ("ROLE" ); err != nil {
1328+ return nil , err
1329+ }
1330+ rname , err := p .parseTableOrIndexOrColumnName ()
1331+ if err != nil {
1332+ return nil , err
1333+ }
1334+ cr := & CreateRole {
1335+ Name : rname ,
1336+
1337+ Position : pos ,
1338+ }
1339+
1340+ return cr , nil
1341+ }
1342+
1343+ func (p * parser ) parseGrantRole () (* GrantRole , * parseError ) {
1344+ pos := p .Pos ()
1345+ g := & GrantRole {
1346+ Position : pos ,
1347+ }
1348+ if p .eat ("ROLE" ) {
1349+ roleList , err := p .parseGrantOrRevokeRoleList ("TO" )
1350+ if err != nil {
1351+ return nil , err
1352+ }
1353+ g .GrantRoleNames = roleList
1354+ } else {
1355+ var privs []Privilege
1356+ privs , err := p .parsePrivileges ()
1357+ if err != nil {
1358+ return nil , err
1359+ }
1360+ g .Privileges = privs
1361+ var tableList []ID
1362+ f := func (p * parser ) * parseError {
1363+ table , err := p .parseTableOrIndexOrColumnName ()
1364+ if err != nil {
1365+ return err
1366+ }
1367+ tableList = append (tableList , table )
1368+ return nil
1369+ }
1370+ if err := p .parseCommaListWithEnds (f , "TO" , "ROLE" ); err != nil {
1371+ return nil , err
1372+ }
1373+ g .TableNames = tableList
1374+ }
1375+ list , err := p .parseIDList ()
1376+ if err != nil {
1377+ return nil , err
1378+ }
1379+ g .ToRoleNames = list
1380+
1381+ return g , nil
1382+ }
1383+
1384+ func (p * parser ) parseRevokeRole () (* RevokeRole , * parseError ) {
1385+ pos := p .Pos ()
1386+ r := & RevokeRole {
1387+ Position : pos ,
1388+ }
1389+ if p .eat ("ROLE" ) {
1390+ roleList , err := p .parseGrantOrRevokeRoleList ("FROM" )
1391+ if err != nil {
1392+ return nil , err
1393+ }
1394+ r .RevokeRoleNames = roleList
1395+ } else {
1396+ var privs []Privilege
1397+ privs , err := p .parsePrivileges ()
1398+ if err != nil {
1399+ return nil , err
1400+ }
1401+ r .Privileges = privs
1402+ var tableList []ID
1403+ f := func (p * parser ) * parseError {
1404+ table , err := p .parseTableOrIndexOrColumnName ()
1405+ if err != nil {
1406+ return err
1407+ }
1408+ tableList = append (tableList , table )
1409+ return nil
1410+ }
1411+ if err := p .parseCommaListWithEnds (f , "FROM" , "ROLE" ); err != nil {
1412+ return nil , err
1413+ }
1414+ r .TableNames = tableList
1415+ }
1416+ list , err := p .parseIDList ()
1417+ if err != nil {
1418+ return nil , err
1419+ }
1420+ r .FromRoleNames = list
1421+
1422+ return r , nil
1423+ }
1424+ func (p * parser ) parseGrantOrRevokeRoleList (end string ) ([]ID , * parseError ) {
1425+ var roleList []ID
1426+ f := func (p * parser ) * parseError {
1427+ role , err := p .parseTableOrIndexOrColumnName ()
1428+ if err != nil {
1429+ return err
1430+ }
1431+ roleList = append (roleList , role )
1432+ return nil
1433+ }
1434+ err := p .parseCommaListWithEnds (f , end , "ROLE" )
1435+ if err != nil {
1436+ return nil , err
1437+ }
1438+ return roleList , nil
1439+ }
1440+
1441+ func (p * parser ) parsePrivileges () ([]Privilege , * parseError ) {
1442+ var privs []Privilege
1443+ for {
1444+ tok := p .next ()
1445+ if tok .err != nil {
1446+ return []Privilege {}, tok .err
1447+ }
1448+
1449+ priv := Privilege {}
1450+ switch {
1451+ default :
1452+ return []Privilege {}, p .errorf ("got %q, want SELECT or UPDATE or INSERT or DELETE" , tok .value )
1453+ case tok .caseEqual ("SELECT" ):
1454+ priv .Type = PrivilegeTypeSelect
1455+ case tok .caseEqual ("UPDATE" ):
1456+ priv .Type = PrivilegeTypeUpdate
1457+ case tok .caseEqual ("INSERT" ):
1458+ priv .Type = PrivilegeTypeInsert
1459+ case tok .caseEqual ("DELETE" ):
1460+ priv .Type = PrivilegeTypeDelete
1461+ }
1462+ // can grant DELETE only at the table level.
1463+ // https://cloud.google.com/spanner/docs/reference/standard-sql/data-definition-language#notes_and_restrictions
1464+ if p .sniff ("(" ) && ! tok .caseEqual ("DELETE" ) {
1465+ list , err := p .parseColumnNameList ()
1466+ if err != nil {
1467+ return nil , err
1468+ }
1469+ priv .Columns = list
1470+ }
1471+ privs = append (privs , priv )
1472+ tok = p .next ()
1473+ if tok .err != nil {
1474+ return []Privilege {}, tok .err
1475+ }
1476+ if tok .value == "," {
1477+ continue
1478+ } else if tok .caseEqual ("ON" ) && p .eat ("TABLE" ) {
1479+ break
1480+ } else {
1481+ return []Privilege {}, p .errorf ("got %q, want , or ON TABLE" , tok .value )
1482+ }
1483+ }
1484+ return privs , nil
1485+ }
13001486func (p * parser ) parseAlterTable () (* AlterTable , * parseError ) {
13011487 debugf ("parseAlterTable: %v" , p )
13021488
@@ -2053,6 +2239,23 @@ func (p *parser) parseColumnNameList() ([]ID, *parseError) {
20532239 return list , err
20542240}
20552241
2242+ func (p * parser ) parseIDList () ([]ID , * parseError ) {
2243+ var list []ID
2244+ for {
2245+ n , err := p .parseTableOrIndexOrColumnName ()
2246+ if err != nil {
2247+ return nil , err
2248+ }
2249+ list = append (list , n )
2250+
2251+ if p .eat ("," ) {
2252+ continue
2253+ }
2254+ break
2255+ }
2256+ return list , nil
2257+ }
2258+
20562259func (p * parser ) parseCreateChangeStream () (* CreateChangeStream , * parseError ) {
20572260 debugf ("parseCreateChangeStream: %v" , p )
20582261
@@ -3898,7 +4101,7 @@ func (p *parser) parseHints(hints map[string]string) (map[string]string, *parseE
38984101
38994102func (p * parser ) parseTableOrIndexOrColumnName () (ID , * parseError ) {
39004103 /*
3901- table_name and column_name and index_name:
4104+ table_name and column_name and index_name and role_name :
39024105 {a—z|A—Z}[{a—z|A—Z|0—9|_}+]
39034106 */
39044107
@@ -4001,3 +4204,31 @@ func (p *parser) parseCommaList(bra, ket string, f func(*parser) *parseError) *p
40014204 }
40024205 }
40034206}
4207+
4208+ // parseCommaListWithEnds parses a comma-separated list to expected ends,
4209+ // delegating to f for the individual element parsing.
4210+ // Only invoke this with symbols as end; they are matched case insensitively.
4211+ func (p * parser ) parseCommaListWithEnds (f func (* parser ) * parseError , end ... string ) * parseError {
4212+ if p .eat (end ... ) {
4213+ return nil
4214+ }
4215+ for {
4216+ err := f (p )
4217+ if err != nil {
4218+ return err
4219+ }
4220+ if p .eat (end ... ) {
4221+ return nil
4222+ }
4223+
4224+ tok := p .next ()
4225+ if tok .err != nil {
4226+ return err
4227+ }
4228+ if tok .value == "," {
4229+ continue
4230+ } else if tok .value == ";" {
4231+ return nil
4232+ }
4233+ }
4234+ }
0 commit comments