From 2646d2d4a9d8b978fda0d0d1affae4788a30f604 Mon Sep 17 00:00:00 2001 From: Simon Riggs Date: Thu, 11 Dec 2014 22:54:05 +0000 Subject: [PATCH] Further changes to REINDEX SCHEMA Ensure we reindex indexes built on Mat Views. Based on patch from Micheal Paquier Add thorough tests to check that indexes on tables, toast tables and mat views are reindexed. Simon Riggs --- src/backend/commands/indexcmds.c | 16 +++--- src/test/regress/expected/create_index.out | 60 +++++++++++++++++++--- src/test/regress/sql/create_index.sql | 34 ++++++++++-- 3 files changed, 95 insertions(+), 15 deletions(-) diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index cf4de7281d..2b45699107 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -1867,16 +1867,16 @@ ReindexObject(const char *objectName, ReindexObjectType objectKind) */ if (objectKind == REINDEX_OBJECT_SCHEMA) { - scan_keys = palloc(sizeof(ScanKeyData) * 2); + /* + * Return all objects in schema. We filter out + * inappropriate objects as we walk through results. + */ + num_keys = 1; + scan_keys = palloc(sizeof(ScanKeyData)); ScanKeyInit(&scan_keys[0], Anum_pg_class_relnamespace, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectOid)); - ScanKeyInit(&scan_keys[1], - Anum_pg_class_relkind, - BTEqualStrategyNumber, F_CHAREQ, - 'r'); - num_keys = 2; } else num_keys = 0; @@ -1894,6 +1894,10 @@ ReindexObject(const char *objectName, ReindexObjectType objectKind) Form_pg_class classtuple = (Form_pg_class) GETSTRUCT(tuple); Oid relid = HeapTupleGetOid(tuple); + /* + * Only regular tables and matviews can have indexes, + * so filter out any other kind of object. + */ if (classtuple->relkind != RELKIND_RELATION && classtuple->relkind != RELKIND_MATVIEW) continue; diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out index 06c6716297..97f415c307 100644 --- a/src/test/regress/expected/create_index.out +++ b/src/test/regress/expected/create_index.out @@ -2837,9 +2837,53 @@ explain (costs off) REINDEX SCHEMA schema_to_reindex; -- failure, schema does not exist ERROR: schema "schema_to_reindex" does not exist CREATE SCHEMA schema_to_reindex; -CREATE TABLE schema_to_reindex.table1(col1 SERIAL PRIMARY KEY); -CREATE TABLE schema_to_reindex.table2(col1 SERIAL PRIMARY KEY, col2 VARCHAR(100) NOT NULL); -CREATE INDEX ON schema_to_reindex.table2(col2); +SET search_path = 'schema_to_reindex'; +CREATE TABLE table1(col1 SERIAL PRIMARY KEY); +INSERT INTO table1 SELECT generate_series(1,400); +CREATE TABLE table2(col1 SERIAL PRIMARY KEY, col2 TEXT NOT NULL); +INSERT INTO table2 SELECT generate_series(1,400), 'abc'; +CREATE INDEX ON table2(col2); +CREATE MATERIALIZED VIEW matview AS SELECT col1 FROM table2; +CREATE INDEX ON matview(col1); +CREATE VIEW view AS SELECT col2 FROM table2; +CREATE TABLE reindex_before AS +SELECT oid, relname, relfilenode, relkind, reltoastrelid + FROM pg_class + where relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'schema_to_reindex'); +INSERT INTO reindex_before +SELECT oid, 'pg_toast_TABLE', relfilenode, relkind, reltoastrelid +FROM pg_class WHERE oid IN + (SELECT reltoastrelid FROM reindex_before WHERE reltoastrelid > 0); +INSERT INTO reindex_before +SELECT oid, 'pg_toast_TABLE_index', relfilenode, relkind, reltoastrelid +FROM pg_class where oid in + (select indexrelid from pg_index where indrelid in + (select reltoastrelid from reindex_before where reltoastrelid > 0)); + REINDEX SCHEMA schema_to_reindex; +CREATE TABLE reindex_after AS SELECT oid, relname, relfilenode, relkind + FROM pg_class + where relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'schema_to_reindex'); +SELECT b.relname, + b.relkind, + CASE WHEN a.relfilenode = b.relfilenode THEN 'relfilenode is unchanged' + ELSE 'relfilenode has changed' END +FROM reindex_before b JOIN pg_class a ON b.oid = a.oid; + relname | relkind | case +----------------------+---------+-------------------------- + table1_col1_seq | S | relfilenode is unchanged + table1 | r | relfilenode is unchanged + table1_pkey | i | relfilenode has changed + table2_col1_seq | S | relfilenode is unchanged + table2 | r | relfilenode is unchanged + table2_pkey | i | relfilenode has changed + table2_col2_idx | i | relfilenode has changed + matview | m | relfilenode is unchanged + matview_col1_idx | i | relfilenode has changed + view | v | relfilenode is unchanged + pg_toast_TABLE | t | relfilenode is unchanged + pg_toast_TABLE_index | i | relfilenode has changed +(12 rows) + REINDEX SCHEMA schema_to_reindex; BEGIN; REINDEX SCHEMA schema_to_reindex; -- failure, cannot run in a transaction @@ -2854,6 +2898,10 @@ ERROR: must be owner of schema schema_to_reindex RESET ROLE; DROP ROLE regression_reindexuser; DROP SCHEMA schema_to_reindex CASCADE; -NOTICE: drop cascades to 2 other objects -DETAIL: drop cascades to table schema_to_reindex.table1 -drop cascades to table schema_to_reindex.table2 +NOTICE: drop cascades to 6 other objects +DETAIL: drop cascades to table table1 +drop cascades to table table2 +drop cascades to materialized view matview +drop cascades to view view +drop cascades to table reindex_before +drop cascades to table reindex_after diff --git a/src/test/regress/sql/create_index.sql b/src/test/regress/sql/create_index.sql index fdda078c3a..498fce0042 100644 --- a/src/test/regress/sql/create_index.sql +++ b/src/test/regress/sql/create_index.sql @@ -970,9 +970,37 @@ explain (costs off) -- REINDEX SCHEMA schema_to_reindex; -- failure, schema does not exist CREATE SCHEMA schema_to_reindex; -CREATE TABLE schema_to_reindex.table1(col1 SERIAL PRIMARY KEY); -CREATE TABLE schema_to_reindex.table2(col1 SERIAL PRIMARY KEY, col2 VARCHAR(100) NOT NULL); -CREATE INDEX ON schema_to_reindex.table2(col2); +SET search_path = 'schema_to_reindex'; +CREATE TABLE table1(col1 SERIAL PRIMARY KEY); +INSERT INTO table1 SELECT generate_series(1,400); +CREATE TABLE table2(col1 SERIAL PRIMARY KEY, col2 TEXT NOT NULL); +INSERT INTO table2 SELECT generate_series(1,400), 'abc'; +CREATE INDEX ON table2(col2); +CREATE MATERIALIZED VIEW matview AS SELECT col1 FROM table2; +CREATE INDEX ON matview(col1); +CREATE VIEW view AS SELECT col2 FROM table2; +CREATE TABLE reindex_before AS +SELECT oid, relname, relfilenode, relkind, reltoastrelid + FROM pg_class + where relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'schema_to_reindex'); +INSERT INTO reindex_before +SELECT oid, 'pg_toast_TABLE', relfilenode, relkind, reltoastrelid +FROM pg_class WHERE oid IN + (SELECT reltoastrelid FROM reindex_before WHERE reltoastrelid > 0); +INSERT INTO reindex_before +SELECT oid, 'pg_toast_TABLE_index', relfilenode, relkind, reltoastrelid +FROM pg_class where oid in + (select indexrelid from pg_index where indrelid in + (select reltoastrelid from reindex_before where reltoastrelid > 0)); + REINDEX SCHEMA schema_to_reindex; +CREATE TABLE reindex_after AS SELECT oid, relname, relfilenode, relkind + FROM pg_class + where relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'schema_to_reindex'); +SELECT b.relname, + b.relkind, + CASE WHEN a.relfilenode = b.relfilenode THEN 'relfilenode is unchanged' + ELSE 'relfilenode has changed' END +FROM reindex_before b JOIN pg_class a ON b.oid = a.oid; REINDEX SCHEMA schema_to_reindex; BEGIN; REINDEX SCHEMA schema_to_reindex; -- failure, cannot run in a transaction