diff --git a/go/vt/schemadiff/diff_test.go b/go/vt/schemadiff/diff_test.go index ab9d8aaf9c8..c271a7662b1 100644 --- a/go/vt/schemadiff/diff_test.go +++ b/go/vt/schemadiff/diff_test.go @@ -560,7 +560,7 @@ func TestDiffSchemas(t *testing.T) { name: "create view: unresolved dependencies", from: "create table t(id int)", to: "create table t(id int); create view v1 as select id from t2", - expectError: ErrViewDependencyUnresolved.Error(), + expectError: (&ApplyViewNotFoundError{View: "v1"}).Error(), }, { name: "convert table to view", diff --git a/go/vt/schemadiff/errors.go b/go/vt/schemadiff/errors.go index 06d6aa6bc6d..0ea4dfecda1 100644 --- a/go/vt/schemadiff/errors.go +++ b/go/vt/schemadiff/errors.go @@ -14,7 +14,6 @@ var ( ErrUnexpectedTableSpec = errors.New("unexpected table spec") ErrExpectedCreateTable = errors.New("expected a CREATE TABLE statement") ErrExpectedCreateView = errors.New("expected a CREATE VIEW statement") - ErrViewDependencyUnresolved = errors.New("views have unresolved/loop dependencies") ) type UnsupportedEntityError struct { @@ -239,3 +238,11 @@ func (e *InvalidColumnInForeignKeyConstraintError) Error() string { return fmt.Sprintf("invalid column %s referenced by foreign key constraint %s in table %s", sqlescape.EscapeID(e.Column), sqlescape.EscapeID(e.Constraint), sqlescape.EscapeID(e.Table)) } + +type ViewDependencyUnresolvedError struct { + View string +} + +func (e *ViewDependencyUnresolvedError) Error() string { + return fmt.Sprintf("view %s has unresolved/loop dependencies", sqlescape.EscapeID(e.View)) +} diff --git a/go/vt/schemadiff/schema.go b/go/vt/schemadiff/schema.go index abe307cf987..ec9b3476052 100644 --- a/go/vt/schemadiff/schema.go +++ b/go/vt/schemadiff/schema.go @@ -230,7 +230,13 @@ func (s *Schema) normalize() error { // We have leftover views. This can happen if the schema definition is invalid: // - a view depends on a nonexistent table // - two views have a circular dependency - return ErrViewDependencyUnresolved + for _, v := range s.views { + if _, ok := dependencyLevels[v.Name()]; !ok { + // We _know_ that in this iteration, at least one view is found unassigned a dependency level. + // We return the first one. + return &ApplyViewNotFoundError{View: v.ViewName.Name.String()} + } + } } return nil } diff --git a/go/vt/schemadiff/schema_test.go b/go/vt/schemadiff/schema_test.go index 44d116a0892..1a916f4b7a0 100644 --- a/go/vt/schemadiff/schema_test.go +++ b/go/vt/schemadiff/schema_test.go @@ -110,7 +110,7 @@ func TestNewSchemaFromQueriesUnresolved(t *testing.T) { ) _, err := NewSchemaFromQueries(queries) assert.Error(t, err) - assert.ErrorIs(t, err, ErrViewDependencyUnresolved) + assert.EqualError(t, err, (&ApplyViewNotFoundError{View: "v7"}).Error()) } func TestNewSchemaFromQueriesUnresolvedAlias(t *testing.T) { @@ -120,7 +120,7 @@ func TestNewSchemaFromQueriesUnresolvedAlias(t *testing.T) { ) _, err := NewSchemaFromQueries(queries) assert.Error(t, err) - assert.ErrorIs(t, err, ErrViewDependencyUnresolved) + assert.EqualError(t, err, (&ApplyViewNotFoundError{View: "v7"}).Error()) } func TestNewSchemaFromQueriesLoop(t *testing.T) { @@ -131,7 +131,7 @@ func TestNewSchemaFromQueriesLoop(t *testing.T) { ) _, err := NewSchemaFromQueries(queries) assert.Error(t, err) - assert.ErrorIs(t, err, ErrViewDependencyUnresolved) + assert.EqualError(t, err, (&ApplyViewNotFoundError{View: "v7"}).Error()) } func TestToSQL(t *testing.T) {