Skip to content
2 changes: 1 addition & 1 deletion go/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ require (
github.com/dolthub/dolt-mcp v0.2.2
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.20260106231211-877fb58d389e
github.com/dolthub/go-mysql-server v0.20.1-0.20260108001605-ff0a497ea62f
github.com/dolthub/gozstd v0.0.0-20240423170813-23a2903bca63
github.com/edsrzf/mmap-go v1.2.0
github.com/esote/minmaxheap v1.0.0
Expand Down
4 changes: 2 additions & 2 deletions go/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,8 @@ github.com/dolthub/fslock v0.0.0-20251215194149-ef20baba2318 h1:n+vdH5G5Db+1qnDC
github.com/dolthub/fslock v0.0.0-20251215194149-ef20baba2318/go.mod h1:QWql+P17oAAMLnL4HGB5tiovtDuAjdDTPbuqx7bYfa0=
github.com/dolthub/go-icu-regex v0.0.0-20250916051405-78a38d478790 h1:zxMsH7RLiG+dlZ/y0LgJHTV26XoiSJcuWq+em6t6VVc=
github.com/dolthub/go-icu-regex v0.0.0-20250916051405-78a38d478790/go.mod h1:F3cnm+vMRK1HaU6+rNqQrOCyR03HHhR1GWG2gnPOqaE=
github.com/dolthub/go-mysql-server v0.20.1-0.20260106231211-877fb58d389e h1:Ro9BWRdOTiZ4HaVc8U8Zj+hJSauf3inWpXw5vuy+qcg=
github.com/dolthub/go-mysql-server v0.20.1-0.20260106231211-877fb58d389e/go.mod h1:T+oVXfQAETbWm9R55daMqg0HE7W7Fz7bzh+pGiQgaPI=
github.com/dolthub/go-mysql-server v0.20.1-0.20260108001605-ff0a497ea62f h1:pKwWXc4w96VvPKQ81S8uVBXRJxsxRInvKZIS/hpoCg4=
github.com/dolthub/go-mysql-server v0.20.1-0.20260108001605-ff0a497ea62f/go.mod h1:T+oVXfQAETbWm9R55daMqg0HE7W7Fz7bzh+pGiQgaPI=
github.com/dolthub/gozstd v0.0.0-20240423170813-23a2903bca63 h1:OAsXLAPL4du6tfbBgK0xXHZkOlos63RdKYS3Sgw/dfI=
github.com/dolthub/gozstd v0.0.0-20240423170813-23a2903bca63/go.mod h1:lV7lUeuDhH5thVGDCKXbatwKy2KW80L4rMT46n+Y2/Q=
github.com/dolthub/ishell v0.0.0-20240701202509-2b217167d718 h1:lT7hE5k+0nkBdj/1UOSFwjWpNxf+LCApbRHgnCA17XE=
Expand Down
51 changes: 50 additions & 1 deletion go/libraries/doltcore/doltdb/root_val.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,10 @@ var DoltFeatureVersion FeatureVersion = 7 // last bumped when fixing bug related
// RootValue is the value of the Database and is the committed value in every Dolt or Doltgres commit.
type RootValue interface {
Rootish

// CreateDatabaseSchema creates the given schema. This differs from a table's schema.
CreateDatabaseSchema(ctx context.Context, dbSchema schema.DatabaseSchema) (RootValue, error)
// DropDatabaseSchema drops the given schema. This differs from a table's schema.
DropDatabaseSchema(ctx context.Context, dbSchema schema.DatabaseSchema) (RootValue, error)
// DebugString returns a human readable string with the contents of this root. If |transitive| is true, row data from
// all tables is also included. This method is very expensive for large root values, so |transitive| should only be used
// when debugging tests.
Expand Down Expand Up @@ -1060,6 +1061,54 @@ func (root *rootValue) CreateDatabaseSchema(ctx context.Context, dbSchema schema
return root.withStorage(r), nil
}

// DropDatabaseSchema drops a database schema from the root value.
// This is currently unused in Dolt because dolt always has only a single (unnamed) schema. But it's implemented
// because technically Dolt can support multiple schemas whenever we decide to.
func (root *rootValue) DropDatabaseSchema(ctx context.Context, dbSchema schema.DatabaseSchema) (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)
}

tableMap, err := root.getTableMap(ctx, schemaName)
if err != nil {
return nil, err
}

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

if tablesInSchema {
return nil, fmt.Errorf("Cannot drop schema %s because it still contains tables", schemaName)
}

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

return root.withStorage(r), nil
}

