Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

schemachanger: Implement CREATE DATABASE in declarative schema changer #117292

Merged
Merged
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
8 changes: 6 additions & 2 deletions pkg/ccl/logictestccl/testdata/logic_test/as_of
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ SET DEFAULT_TRANSACTION_USE_FOLLOWER_READS TO TRUE
statement error pgcode 3D000 pq: database "test" does not exist
SELECT * FROM t

statement error pq: cannot execute CREATE DATABASE in a read-only transaction
# LSC and DSC would return slightly different error message when attempting to create a
# database as of system time follower_read_timestamp() soon after a node has started.
statement error pq: (cannot execute CREATE DATABASE in a read-only transaction|referenced descriptor ID 1: looking up ID 1: descriptor not found)
CREATE DATABASE IF NOT EXISTS d2

statement error pgcode 3D000 pq: database "test" does not exist
Expand Down Expand Up @@ -88,7 +90,9 @@ SET SESSION CHARACTERISTICS AS TRANSACTION AS OF SYSTEM TIME follower_read_times
statement error pgcode 3D000 pq: database "test" does not exist
SELECT * FROM t

statement error pq: cannot execute CREATE DATABASE in a read-only transaction
# LSC and DSC would return slightly different error message when attempting to create a
# database as of system time follower_read_timestamp() soon after a node has started.
statement error pq: (cannot execute CREATE DATABASE in a read-only transaction|referenced descriptor ID 1: looking up ID 1: descriptor not found)
CREATE DATABASE IF NOT EXISTS d2

statement error pgcode 3D000 pq: database "test" does not exist
Expand Down
84 changes: 84 additions & 0 deletions pkg/ccl/schemachangerccl/backup_base_generated_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

122 changes: 122 additions & 0 deletions pkg/internal/team/TEAMS.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# This is a YAML file mapping team aliases from GitHub to
# metadata about the team.
# Expected structure is available in pkg/internal/team/team.go.

# Finding triage_column_id:
# TriageColumnID is the column id of the project column the team uses to
# triage issues. To get it, open the project, click the "..." on top of
# the project column, and click "Copy column link". That link contains
# the ID as the `#column-<ID>` fragment.
#
# You can also use:
# https://github.com/cockroachlabs/github-find-triage-column-id using
# `go install github.com/cockroachlabs/github-find-triage-column-id@latest`.
#
# Then to retrieve triage_column_id from a repo-based project, run:
# github-get-column-id --repo "cockroach" --project "Bazel" --column "To do"
# Or retrieve the triage_column_id from a organization-based project, run:
# github-get-column-id --project "Spatial" --column "Backlog"

