From ac1dd85d159b7f603d3fa10c09544ebb365e6bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Tue, 5 Nov 2024 10:25:32 +0100 Subject: [PATCH] Add support for creating unique indexes (#442) This PR adds a new attribute to `create_index` operation. From now on it is possible to create a unique index on one or more columns in a table. --- docs/README.md | 2 ++ examples/39_create_unique_index.json | 15 +++++++++++++++ pkg/migrations/op_create_index.go | 6 +++++- pkg/migrations/types.go | 3 +++ schema.json | 4 ++++ 5 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 examples/39_create_unique_index.json diff --git a/docs/README.md b/docs/README.md index 9c3a0801..e3ade53b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -974,12 +974,14 @@ A create index operation creates a new index on a set of columns. The field `method` can be `btree`, `hash`, `gist`, `spgist`, `gin`, `brin`. You can also specify storage parameters for the index in `storage_parameters`. +To create a unique index set `unique` to `true`. Example **create index** migrations: * [10_create_index.json](../examples/10_create_index.json) * [37_create_partial_index.json](../examples/37_create_partial_index.json) * [38_create_hash_index_with_fillfactor.json](../examples/38_create_hash_index_with_fillfactor.json) +* [39_create_unique_index.json](../examples/39_create_unique_index.json) ### Create table diff --git a/examples/39_create_unique_index.json b/examples/39_create_unique_index.json new file mode 100644 index 00000000..1aeee7a1 --- /dev/null +++ b/examples/39_create_unique_index.json @@ -0,0 +1,15 @@ +{ + "name": "39_create_unique_index", + "operations": [ + { + "create_index": { + "name": "idx_fruits_unique_name", + "table": "fruits", + "columns": [ + "name" + ], + "unique": true + } + } + ] +} diff --git a/pkg/migrations/op_create_index.go b/pkg/migrations/op_create_index.go index 4ccd97bf..55a1297e 100644 --- a/pkg/migrations/op_create_index.go +++ b/pkg/migrations/op_create_index.go @@ -17,7 +17,11 @@ 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) { // create index concurrently - stmt := fmt.Sprintf("CREATE INDEX CONCURRENTLY %s ON %s", + 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)) diff --git a/pkg/migrations/types.go b/pkg/migrations/types.go index efd401da..ec60e114 100644 --- a/pkg/migrations/types.go +++ b/pkg/migrations/types.go @@ -138,6 +138,9 @@ type OpCreateIndex struct { // Name of table on which to define the index Table string `json:"table"` + + // Indicates if the index is unique + Unique *bool `json:"unique,omitempty"` } type OpCreateIndexMethod string diff --git a/schema.json b/schema.json index e129f63c..ac607392 100644 --- a/schema.json +++ b/schema.json @@ -236,6 +236,10 @@ "storage_parameters": { "description": "Storage parameters for the index", "type": "string" + }, + "unique": { + "description": "Indicates if the index is unique", + "type": "boolean" } }, "required": ["columns", "name", "table"],