-# $PostgreSQL: pgsql/contrib/Makefile,v 1.58 2005/07/29 14:46:55 momjian Exp $
+# $PostgreSQL: pgsql/contrib/Makefile,v 1.59 2005/07/29 15:13:10 momjian Exp $
subdir = contrib
top_builddir = ..
# mSQL-interface \ (requires msql installed)
# mac \ (does not have a makefile)
# oracle \ (does not have a makefile)
-# reindexdb \ (does not have a makefile)
# start-scripts \ (does not have a makefile)
# xml2 \ (non-standard makefile)
space within a table
by Tatsuo Ishii <t-ishii@sra.co.jp>
-reindexdb -
- Reindexes a database
- by Shaun Thomas <sthomas@townnews.com>
-
seg -
Confidence-interval datatype (GiST indexing example)
by Gene Selkov, Jr. <selkovjr@mcs.anl.gov>
+++ /dev/null
-
- reindexdb
-
-Indexes are known to grow over time. Being as vacuum doesn't slow or
-clean up after this growth, and there is no command to reindex all tables
-in a database, it made sense to construct this utility to do it.
-
-Shaun Thomas <sthomas@townnews.com>
-
+++ /dev/null
-#!/bin/sh
-# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #
-# Package : reindexdb Version : $Revision: 1.6 $
-# Date : 05/08/2002 Author : Shaun Thomas
-# Req : psql, sh, perl, sed Type : Utility
-#
-# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #
-
-# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #
-# Function Definitions
-# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #
-
-usage()
-{
- echo "$CMDNAME reindexes a PostgreSQL database."
- echo
- echo "Usage:"
- echo " $CMDNAME [options] [dbname]"
- echo
- echo "Options:"
- echo " -h, --host=HOSTNAME Database server host"
- echo " -p, --port=PORT Database server port"
- echo " -U, --username=USERNAME Username to connect as"
- echo " -W, --password Prompt for password"
- echo " -d, --dbname=DBNAME Database to reindex"
- echo " -a, --all Reindex all databases"
- echo " -t, --table=TABLE Reindex specific table only"
- echo " -i, --index=INDEX Reindex specific index only"
- echo " -e, --echo Show the command(s) sent to the backend"
- echo " -q, --quiet Don't write any output"
- echo
- echo "Read the description of the SQL command REINDEX for details."
- echo
- exit 0
-}
-
-# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #
-# Program Body
-# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #
-
-CMDNAME=`basename "$0"`
-PATHNAME=`echo $0 | sed "s,$CMDNAME\$,,"`
-
-# Try valiantly to get the location of psql, since you can't ever
-# really know where it has been placed. We'll start by trying the
-# path. If that fails, we'll try the directory where this script
-# resides. Then on to whereis, and finally locate. Wish us luck.
-
-if x=`psql -V 2>/dev/null | grep psql`; then
- PSQL='psql'
-elif [ -f ${PATHNAME}psql ]; then
- PSQL=${PATHNAME}psql;
-elif x=`whereis -b psql 2>/dev/null | sed 's/.* //'`; then
- PSQL=$x
-elif x=`locate -r bin/psql$ -n 1 2>/dev/null`; then
- PSQL=$x
-else
- echo "$CMDNAME: Could not find psql to talk to postgres installation."
- echo "Please make sure psql is in your path, or that this script is in"
- echo "the same directory as psql was installed."
- exit 1
-fi
-
-# Now, go through all of our command-line options and get each operation
-# we said we'd accept in the usage listing.
-
-while [ "$#" -gt 0 ]
-do
- # Show help.
- case "$1" in
- --help|-\?)
- usage
- exit 0
- ;;
-
- # All of the following are postgres options. We can pass them on
- # directly, without interpreting them in any way. We don't care.
- # Anything that allows a space, we'll get the next *two* arguments
- # and make sure to pass those along.
-
- --host|-h|-p|--port|-U|--username)
- PSQLOPT="$PSQLOPT $1 $2"
- shift
- ;;
- -h*|--host=*|-p*|--port=*|-U*|--username=*|-W|--password)
- PSQLOPT="$PSQLOPT $1"
- ;;
-
- # From this point on, we're setting options that are required for
- # or only valid in This script. This includes which database(s) to
- # reindex, which tables, or which indexes, and so on.
-
- # Echoing. We'll *not* use this in queries we use to get lists.
- --echo|-e)
- ECHOOPT="-e"
- ;;
-
- # Do not echo messages.
- --quiet|-q)
- ECHOOPT="-q"
- quiet=1
- ;;
-
- # Reindex all databases, all tables, all applicable indexes.
- --all|-a)
- alldb=1
- ;;
-
- # Database to connect to, if not all of them.
- --dbname|-d)
- dbname="$2"
- shift
- ;;
- -d*)
- dbname=`echo "$1" | sed 's/^-d/'`
- ;;
- --dbname=*)
- dbname=`echo "$1" | sed 's/^--dbname=//'`
- ;;
-
- # Reindex specific Table. Disables index reindexing.
- --table|-t)
- table="$2"
- shift
- ;;
- -t*)
- table=`echo "$1" | sed 's/^-t//'`
- ;;
- --table=*)
- table=`echo "$1" | sed 's/^--table=//'`
- ;;
-
- # Reindex specific index. Disables table reindexing.
- --index|-i)
- index="$2"
- shift
- ;;
- -i*)
- index=`echo "$1" | sed 's/^-i//'`
- ;;
- --index=*)
- index=`echo "$1" | sed 's/^--index=//'`
- ;;
-
- # Yeah, no options? Whine, and show usage.
- -*)
- echo "$CMDNAME: invalid option: $1" 1>&2
- usage;
- exit 1
- ;;
-
- # Finally, it's possible that the database name was just the last
- # unlabeled option. So, let's get that.
- *)
- dbname="$1"
- ;;
- esac
-
- shift # Shift off each argument as we loop.
-
-done
-
-# Get a list of all databases we'll be using. This first case is if we
-# were asked to do all databases.
-if [ "$alldb" ]; then
-
- if [ "$dbname" ] || [ "$index" ] || [ "$table" ]; then
- echo "$CMDNAME: cannot reindex all databases and a specific database," 1>&2
- echo " table, or index at the same time." 1>&2
- exit 1
- fi
-
- # Execute a command to pull back all databases the user specified can
- # connect to. That's the list we'll be using. It's also why it's
- # a good idea for this to be run as a super-user.
- sql='SELECT datname FROM pg_database WHERE datallowconn'
- dbname=`$PSQL $PSQLOPT -q -t -A -d postgres -c "$sql"`
-
-# Ok, if it's not all databases, make sure at least one database is
-# specified before continuing.
-elif [ -z "$dbname" ]; then
- echo "$CMDNAME: missing required argument: database name" 1>&2
- usage;
- exit 1
-fi
-
-# No. We can't reindex a specific index and table at the same time.
-# Complain about this, and move on.
-if [ "$table" ] && [ "$index" ]; then
- echo "$CMDNAME: cannot reindex a specific table and a specific index" 1>&2
- echo "at the same time." 1>&2
- exit 1
-fi
-
-# If index was selected, reindex that index.
-if [ "$index" ]; then
- $PSQL $PSQLOPT $ECHOOPT -c "REINDEX INDEX \"$index\"" -d "$dbname"
- if [ "$?" -ne 0 ]; then
- echo "$CMDNAME: reindex index \"$index\" failed" 1>&2
- exit 1
- fi
-
-# Ok, no index. Is there a specific table to reindex?
-elif [ "$table" ]; then
- $PSQL $PSQLOPT $ECHOOPT -c "REINDEX TABLE \"$table\"" -d "$dbname"
- if [ "$?" -ne 0 ]; then
- echo "$CMDNAME: reindex table \"$table\" failed" 1>&2
- exit 1
- fi
-
-# No specific table, no specific index, either we have a specific database,
-# or were told to do all databases. Do it!
-else
-
- # We set IFS to newline only so that the for-loops won't misinterpret
- # spaces in the lists we retrieved via psql. Note also the use of
- # regclass to handle spaces, mixed-case names, and schema awareness.
- sql="SELECT DISTINCT c.oid::pg_catalog.regclass FROM pg_catalog.pg_index x JOIN pg_catalog.pg_class c ON c.oid = x.indrelid JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid WHERE nspname NOT LIKE 'pg\\\\_%'"
-
- IFS='
-'
- for db in $dbname; do
-
- # Only print which database we're currently reindexing if not in
- # quiet mode, and we're doing more than one database.
- [ "$alldb" ] && [ -z "$quiet" ] && echo "Reindexing $db"
-
- IFS='
-'
- # Get a list of non-system tables that have indexes.
- tables=`$PSQL $PSQLOPT -q -t -A -d "$db" -c "$sql"`
-
- # Ok, reindex every table in the database.
- IFS='
-'
- for tab in $tables; do
- IFS='
-'
- $PSQL $PSQLOPT $ECHOOPT -c "REINDEX TABLE $tab" -d "$db"
- if [ "$?" -ne 0 ]; then
- echo "$CMDNAME: reindex table $tab failed" 1>&2
- exit 1
- fi
- IFS='
-'
- done
-
- done
-
-fi
-
-exit 0
<!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.65 2005/07/26 23:24:02 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.66 2005/07/29 15:13:11 momjian Exp $
PostgreSQL documentation
Complete list of usable sgml source files in this directory.
-->
<!entity postgres system "postgres-ref.sgml">
<!entity postmaster system "postmaster.sgml">
<!entity psqlRef system "psql-ref.sgml">
+<!entity reindexdb system "reindexdb.sgml">
<!entity vacuumdb system "vacuumdb.sgml">
--- /dev/null
+<!--
+$PostgreSQL $
+PostgreSQL documentation
+-->
+
+<refentry id="APP-REINDEXDB">
+ <refmeta>
+ <refentrytitle id="APP-REINDEXDB-TITLE"><application>reindexdb</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="reindexdb">reindexdb</refname>
+ <refpurpose>reindex a <productname>PostgreSQL</productname> database</refpurpose>
+ </refnamediv>
+
+ <indexterm zone="app-reindexdb">
+ <primary>reindexdb</primary>
+ </indexterm>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>reindexdb</command>
+ <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
+ <arg>--table | -t <replaceable>table</replaceable> </arg>
+ <arg>--index | -i <replaceable>index</replaceable> </arg>
+ <arg><replaceable>dbname</replaceable></arg>
+ <sbr>
+ <command>reindexdb</command>
+ <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
+ <arg>--all | -a</arg>
+ <sbr>
+ <command>reindexdb</command>
+ <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
+ <arg>--system | -s</arg>
+ <arg><replaceable>dbname</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <application>reindexdb</application> is a utility for rebuilding indexes
+ in a <productname>PostgreSQL</productname> database.
+ </para>
+
+ <para>
+ <application>reindexdb</application> is a wrapper around the SQL
+ command <xref linkend="SQL-REINDEX" endterm="sql-reindex-title">.
+ There is no effective difference between reindexing databases via
+ this utility and via other methods for accessing the server.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ <application>reindexdb</application> accepts the following command-line arguments:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-a</></term>
+ <term><option>--all</></term>
+ <listitem>
+ <para>
+ Reindex all databases.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s</></term>
+ <term><option>--system</></term>
+ <listitem>
+ <para>
+ Reindex database's system catalogs.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t <replaceable class="parameter">table</replaceable></></term>
+ <term><option>--table <replaceable class="parameter">table</replaceable></></term>
+ <listitem>
+ <para>
+ Reindex <replaceable class="parameter">table</replaceable> only.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-i <replaceable class="parameter">index</replaceable></></term>
+ <term><option>--index <replaceable class="parameter">index</replaceable></></term>
+ <listitem>
+ <para>
+ Recreate <replaceable class="parameter">index</replaceable> only.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option><optional>-d</> <replaceable class="parameter">dbname</replaceable></></term>
+ <term><option><optional>--dbname</> <replaceable class="parameter">dbname</replaceable></></term>
+ <listitem>
+ <para>
+ Specifies the name of the database to be reindexed.
+ If this is not specified and <option>-a</option> (or
+ <option>--all</option>) is not used, the database name is read
+ from the environment variable <envar>PGDATABASE</envar>. If
+ that is not set, the user name specified for the connection is
+ used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-e</></term>
+ <term><option>--echo</></term>
+ <listitem>
+ <para>
+ Echo the commands that <application>reindexdb</application> generates
+ and sends to the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-q</></term>
+ <term><option>--quiet</></term>
+ <listitem>
+ <para>
+ Do not display a response.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ <application>reindexdb</application> also accepts
+ the following command-line arguments for connection parameters:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-h <replaceable class="parameter">host</replaceable></></term>
+ <term><option>--host <replaceable class="parameter">host</replaceable></></term>
+ <listitem>
+ <para>
+ Specifies the host name of the machine on which the server is
+ running. If the value begins with a slash, it is used as the
+ directory for the Unix domain socket.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable class="parameter">port</replaceable></></term>
+ <term><option>--port <replaceable class="parameter">port</replaceable></></term>
+ <listitem>
+ <para>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server
+ is listening for connections.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable class="parameter">username</replaceable></></term>
+ <term><option>--username <replaceable class="parameter">username</replaceable></></term>
+ <listitem>
+ <para>
+ User name to connect as.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</></term>
+ <term><option>--password</></term>
+ <listitem>
+ <para>
+ Force password prompt.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGDATABASE</envar></term>
+ <term><envar>PGHOST</envar></term>
+ <term><envar>PGPORT</envar></term>
+ <term><envar>PGUSER</envar></term>
+
+ <listitem>
+ <para>
+ Default connection parameters
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Diagnostics</title>
+
+ <para>
+ In case of difficulty, see <xref linkend="SQL-REINDEX"
+ endterm="sql-reindex-title"> and <xref linkend="APP-PSQL"> for
+ discussions of potential problems and error messages.
+ The database server must be running at the
+ targeted host. Also, any default connection settings and environment
+ variables used by the <application>libpq</application> front-end
+ library will apply.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <application>reindexdb</application> might need to connect several
+ times to the <productname>PostgreSQL</productname> server, asking
+ for a password each time. It is convenient to have a
+ <filename>~/.pgpass</> file in such cases. See <xref
+ linkend="libpq-pgpass"> for more information.
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To reindex the database <literal>test</literal>:
+<screen>
+<prompt>$ </prompt><userinput>reindexdb test</userinput>
+</screen>
+ </para>
+
+ <para>
+ To reindex the table <literal>foo</literal> and the index
+ <literal>bar</literal> in a database named <literal>abcd</literal>:
+<screen>
+<prompt>$ </prompt><userinput>reindexdb --table foo --index bar abcd</userinput>
+</screen>
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-reindex" endterm="sql-reindex-title"></member>
+ <member>Environment Variables (<xref linkend="libpq-envars">)</member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"../reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:"/usr/lib/sgml/catalog"
+sgml-local-ecat-files:nil
+End:
+-->
<!-- reference.sgml
-$PostgreSQL: pgsql/doc/src/sgml/reference.sgml,v 1.55 2005/07/26 23:24:01 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/reference.sgml,v 1.56 2005/07/29 15:13:11 momjian Exp $
PostgreSQL Reference Manual
-->
&pgDumpall;
&pgRestore;
&psqlRef;
+ &reindexdb;
&vacuumdb;
</reference>
# Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California
#
-# $PostgreSQL: pgsql/src/bin/scripts/Makefile,v 1.33 2005/03/25 18:17:14 momjian Exp $
+# $PostgreSQL: pgsql/src/bin/scripts/Makefile,v 1.34 2005/07/29 15:13:11 momjian Exp $
#
#-------------------------------------------------------------------------
top_builddir = ../../..
include $(top_builddir)/src/Makefile.global
-PROGRAMS = createdb createlang createuser dropdb droplang dropuser clusterdb vacuumdb
+PROGRAMS = createdb createlang createuser dropdb droplang dropuser clusterdb vacuumdb reindexdb
override CPPFLAGS := -DFRONTEND -I$(top_srcdir)/src/bin/pg_dump -I$(top_srcdir)/src/bin/psql -I$(libpq_srcdir) $(CPPFLAGS)
dropuser: dropuser.o common.o dumputils.o $(top_builddir)/src/backend/parser/keywords.o
clusterdb: clusterdb.o common.o dumputils.o $(top_builddir)/src/backend/parser/keywords.o
vacuumdb: vacuumdb.o common.o
+reindexdb: reindexdb.o common.o dumputils.o $(top_builddir)/src/backend/parser/keywords.o
dumputils.c: % : $(top_srcdir)/src/bin/pg_dump/%
rm -f $@ && $(LN_S) $< .
$(INSTALL_PROGRAM) dropuser$(X) $(DESTDIR)$(bindir)/dropuser$(X)
$(INSTALL_PROGRAM) clusterdb$(X) $(DESTDIR)$(bindir)/clusterdb$(X)
$(INSTALL_PROGRAM) vacuumdb$(X) $(DESTDIR)$(bindir)/vacuumdb$(X)
+ $(INSTALL_PROGRAM) reindexdb$(X) $(DESTDIR)$(bindir)/reindexdb$(X)
installdirs:
$(mkinstalldirs) $(DESTDIR)$(bindir)
-# $PostgreSQL: pgsql/src/bin/scripts/nls.mk,v 1.18 2005/01/17 03:05:22 petere Exp $
+# $PostgreSQL: pgsql/src/bin/scripts/nls.mk,v 1.19 2005/07/29 15:13:11 momjian Exp $
CATALOG_NAME := pgscripts
AVAIL_LANGUAGES := cs de es fr it ko pt_BR ro ru sk sl sv tr zh_CN zh_TW
GETTEXT_FILES := createdb.c createlang.c createuser.c \
dropdb.c droplang.c dropuser.c \
- clusterdb.c vacuumdb.c \
+ clusterdb.c vacuumdb.c reindexdb.c \
common.c
GETTEXT_TRIGGERS:= _ simple_prompt
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * reindexdb
+ *
+ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
+ *
+ * $PostgreSQL: pgsql/src/bin/scripts/reindexdb.c,v 1.1 2005/07/29 15:13:11 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+#include "common.h"
+#include "dumputils.h"
+
+
+static void reindex_one_database(const char *name, const char *dbname,
+ const char *type, const char *host,
+ const char *port, const char *username,
+ bool password, const char *progname,
+ bool echo, bool quiet);
+static void reindex_all_databases(const char *host, const char *port,
+ const char *username, bool password,
+ const char *progname, bool echo,
+ bool quiet);
+static void reindex_system_catalogs(const char *dbname,
+ const char *host, const char *port,
+ const char *username, bool password,
+ const char *progname, bool echo,
+ bool quiet);
+static void help(const char *progname);
+
+int
+main(int argc, char *argv[])
+{
+ static struct option long_options[] = {
+ {"host", required_argument, NULL, 'h'},
+ {"port", required_argument, NULL, 'p'},
+ {"username", required_argument, NULL, 'U'},
+ {"password", no_argument, NULL, 'W'},
+ {"echo", no_argument, NULL, 'e'},
+ {"quiet", no_argument, NULL, 'q'},
+ {"dbname", required_argument, NULL, 'd'},
+ {"all", no_argument, NULL, 'a'},
+ {"system", no_argument, NULL, 's'},
+ {"table", required_argument, NULL, 't'},
+ {"index", required_argument, NULL, 'i'},
+ {NULL, 0, NULL, 0}
+ };
+
+ const char *progname;
+ int optindex;
+ int c;
+
+ const char *dbname = NULL;
+ const char *host = NULL;
+ const char *port = NULL;
+ const char *username = NULL;
+ bool password = false;
+ bool syscatalog = false;
+ bool alldb = false;
+ bool echo = false;
+ bool quiet = false;
+ const char *table = NULL;
+ const char *index = NULL;
+
+ progname = get_progname(argv[0]);
+ set_pglocale_pgservice(argv[0], "pgscripts");
+
+ handle_help_version_opts(argc, argv, "reindexdb", help);
+
+ /* process command-line options */
+ while ((c = getopt_long(argc, argv, "h:p:U:Weqd:ast:i:", long_options, &optindex)) != -1)
+ {
+ switch (c)
+ {
+ case 'h':
+ host = optarg;
+ break;
+ case 'p':
+ port = optarg;
+ break;
+ case 'U':
+ username = optarg;
+ break;
+ case 'W':
+ password = true;
+ break;
+ case 'e':
+ echo = true;
+ break;
+ case 'q':
+ quiet = true;
+ break;
+ case 'd':
+ dbname = optarg;
+ break;
+ case 'a':
+ alldb = true;
+ break;
+ case 's':
+ syscatalog = true;
+ break;
+ case 't':
+ table = optarg;
+ break;
+ case 'i':
+ index = optarg;
+ break;
+ default:
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ exit(1);
+ }
+ }
+
+ switch (argc - optind)
+ {
+ case 0:
+ break;
+ case 1:
+ dbname = argv[optind];
+ break;
+ default:
+ fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), progname, argv[optind + 1]);
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ exit(1);
+ }
+
+ if (alldb)
+ {
+ if (dbname)
+ {
+ fprintf(stderr, _("%s: cannot reindex all databases and a specific one at the same time\n"), progname);
+ exit(1);
+ }
+ if (syscatalog)
+ {
+ fprintf(stderr, _("%s: cannot reindex all databases and system catalogs at the same time\n"), progname);
+ exit(1);
+ }
+ if (table)
+ {
+ fprintf(stderr, _("%s: cannot reindex a specific table in all databases\n"), progname);
+ exit(1);
+ }
+ if (index)
+ {
+ fprintf(stderr, _("%s: cannot reindex a specific index in all databases\n"), progname);
+ exit(1);
+ }
+
+ reindex_all_databases(host, port, username, password,
+ progname, echo, quiet);
+ }
+ else if (syscatalog)
+ {
+ if (table)
+ {
+ fprintf(stderr, _("%s: cannot reindex a specific table and system catalogs at the same time\n"), progname);
+ exit(1);
+ }
+ if (index)
+ {
+ fprintf(stderr, _("%s: cannot reindex a specific index and system catalogs 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(progname);
+ }
+
+ reindex_system_catalogs(dbname, host, port, username, password,
+ progname, echo, quiet);
+ }
+ else
+ {
+ if (dbname == NULL)
+ {
+ if (getenv("PGDATABASE"))
+ dbname = getenv("PGDATABASE");
+ else if (getenv("PGUSER"))
+ dbname = getenv("PGUSER");
+ else
+ dbname = get_user_name(progname);
+ }
+
+ if (index)
+ reindex_one_database(index, dbname, "INDEX", host, port,
+ username, password, progname, echo, quiet);
+ if (table)
+ reindex_one_database(table, dbname, "TABLE", host, port,
+ username, password, progname, echo, quiet);
+ /* reindex database only if index or table is not specified */
+ if (index == NULL && table == NULL)
+ reindex_one_database(dbname, dbname, "DATABASE", host, port,
+ username, password, progname, echo, quiet);
+ }
+
+ exit(0);
+}
+
+static void
+reindex_one_database(const char *name, const char *dbname, const char *type,
+ const char *host, const char *port, const char *username,
+ bool password, const char *progname, bool echo,
+ bool quiet)
+{
+ PQExpBufferData sql;
+
+ PGconn *conn;
+ PGresult *result;
+
+ initPQExpBuffer(&sql);
+
+ appendPQExpBuffer(&sql, "REINDEX");
+ if (strcmp(type, "TABLE") == 0)
+ appendPQExpBuffer(&sql, " TABLE %s", fmtId(name));
+ else if (strcmp(type, "INDEX") == 0)
+ appendPQExpBuffer(&sql, " INDEX %s", fmtId(name));
+ else if (strcmp(type, "DATABASE") == 0)
+ appendPQExpBuffer(&sql, " DATABASE %s", fmtId(name));
+ appendPQExpBuffer(&sql, ";\n");
+
+ conn = connectDatabase(dbname, host, port, username, password, progname);
+
+ if (echo)
+ printf("%s", sql.data);
+ result = PQexec(conn, sql.data);
+
+ if (PQresultStatus(result) != PGRES_COMMAND_OK)
+ {
+ if (strcmp(type, "TABLE") == 0)
+ fprintf(stderr, _("%s: reindexing of table \"%s\" in database \"%s\" failed: %s"),
+ progname, name, dbname, PQerrorMessage(conn));
+ if (strcmp(type, "INDEX") == 0)
+ fprintf(stderr, _("%s: reindexing of index \"%s\" in database \"%s\" failed: %s"),
+ progname, name, dbname, PQerrorMessage(conn));
+ else
+ fprintf(stderr, _("%s: reindexing of database \"%s\" failed: %s"),
+ progname, dbname, PQerrorMessage(conn));
+ PQfinish(conn);
+ exit(1);
+ }
+
+ PQclear(result);
+ PQfinish(conn);
+ termPQExpBuffer(&sql);
+
+ if (!quiet)
+ {
+ puts("REINDEX");
+ fflush(stdout);
+ }
+}
+
+static void
+reindex_all_databases(const char *host, const char *port,
+ const char *username, bool password,
+ const char *progname, bool echo, bool quiet)
+{
+ PGconn *conn;
+ PGresult *result;
+ int i;
+
+ conn = connectDatabase("postgres", host, port, username, password, progname);
+ result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn;", progname, echo);
+ PQfinish(conn);
+
+ for (i = 0; i < PQntuples(result); i++)
+ {
+ char *dbname = PQgetvalue(result, i, 0);
+
+ if (!quiet)
+ fprintf(stderr, _("%s: reindexing database \"%s\"\n"), progname, dbname);
+
+ reindex_one_database(dbname, dbname, "DATABASE", host, port, username,
+ password, progname, echo, quiet);
+ }
+
+ PQclear(result);
+}
+
+static void
+reindex_system_catalogs(const char *dbname, const char *host, const char *port,
+ const char *username, bool password,
+ const char *progname, bool echo, bool quiet)
+{
+ PQExpBufferData sql;
+
+ PGconn *conn;
+ PGresult *result;
+
+ initPQExpBuffer(&sql);
+
+ appendPQExpBuffer(&sql, "REINDEX SYSTEM %s;\n", dbname);
+
+ conn = connectDatabase(dbname, host, port, username, password, progname);
+
+ if (echo)
+ printf("%s", sql.data);
+ result = PQexec(conn, sql.data);
+
+ if (PQresultStatus(result) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, _("%s: reindexing of system catalogs failed: %s"),
+ progname, PQerrorMessage(conn));
+ PQfinish(conn);
+ exit(1);
+ }
+
+ PQclear(result);
+ PQfinish(conn);
+ termPQExpBuffer(&sql);
+
+ if (!quiet)
+ {
+ puts("REINDEX");
+ fflush(stdout);
+ }
+}
+
+static void
+help(const char *progname)
+{
+ printf(_("%s reindexes a PostgreSQL database.\n\n"), progname);
+ printf(_("Usage:\n"));
+ printf(_(" %s [OPTION]... [DBNAME]\n"), progname);
+ printf(_("\nOptions:\n"));
+ printf(_(" -a, --all reindex all databases\n"));
+ printf(_(" -s, --system reindex system catalogs\n"));
+ printf(_(" -d, --dbname=DBNAME database to reindex\n"));
+ printf(_(" -t, --table=TABLE reindex specific table only\n"));
+ printf(_(" -i, --index=INDEX recreate specific index only\n"));
+ printf(_(" -e, --echo show the commands sent to the server\n"));
+ printf(_(" -q, --quiet don't write any output\n"));
+ printf(_(" --help show this help, then exit\n"));
+ printf(_(" --version output version information, then exit\n"));
+ printf(_("\nConnection options:\n"));
+ printf(_(" -h, --host=HOSTNAME database server host or socket direcotry\n"));
+ printf(_(" -p, --port=PORT database server port\n"));
+ printf(_(" -U, --username=NAME user name to connect as\n"));
+ printf(_(" -W, --password prompt for password\n"));
+ printf(_("\nRead the description of the SQL command REINDEX for details.\n"));
+ printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
+}