Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
57 changes: 57 additions & 0 deletions core/rootvalue.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package core
import (
"bytes"
"context"
"fmt"
"slices"
"sort"
"strconv"
Expand Down Expand Up @@ -87,6 +88,62 @@ func (root *RootValue) CreateDatabaseSchema(ctx context.Context, dbSchema schema
return root.withStorage(r), nil
}

// DropDatabaseSchema implements the interface doltdb.RootValue.
func (root *RootValue) DropDatabaseSchema(ctx context.Context, dbSchema schema.DatabaseSchema) (doltdb.RootValue, error) {
schemas, err := root.st.GetSchemas(ctx)
if err != nil {
return nil, err
}

found := false
schemaName := dbSchema.Name
for i, s := range schemas {
if strings.EqualFold(s.Name, dbSchema.Name) {
found = true
schemaName = s.Name
// remove this element in the slice
schemas = append(schemas[:i], schemas[i+1:]...)
break
}
}

if !found {
return nil, fmt.Errorf("No schema with the name %s exists", dbSchema.Name)
}

// Check for dangling objects in the schema and reject the drop if there are any
danglingObjects := false
root.IterRootObjects(ctx, func(name doltdb.TableName, table doltdb.RootObject) (stop bool, err error) {
if strings.EqualFold(name.Schema, dbSchema.Name) {
danglingObjects = true
}
return false, nil
})

// check the tables specifically in addition to root objects. This is just an extra paranoid step to avoid
// removing a schema that still has tables.
tableMap, err := root.getTableMap(ctx, schemaName)
if err != nil {
return nil, err
}

tableMap.Iter(ctx, func(name string, addr hash.Hash) (bool, error) {
danglingObjects = true
return true, nil
})

if danglingObjects {
return nil, fmt.Errorf("cannot drop schema %s because other objects depend on it", dbSchema.Name)
}

r, err := root.st.SetSchemas(ctx, schemas)
if err != nil {
return nil, err
}

return root.withStorage(r), nil
}

// validateSchemaForCreate returns an error if a schema with the name given cannot be created
func validateSchemaForCreate(existingSchemas []schema.DatabaseSchema, dbSchema schema.DatabaseSchema) error {
if dbSchema.Name == "" {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
github.com/PuerkitoBio/goquery v1.8.1
github.com/cockroachdb/apd/v2 v2.0.3-0.20200518165714-d020e156310a
github.com/cockroachdb/errors v1.7.5
github.com/dolthub/dolt/go v0.40.5-0.20260106173753-e3c81824fc90
github.com/dolthub/dolt/go v0.40.5-0.20260107002642-c6d39505a1d7
github.com/dolthub/eventsapi_schema v0.0.0-20250915094920-eadfd39051ca
github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2
github.com/dolthub/go-mysql-server v0.20.1-0.20260106170317-759307e19edd
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,8 @@ github.com/dolthub/aws-sdk-go-ini-parser v0.0.0-20250305001723-2821c37f6c12 h1:I
github.com/dolthub/aws-sdk-go-ini-parser v0.0.0-20250305001723-2821c37f6c12/go.mod h1:rN7X8BHwkjPcfMQQ2QTAq/xM3leUSGLfb+1Js7Y6TVo=
github.com/dolthub/dolt-mcp v0.2.2 h1:bpROmam74n95uU4EA3BpOIVlTDT0pzeFMBwe/YRq2mI=
github.com/dolthub/dolt-mcp v0.2.2/go.mod h1:S++DJ4QWTAXq+0TNzFa7Oq3IhoT456DJHwAINFAHgDQ=
github.com/dolthub/dolt/go v0.40.5-0.20260106173753-e3c81824fc90 h1:lWOjwImXbtzaL34XjFYVCcnniJUt/jjGx9omvu4y5NU=
github.com/dolthub/dolt/go v0.40.5-0.20260106173753-e3c81824fc90/go.mod h1:RrRSqn/03/yMFx3nxUyL1H8YkC60tJwhqq2UyuvIGNA=
github.com/dolthub/dolt/go v0.40.5-0.20260107002642-c6d39505a1d7 h1:YNtBsIk6FyAmJ2Axf9whKRnH3zDfgyT8ovcxBPRlV6Y=
github.com/dolthub/dolt/go v0.40.5-0.20260107002642-c6d39505a1d7/go.mod h1:1VZsnS76rDdgrOnzIiRwssoRXZVWHCC1F9gcWFYrlZA=
github.com/dolthub/eventsapi_schema v0.0.0-20250915094920-eadfd39051ca h1:BGFz/0OlKIuC6qHIZQbvPapFvdAJkeEyGXWVgL5clmE=
github.com/dolthub/eventsapi_schema v0.0.0-20250915094920-eadfd39051ca/go.mod h1:CoDLfgPqHyBtth0Cp+fi/CmC4R81zJNX4wPjShdZ+Bw=
github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2 h1:u3PMzfF8RkKd3lB9pZ2bfn0qEG+1Gms9599cr0REMww=
Expand Down
25 changes: 24 additions & 1 deletion server/ast/drop_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ package ast
import (
vitess "github.com/dolthub/vitess/go/vt/sqlparser"

"github.com/dolthub/doltgresql/server/auth"

"github.com/dolthub/doltgresql/postgres/parser/sem/tree"
)

Expand All @@ -27,5 +29,26 @@ func nodeDropSchema(ctx *Context, node *tree.DropSchema) (vitess.Statement, erro
return nil, nil
}

return NotYetSupportedError("DROP SCHEMA is not yet supported")
if len(node.Names) > 1 {
return NotYetSupportedError("DROP SCHEMA with multiple schema names is not yet supported.")
}

if node.DropBehavior == tree.DropCascade {
return NotYetSupportedError("DROP SCHEMA with CASCADE behavior is not yet supported.")
}

schemaName := node.Names[0]

return &vitess.DBDDL{
Action: vitess.DropStr,
SchemaOrDatabase: "schema",
DBName: schemaName,
CharsetCollate: nil,
IfExists: node.IfExists,
Auth: vitess.AuthInformation{
AuthType: auth.AuthType_DELETE,
TargetType: auth.AuthTargetType_SchemaIdentifiers,
TargetNames: []string{"", schemaName},
},
}, nil
}
2 changes: 1 addition & 1 deletion server/ast/no_op.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,5 @@ func NotYetSupportedError(errorMsg string) (vitess.Statement, error) {
return NewNoOp(errorMsg), nil
}

return nil, errors.New(errorMsg)
return nil, errors.Errorf(errorMsg + " Please file an issue at https://github.com/dolthub/doltgresql/issues")
}
8 changes: 4 additions & 4 deletions testing/generation/command_docs/output/drop_schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ import "testing"

func TestDropSchema(t *testing.T) {
tests := []QueryParses{
Parses("DROP SCHEMA name"),
Parses("DROP SCHEMA IF EXISTS name"),
Converts("DROP SCHEMA name"),
Converts("DROP SCHEMA IF EXISTS name"),
Parses("DROP SCHEMA name , name"),
Parses("DROP SCHEMA IF EXISTS name , name"),
Parses("DROP SCHEMA name CASCADE"),
Parses("DROP SCHEMA IF EXISTS name CASCADE"),
Parses("DROP SCHEMA name , name CASCADE"),
Parses("DROP SCHEMA IF EXISTS name , name CASCADE"),
Parses("DROP SCHEMA name RESTRICT"),
Parses("DROP SCHEMA IF EXISTS name RESTRICT"),
Converts("DROP SCHEMA name RESTRICT"),
Converts("DROP SCHEMA IF EXISTS name RESTRICT"),
Parses("DROP SCHEMA name , name RESTRICT"),
Parses("DROP SCHEMA IF EXISTS name , name RESTRICT"),
}
Expand Down
4 changes: 2 additions & 2 deletions testing/go/auth_quick_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,13 @@ func TestAuthQuick(t *testing.T) {
"CREATE SCHEMA newsch;",
},
},
{ // This isn't supported yet, but it is supposed to fail since tester is not an owner
{
Queries: []string{
"GRANT CREATE ON DATABASE postgres TO tester;",
"CREATE SCHEMA newsch;",
"DROP SCHEMA newsch;",
},
ExpectedErr: "not yet supported",
ExpectedErr: "permission denied for schema",
},
{
Queries: []string{
Expand Down
52 changes: 51 additions & 1 deletion testing/go/schemas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -869,11 +869,61 @@ var SchemaTests = []ScriptTest{
},
},
},
{
Name: "drop schema",
Focus: true,
SetUpScript: []string{
"CREATE SCHEMA dropme",
`CREATE schema "hasTables"`,
"CREATE TABLE hasTables.t1 (pk BIGINT PRIMARY KEY, v1 BIGINT);",
},
Assertions: []ScriptTestAssertion{
{
Query: "Show schemas",
Expected: []sql.Row{
{"dolt"},
{"dropme"},
{"hasTables"},
{"pg_catalog"},
{"public"},
{"information_schema"},
},
},
{
Query: "DROP SCHEMA dropme;",
Expected: []sql.Row{},
},
{
Query: "Show schemas",
Expected: []sql.Row{
{"dolt"},
{"hasTables"},
{"pg_catalog"},
{"public"},
{"information_schema"},
},
},
{
Query: "DROP SCHEMA dropme;",
ExpectedErr: "database schema not found",
},
{
Query: "drop schema if exists dropme;",
},
{
Query: "DROP SCHEMA hasTables;",
ExpectedErr: "cannot drop schema hastables because other objects depend on it",
},
{
Skip: true, // not implemented yet
Query: "drop schema hasTables cascade;",
},
},
},
Comment thread
zachmu marked this conversation as resolved.
// More tests:
// * alter table statements, when they work better
// * AS OF (when supported)
// * revision qualifiers
// * drop schema
// * more statement types
// * INSERT INTO schema1 SELECT FROM schema2
// * Subqueries accessing different schemas in the same SELECT
Expand Down
Loading