Record index uniqueness in pgroll's internal schema representation (#247)

Add uniqueness information to each index recorded in `pgroll`'s internal
schema representation.

With the extra information, the entry for indexes in the schema
representation now looks like:

```json
"indexes": {                                                           
    "products_name_unique": {                                          
        "name": "products_name_unique",                                
        "unique": true,                                                                                                              
    },                                                                  
    "_pgroll_new_products_pkey": {                                     
        "name": "_pgroll_new_products_pkey",                           
        "unique": true,                                                                                                          
    }                                                                  
}
```

Having index uniqueness recorded in the schema representation will help
with preserving uniqueness constraints on columns duplicated for
backfilling (see https://github.com/xataio/pgroll/issues/227).
This commit is contained in:
Andrew Farries 2024-01-22 15:04:54 +00:00 committed by GitHub
parent 7c1167a140
commit 4bee7acf06
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 45 additions and 6 deletions

View File

@ -75,6 +75,9 @@ type Column struct {
type Index struct {
// Name is the name of the index in postgres
Name string `json:"name"`
// Unique indicates whether or not the index is unique
Unique bool `json:"unique"`
}
type ForeignKey struct {

View File

@ -168,7 +168,8 @@ BEGIN
),
'indexes', (
SELECT json_object_agg(pi.indexrelid::regclass, json_build_object(
'name', pi.indexrelid::regclass
'name', pi.indexrelid::regclass,
'unique', pi.indisunique
))
FROM pg_index pi
WHERE pi.indrelid = t.oid::regclass

View File

@ -104,7 +104,8 @@ func TestReadSchema(t *testing.T) {
},
Indexes: map[string]schema.Index{
"id_unique": {
Name: "id_unique",
Name: "id_unique",
Unique: true,
},
},
UniqueConstraints: map[string]schema.UniqueConstraint{
@ -117,6 +118,36 @@ func TestReadSchema(t *testing.T) {
},
},
},
{
name: "non-unique index",
createStmt: "CREATE TABLE public.table1 (id int, name text); CREATE INDEX idx_name ON public.table1 (name)",
wantSchema: &schema.Schema{
Name: "public",
Tables: map[string]schema.Table{
"table1": {
Name: "table1",
Columns: map[string]schema.Column{
"id": {
Name: "id",
Type: "integer",
Nullable: true,
},
"name": {
Name: "name",
Type: "text",
Nullable: true,
},
},
Indexes: map[string]schema.Index{
"idx_name": {
Name: "idx_name",
Unique: false,
},
},
},
},
},
},
{
name: "foreign key",
createStmt: "CREATE TABLE public.table1 (id int PRIMARY KEY); CREATE TABLE public.table2 (fk int NOT NULL, CONSTRAINT fk_fkey FOREIGN KEY (fk) REFERENCES public.table1 (id))",
@ -136,7 +167,8 @@ func TestReadSchema(t *testing.T) {
PrimaryKey: []string{"id"},
Indexes: map[string]schema.Index{
"table1_pkey": {
Name: "table1_pkey",
Name: "table1_pkey",
Unique: true,
},
},
},
@ -185,7 +217,8 @@ func TestReadSchema(t *testing.T) {
PrimaryKey: []string{"id"},
Indexes: map[string]schema.Index{
"table1_pkey": {
Name: "table1_pkey",
Name: "table1_pkey",
Unique: true,
},
},
CheckConstraints: map[string]schema.CheckConstraint{
@ -224,10 +257,12 @@ func TestReadSchema(t *testing.T) {
PrimaryKey: []string{"id"},
Indexes: map[string]schema.Index{
"table1_pkey": {
Name: "table1_pkey",
Name: "table1_pkey",
Unique: true,
},
"name_unique": {
Name: "name_unique",
Name: "name_unique",
Unique: true,
},
},
UniqueConstraints: map[string]schema.UniqueConstraint{