Skip to content

Commit

Permalink
Allow adding an index to a table created in the same migration (xatai…
Browse files Browse the repository at this point in the history
…o#451)

Allow the `create_index` operation to add an index to a table that was
created by an operation earlier in the same migration.

The following migration would previously have failed to start:

```json
{
  "name": "43_multiple_ops",
  "operations": [
    {
      "create_table": {
        "name": "players",
        "columns": [
          {
            "name": "id",
            "type": "serial",
            "pk": true
          },
          {
            "name": "name",
            "type": "varchar(255)",
            "check": {
              "name": "name_length_check",
              "constraint": "length(name) > 2"
            }
          }
        ]
      }
    },
    {
      "create_index": {
        "name": "idx_player_name",
        "table": "players",
        "columns": [
          "name"
        ]
      }
    }
  ]
}
```

As of this PR the migration can be started.

The above migration does not validate yet, but it can be started
successfully with the --skip-validation flag to the start command.

Part of xataio#239
  • Loading branch information
andrew-farries authored and kvch committed Nov 11, 2024
1 parent 8fee548 commit 8297c87
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
4 changes: 3 additions & 1 deletion pkg/migrations/op_create_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ import (
var _ Operation = (*OpCreateIndex)(nil)

func (o *OpCreateIndex) Start(ctx context.Context, conn db.DB, latestSchema string, tr SQLTransformer, s *schema.Schema, cbs ...CallbackFn) (*schema.Table, error) {
table := s.GetTable(o.Table)

// create index concurrently
stmtFmt := "CREATE INDEX CONCURRENTLY %s ON %s"
if o.Unique != nil && *o.Unique {
stmtFmt = "CREATE UNIQUE INDEX CONCURRENTLY %s ON %s"
}
stmt := fmt.Sprintf(stmtFmt,
pq.QuoteIdentifier(o.Name),
pq.QuoteIdentifier(o.Table))
pq.QuoteIdentifier(table.Name))

if o.Method != nil {
stmt += fmt.Sprintf(" USING %s", string(*o.Method))
Expand Down
50 changes: 50 additions & 0 deletions pkg/migrations/op_create_index_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"testing"

"github.com/xataio/pgroll/pkg/migrations"
"github.com/xataio/pgroll/pkg/roll"
)

func TestCreateIndex(t *testing.T) {
Expand Down Expand Up @@ -313,3 +314,52 @@ func TestCreateIndexOnMultipleColumns(t *testing.T) {
},
}})
}

func TestCreateIndexOnTableCreatedInSameMigration(t *testing.T) {
t.Parallel()

ExecuteTests(t, TestCases{
{
name: "create index on newly created table",
migrations: []migrations.Migration{
{
Name: "01_add_table",
Operations: migrations.Operations{
&migrations.OpCreateTable{
Name: "users",
Columns: []migrations.Column{
{
Name: "id",
Type: "serial",
Pk: ptr(true),
},
{
Name: "name",
Type: "varchar(255)",
Nullable: ptr(false),
},
},
},
&migrations.OpCreateIndex{
Name: "idx_users_name",
Table: "users",
Columns: []string{"name"},
},
},
},
},
afterStart: func(t *testing.T, db *sql.DB, schema string) {
// The index has been created on the underlying table.
IndexMustExist(t, db, schema, migrations.TemporaryName("users"), "idx_users_name")
},
afterRollback: func(t *testing.T, db *sql.DB, schema string) {
// The index has been dropped from the the underlying table.
IndexMustNotExist(t, db, schema, "users", "idx_users_name")
},
afterComplete: func(t *testing.T, db *sql.DB, schema string) {
// The index remains on the underlying table.
IndexMustExist(t, db, schema, "users", "idx_users_name")
},
},
}, roll.WithSkipValidation(true)) // TODO: Remove once this migration passes validation
}

0 comments on commit 8297c87

Please sign in to comment.