// HashOf gets the hash of the root value
func (root *rootValue) HashOf() (hash.Hash, error) {
if root.rootHash.IsEmpty() {
Expand Down
8 changes: 8 additions & 0 deletions go/libraries/doltcore/sqle/clusterdb/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,18 @@ func (db database) GetSchema(ctx *sql.Context, schemaName string) (sql.DatabaseS
panic(fmt.Sprintf("GetSchema is not implemented for database %T", db))
}

func (db database) SupportsDatabaseSchemas() bool {
return false
}

func (db database) CreateSchema(ctx *sql.Context, schemaName string) error {
panic(fmt.Sprintf("CreateSchema is not implemented for database %T", db))
}

func (db database) DropSchema(ctx *sql.Context, schemaName string) error {
panic(fmt.Sprintf("DropSchema is not implemented for database %T", db))
}

func (db database) AllSchemas(ctx *sql.Context) ([]sql.DatabaseSchema, error) {
panic(fmt.Sprintf("AllSchemas is not implemented for database %T", db))
}
Expand Down
42 changes: 40 additions & 2 deletions go/libraries/doltcore/sqle/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -2173,6 +2173,14 @@ func (db Database) CreateTemporaryTable(ctx *sql.Context, tableName string, pkSc
return nil
}

// SupportsDatabaseSchemas implements sql.SchemaDatabase
// TODO: this interface is only necessary because we don't have a separate sql.Database implementation for doltgres,
// which has additional capabilities (like schema creation). Dolt technically can create schemas (multiple DBs in
// the same commit graph), but there's no way for users to access this functionality currently.
func (db Database) SupportsDatabaseSchemas() bool {
return resolve.UseSearchPath
}

// CreateSchema implements sql.SchemaDatabase
func (db Database) CreateSchema(ctx *sql.Context, schemaName string) error {
if err := dsess.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil {
Expand Down Expand Up @@ -2203,6 +2211,36 @@ func (db Database) CreateSchema(ctx *sql.Context, schemaName string) error {
return db.SetRoot(ctx, root)
}

// DropSchema implements sql.SchemaDatabase
func (db Database) DropSchema(ctx *sql.Context, schemaName string) error {
if err := dsess.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil {
return err
}

root, err := db.GetRoot(ctx)
if err != nil {
return err
}

_, exists, err := doltdb.ResolveDatabaseSchema(ctx, root, schemaName)
if err != nil {
return err
}

if !exists {
return sql.ErrDatabaseSchemaNotFound.New(schemaName)
}

root, err = root.DropDatabaseSchema(ctx, schema.DatabaseSchema{
Name: schemaName,
})
if err != nil {
return err
}

return db.SetRoot(ctx, root)
}

// GetSchema implements sql.SchemaDatabase
func (db Database) GetSchema(ctx *sql.Context, schemaName string) (sql.DatabaseSchema, bool, error) {
// For doltgres, the information_schema database should be a schema.
Expand Down Expand Up @@ -2558,13 +2596,13 @@ func (db Database) CreateTrigger(ctx *sql.Context, definition sql.TriggerDefinit
definition.Name,
definition.CreateStatement,
definition.CreatedAt,
fmt.Errorf("triggers `%s` already exists", definition.Name), //TODO: add a sql error and return that instead
fmt.Errorf("triggers `%s` already exists", definition.Name), // TODO: add a sql error and return that instead
)
}

// DropTrigger implements sql.TriggerDatabase.
func (db Database) DropTrigger(ctx *sql.Context, name string) error {
//TODO: add a sql error and use that as the param error instead
// TODO: add a sql error and use that as the param error instead
return db.dropFragFromSchemasTable(ctx, "trigger", name, sql.ErrTriggerDoesNotExist.New(name))
}

Expand Down
8 changes: 8 additions & 0 deletions go/libraries/doltcore/sqle/user_space_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,18 @@ func (db *UserSpaceDatabase) GetSchema(ctx *sql.Context, schemaName string) (sql
panic(fmt.Sprintf("GetSchema is not implemented for database %T", db))
}

func (db UserSpaceDatabase) SupportsDatabaseSchemas() bool {
return false
}

func (db *UserSpaceDatabase) CreateSchema(ctx *sql.Context, schemaName string) error {
panic(fmt.Sprintf("CreateSchema is not implemented for database %T", db))
}

func (db *UserSpaceDatabase) DropSchema(ctx *sql.Context, schemaName string) error {
panic(fmt.Sprintf("DropSchema is not implemented for database %T", db))
}

func (db *UserSpaceDatabase) AllSchemas(ctx *sql.Context) ([]sql.DatabaseSchema, error) {
panic(fmt.Sprintf("AllSchemas is not implemented for database %T", db))
}
Expand Down
Loading