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

No previous version exists for the first migration #641

Open
agedemenli opened this issue Jan 30, 2025 · 0 comments
Open

No previous version exists for the first migration #641

agedemenli opened this issue Jan 30, 2025 · 0 comments
Assignees

Comments

@agedemenli
Copy link
Contributor

Since there is no "previous" version/schema for the first migration that is being run right after pgroll init, segv happens for column related changes such as adding unique constaint or a column; similar to #623

Having no previous version/schema might cause segv during Rollback, because it first tries to fetch the schema before the migration, in order to replay that migration on that schema. A similar issue that is happening when a sql command is run between migrations is fixed in #631 by taking inferred migrations into account. However, if the sql command is not added into migrations table, presumably because it is executed before pgroll init, pgroll wouldn't be able to find it.

To reproduce, first create a table:

create table products (id serial primary key, name varchar(255) unique, price decimal(10,2));

Then:

pgroll init
pgroll start ./examples/03_add_column.json
pgroll rollback ./examples/03_add_column.json
▀  Rolling back migration... (0s)panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x10 pc=0x10446ffe4]

goroutine 1 [running]:
github.com/xataio/pgroll/pkg/migrations.addColumn({0x104a6f4c0, 0x104eea2e0}, {0x104a6faa8, 0x104eea2e0}, {{0x0, 0x0, 0x0, 0x0, {0x14000292150, 0x17}, ...}, ...}, ...)
        /Users/ahmet/pgroll/pkg/migrations/op_add_column.go:242 +0x114
github.com/xataio/pgroll/pkg/migrations.(*OpAddColumn).Start(0x140002a2180, {0x104a6f4c0, 0x104eea2e0}, {0x104a6faa8, 0x104eea2e0}, {0x0, 0x0}, {0x104a67220, 0x104a62c10}, 0x1400028e3f0, ...)
        /Users/ahmet/pgroll/pkg/migrations/op_add_column.go:23 +0x134
github.com/xataio/pgroll/pkg/migrations.(*Migration).UpdateVirtualSchema(0x1400028e198?, {0x104a6f4c0, 0x104eea2e0}, 0x1400028e3f0)
        /Users/ahmet/pgroll/pkg/migrations/migrations.go:103 +0x84
github.com/xataio/pgroll/pkg/roll.(*Roll).Rollback(0x140000ed280, {0x104a6f4c0, 0x104eea2e0})
        /Users/ahmet/pgroll/pkg/roll/execute.go:259 +0x250
github.com/xataio/pgroll/cmd.init.func4(0x104e56440, {0x1046ca38b?, 0x4?, 0x1046ca363?})
        /Users/ahmet/pgroll/cmd/rollback.go:23 +0xf4
github.com/spf13/cobra.(*Command).execute(0x104e56440, {0x14000048980, 0x1, 0x1})
        /Users/ahmet/go/pkg/mod/github.com/spf13/[email protected]/command.go:985 +0x834
github.com/spf13/cobra.(*Command).ExecuteC(0x140001be608)
        /Users/ahmet/go/pkg/mod/github.com/spf13/[email protected]/command.go:1117 +0x344
github.com/spf13/cobra.(*Command).Execute(...)
        /Users/ahmet/go/pkg/mod/github.com/spf13/[email protected]/command.go:1041
github.com/xataio/pgroll/cmd.Execute()
        /Users/ahmet/pgroll/cmd/root.go:87 +0x20
main.main()
        /Users/ahmet/pgroll/main.go:12 +0x1c

Some candidate solutions:

  • Add a GUC, something like pgroll.initial_schema, and load it with the output of read_schema during pgroll init. If no previous version is found when Rollback, use it.
  • Add a new column to pgroll.migrations, something like previous_schema. At the beginning of Start, call read_schema and save the output in that column when inserting current migration into migrations. If no previous version is found when Rollback, use it.
  • At the beginning of Start, call read_schema and save the output in column resulting_schema when inserting current migration into migrations. If no previous version is found when Rollback, use it.

The third option doesn't sound good because what we are inserting there is not a 'resulting' schema. Kind of a hacky way but it will be updated during Complete anyway if the migration doesn't Rollback, so it looks harmless. If a Rollback happens instead of Complete it will be first useful for this case, and then deleted, harmless again. It would also save us from having another column added to migrations.

@agedemenli agedemenli self-assigned this Jan 30, 2025
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

No branches or pull requests

1 participant