diff --git a/doc/src/sgml/ref/reindex.sgml b/doc/src/sgml/ref/reindex.sgml
index cabae19..d05e1ac 100644
--- a/doc/src/sgml/ref/reindex.sgml
+++ b/doc/src/sgml/ref/reindex.sgml
@@ -22,6 +22,7 @@ PostgreSQL documentation
REINDEX { INDEX | TABLE | DATABASE | SYSTEM } name [ FORCE ]
+REINDEX USER TABLES
@@ -126,14 +127,26 @@ REINDEX { INDEX | TABLE | DATABASE | SYSTEM } nam
+ USER TABLES
+
+
+ Recreate all indexes on user tables within the current database.
+ Indexes on system catalogs are not processed.
+ This form of REINDEX cannot be executed inside a
+ transaction block.
+
+
+
+
+
name
The name of the specific index, table, or database to be
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.
+ Presently, REINDEX DATABASE>, REINDEX SYSTEM>,
+ and REINDEX USER TABLES> can only reindex the current
+ database, so their parameter must match the current database's name.
diff --git a/doc/src/sgml/ref/reindexdb.sgml b/doc/src/sgml/ref/reindexdb.sgml
index 486f5c9..f69d84b 100644
--- a/doc/src/sgml/ref/reindexdb.sgml
+++ b/doc/src/sgml/ref/reindexdb.sgml
@@ -65,6 +65,15 @@ PostgreSQL documentation
dbname
+
+
+ reindexdb
+ connection-option
+
+
+
+
+
@@ -173,6 +182,16 @@ PostgreSQL documentation
+
+
+
+
+
+ Reindex database's user tables.
+
+
+
+
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index fdfa6ca..23e13f0 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -1772,6 +1772,9 @@ ReindexTable(RangeVar *relation)
* To reduce the probability of deadlocks, each table is reindexed in a
* separate transaction, so we can release the lock on it right away.
* That means this must not be called within a user transaction block!
+ *
+ * databaseName can be NULL when do_user is set and do_system isn't; this
+ * is the REINDEX USER TABLES case.
*/
Oid
ReindexDatabase(const char *databaseName, bool do_system, bool do_user)
@@ -1784,9 +1787,10 @@ ReindexDatabase(const char *databaseName, bool do_system, bool do_user)
List *relids = NIL;
ListCell *l;
- AssertArg(databaseName);
+ AssertArg(databaseName || (do_user && !do_system));
- if (strcmp(databaseName, get_database_name(MyDatabaseId)) != 0)
+ if (databaseName &&
+ strcmp(databaseName, get_database_name(MyDatabaseId)) != 0)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("can only reindex the currently open database")));
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 6f4d645..0baef83 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -7040,6 +7040,7 @@ opt_if_exists: IF_P EXISTS { $$ = TRUE; }
* QUERY:
*
* REINDEX type [FORCE]
+ * REINDEX USER TABLES
*
* FORCE no longer does anything, but we accept it for backwards compatibility
*****************************************************************************/
@@ -7073,6 +7074,16 @@ ReindexStmt:
n->do_user = true;
$$ = (Node *)n;
}
+ | REINDEX USER TABLES
+ {
+ ReindexStmt *n = makeNode(ReindexStmt);
+ n->kind = OBJECT_DATABASE;
+ n->name = NULL;
+ n->relation = NULL;
+ n->do_system = false;
+ n->do_user = true;
+ $$ = (Node *)n;
+ }
;
reindex_type:
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 76b2b04..490d200 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3148,7 +3148,7 @@ psql_completion(const char *text, int start, int end)
else if (pg_strcasecmp(prev_wd, "REINDEX") == 0)
{
static const char *const list_REINDEX[] =
- {"TABLE", "INDEX", "SYSTEM", "DATABASE", NULL};
+ {"TABLE", "INDEX", "SYSTEM", "DATABASE", "USER TABLES", NULL};
COMPLETE_WITH_LIST(list_REINDEX);
}
@@ -3161,6 +3161,8 @@ psql_completion(const char *text, int start, int end)
else if (pg_strcasecmp(prev_wd, "SYSTEM") == 0 ||
pg_strcasecmp(prev_wd, "DATABASE") == 0)
COMPLETE_WITH_QUERY(Query_for_list_of_databases);
+ else if (pg_strcasecmp(prev_wd, "USER") == 0)
+ COMPLETE_WITH_CONST("TABLES");
}
/* SECURITY LABEL */
diff --git a/src/bin/scripts/reindexdb.c b/src/bin/scripts/reindexdb.c
index 561bbce..8e1b52d 100644
--- a/src/bin/scripts/reindexdb.c
+++ b/src/bin/scripts/reindexdb.c
@@ -28,8 +28,14 @@ static void reindex_system_catalogs(const char *dbname,
const char *host, const char *port,
const char *username, enum trivalue prompt_password,
const char *progname, bool echo);
+static void reindex_user_tables(const char *dbname,
+ const char *host, const char *port,
+ const char *username, enum trivalue prompt_password,
+ const char *progname, bool echo);
static void help(const char *progname);
+#define exit_nicely(code) exit(code)
+
int
main(int argc, char *argv[])
{
@@ -46,6 +52,7 @@ main(int argc, char *argv[])
{"system", no_argument, NULL, 's'},
{"table", required_argument, NULL, 't'},
{"index", required_argument, NULL, 'i'},
+ {"user-tables", no_argument, NULL, 'u'},
{"maintenance-db", required_argument, NULL, 2},
{NULL, 0, NULL, 0}
};
@@ -61,6 +68,7 @@ main(int argc, char *argv[])
const char *username = NULL;
enum trivalue prompt_password = TRI_DEFAULT;
bool syscatalog = false;
+ bool usertables = false;
bool alldb = false;
bool echo = false;
bool quiet = false;
@@ -73,7 +81,7 @@ main(int argc, char *argv[])
handle_help_version_opts(argc, argv, "reindexdb", help);
/* process command-line options */
- while ((c = getopt_long(argc, argv, "h:p:U:wWeqd:ast:i:", long_options, &optindex)) != -1)
+ while ((c = getopt_long(argc, argv, "h:p:U:wWeqd:ast:i:u", long_options, &optindex)) != -1)
{
switch (c)
{
@@ -113,6 +121,9 @@ main(int argc, char *argv[])
case 'i':
simple_string_list_append(&indexes, optarg);
break;
+ case 'u':
+ usertables = true;
+ break;
case 2:
maintenance_db = pg_strdup(optarg);
break;
@@ -194,6 +205,32 @@ main(int argc, char *argv[])
reindex_system_catalogs(dbname, host, port, username, prompt_password,
progname, echo);
}
+ else if (usertables)
+ {
+ if (tables.head != NULL)
+ {
+ fprintf(stderr, _("%s: cannot reindex specific table(s) and all user tables at the same time\n"), progname);
+ exit(1);
+ }
+ if (indexes.head != NULL)
+ {
+ fprintf(stderr, _("%s: cannot reindex specific index(es) and all user tables at the same time\n"), progname);
+ exit(1);
+ }
+
+ if (dbname == NULL)
+ {
+ if (getenv("PGDATABASE"))
+ dbname = getenv("PGDATABASE");
+ else if (getenv("PGUSER"))
+ dbname = getenv("PGUSER");
+ else
+ dbname = get_user_name_or_exit(progname);
+ }
+
+ reindex_user_tables(dbname, host, port, username, prompt_password,
+ progname, echo);
+ }
else
{
if (dbname == NULL)
@@ -336,6 +373,41 @@ reindex_system_catalogs(const char *dbname, const char *host, const char *port,
}
static void
+reindex_user_tables(const char *dbname, const char *host, const char *port,
+ const char *username, enum trivalue prompt_password,
+ const char *progname, bool echo)
+{
+ PQExpBufferData sql;
+
+ PGconn *conn;
+
+ initPQExpBuffer(&sql);
+
+ appendPQExpBuffer(&sql, "REINDEX USER TABLES;");
+
+ conn = connectDatabase(dbname, host, port, username, prompt_password,
+ progname, false);
+
+ /* This feature is only available starting in 9.5 */
+ if (PQserverVersion(conn) < 90500)
+ {
+ fprintf(stderr, _("%s: REINDEX USER TABLES is only available in server versions 9.5 and newer\n"),
+ progname);
+ exit_nicely(1);
+ }
+
+ if (!executeMaintenanceCommand(conn, sql.data, echo))
+ {
+ fprintf(stderr, _("%s: reindexing of user tables failed: %s"),
+ progname, PQerrorMessage(conn));
+ PQfinish(conn);
+ exit(1);
+ }
+ PQfinish(conn);
+ termPQExpBuffer(&sql);
+}
+
+static void
help(const char *progname)
{
printf(_("%s reindexes a PostgreSQL database.\n\n"), progname);
@@ -349,6 +421,7 @@ help(const char *progname)
printf(_(" -q, --quiet don't write any messages\n"));
printf(_(" -s, --system reindex system catalogs\n"));
printf(_(" -t, --table=TABLE reindex specific table(s) only\n"));
+ printf(_(" -u, --user-tables reindex all user tables\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nConnection options:\n"));
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index d2c0b29..226fffd 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -2689,9 +2689,9 @@ typedef struct ConstraintsSetStmt
typedef struct ReindexStmt
{
NodeTag type;
- ObjectType kind; /* OBJECT_INDEX, OBJECT_TABLE, etc. */
- RangeVar *relation; /* Table or index to reindex */
- const char *name; /* name of database to reindex */
+ ObjectType kind; /* OBJECT_INDEX, OBJECT_TABLE, OBJECT_DATABASE */
+ RangeVar *relation; /* Table or index to reindex; NULL for all */
+ const char *name; /* name of database to reindex, or NULL */
bool do_system; /* include system tables in database case */
bool do_user; /* include user tables in database case */
} ReindexStmt;