cockroachdb/docs:
triage_column_id: 3971225
aliases:
cockroachdb/docs-infra-prs: other
cockroachdb/sql-foundations:
aliases:
cockroachdb/sql-syntax-prs: other
cockroachdb/sqlproxy-prs: other
cockroachdb/sql-api-prs: other
triage_column_id: 19467489
label: T-sql-foundations
cockroachdb/sql-queries:
aliases:
cockroachdb/sql-queries-prs: other
cockroachdb/sql-optimizer: other
cockroachdb/sql-opt-prs: other
# SQL Queries team uses GH projects v2, which doesn't have a REST API, so
# there is no triage column ID.
# See .github/workflows/add-issues-to-project.yml.
label: T-sql-queries
cockroachdb/cluster-observability:
triage_column_id: 12618343
label: T-cluster-observability
cockroachdb/kv:
aliases:
cockroachdb/kv-triage: roachtest
cockroachdb/kv-prs: other
triage_column_id: 14242655
label: T-kv
cockroachdb/replication:
aliases:
cockroachdb/repl-prs: other
label: T-kv-replication
cockroachdb/spatial:
triage_column_id: 9487269
label: T-spatial
cockroachdb/dev-inf:
triage_column_id: 10210759
label: T-dev-inf
cockroachdb/multiregion:
triage_column_id: 11926170
label: T-multiregion
cockroachdb/storage:
aliases:
cockroachdb/admission-control: other
triage_column_id: 6668367
label: T-storage
cockroachdb/test-eng:
triage_column_id: 14041337
label: T-testeng
cockroachdb/test-eng-prs:
triage_column_id: 14041337
label: T-testeng
cockroachdb/security:
label: T-cross-product-security
cockroachdb/prodsec:
label: T-cross-product-security
cockroachdb/disaster-recovery:
triage_column_id: 3097123
label: T-disaster-recovery
cockroachdb/cdc:
aliases:
cockroachdb/cdc-prs: other
# CDC team uses GH projects v2, which doesn't have a REST API, so no triage column ID
# see .github/workflows/add-issues-to-project.yml
label: T-cdc
cockroachdb/server:
aliases:
cockroachdb/cli-prs: other
cockroachdb/server-prs: other
triage_column_id: 2521812
cockroachdb/admin-ui:
aliases:
cockroachdb/admin-ui-prs: other
triage_column_id: 6598672
label: T-observability-inf
cockroachdb/obs-inf-prs:
aliases:
cockroachdb/http-api-prs: other
triage_column_id: 14196277
label: T-observability-inf
cockroachdb/multi-tenant:
# Multi-tenant team uses GH projects v2, which doesn't have a REST API, so no triage column ID
# see .github/workflows/add-issues-to-project.yml
label: T-multitenant
cockroachdb/jobs:
aliases:
cockroachdb/jobs-prs: other
# Jobs uses GH projects v2, which doesn't have a REST API, so no triage column ID
# see .github/workflows/add-issues-to-project.yml
label: T-jobs
cockroachdb/cloud-identity:
triage_column_id: 18588697
cockroachdb/unowned:
aliases:
cockroachdb/rfc-prs: other
triage_column_id: 0 # TODO
cockroachdb/migrations:
label: T-migrations
triage_column_id: 18330909
cockroachdb/release-eng:
label: T-release
triage_column_id: 9149730
4 changes: 2 additions & 2 deletions pkg/sql/create_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ func (p *planner) CreateDatabase(ctx context.Context, n *tree.CreateDatabase) (p
return &createDatabaseNode{n: n}, nil
}

