Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions postgres/parser/parser/sql.y
Original file line number Diff line number Diff line change
Expand Up @@ -1747,11 +1747,11 @@ alter_default_privileges_stmt:
{
$$.val = $4.alterDefaultPrivileges()
}
| ALTER DEFAULT PRIVILEGES FOR role_or_user opt_role_list adp_abbreviated_grant_or_revoke
| ALTER DEFAULT PRIVILEGES FOR role_or_user opt_role adp_abbreviated_grant_or_revoke
{
adp := $7.alterDefaultPrivileges()
adp.ForRole = $5.bool()
adp.TargetRoles = $6.strs()
adp.TargetRole = $6
$$.val = adp
}
| ALTER DEFAULT PRIVILEGES IN SCHEMA schema_name_list adp_abbreviated_grant_or_revoke
Expand All @@ -1760,11 +1760,11 @@ alter_default_privileges_stmt:
adp.Target.InSchema = $6.strs()
$$.val = adp
}
| ALTER DEFAULT PRIVILEGES FOR role_or_user opt_role_list IN SCHEMA schema_name_list adp_abbreviated_grant_or_revoke
| ALTER DEFAULT PRIVILEGES FOR role_or_user opt_role IN SCHEMA schema_name_list adp_abbreviated_grant_or_revoke
{
adp := $10.alterDefaultPrivileges()
adp.ForRole = $5.bool()
adp.TargetRoles = $6.strs()
adp.TargetRole = $6
adp.Target.InSchema = $9.strs()
$$.val = adp
}
Expand Down Expand Up @@ -2026,9 +2026,9 @@ alter_oneindex_stmt:
{
$$.val = &tree.AlterIndex{Index: $5.tableIndexName(), IfExists: true, Cmd: $6.alterIndexCmd()}
}
| ALTER INDEX table_index_name ATTACH PARTITION index_name
| ALTER INDEX table_index_name ATTACH PARTITION db_object_name
{
$$.val = &tree.AlterIndex{Index: $3.tableIndexName(), Cmd: &tree.AlterIndexAttachPartition{Index: tree.UnrestrictedName($6)}}
$$.val = &tree.AlterIndex{Index: $3.tableIndexName(), Cmd: &tree.AlterIndexAttachPartition{Index: $6.unresolvedObjectName()}}
}
| ALTER INDEX table_index_name opt_no DEPENDS ON EXTENSION name
{
Expand Down Expand Up @@ -2128,9 +2128,9 @@ alter_table_action:
}
}
// ALTER TABLE <name> ADD CONSTRAINT ... USING INDEX
| ADD CONSTRAINT constraint_name unique_or_primary USING INDEX index_name opt_deferrable_mode opt_initially
| ADD CONSTRAINT constraint_name unique_or_primary USING INDEX db_object_name opt_deferrable_mode opt_initially
{
$$.val = tree.AlterTableConstraintUsingIndex{Constraint: tree.Name($3), IsUnique: $4.bool(), Index: tree.Name($7), Deferrable: $8.deferrableMode(), Initially: $9.initiallyMode()}
$$.val = tree.AlterTableConstraintUsingIndex{Constraint: tree.Name($3), IsUnique: $4.bool(), Index: $7.unresolvedObjectName(), Deferrable: $8.deferrableMode(), Initially: $9.initiallyMode()}
}
// ALTER TABLE <name> ALTER CONSTRAINT ...
| ALTER CONSTRAINT constraint_name opt_deferrable_mode opt_initially
Expand Down
6 changes: 3 additions & 3 deletions postgres/parser/sem/tree/alter_default_privileges.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var _ Statement = &AlterDefaultPrivileges{}
// AlterDefaultPrivileges represents a ALTER DEFAULT PRIVILEGES statement.
type AlterDefaultPrivileges struct {
ForRole bool
TargetRoles []string
TargetRole string
Privileges privilege.List
Target TargetList
Grantees []string
Expand All @@ -38,14 +38,14 @@ type AlterDefaultPrivileges struct {
// Format implements the NodeFormatter interface.
func (node *AlterDefaultPrivileges) Format(ctx *FmtCtx) {
ctx.WriteString("ALTER DEFAULT PRIVILEGES ")
if len(node.TargetRoles) > 0 {
if node.TargetRole != "" {
ctx.WriteString("FOR ")
if node.ForRole {
ctx.WriteString("ROLE ")
} else {
ctx.WriteString("USER ")
}
ctx.WriteString(strings.Join(node.TargetRoles, ", "))
ctx.WriteString(node.TargetRole)
}
if len(node.Target.InSchema) > 0 {
ctx.WriteString("IN SCHEMAS ")
Expand Down
4 changes: 2 additions & 2 deletions postgres/parser/sem/tree/alter_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,13 @@ var _ AlterIndexCmd = &AlterIndexSetTablespace{}

// AlterIndexAttachPartition represents an ALTER INDEX ... ATTACH PARTITION statement.
type AlterIndexAttachPartition struct {
Index UnrestrictedName
Index *UnresolvedObjectName
}

// Format implements the NodeFormatter interface.
func (node *AlterIndexAttachPartition) Format(ctx *FmtCtx) {
ctx.WriteString(" ATTACH PARTITION ")
ctx.FormatNode(&node.Index)
node.Index.Format(ctx)
}

// AlterIndexExtension represents an ALTER INDEX ... [NO] DEPENDS ON EXTENSION statement.
Expand Down
8 changes: 4 additions & 4 deletions postgres/parser/sem/tree/alter_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ func (node *AlterTableComputed) GetColumn() Name {
type AlterTableConstraintUsingIndex struct {
Constraint Name
IsUnique bool
Index Name
Index *UnresolvedObjectName
Deferrable DeferrableMode
Initially InitiallyMode
}
Expand All @@ -421,7 +421,7 @@ func (node *AlterTableConstraintUsingIndex) Format(ctx *FmtCtx) {
ctx.WriteString(" PRIMARY KEY")
}
ctx.WriteString(" USING INDEX")
ctx.FormatNode(&node.Index)
node.Index.Format(ctx)
switch node.Deferrable {
case Deferrable:
ctx.WriteString(" DEFERRABLE")
Expand Down Expand Up @@ -966,7 +966,7 @@ func (node *AlterTablePartition) Format(ctx *FmtCtx) {
node.Name.Format(ctx)
if node.IsDetach {
ctx.WriteString(" DETACH PARTITION ")
node.Name.Format(ctx)
node.Partition.Format(ctx)
switch node.DetachType {
case DetachPartitionNone:
case DetachPartitionConcurrently:
Expand All @@ -976,7 +976,7 @@ func (node *AlterTablePartition) Format(ctx *FmtCtx) {
}
} else {
ctx.WriteString(" ATTACH PARTITION ")
node.Name.Format(ctx)
node.Partition.Format(ctx)
ctx.WriteByte(' ')
ctx.FormatNode(&node.Spec)
}
Expand Down
56 changes: 55 additions & 1 deletion server/ast/alter_default_privileges.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,66 @@
package ast

import (
"github.com/cockroachdb/errors"
vitess "github.com/dolthub/vitess/go/vt/sqlparser"

"github.com/dolthub/doltgresql/postgres/parser/privilege"
"github.com/dolthub/doltgresql/postgres/parser/sem/tree"
"github.com/dolthub/doltgresql/server/auth"
pgnodes "github.com/dolthub/doltgresql/server/node"
)

// nodeAlterDefaultPrivileges handles *tree.AlterDefaultPrivileges nodes.
func nodeAlterDefaultPrivileges(ctx *Context, node *tree.AlterDefaultPrivileges) (vitess.Statement, error) {
return NotYetSupportedError("ALTER DEFAULT PRIVILEGES statement is not yet supported")
if node == nil {
return nil, nil
}

objType, err := convertDefaultPrivilegeObjectType(node.Target.TargetType)
if err != nil {
return nil, err
}

privileges, err := convertPrivilegeKinds(objType, node.Privileges)
if err != nil {
return nil, err
}

return vitess.InjectedStatement{
Auth: vitess.AuthInformation{
AuthType: auth.AuthType_CREATE,
TargetType: auth.AuthTargetType_AlterDefaultPrivilegesIdentifiers,
TargetNames: []string{node.TargetRole},
},
Statement: &pgnodes.AlterDefaultPrivileges{
OwnerRole: node.TargetRole,
Schemas: node.Target.InSchema,
ObjectType: objType,
Privileges: privileges,
Grantees: node.Grantees,
Grant: node.Grant,
GrantOption: node.GrantOption,
Cascade: node.DropBehavior == tree.DropCascade,
},
Children: nil,
}, nil
}

// convertDefaultPrivilegeObjectType converts a privilege.ObjectType to an auth.PrivilegeObject for use in default
// privileges. Only the object types valid for ALTER DEFAULT PRIVILEGES are accepted.
func convertDefaultPrivilegeObjectType(objType privilege.ObjectType) (auth.PrivilegeObject, error) {
switch objType {
case privilege.Table:
return auth.PrivilegeObject_TABLE, nil
case privilege.Sequence:
return auth.PrivilegeObject_SEQUENCE, nil
case privilege.Function, privilege.Procedure, privilege.Routine:
return auth.PrivilegeObject_FUNCTION, nil
case privilege.Schema:
return auth.PrivilegeObject_SCHEMA, nil
case privilege.Type:
return auth.PrivilegeObject_TYPE, nil
default:
return 0, errors.Errorf("object type %q is not supported in ALTER DEFAULT PRIVILEGES", string(objType))
}
}
12 changes: 12 additions & 0 deletions server/auth/auth_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,18 @@ func (h *AuthorizationHandler) HandleAuth(ctx *sql.Context, aqs sql.Authorizatio
}
case AuthTargetType_TODO:
// This is similar to IGNORE, except we're meant to replace this at some point
case AuthTargetType_AlterDefaultPrivilegesIdentifiers:
nTargets := len(auth.TargetNames)
if nTargets > 1 {
return errors.Errorf("function identifiers has an unsupported count: %d", len(auth.TargetNames))
}
if state.role.IsSuperUser {
return nil
}
if nTargets == 1 && state.role.Name == auth.TargetNames[0] {
return nil
}
return errors.Errorf("permission denied for %s", auth.TargetNames[0])
default:
if len(auth.TargetType) == 0 {
return errors.New("TargetType is unexpectedly empty")
Expand Down
15 changes: 8 additions & 7 deletions server/auth/auth_information.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,12 @@ const (

// These AuthTargetType_ enums are used as the TargetType in vitess.AuthInformation.
const (
AuthTargetType_Ignore = "IGNORE"
AuthTargetType_DatabaseIdentifiers = "DB_IDENTS"
AuthTargetType_SchemaIdentifiers = "DB_SCH_IDENTS"
AuthTargetType_TableIdentifiers = "DB_SCH_TABLE_IDENTS"
AuthTargetType_FunctionIdentifiers = "DB_SCH_FUNCTION_IDENTS"
AuthTargetType_SequenceIdentifiers = "DB_SCH_SEQUENCE_IDENTS"
AuthTargetType_TODO = "TODO"
AuthTargetType_Ignore = "IGNORE"
AuthTargetType_DatabaseIdentifiers = "DB_IDENTS"
AuthTargetType_SchemaIdentifiers = "DB_SCH_IDENTS"
AuthTargetType_TableIdentifiers = "DB_SCH_TABLE_IDENTS"
AuthTargetType_FunctionIdentifiers = "DB_SCH_FUNCTION_IDENTS"
AuthTargetType_SequenceIdentifiers = "DB_SCH_SEQUENCE_IDENTS"
AuthTargetType_AlterDefaultPrivilegesIdentifiers = "DB_SCH_ADP_IDENTS"
AuthTargetType_TODO = "TODO"
)
11 changes: 11 additions & 0 deletions server/auth/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type Database struct {
sequencePrivileges *SequencePrivileges
routinePrivileges *RoutinePrivileges
roleMembership *RoleMembership
defaultPrivileges *DefaultPrivileges
}

// ClearDatabase clears the internal database, leaving only the default users. This is primarily for use by tests.
Expand All @@ -57,6 +58,7 @@ func ClearDatabase() {
clear(globalDatabase.sequencePrivileges.Data)
clear(globalDatabase.routinePrivileges.Data)
clear(globalDatabase.roleMembership.Data)
clear(globalDatabase.defaultPrivileges.Data)
dbInitDefault()
}

Expand Down Expand Up @@ -96,6 +98,14 @@ func RoleExists(name string) bool {
return ok
}

// GetRoleName returns the name of the role with the given ID. Returns an empty string if the role does not exist.
func GetRoleName(id RoleID) string {
if role, ok := globalDatabase.rolesByID[id]; ok {
return role.Name
}
return ""
}

// SetRole sets the role matching the given name. This will add a role that does not yet exist, and overwrite an
// existing role.
func SetRole(role Role) {
Expand Down Expand Up @@ -143,6 +153,7 @@ func dbInit(dEnv *env.DoltEnv, cfg Config) {
sequencePrivileges: NewSequencePrivileges(),
routinePrivileges: NewRoutinePrivileges(),
roleMembership: NewRoleMembership(),
defaultPrivileges: NewDefaultPrivileges(),
}
globalLock = &sync.RWMutex{}
if dEnv != nil {
Expand Down
2 changes: 1 addition & 1 deletion server/auth/database_privileges.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ func (sp *DatabasePrivileges) serialize(writer *utils.Writer) {
func (sp *DatabasePrivileges) deserialize(version uint32, reader *utils.Reader) {
sp.Data = make(map[DatabasePrivilegeKey]DatabasePrivilegeValue)
switch version {
case 0, 1:
case 0, 1, 2:
// Read the total number of values
dataCount := reader.Uint64()
for dataIdx := uint64(0); dataIdx < dataCount; dataIdx++ {
Expand Down
Loading
Loading