mirror of
https://github.com/xataio/pgroll.git
synced 2024-09-11 05:45:48 +03:00
Distinguish inferred migrations by timestamp for statements within the same transaction (#362)
Set `created_at` and `updated_at` explicitly when inserting inferred migrations into the migrations table. When two statements are run in a transaction, we need to explicitly insert `statement_timestamp()` into the `created_at` and `updated_at` fields rather than relying on the table default of `current_timestamp`. `current_timestamp` is the same for all statements in a transaction, which causes problems when ordering statements by `created_at`. Fixes #361
This commit is contained in:
parent
84ef318cb1
commit
7cef8b1213
@ -309,7 +309,7 @@ BEGIN
|
||||
-- Someone did a schema change without pgroll, include it in the history
|
||||
SELECT INTO migration_id pg_catalog.format('sql_%%s',pg_catalog.substr(pg_catalog.md5(pg_catalog.random()::text), 0, 15));
|
||||
|
||||
INSERT INTO %[1]s.migrations (schema, name, migration, resulting_schema, done, parent, migration_type)
|
||||
INSERT INTO %[1]s.migrations (schema, name, migration, resulting_schema, done, parent, migration_type, created_at, updated_at)
|
||||
VALUES (
|
||||
schemaname,
|
||||
migration_id,
|
||||
@ -328,7 +328,9 @@ BEGIN
|
||||
%[1]s.read_schema(schemaname),
|
||||
true,
|
||||
%[1]s.latest_version(schemaname),
|
||||
'inferred'
|
||||
'inferred',
|
||||
statement_timestamp(),
|
||||
statement_timestamp()
|
||||
);
|
||||
END;
|
||||
$$;
|
||||
|
@ -10,10 +10,12 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/xataio/pgroll/pkg/migrations"
|
||||
"github.com/xataio/pgroll/pkg/schema"
|
||||
"github.com/xataio/pgroll/pkg/state"
|
||||
@ -272,6 +274,55 @@ func TestInferredMigration(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestInferredMigrationsInTransactionHaveDifferentTimestamps(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
testutils.WithStateAndConnectionToContainer(t, func(state *state.State, db *sql.DB) {
|
||||
// Start a transaction
|
||||
tx, err := db.BeginTx(ctx, nil)
|
||||
require.NoError(t, err)
|
||||
defer tx.Rollback()
|
||||
|
||||
// Create two tables in the transaction
|
||||
_, err = tx.ExecContext(ctx, "CREATE TABLE table1 (id int)")
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = tx.ExecContext(ctx, "CREATE TABLE table2 (id int)")
|
||||
require.NoError(t, err)
|
||||
|
||||
// Commit the transaction
|
||||
tx.Commit()
|
||||
|
||||
// Read the migrations from the migrations table
|
||||
rows, err := db.QueryContext(ctx,
|
||||
fmt.Sprintf("SELECT name, created_at, updated_at FROM %s.migrations ORDER BY created_at ASC", state.Schema()))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
type m struct {
|
||||
name string
|
||||
createdAt time.Time
|
||||
updatedAt time.Time
|
||||
}
|
||||
var migrations []m
|
||||
|
||||
for rows.Next() {
|
||||
var migration m
|
||||
if err := rows.Scan(&migration.name, &migration.createdAt, &migration.updatedAt); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
migrations = append(migrations, migration)
|
||||
}
|
||||
|
||||
// Ensure that the two inferred migrations have different timestamps
|
||||
assert.Equal(t, 2, len(migrations), "unexpected number of migrations")
|
||||
assert.NotEqual(t, migrations[0].createdAt, migrations[1].createdAt, "migrations have the same timestamp")
|
||||
})
|
||||
}
|
||||
|
||||
func TestPgRollInitializationInANonDefaultSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user