Skip to content

Commit

Permalink
Add Schema member to AbstractStatement
Browse files Browse the repository at this point in the history
  • Loading branch information
kolbe committed Feb 21, 2025
1 parent ff2e5c5 commit 8ab1f26
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 17 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ cmd/spirit/spirit

# Dependency directories (remove the comment below to include it)
# vendor/

.goosehints
.goose
6 changes: 3 additions & 3 deletions pkg/migration/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,12 @@ func (m *Migration) normalizeOptions() (stmt *statement.AbstractStatement, err e
// This also returns the StmtNode.
stmt, err = statement.New(m.Statement)
if err != nil {
if err == statement.ErrSchemaNameIncluded {
return nil, err
}
// Omit the parser error messages, just show the statement.
return nil, errors.New("could not parse SQL statement: " + m.Statement)
}
if stmt.Schema != "" && stmt.Schema != m.Database {
return nil, errors.New("schema name in statement (`schema`.`table`) does not match --database")
}
} else {
if m.Table == "" {
return nil, errors.New("table name is required")
Expand Down
33 changes: 19 additions & 14 deletions pkg/statement/statement.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ import (
)

type AbstractStatement struct {
Schema string
Table string
Alter string // may be empty.
Statement string
StmtNode *ast.StmtNode
}

var (
ErrSchemaNameIncluded = errors.New("schema name included in the table name is not supported")
ErrNotSupportedStatement = errors.New("not a supported statement type")
ErrNotAlterTable = errors.New("not an ALTER TABLE statement")
)
Expand All @@ -42,18 +42,16 @@ func New(statement string) (*AbstractStatement, error) {
// if the schema name is included it could be different from the --database
// specified, which causes all sorts of problems. The easiest way to handle this
// it just to not permit it.
if alterStmt.Table.Schema.String() != "" {
return nil, ErrSchemaNameIncluded
}
var sb strings.Builder
sb.Reset()
rCtx := format.NewRestoreCtx(format.DefaultRestoreFlags, &sb)
if err = alterStmt.Restore(rCtx); err != nil {
return nil, fmt.Errorf("could not restore alter table statement: %s", err)
return nil, fmt.Errorf("could not restore alter clause statement: %s", err)
}
normalizedStmt := sb.String()
trimLen := len(alterStmt.Table.Name.String()) + 15 // len ALTER TABLE + quotes
return &AbstractStatement{
Schema: alterStmt.Table.Schema.String(),
Table: alterStmt.Table.Name.String(),
Alter: normalizedStmt[trimLen:],
Statement: statement,
Expand All @@ -66,34 +64,41 @@ func New(statement string) (*AbstractStatement, error) {
// but it's not a spirit migration. But the table should be specified.
case *ast.CreateTableStmt:
stmt := stmtNodes[0].(*ast.CreateTableStmt)
if stmt.Table.Schema.String() != "" {
return nil, ErrSchemaNameIncluded
}
return &AbstractStatement{
Schema: stmt.Table.Schema.String(),
Table: stmt.Table.Name.String(),
Statement: statement,
StmtNode: &stmtNodes[0],
}, err
case *ast.DropTableStmt:
stmt := stmtNodes[0].(*ast.DropTableStmt)
distinctSchemas := make(map[string]struct{})
for _, table := range stmt.Tables {
if table.Schema.String() != "" {
return nil, ErrSchemaNameIncluded
}
distinctSchemas[table.Schema.String()] = struct{}{}
}
if len(distinctSchemas) > 1 {
return nil, errors.New("statement attempts to drop tables from multiple schemas")
}
return &AbstractStatement{
Schema: stmt.Tables[0].Schema.String(),
Table: stmt.Tables[0].Name.String(), // TODO: this is just used in log lines, but there could be more than one!
Statement: statement,
StmtNode: &stmtNodes[0],
}, err
case *ast.RenameTableStmt:
stmt := stmtNodes[0].(*ast.RenameTableStmt)
for _, table := range stmt.TableToTables {
if table.OldTable.Schema.String() != "" || table.NewTable.Schema.String() != "" {
return nil, ErrSchemaNameIncluded
distinctSchemas := make(map[string]struct{})
for _, clause := range stmt.TableToTables {
if clause.OldTable.Schema.String() != clause.NewTable.Schema.String() {
return nil, errors.New("statement attempts to move table between schemas")
}
distinctSchemas[clause.OldTable.Schema.String()] = struct{}{}
}
if len(distinctSchemas) > 1 {
return nil, errors.New("statement attempts to rename tables in multiple schemas")
}
return &AbstractStatement{
Schema: stmt.TableToTables[0].OldTable.Schema.String(),
Table: stmt.TableToTables[0].OldTable.Name.String(), // TODO: this is just used in log lines, but there could be more than one!
Statement: statement,
StmtNode: &stmtNodes[0],
Expand Down

0 comments on commit 8ab1f26

Please sign in to comment.