Further changes to REINDEX SCHEMA
authorSimon Riggs <simon@2ndQuadrant.com>
Thu, 11 Dec 2014 22:54:05 +0000 (22:54 +0000)
committerSimon Riggs <simon@2ndQuadrant.com>
Thu, 11 Dec 2014 22:54:05 +0000 (22:54 +0000)
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
src/test/regress/expected/create_index.out
src/test/regress/sql/create_index.sql

index cf4de7281d4948792e9a31f33e8dd43eaca6aac8..2b45699107c5fcb2ed8dd5b177a7760e9423f628 100644 (file)
@@ -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;
index 06c67162971f5e9e6584d6def3ac69cff853bac2..97f415c3070f55e5cb41f45c9b715b27e840188a 100644 (file)
@@ -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
index fdda078c3a873ab310625adf1986bf9fb8155427..498fce0042491f9b0370e14f3469b15f03579bd8 100644 (file)
@@ -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