diff --git a/doc/src/sgml/ref/reindex.sgml b/doc/src/sgml/ref/reindex.sgml index 336ca24b31..ef74a72b3c 100644 --- a/doc/src/sgml/ref/reindex.sgml +++ b/doc/src/sgml/ref/reindex.sgml @@ -22,6 +22,7 @@ PostgreSQL documentation REINDEX [ ( option [, ...] ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURRENTLY ] name +REINDEX [ ( option [, ...] ) ] { DATABASE | SYSTEM } [ CONCURRENTLY ] [ name ] where option can be one of: @@ -126,8 +127,9 @@ REINDEX [ ( option [, ...] ) ] { IN DATABASE - Recreate all indexes within the current database. - Indexes on shared system catalogs are also processed. + Recreate all indexes within the current database, except system + catalogs. + Indexes on shared system catalogs are not processed. This form of REINDEX cannot be executed inside a transaction block. @@ -155,7 +157,7 @@ REINDEX [ ( option [, ...] ) ] { IN reindexed. Index and table names can be schema-qualified. Presently, REINDEX DATABASE and REINDEX SYSTEM can only reindex the current database, so their parameter must match - the current database's name. + the current database's name, if supplied, though supplying the name is optional. diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 99f5ab83c3..df10262f73 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -2877,10 +2877,13 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, bool concurrent_warning = false; bool tablespace_warning = false; - AssertArg(objectName); Assert(objectKind == REINDEX_OBJECT_SCHEMA || objectKind == REINDEX_OBJECT_SYSTEM || objectKind == REINDEX_OBJECT_DATABASE); + /* + * This matches the options enforced by the grammar. + */ + AssertArg(objectName || objectKind != REINDEX_OBJECT_SCHEMA); if (objectKind == REINDEX_OBJECT_SYSTEM && (params->options & REINDEXOPT_CONCURRENTLY) != 0) @@ -2906,13 +2909,13 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, { objectOid = MyDatabaseId; - if (strcmp(objectName, get_database_name(objectOid)) != 0) + if (objectName && strcmp(objectName, get_database_name(objectOid)) != 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("can only reindex the currently open database"))); if (!pg_database_ownercheck(objectOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE, - objectName); + get_database_name(objectOid)); } /* @@ -2970,10 +2973,24 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, !isTempNamespace(classtuple->relnamespace)) continue; - /* Check user/system classification, and optionally skip */ - if (objectKind == REINDEX_OBJECT_SYSTEM && - !IsSystemClass(relid, classtuple)) - continue; + /* + * Check user/system classification, and skip appropriately. + */ + if (objectKind == REINDEX_OBJECT_SYSTEM) + { + if (!IsSystemClass(relid, classtuple)) + continue; + } + else if (objectKind == REINDEX_OBJECT_DATABASE) + { + /* + * You might think it would be good to include catalogs, + * but doing that can deadlock, so isn't much use in real world, + * nor can we safely test that it even works. + */ + if (IsSystemClass(relid, classtuple)) + continue; + } /* * The table can be reindexed if the user is superuser, the table diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 969c9c158f..25a5192595 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -560,7 +560,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type generic_option_elem alter_generic_option_elem %type generic_option_list alter_generic_option_list -%type reindex_target_type reindex_target_multitable +%type reindex_target_type reindex_target_multitable reindex_name_optional %type copy_generic_opt_arg copy_generic_opt_arg_list_item %type copy_generic_opt_elem @@ -9105,6 +9105,24 @@ ReindexStmt: makeDefElem("concurrently", NULL, @3)); $$ = (Node *) n; } + | REINDEX reindex_name_optional + { + ReindexStmt *n = makeNode(ReindexStmt); + n->kind = $2; + n->name = NULL; + n->relation = NULL; + n->params = NIL; + $$ = (Node *)n; + } + | REINDEX '(' utility_option_list ')' reindex_name_optional + { + ReindexStmt *n = makeNode(ReindexStmt); + n->kind = $5; + n->name = NULL; + n->relation = NULL; + n->params = $3; + $$ = (Node *)n; + } | REINDEX '(' utility_option_list ')' reindex_target_type opt_concurrently qualified_name { ReindexStmt *n = makeNode(ReindexStmt); @@ -9141,6 +9159,11 @@ reindex_target_multitable: | SYSTEM_P { $$ = REINDEX_OBJECT_SYSTEM; } | DATABASE { $$ = REINDEX_OBJECT_DATABASE; } ; +/* For these options the name is optional */ +reindex_name_optional: + SYSTEM_P { $$ = REINDEX_OBJECT_SYSTEM; } + | DATABASE { $$ = REINDEX_OBJECT_DATABASE; } + ; /***************************************************************************** * diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out index d55aec3a1d..e697da6e81 100644 --- a/src/test/regress/expected/create_index.out +++ b/src/test/regress/expected/create_index.out @@ -2808,6 +2808,12 @@ ERROR: REINDEX SCHEMA cannot run inside a transaction block END; -- concurrently REINDEX SCHEMA CONCURRENTLY schema_to_reindex; +-- unqualified reindex database +-- if you want to test REINDEX DATABASE, uncomment the following line, +-- but note that this adds about 0.5s to the regression tests and the +-- results are volatile when run in parallel to other tasks. Note also +-- that REINDEX SYSTEM is specifically not tested because it can deadlock. +-- REINDEX (VERBOSE) DATABASE; -- Failure for unauthorized user CREATE ROLE regress_reindexuser NOLOGIN; SET SESSION ROLE regress_reindexuser; diff --git a/src/test/regress/sql/create_index.sql b/src/test/regress/sql/create_index.sql index d8fded3d93..19abc1d210 100644 --- a/src/test/regress/sql/create_index.sql +++ b/src/test/regress/sql/create_index.sql @@ -1235,6 +1235,13 @@ END; -- concurrently REINDEX SCHEMA CONCURRENTLY schema_to_reindex; +-- unqualified reindex database +-- if you want to test REINDEX DATABASE, uncomment the following line, +-- but note that this adds about 0.5s to the regression tests and the +-- results are volatile when run in parallel to other tasks. Note also +-- that REINDEX SYSTEM is specifically not tested because it can deadlock. +-- REINDEX (VERBOSE) DATABASE; + -- Failure for unauthorized user CREATE ROLE regress_reindexuser NOLOGIN; SET SESSION ROLE regress_reindexuser;