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

Add support for comments in Spanner migrations #409

Merged
merged 1 commit into from
Jun 30, 2020

Conversation

alethenorio
Copy link
Contributor

At the moment GCP Spanner backend does not seem to support comments (issue being tracked at https://issuetracker.google.com/issues/159730604).
By parsing the migration DDL with spansql we are able to support comments and remove them before applying on the database.

Includes tests for comments as well

@coveralls
Copy link

coveralls commented Jun 24, 2020

Pull Request Test Coverage Report for Build 800

  • 10 of 27 (37.04%) changed or added relevant lines in 1 file are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage decreased (-0.2%) to 53.218%

Changes Missing Coverage Covered Lines Changed/Added Lines %
database/spanner/spanner.go 10 27 37.04%
Files with Coverage Reduction New Missed Lines %
database/spanner/spanner.go 1 7.01%
Totals Coverage Status
Change from base Build 795: -0.2%
Covered Lines: 2613
Relevant Lines: 4910

💛 - Coveralls

@alethenorio
Copy link
Contributor Author

What's the procedure here given the tiny coverage decrease due to a error check (which is already being tested on the library that returns the actual error anyway)?

Copy link
Member

@dhui dhui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!
Don't worry about the drop in test coverage since spanner doesn't have integration tests...

@@ -142,9 +143,12 @@ func (s *Spanner) Run(migration io.Reader) error {
}

// run migration
stmts := migrationStatements(migr)
ctx := context.Background()
stmts, err := migrationStatements(migr)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make statement parsing optional and disabled by default.
migrate should not be parsing migrations since we treat the migration contents as an opaque blob

Not sure why this isn't already behind an optional. Let's name it something like x-clean-statements and put it in Config.CleanStatements

Copy link
Contributor Author

@alethenorio alethenorio Jun 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright. I assumed the way it was working before was not considered parsing so I restored it and put behind a flag. Felt that x-strip-comments is a little more representative of the feature. What do you think?

Or did you mean to take the incoming byte slice and pass it straight as one statement?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe ParseDDL() also supports multiple statements, so x-strip-comments isn't an accurate description of the behavior.
CleanStatements seems like be best name so far since it re-formats the statements. e.g. does more than just parsing and validating structure.

I'm ok with making this a backwards incompatible change since it's limited to the spanner db driver and the trade-off of cleaner code is worth it. So anyone using this updated driver will need to specify x-clean-statements to continue multi-statement support. We'll document this in the release notes as a breaking change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright. Another push. Added a little more documentation on the README as well

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like it didn't end up getting listed as breaking, FWIW.

Running into some issues with this after updating, mentioned in #426

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @wyardley! I've updated the v4.12.0 release notes to mention this breaking change.

@dhui
Copy link
Member

dhui commented Jun 24, 2020

@alethenorio if you have bandwidth, we can bump up the test coverage for spanner in a separate PR: #410

@alethenorio
Copy link
Contributor Author

@alethenorio if you have bandwidth, we can bump up the test coverage for spanner in a separate PR: #410

No promises but I'll try to get to it

Copy link
Member

@dhui dhui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update!
Just a few minor things left.

}
} else {
// run migration
stmts = migrationStatements(migr)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remove migrationStatements() since it's now replaced by cleanStatements()?
e.g. something along the lines of:

stmts := []string{string(migr)}
if s.config.CleanStatements {
	stmts, err = cleanStatements(migr)
	if err != nil {
		return err
	}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -12,6 +12,7 @@ See [Google Spanner Documentation](https://cloud.google.com/spanner/docs) for de
| Param | WithInstance Config | Description |
| ----- | ------------------- | ----------- |
| `x-migrations-table` | `MigrationsTable` | Name of the migrations table |
| `x-clean-statements` | `CleanStatements` | Whether to parse DDL statements before running migration towards Spanner |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change this to "Whether to parse and clean". Also add something in the description about this flag and multi statement support.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

if err != nil {
return nil, err
}
stmts := []string{}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: pre-allocate the slice e.g. make([]string, 0, len(ddl.List))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@alethenorio
Copy link
Contributor Author

All very good comments. Fixed them all 👍

@alethenorio alethenorio requested a review from dhui June 29, 2020 08:54
Copy link
Member

@dhui dhui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing my feedback!
2 final things and we're good to merge.

if stmts := migrationStatements([]byte(tc.multiStatement)); !assert.Equal(t, stmts, tc.expected) {
stmts, err := cleanStatements([]byte(tc.multiStatement))
if err != nil {
t.Error()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this t.Fatal("Error cleaning statements:", err)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Since we are already using testify I switched the whole if statement to use require.NoError which does the same but avoids the extra if. Let me know if this is an issue

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, didn't know about require.NoError()!

if err != nil {
t.Error()
}
if !assert.Equal(t, tc.expected, stmts) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doh, I've done this a million times before and probably missed this on copy paste

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

At the moment GCP Spanner backend does not seem to support comments
(issue being tracked at
https://issuetracker.google.com/issues/159730604).
By adding support for parsing the migration DDL with spansql we are
able to support comments and remove them before applying on the
database
Copy link
Member

@dhui dhui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again for the PR!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants