(stmt *pgquery.GrantStmt)
| 1646 | } |
| 1647 | |
| 1648 | func (p PostgresParser) parseGrantStmt(stmt *pgquery.GrantStmt) (parser.Statement, error) { |
| 1649 | if stmt.Objtype != pgquery.ObjectType_OBJECT_TABLE { |
| 1650 | // For now, only support table grants |
| 1651 | return nil, fmt.Errorf("only table grants are supported") |
| 1652 | } |
| 1653 | |
| 1654 | if len(stmt.Objects) == 0 { |
| 1655 | return nil, fmt.Errorf("no objects specified in grant statement") |
| 1656 | } |
| 1657 | |
| 1658 | // Check for unsupported WITH GRANT OPTION |
| 1659 | if stmt.GrantOption { |
| 1660 | return nil, validationError{"WITH GRANT OPTION is not supported yet"} |
| 1661 | } |
| 1662 | |
| 1663 | // Check for unsupported CASCADE/RESTRICT (for REVOKE) |
| 1664 | // Note: DROP_RESTRICT is the default behavior and is allowed |
| 1665 | if !stmt.IsGrant && stmt.Behavior == pgquery.DropBehavior_DROP_CASCADE { |
| 1666 | return nil, validationError{"CASCADE/RESTRICT options are not supported yet"} |
| 1667 | } |
| 1668 | |
| 1669 | // Handle multiple tables - return multiple DDL statements |
| 1670 | var statements []parser.Statement |
| 1671 | |
| 1672 | for _, obj := range stmt.Objects { |
| 1673 | var tableName parser.TableName |
| 1674 | if rangeVar, ok := obj.Node.(*pgquery.Node_RangeVar); ok { |
| 1675 | parsedName, err := p.parseTableName(rangeVar.RangeVar) |
| 1676 | if err != nil { |
| 1677 | return nil, err |
| 1678 | } |
| 1679 | tableName = parsedName |
| 1680 | } else { |
| 1681 | return nil, fmt.Errorf("unexpected object type in grant statement") |
| 1682 | } |
| 1683 | |
| 1684 | var privileges []string |
| 1685 | if stmt.Privileges == nil { |
| 1686 | // ALL PRIVILEGES case |
| 1687 | privileges = []string{"ALL"} |
| 1688 | } else { |
| 1689 | for _, priv := range stmt.Privileges { |
| 1690 | if accessPriv, ok := priv.Node.(*pgquery.Node_AccessPriv); ok { |
| 1691 | if accessPriv.AccessPriv.Cols == nil { |
| 1692 | privileges = append(privileges, strings.ToUpper(accessPriv.AccessPriv.PrivName)) |
| 1693 | } |
| 1694 | } |
| 1695 | } |
| 1696 | } |
| 1697 | |
| 1698 | if len(stmt.Grantees) == 0 { |
| 1699 | return nil, fmt.Errorf("no grantees specified in grant statement") |
| 1700 | } |
| 1701 | |
| 1702 | var grantees []string |
| 1703 | for _, granteeNode := range stmt.Grantees { |
| 1704 | if roleSpec, ok := granteeNode.Node.(*pgquery.Node_RoleSpec); ok { |
| 1705 | switch roleSpec.RoleSpec.Roletype { |
no test coverage detected