summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2021-11-01 11:40:29 +0900
committerMichael Paquier <michael@paquier.xyz>2021-11-01 11:40:29 +0900
commit77f7909a409eac9ee9a5728a4f80741925580fb6 (patch)
treeb72532b036af3a3b258b7809ad2d9930085468b4 /src
parent3a5b313ce74864303a8a5d6556b49d642c422922 (diff)
Preserve opclass parameters across REINDEX CONCURRENTLY
The opclass parameter Datums from the old index are fetched in the same way as for predicates and expressions, by grabbing them directly from the system catalogs. They are then copied into the new IndexInfo that will be used for the creation of the new copy. This caused the new index to be rebuilt with default parameters rather than the ones pre-defined by a user. The only way to get back a new index with correct opclass parameters would be to recreate a new index from scratch. The issue has been introduced by 911e702. Author: Michael Paquier Reviewed-by: Zhihong Yu Discussion: https://postgr.es/m/YX0CG/QpLXcPr8HJ@paquier.xyz Backpatch-through: 13
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/index.c10
-rw-r--r--src/test/regress/expected/create_index.out19
-rw-r--r--src/test/regress/sql/create_index.sql9
3 files changed, 38 insertions, 0 deletions
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 852b9484ead..54f807af577 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -71,6 +71,7 @@
#include "storage/procarray.h"
#include "storage/smgr.h"
#include "utils/builtins.h"
+#include "utils/datum.h"
#include "utils/fmgroids.h"
#include "utils/guc.h"
#include "utils/inval.h"
@@ -1362,6 +1363,15 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId, const char
newInfo->ii_IndexAttrNumbers[i] = oldInfo->ii_IndexAttrNumbers[i];
}
+ /* Extract opclass parameters for each attribute, if any */
+ if (oldInfo->ii_OpclassOptions != NULL)
+ {
+ newInfo->ii_OpclassOptions = palloc0(sizeof(Datum) *
+ newInfo->ii_NumIndexAttrs);
+ for (int i = 0; i < newInfo->ii_NumIndexAttrs; i++)
+ newInfo->ii_OpclassOptions[i] = get_attoptions(oldIndexId, i + 1);
+ }
+
/*
* Now create the new index.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 977180a463a..0cf5624d28f 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2174,6 +2174,25 @@ SELECT indexrelid::regclass, indisreplident FROM pg_index
(1 row)
DROP TABLE concur_replident;
+-- Check that opclass parameters are preserved
+CREATE TABLE concur_appclass_tab(i tsvector, j tsvector, k tsvector);
+CREATE INDEX concur_appclass_ind on concur_appclass_tab
+ USING gist (i tsvector_ops (siglen='1000'), j tsvector_ops (siglen='500'));
+CREATE INDEX concur_appclass_ind_2 on concur_appclass_tab
+ USING gist (k tsvector_ops (siglen='300'), j tsvector_ops);
+REINDEX TABLE CONCURRENTLY concur_appclass_tab;
+\d concur_appclass_tab
+ Table "public.concur_appclass_tab"
+ Column | Type | Collation | Nullable | Default
+--------+----------+-----------+----------+---------
+ i | tsvector | | |
+ j | tsvector | | |
+ k | tsvector | | |
+Indexes:
+ "concur_appclass_ind" gist (i tsvector_ops (siglen='1000'), j tsvector_ops (siglen='500'))
+ "concur_appclass_ind_2" gist (k tsvector_ops (siglen='300'), j)
+
+DROP TABLE concur_appclass_tab;
-- Partitions
-- Create some partitioned tables
CREATE TABLE concur_reindex_part (c1 int, c2 int) PARTITION BY RANGE (c1);
diff --git a/src/test/regress/sql/create_index.sql b/src/test/regress/sql/create_index.sql
index 85eee18bb00..e6096a65257 100644
--- a/src/test/regress/sql/create_index.sql
+++ b/src/test/regress/sql/create_index.sql
@@ -888,6 +888,15 @@ REINDEX TABLE CONCURRENTLY concur_replident;
SELECT indexrelid::regclass, indisreplident FROM pg_index
WHERE indrelid = 'concur_replident'::regclass;
DROP TABLE concur_replident;
+-- Check that opclass parameters are preserved
+CREATE TABLE concur_appclass_tab(i tsvector, j tsvector, k tsvector);
+CREATE INDEX concur_appclass_ind on concur_appclass_tab
+ USING gist (i tsvector_ops (siglen='1000'), j tsvector_ops (siglen='500'));
+CREATE INDEX concur_appclass_ind_2 on concur_appclass_tab
+ USING gist (k tsvector_ops (siglen='300'), j tsvector_ops);
+REINDEX TABLE CONCURRENTLY concur_appclass_tab;
+\d concur_appclass_tab
+DROP TABLE concur_appclass_tab;
-- Partitions
-- Create some partitioned tables