// CanCreateDatabase verifies that the current user has the CREATEDB
// role option.
// CanCreateDatabase returns nil if current user has CREATEDB system privilege
// or the equivalent, legacy role options.
func (p *planner) CanCreateDatabase(ctx context.Context) error {
hasCreateDB, err := p.HasGlobalPrivilegeOrRoleOption(ctx, privilege.CREATEDB)
if err != nil {
Expand Down
7 changes: 6 additions & 1 deletion pkg/sql/logictest/testdata/logic_test/bytes
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,12 @@ DROP TABLE t
subtest Regression_4312

statement ok
PREPARE r1(bytes) AS SELECT descriptor::STRING FROM system.descriptor WHERE descriptor != $1 ORDER BY descriptor DESC LIMIT 1
PREPARE r1(bytes) AS
SELECT descriptor::STRING
FROM system.descriptor
WHERE id = (
SELECT id FROM system.namespace WHERE name = 'defaultdb'
);

query T
EXECUTE r1('abc')
Expand Down
14 changes: 14 additions & 0 deletions pkg/sql/schemachanger/scbuild/builder_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
package scbuild

import (
"context"
"sort"

"github.com/cockroachdb/cockroach/pkg/keys"
Expand Down Expand Up @@ -297,6 +298,7 @@ func (b *builderState) CheckPrivilege(e scpb.Element, privilege privilege.Kind)
b.checkPrivilege(screl.GetDescID(e), privilege)
}

// checkPrivilege checks if current user has privilege `priv` on descriptor with `id`.
func (b *builderState) checkPrivilege(id catid.DescID, priv privilege.Kind) {
b.ensureDescriptor(id)
c := b.descCache[id]
Expand Down Expand Up @@ -325,6 +327,13 @@ func (b *builderState) checkPrivilege(id catid.DescID, priv privilege.Kind) {
}
}

// HasGlobalPrivilegeOrRoleOption implements the scbuildstmt.PrivilegeChecker interface.
func (b *builderState) HasGlobalPrivilegeOrRoleOption(
ctx context.Context, privilege privilege.Kind,
) (bool, error) {
return b.auth.HasGlobalPrivilegeOrRoleOption(ctx, privilege)
}

// CurrentUserHasAdminOrIsMemberOf implements the scbuildstmt.PrivilegeChecker interface.
func (b *builderState) CurrentUserHasAdminOrIsMemberOf(role username.SQLUsername) bool {
if b.hasAdmin {
Expand All @@ -345,6 +354,11 @@ func (b *builderState) CurrentUser() username.SQLUsername {
return b.evalCtx.SessionData().User()
}

// CheckRoleExists implements the scbuild.AuthorizationAccessor interface.
func (b *builderState) CheckRoleExists(ctx context.Context, role username.SQLUsername) error {
return b.auth.CheckRoleExists(ctx, role)
}

var _ scbuildstmt.TableHelpers = (*builderState)(nil)

// NextTableColumnID implements the scbuildstmt.TableHelpers interface.
Expand Down
13 changes: 10 additions & 3 deletions pkg/sql/schemachanger/scbuild/dependencies.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,14 +178,14 @@ type AuthorizationAccessor interface {
ctx context.Context, privilegeObject privilege.Object, privilege privilege.Kind,
) error

// HasAdminRole verifies if a user has an admin role.
// HasAdminRole verifies if current user has an admin role.
HasAdminRole(ctx context.Context) (bool, error)

// HasOwnership returns true iff the role, or any role the role is a member
// of, has ownership privilege of the desc.
HasOwnership(ctx context.Context, privilegeObject privilege.Object) (bool, error)

// CheckPrivilegeForUser verifies that the user has `privilege` on `descriptor`.
// CheckPrivilegeForUser verifies that `user` has `privilege` on `descriptor`.
CheckPrivilegeForUser(
ctx context.Context, privilegeObject privilege.Object, privilege privilege.Kind, user username.SQLUsername,
) error
Expand All @@ -194,11 +194,18 @@ type AuthorizationAccessor interface {
// and indirect) and returns a map of "role" -> "isAdmin".
MemberOfWithAdminOption(ctx context.Context, member username.SQLUsername) (map[username.SQLUsername]bool, error)

// HasPrivilege checks if the user has `privilege` on `descriptor`.
// HasPrivilege checks if the `user` has `privilege` on `privilegeObject`.
HasPrivilege(ctx context.Context, privilegeObject privilege.Object, privilege privilege.Kind, user username.SQLUsername) (bool, error)

// HasAnyPrivilege returns true if user has any privileges at all.
HasAnyPrivilege(ctx context.Context, privilegeObject privilege.Object) (bool, error)

// HasGlobalPrivilegeOrRoleOption returns a bool representing whether the current user
// has a global privilege or the corresponding legacy role option.
HasGlobalPrivilegeOrRoleOption(ctx context.Context, privilege privilege.Kind) (bool, error)

// CheckRoleExists returns nil if `role` exists.
CheckRoleExists(ctx context.Context, role username.SQLUsername) error
}

// AstFormatter provides interfaces for formatting AST nodes.
Expand Down
4 changes: 3 additions & 1 deletion pkg/sql/schemachanger/scbuild/event_log.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,9 @@ func (pb payloadBuilder) build(b buildCtx) logpb.EventPayload {
switch e := pb.Element().(type) {
case *scpb.Database:
if pb.TargetStatus == scpb.Status_PUBLIC {
return nil
return &eventpb.CreateDatabase{
DatabaseName: fullyQualifiedName(b, e),
}
} else {
return &eventpb.DropDatabase{
DatabaseName: fullyQualifiedName(b, e),
Expand Down
Loading
Loading