Skip to content

Commit 7b383dc

Browse files
authored
Improve create_index operation with extra index element settings (#697)
This PR adds a breaking change to `create_index` operation. From now on `columns` does not accept a list of column names. Instead it expects a map, so we can support for additional index elements settings. New settings: * `collation`: name of the collation to use on the column * `opclass`: `opclass.name` sets the name of the operator class and `opclass.params` expects a KV pairs for operator class settings * `sort`: change the ordering (`ASC` or `DESC`) * `nulls`: change the position of null values in the index (`FIRST` or `LAST`)
1 parent e4d2408 commit 7b383dc

19 files changed

+444
-79
lines changed

docs/operations/create_index.mdx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,20 @@ description: A create index operation creates a new index on a set of columns.
1010
"create_index": {
1111
"table": "name of table on which to define the index",
1212
"name": "index name",
13-
"columns": [ "names of columns on which to define the index" ]
13+
"columns": [
14+
"column_name": {
15+
"collate": "collation name",
16+
"sort": "ASC | DESC",
17+
"nulls": "FIRST | LAST",
18+
"opclass": {
19+
"name": "operator_class_name",
20+
"params": [
21+
"param1=val",
22+
"param2=val"
23+
]
24+
}
25+
}
26+
]
1427
"predicate": "conditional expression for defining a partial index",
1528
"storage_parameters": "comma-separated list of storage parameters",
1629
"unique": true | false,
@@ -51,3 +64,9 @@ Set storage parameters and index method:
5164
Create a unique index:
5265

5366
<ExampleSnippet example="42_create_unique_index.json" language="json" />
67+
68+
### Create an index with custom operator class
69+
70+
Create an index with a custom operator class:
71+
72+
<ExampleSnippet example="54_create_index_with_opclass.json" language="json" />

examples/.ledger

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,4 @@
5151
51_create_table_with_table_foreign_key_constraint.json
5252
52_create_table_with_exclusion_constraint.json
5353
53_add_column_with_volatile_default.json
54+
54_create_index_with_opclass.json

examples/10_create_index.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
"create_index": {
66
"name": "idx_fruits_name",
77
"table": "fruits",
8-
"columns": [
9-
"name"
10-
]
8+
"columns": {
9+
"name": {}
10+
}
1111
}
1212
}
1313
]

examples/37_create_partial_index.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
"create_index": {
66
"name": "idx_fruits_id_gt_10",
77
"table": "fruits",
8-
"columns": [
9-
"id"
10-
],
8+
"columns": {
9+
"id": {}
10+
},
1111
"predicate": "id > 10"
1212
}
1313
}

examples/38_create_hash_index_with_fillfactor.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
"create_index": {
66
"name": "idx_fruits_name",
77
"table": "fruits",
8-
"columns": [
9-
"name"
10-
],
8+
"columns": {
9+
"name": {}
10+
},
1111
"method": "hash",
1212
"storage_parameters": "fillfactor = 70"
1313
}

examples/42_create_unique_index.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
"create_index": {
66
"name": "idx_fruits_unique_name",
77
"table": "fruits",
8-
"columns": [
9-
"name"
10-
],
8+
"columns": {
9+
"name": {}
10+
},
1111
"unique": true
1212
}
1313
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "54_create_index_with_opclass",
3+
"operations": [
4+
{
5+
"create_index": {
6+
"name": "idx_fruits_custom_opclass",
7+
"table": "fruits",
8+
"columns": {
9+
"id": {
10+
"opclass": {
11+
"name": "int8_ops"
12+
}
13+
}
14+
}
15+
}
16+
}
17+
]
18+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ require (
1515
github.com/stretchr/testify v1.10.0
1616
github.com/testcontainers/testcontainers-go v0.35.0
1717
github.com/testcontainers/testcontainers-go/modules/postgres v0.35.0
18-
github.com/xataio/pg_query_go/v6 v6.0.0-20250124115938-4fa82ad6d036
18+
github.com/xataio/pg_query_go/v6 v6.0.0-20250226155420-277802e03678
1919
golang.org/x/tools v0.30.0
2020
)
2121

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,10 @@ github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYg
223223
github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE=
224224
github.com/xataio/pg_query_go/v6 v6.0.0-20250124115938-4fa82ad6d036 h1:QMjBW1XIFUDzyUs/zlYmUo8lNO+hQ4VVt0msFv2AYpw=
225225
github.com/xataio/pg_query_go/v6 v6.0.0-20250124115938-4fa82ad6d036/go.mod h1:GK6bpfAhPtZb7wG/IccqvnH+cz3cmvvRTkC+MosESGo=
226+
github.com/xataio/pg_query_go/v6 v6.0.0-20250226124908-814e464c6798 h1:rfb51gWpD24si3My5eiSJBGFKl+uzxN+He53bZCMsOw=
227+
github.com/xataio/pg_query_go/v6 v6.0.0-20250226124908-814e464c6798/go.mod h1:GK6bpfAhPtZb7wG/IccqvnH+cz3cmvvRTkC+MosESGo=
228+
github.com/xataio/pg_query_go/v6 v6.0.0-20250226155420-277802e03678 h1:jNslWEyKOXeYi7wZfkcSfsR/slEemAU5rVKBvkNnSsg=
229+
github.com/xataio/pg_query_go/v6 v6.0.0-20250226155420-277802e03678/go.mod h1:GK6bpfAhPtZb7wG/IccqvnH+cz3cmvvRTkC+MosESGo=
226230
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
227231
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
228232
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=

pkg/migrations/op_common_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,13 @@ func IndexMustExist(t *testing.T, db *sql.DB, schema, table, index string) {
309309
}
310310
}
311311

312+
func IndexDescendingMustExist(t *testing.T, db *sql.DB, schema, table, index string, columnIdx int) {
313+
t.Helper()
314+
if !indexDescendingExists(t, db, schema, table, index, columnIdx) {
315+
t.Fatalf("Expected index %q to exist", index)
316+
}
317+
}
318+
312319
func IndexMustNotExist(t *testing.T, db *sql.DB, schema, table, index string) {
313320
t.Helper()
314321
if indexExists(t, db, schema, table, index) {
@@ -357,6 +364,25 @@ func indexExists(t *testing.T, db *sql.DB, schema, table, index string) bool {
357364
return exists
358365
}
359366

367+
func indexDescendingExists(t *testing.T, db *sql.DB, schema, table, index string, columnIdx int) bool {
368+
t.Helper()
369+
370+
var flags []uint8
371+
err := db.QueryRow(`
372+
SELECT indoption
373+
FROM pg_index
374+
WHERE indrelid = $1::regclass
375+
AND indexrelid = $2::regclass`,
376+
fmt.Sprintf("%s.%s", schema, table), fmt.Sprintf("%s.%s", schema, index)).Scan(&flags)
377+
if err != nil {
378+
t.Fatal(err)
379+
}
380+
381+
// check if index is descending using the 1st bit of the flags
382+
indoptionDesc := uint8(1)
383+
return flags[columnIdx]&indoptionDesc == 1
384+
}
385+
360386
func CheckIndexDefinition(t *testing.T, db *sql.DB, schema, table, index, expectedDefinition string) {
361387
t.Helper()
362388

0 commit comments

Comments
 (0)