Tablespaces. Alternate database locations are dead, long live tablespaces.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 18 Jun 2004 06:14:31 +0000 (06:14 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 18 Jun 2004 06:14:31 +0000 (06:14 +0000)
There are various things left to do: contrib dbsize and oid2name modules
need work, and so does the documentation.  Also someone should think about
COMMENT ON TABLESPACE and maybe RENAME TABLESPACE.  Also initlocation is
dead, it just doesn't know it yet.

Gavin Sherry and Tom Lane.

94 files changed:
doc/src/sgml/catalogs.sgml
doc/src/sgml/manage-ag.sgml
doc/src/sgml/ref/allfiles.sgml
doc/src/sgml/ref/create_database.sgml
doc/src/sgml/ref/create_index.sgml
doc/src/sgml/ref/create_schema.sgml
doc/src/sgml/ref/create_sequence.sgml
doc/src/sgml/ref/create_table.sgml
doc/src/sgml/ref/create_tablespace.sgml [new file with mode: 0644]
doc/src/sgml/ref/drop_tablespace.sgml [new file with mode: 0644]
doc/src/sgml/ref/grant.sgml
doc/src/sgml/ref/psql-ref.sgml
doc/src/sgml/ref/revoke.sgml
doc/src/sgml/reference.sgml
src/backend/access/heap/heapam.c
src/backend/access/nbtree/nbtxlog.c
src/backend/access/transam/xlogutils.c
src/backend/bootstrap/bootparse.y
src/backend/catalog/Makefile
src/backend/catalog/aclchk.c
src/backend/catalog/catalog.c
src/backend/catalog/heap.c
src/backend/catalog/index.c
src/backend/catalog/namespace.c
src/backend/catalog/pg_namespace.c
src/backend/commands/Makefile
src/backend/commands/cluster.c
src/backend/commands/dbcommands.c
src/backend/commands/indexcmds.c
src/backend/commands/schemacmds.c
src/backend/commands/sequence.c
src/backend/commands/tablecmds.c
src/backend/commands/tablespace.c [new file with mode: 0644]
src/backend/commands/typecmds.c
src/backend/commands/view.c
src/backend/executor/execMain.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/outfuncs.c
src/backend/parser/analyze.c
src/backend/parser/gram.y
src/backend/parser/keywords.c
src/backend/storage/buffer/bufmgr.c
src/backend/storage/buffer/localbuf.c
src/backend/storage/freespace/freespace.c
src/backend/storage/smgr/md.c
src/backend/storage/smgr/smgr.c
src/backend/tcop/utility.c
src/backend/utils/adt/acl.c
src/backend/utils/adt/ruleutils.c
src/backend/utils/cache/inval.c
src/backend/utils/cache/lsyscache.c
src/backend/utils/cache/relcache.c
src/backend/utils/init/globals.c
src/backend/utils/init/miscinit.c
src/backend/utils/init/postinit.c
src/backend/utils/misc/database.c
src/bin/initdb/initdb.c
src/bin/pg_dump/dumputils.c
src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.h
src/bin/pg_dump/pg_dumpall.c
src/bin/psql/command.c
src/bin/psql/describe.c
src/bin/psql/describe.h
src/bin/psql/help.c
src/include/catalog/catalog.h
src/include/catalog/catname.h
src/include/catalog/catversion.h
src/include/catalog/heap.h
src/include/catalog/index.h
src/include/catalog/indexing.h
src/include/catalog/pg_attribute.h
src/include/catalog/pg_class.h
src/include/catalog/pg_database.h
src/include/catalog/pg_namespace.h
src/include/catalog/pg_tablespace.h [new file with mode: 0644]
src/include/catalog/pg_type.h
src/include/commands/defrem.h
src/include/commands/tablespace.h [new file with mode: 0644]
src/include/miscadmin.h
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/include/storage/buf_internals.h
src/include/storage/relfilenode.h
src/include/utils/acl.h
src/include/utils/lsyscache.h
src/include/utils/relcache.h
src/test/regress/GNUmakefile
src/test/regress/expected/sanity_check.out
src/test/regress/input/tablespace.source [new file with mode: 0644]
src/test/regress/output/tablespace.source [new file with mode: 0644]
src/test/regress/parallel_schedule
src/test/regress/serial_schedule

index 84ae3cb205f543b56d909a0125ac3becd92ec7a3..36695e6811f80e35344a382578dbcc7630493753 100644 (file)
@@ -1,6 +1,6 @@
 <!--
  Documentation of the system catalogs, directed toward PostgreSQL developers
- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.87 2004/06/16 01:26:33 tgl Exp $
+ $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.88 2004/06/18 06:13:02 tgl Exp $
  -->
 
 <chapter id="catalogs">
       <entry>planner statistics</entry>
      </row>
 
+     <row>
+      <entry><link linkend="catalog-pg-tablespace"><structname>pg_tablespace</structname></link></entry>
+      <entry>tablespaces within this database cluster</entry>
+     </row>
+
      <row>
       <entry><link linkend="catalog-pg-trigger"><structname>pg_trigger</structname></link></entry>
       <entry>triggers</entry>
       <entry>Name of the on-disk file of this relation; 0 if none</entry>
      </row>
 
+     <row>
+      <entry><structfield>reltablespace</structfield></entry>
+      <entry><type>oid</type></entry>
+      <entry><literal><link linkend="catalog-pg-tablespace"><structname>pg_tablespace</structname></link>.oid</literal></entry>
+      <entry>
+       The tablespace in which this relation is stored.  If zero,
+       the database's default tablespace is implied.  (Not meaningful
+       if the relation has no on-disk file.)
+      </entry>
+     </row>
+
      <row>
       <entry><structfield>relpages</structfield></entry>
       <entry><type>int4</type></entry>
      </row>
 
      <row>
-      <entry><structfield>datpath</structfield></entry>
-      <entry><type>text</type></entry>
-      <entry></entry>
+      <entry><structfield>dattablespace</structfield></entry>
+      <entry><type>oid</type></entry>
+      <entry><literal><link linkend="catalog-pg-tablespace"><structname>pg_tablespace</structname></link>.oid</literal></entry>
       <entry>
-       If the database is stored at an alternative location then this
-       records the location.  It's either an environment variable name
-       or an absolute path, depending how it was entered.
+       The default tablespace for the database.
+       Within this database, all tables for which
+       <structname>pg_class</>.<structfield>reltablespace</> is zero
+       will be stored in this tablespace; in particular, all the non-shared
+       system catalogs will be there.
       </entry>
      </row>
 
       <entry>Owner of the namespace</entry>
      </row>
 
+     <row>
+      <entry><structfield>nsptablespace</structfield></entry>
+      <entry><type>oid</type></entry>
+      <entry><literal><link linkend="catalog-pg-tablespace"><structname>pg_tablespace</structname></link>.oid</literal></entry>
+      <entry>
+       The default tablespace in which to place relations created in this
+       namespace.  If zero, the database's default tablespace is implied.
+       (Changing this does not affect pre-existing relations.)
+      </entry>
+     </row>
+
      <row>
       <entry><structfield>nspacl</structfield></entry>
       <entry><type>aclitem[]</type></entry>
  </sect1>
 
 
+ <sect1 id="catalog-pg-tablespace">
+  <title><structname>pg_tablespace</structname></title>
+
+  <indexterm zone="catalog-pg-tablespace">
+   <primary>pg_tablespace</primary>
+  </indexterm>
+
+  <para>
+   The catalog <structname>pg_tablespace</structname> stores information
+   about the available tablespaces.  Tables can be placed in particular
+   tablespaces to aid administration of disk layout.
+  </para>
+
+  <para>
+   Unlike most system catalogs, <structname>pg_tablespace</structname>
+   is shared across all databases of a cluster: there is only one
+   copy of <structname>pg_tablespace</structname> per cluster, not
+   one per database.
+  </para>
+
+  <table>
+   <title><structname>pg_tablespace</> Columns</title>
+
+   <tgroup cols=4>
+    <thead>
+     <row>
+      <entry>Name</entry>
+      <entry>Type</entry>
+      <entry>References</entry>
+      <entry>Description</entry>
+     </row>
+    </thead>
+
+    <tbody>
+     <row>
+      <entry><structfield>spcname</structfield></entry>
+      <entry><type>name</type></entry>
+      <entry></entry>
+      <entry>Tablespace name</entry>
+     </row>
+
+     <row>
+      <entry><structfield>spcowner</structfield></entry>
+      <entry><type>int4</type></entry>
+      <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry>
+      <entry>Owner of the tablespace, usually the user who created it</entry>
+     </row>
+
+     <row>
+      <entry><structfield>spclocation</structfield></entry>
+      <entry><type>text</type></entry>
+      <entry></entry>
+      <entry>Location (directory path) of the tablespace</entry>
+     </row>
+
+     <row>
+      <entry><structfield>spcacl</structfield></entry>
+      <entry><type>aclitem[]</type></entry>
+      <entry></entry>
+      <entry>Access privileges</entry>
+     </row>
+    </tbody>
+   </tgroup>
+  </table>
+ </sect1>
+
+
  <sect1 id="catalog-pg-trigger">
   <title><structname>pg_trigger</structname></title>
 
index df6d85afab1090a2fc0f8781f2ebca31cf8ac91f..34737ffd4fe9cdf9f8a61b4572665d6da0a77235 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/manage-ag.sgml,v 2.29 2003/11/29 19:51:37 pgsql Exp $
+$PostgreSQL: pgsql/doc/src/sgml/manage-ag.sgml,v 2.30 2004/06/18 06:13:02 tgl Exp $
 -->
 
 <chapter id="managing-databases">
@@ -298,6 +298,11 @@ ALTER DATABASE mydb SET geqo TO off;
  <sect1 id="manage-ag-alternate-locs">
   <title>Alternative Locations</title>
 
+   <para>
+    XXX this is entirely dead now, and needs to be replaced by a DBA-level
+    description of tablespaces.
+   </para>
+
    <para>
     It is possible to create a database in a location other than the
     default location for the installation. But remember that all database access
@@ -368,21 +373,6 @@ CREATE DATABASE <replaceable>name</> WITH LOCATION '<replaceable>location</>';
     Databases created in alternative locations can be
     accessed and dropped like any other database.
    </para>
-
-   <note>
-    <para>
-     It can also be possible to specify absolute paths directly to the
-     <command>CREATE DATABASE</> command without defining environment
-     variables. This is disallowed by default because it is a security
-     risk. To allow it, you must compile <productname>PostgreSQL</> with
-     the C preprocessor macro <literal>ALLOW_ABSOLUTE_DBPATHS</>
-     defined. One way to do this is to run the compilation step like
-     this:
-<programlisting>
-gmake CPPFLAGS=-DALLOW_ABSOLUTE_DBPATHS all
-</programlisting>
-    </para>
-   </note>
  </sect1>
 
  <sect1 id="manage-ag-dropdb">
index a44e21e69eca570947382d6100cdc90950421f2f..352a21c292dd88c4d80ed7157903100be9700597 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.56 2004/04/20 01:11:49 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.57 2004/06/18 06:13:05 tgl Exp $
 PostgreSQL documentation
 Complete list of usable sgml source files in this directory.
 -->
@@ -44,6 +44,7 @@ Complete list of usable sgml source files in this directory.
 <!entity createSequence     system "create_sequence.sgml">
 <!entity createTable        system "create_table.sgml">
 <!entity createTableAs      system "create_table_as.sgml">
+<!entity createTableSpace   system "create_tablespace.sgml">
 <!entity createTrigger      system "create_trigger.sgml">
 <!entity createType         system "create_type.sgml">
 <!entity createUser         system "create_user.sgml">
@@ -66,6 +67,7 @@ Complete list of usable sgml source files in this directory.
 <!entity dropSchema         system "drop_schema.sgml">
 <!entity dropSequence       system "drop_sequence.sgml">
 <!entity dropTable          system "drop_table.sgml">
+<!entity dropTableSpace     system "drop_tablespace.sgml">
 <!entity dropTrigger        system "drop_trigger.sgml">
 <!entity dropType           system "drop_type.sgml">
 <!entity dropUser           system "drop_user.sgml">
index 065ee479366af5d1606b8eae8ff4af1f900fbe19..deb76d30f5072d059ba8dae1011d3d4d9ea33339 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/create_database.sgml,v 1.38 2004/03/23 02:47:35 neilc Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_database.sgml,v 1.39 2004/06/18 06:13:05 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -22,9 +22,9 @@ PostgreSQL documentation
 <synopsis>
 CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
     [ [ WITH ] [ OWNER [=] <replaceable class="parameter">dbowner</replaceable> ]
-           [ LOCATION [=] '<replaceable class="parameter">dbpath</replaceable>' ]
            [ TEMPLATE [=] <replaceable class="parameter">template</replaceable> ]
-           [ ENCODING [=] <replaceable class="parameter">encoding</replaceable> ] ]
+           [ ENCODING [=] <replaceable class="parameter">encoding</replaceable> ]
+           [ TABLESPACE [=] <replaceable class="parameter">tablespace</replaceable> ] ]
 </synopsis>
  </refsynopsisdiv>
 
@@ -50,29 +50,6 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
    privilege can only create databases owned by themselves.
   </para>
 
-  <para>
-   An alternative location can be specified in order to,
-   for example, store the database on a different disk.
-   The path must have been prepared with the 
-   <xref linkend="APP-INITLOCATION" endterm="APP-INITLOCATION-title">
-   command.
-  </para>
-
-  <para>
-   If the path name does not contain a slash, it is interpreted
-   as an environment variable name, which must be known to the
-   server process. This way the database administrator can
-   exercise control over locations in which databases can be created.
-   (A customary choice is, e.g., <envar>PGDATA2</envar>.)
-   If the server is compiled with <literal>ALLOW_ABSOLUTE_DBPATHS</literal>
-   (not so by default), absolute path names, as identified by
-   a leading slash
-   (e.g., <filename>/usr/local/pgsql/data</filename>),
-   are allowed as well.
-   In either case, the final path name must be absolute and must not
-   contain any single quotes.
-  </para>
-
   <para>
    By default, the new database will be created by cloning the standard
    system database <literal>template1</>.  A different template can be
@@ -83,13 +60,7 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
    version of <productname>PostgreSQL</productname>.  This is useful
    if you wish to avoid copying
    any installation-local objects that may have been added to
-   <literal>template1</>. 
-  </para>
-
-  <para>
-   The optional encoding parameter allows selection of the database
-   encoding.  When not specified, it defaults to the encoding used by
-   the selected template database.
+   <literal>template1</>.
   </para>
  </refsect1>
 
@@ -101,7 +72,7 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
       <term><replaceable class="parameter">name</replaceable></term>
       <listitem>
        <para>
-   The name of a database to create.
+        The name of a database to create.
        </para>
       </listitem>
      </varlistentry>
@@ -110,41 +81,43 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
       <listitem>
        <para>
         The name of the database user who will own the new database,
-   or <literal>DEFAULT</literal> to use the default (namely, the
-   user executing the command).
+        or <literal>DEFAULT</literal> to use the default (namely, the
+        user executing the command).
        </para>
       </listitem>
      </varlistentry>
      <varlistentry>
-      <term><replaceable class="parameter">dbpath</replaceable></term>
+      <term><replaceable class="parameter">template</replaceable></term>
       <listitem>
        <para>
-   An alternate file-system location in which to store the new database,
-   specified as a string literal;
-   or <literal>DEFAULT</literal> to use the default location.
+        The name of the template from which to create the new database,
+        or <literal>DEFAULT</literal> to use the default template
+        (<literal>template1</literal>).
        </para>
       </listitem>
      </varlistentry>
      <varlistentry>
-      <term><replaceable class="parameter">template</replaceable></term>
+      <term><replaceable class="parameter">encoding</replaceable></term>
       <listitem>
        <para>
-        The name of the template from which to create the new database,
-   or <literal>DEFAULT</literal> to use the default template
-   (<literal>template1</literal>).
+        Character set encoding to use in the new database.  Specify
+        a string constant (e.g., <literal>'SQL_ASCII'</literal>),
+        or an integer encoding number, or <literal>DEFAULT</literal>
+        to use the default encoding. The character sets supported by the
+        <productname>PostgreSQL</productname> server are described in
+        <xref linkend="multibyte-charset-supported">.
        </para>
       </listitem>
      </varlistentry>
      <varlistentry>
-      <term><replaceable class="parameter">encoding</replaceable></term>
+      <term><replaceable class="parameter">tablespace</replaceable></term>
       <listitem>
        <para>
-    Character set encoding to use in the new database.  Specify
-   a string constant (e.g., <literal>'SQL_ASCII'</literal>),
-   or an integer encoding number, or <literal>DEFAULT</literal>
-   to use the default encoding. The character sets supported by the
-   <productname>PostgreSQL</productname> server are described in
-   <xref linkend="multibyte-charset-supported">.
+        Specifies the default tablespace for the new database.
+        If not specified, the same tablespace that is default for
+        the template database is used.  See
+        <xref linkend="sql-createtablespace" endterm="sql-createtablespace-title">
+        for more information.
        </para>
       </listitem>
      </varlistentry>
@@ -167,9 +140,7 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
    <para>
     Errors along the line of <quote>could not initialize database directory</>
     are most likely related to insufficient permissions on the data
-    directory, a full disk, or other file system problems.  When using an
-    alternate location, the user under
-    which the database server is running must have access to the location.
+    directory, a full disk, or other file system problems.
    </para>
 
    <para>
@@ -181,13 +152,6 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
     wrapper program around this command, provided for convenience.
    </para>
 
-  <para>
-   There are security issues involved with using alternate database
-   locations specified with absolute path names; this is why the feature
-   is not enabled by default.  See <xref
-   linkend="manage-ag-alternate-locs"> for more information.
-  </para>
-
   <para>
    Although it is possible to copy a database other than <literal>template1</>
    by specifying its name as the template, this is not (yet) intended as
@@ -205,24 +169,6 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
 
 <programlisting>
 CREATE DATABASE lusiadas;
-</programlisting>
-  </para>
-
-  <para>
-   To create a new database in an alternate area
-   <filename>~/private_db</filename>, execute the following from the
-   shell:
-
-<programlisting>
-mkdir private_db
-initlocation ~/private_db
-</programlisting>
-
-   Then execute the following from within a
-   <application>psql</application> session:
-
-<programlisting>
-CREATE DATABASE elsewhere WITH LOCATION '/home/olly/private_db';
 </programlisting>
   </para>
  </refsect1>
index bfde61ee6c7b1e1fb0a85e37f4bdd6ff2d7c752e..93ae0c1c8165e698d295e3c3306997bf50c37ec6 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/create_index.sgml,v 1.47 2004/04/20 12:53:28 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_index.sgml,v 1.48 2004/06/18 06:13:05 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -22,6 +22,7 @@ PostgreSQL documentation
 <synopsis>
 CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table</replaceable> [ USING <replaceable class="parameter">method</replaceable> ]
     ( { <replaceable class="parameter">column</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ <replaceable class="parameter">opclass</replaceable> ] [, ...] )
+    [ TABLESPACE <replaceable class="parameter">tablespace</replaceable> ]
     [ WHERE <replaceable class="parameter">predicate</replaceable> ]
 </synopsis>
  </refsynopsisdiv>
@@ -78,7 +79,7 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
 
   <para>
    Indexes are not used for <literal>IS NULL</> clauses by default.
-   The best way to use indexes in such cases is to create a partial index 
+   The best way to use indexes in such cases is to create a partial index
    using an <literal>IS NULL</> comparison.
   </para>
 
@@ -109,11 +110,11 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
       <term><literal>UNIQUE</literal></term>
       <listitem>
        <para>
-   Causes the system to check for
-   duplicate values in the table when the index is created (if data
-   already exist) and each time data is added. Attempts to
-   insert or update data which would result in duplicate entries
-   will generate an error.
+        Causes the system to check for
+        duplicate values in the table when the index is created (if data
+        already exist) and each time data is added. Attempts to
+        insert or update data which would result in duplicate entries
+        will generate an error.
        </para>
       </listitem>
      </varlistentry>
@@ -122,9 +123,9 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
       <term><replaceable class="parameter">name</replaceable></term>
       <listitem>
        <para>
-   The name of the index to be created.  No schema name can be included
-   here; the index is always created in the same schema as its parent
-   table.
+        The name of the index to be created.  No schema name can be included
+        here; the index is always created in the same schema as its parent
+        table.
        </para>
       </listitem>
      </varlistentry>
@@ -133,7 +134,7 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
       <term><replaceable class="parameter">table</replaceable></term>
       <listitem>
        <para>
-   The name (possibly schema-qualified) of the table to be indexed.
+        The name (possibly schema-qualified) of the table to be indexed.
        </para>
       </listitem>
      </varlistentry>
@@ -154,7 +155,7 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
       <term><replaceable class="parameter">column</replaceable></term>
       <listitem>
        <para>
-   The name of a column of the table.
+        The name of a column of the table.
        </para>
       </listitem>
      </varlistentry>
@@ -163,10 +164,10 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
       <term><replaceable class="parameter">expression</replaceable></term>
       <listitem>
        <para>
-   An expression based on one or more columns of the table.  The
-   expression usually must be written with surrounding parentheses,
-   as shown in the syntax.  However, the parentheses may be omitted
-   if the expression has the form of a function call.
+        An expression based on one or more columns of the table.  The
+        expression usually must be written with surrounding parentheses,
+        as shown in the syntax.  However, the parentheses may be omitted
+        if the expression has the form of a function call.
        </para>
       </listitem>
      </varlistentry>
@@ -175,7 +176,17 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
       <term><replaceable class="parameter">opclass</replaceable></term>
       <listitem>
        <para>
-   The name of an operator class. See below for details.
+        The name of an operator class. See below for details.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><replaceable class="parameter">tablespace</replaceable></term>
+      <listitem>
+       <para>
+        The tablespace in which to create the index.  If not specified,
+        the tablespace of the parent table is used.
        </para>
       </listitem>
      </varlistentry>
@@ -184,10 +195,11 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
       <term><replaceable class="parameter">predicate</replaceable></term>
       <listitem>
        <para>
-   The constraint expression for a partial index.
+        The constraint expression for a partial index.
        </para>
       </listitem>
      </varlistentry>
+
     </variablelist>
  </refsect1>
 
@@ -260,7 +272,7 @@ SELECT * FROM points
 -->
 
  </refsect1>
+
  <refsect1>
   <title>Compatibility</title>
 
index 807f358d1f99a19e50d033e9418ae1ae81aeaf0b..8668612cc6aaa97cf273874e93bac21d196a1b6b 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/create_schema.sgml,v 1.11 2004/01/11 05:46:58 neilc Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_schema.sgml,v 1.12 2004/06/18 06:13:05 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -12,7 +12,7 @@ PostgreSQL documentation
  <refnamediv>
   <refname>CREATE SCHEMA</refname>
   <refpurpose>define a new schema</refpurpose>
- </refnamediv> 
+ </refnamediv>
 
  <indexterm zone="sql-createschema">
   <primary>CREATE SCHEMA</primary>
@@ -20,8 +20,8 @@ PostgreSQL documentation
 
  <refsynopsisdiv>
 <synopsis>
-CREATE SCHEMA <replaceable class="parameter">schemaname</replaceable> [ AUTHORIZATION <replaceable class="parameter">username</replaceable> ] [ <replaceable class="parameter">schema_element</replaceable> [ ... ] ]
-CREATE SCHEMA AUTHORIZATION <replaceable class="parameter">username</replaceable> [ <replaceable class="parameter">schema_element</replaceable> [ ... ] ]
+CREATE SCHEMA <replaceable class="parameter">schemaname</replaceable> [ AUTHORIZATION <replaceable class="parameter">username</replaceable> ] [ TABLESPACE <replaceable class="parameter">tablespace</replaceable> ] [ <replaceable class="parameter">schema_element</replaceable> [ ... ] ]
+CREATE SCHEMA AUTHORIZATION <replaceable class="parameter">username</replaceable> [ TABLESPACE <replaceable class="parameter">tablespace</replaceable> ] [ <replaceable class="parameter">schema_element</replaceable> [ ... ] ]
 </synopsis>
  </refsynopsisdiv>
 
@@ -54,7 +54,7 @@ CREATE SCHEMA AUTHORIZATION <replaceable class="parameter">username</replaceable
    all the created objects will be owned by that user.
   </para>
  </refsect1>
-  
+
  <refsect1>
   <title>Parameters</title>
 
@@ -63,8 +63,8 @@ CREATE SCHEMA AUTHORIZATION <replaceable class="parameter">username</replaceable
       <term><replaceable class="parameter">schemaname</replaceable></term>
       <listitem>
        <para>
-   The name of a schema to be created.  If this is omitted, the user name
-   is used as the schema name.
+        The name of a schema to be created.  If this is omitted, the user name
+        is used as the schema name.
        </para>
       </listitem>
      </varlistentry>
@@ -74,8 +74,19 @@ CREATE SCHEMA AUTHORIZATION <replaceable class="parameter">username</replaceable
       <listitem>
        <para>
         The name of the user who will own the schema.  If omitted,
-   defaults to the user executing the command.  Only superusers
-   may create schemas owned by users other than themselves.
+        defaults to the user executing the command.  Only superusers
+        may create schemas owned by users other than themselves.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><replaceable class="parameter">tablespace</replaceable></term>
+      <listitem>
+       <para>
+        The name of the tablespace that is to be the default tablespace
+        for all new objects created in the schema. If not supplied, the schema
+        will inherit the default tablespace of the database.
        </para>
       </listitem>
      </varlistentry>
@@ -102,8 +113,10 @@ CREATE SCHEMA AUTHORIZATION <replaceable class="parameter">username</replaceable
 
   <para>
    To create a schema, the invoking user must have the
-   <literal>CREATE</> privilege for the current database.  (Of course,
-   superusers bypass this check.)
+   <literal>CREATE</> privilege for the current database.
+   Also, the <literal>TABLESPACE</> option requires having
+   <literal>CREATE</> privilege for the specified tablespace.
+   (Of course, superusers bypass these checks.)
   </para>
  </refsect1>
 
@@ -181,7 +194,8 @@ CREATE VIEW hollywood.winners AS
   <simplelist type="inline">
    <member><xref linkend="sql-alterschema" endterm="sql-alterschema-title"></member>
    <member><xref linkend="sql-dropschema" endterm="sql-dropschema-title"></member>
-  </simplelist>
+    <member><xref linkend="sql-createtablespace" endterm="sql-createtablespace-title"></member>
+ </simplelist>
  </refsect1>
 
 </refentry>
index de5fd180f765f9e1825728757f33e4d98a148497..de9fa57ee14f7fdc560354011ddb084e7df1d561 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/create_sequence.sgml,v 1.39 2003/11/29 19:51:38 pgsql Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_sequence.sgml,v 1.40 2004/06/18 06:13:05 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -12,7 +12,7 @@ PostgreSQL documentation
  <refnamediv>
   <refname>CREATE SEQUENCE</refname>
   <refpurpose>define a new sequence generator</refpurpose>
- </refnamediv> 
+ </refnamediv>
 
  <indexterm zone="sql-createsequence">
   <primary>CREATE SEQUENCE</primary>
@@ -23,6 +23,7 @@ PostgreSQL documentation
 CREATE [ TEMPORARY | TEMP ] SEQUENCE <replaceable class="parameter">name</replaceable> [ INCREMENT [ BY ] <replaceable class="parameter">increment</replaceable> ]
     [ MINVALUE <replaceable class="parameter">minvalue</replaceable> | NO MINVALUE ] [ MAXVALUE <replaceable class="parameter">maxvalue</replaceable> | NO MAXVALUE ]
     [ START [ WITH ] <replaceable class="parameter">start</replaceable> ] [ CACHE <replaceable class="parameter">cache</replaceable> ] [ [ NO ] CYCLE ]
+    [ TABLESPACE <replaceable class="parameter">tablespace</replaceable> ]
 </synopsis>
  </refsynopsisdiv>
 
@@ -193,6 +194,19 @@ SELECT * FROM <replaceable>name</replaceable>;
      </para>
     </listitem>
    </varlistentry>
+
+   <varlistentry>
+    <term><replaceable class="parameter">tablespace</replaceable></term>
+    <listitem>
+     <para>
+      The optional clause <literal>TABLESPACE</> <replaceable
+      class="parameter">tablespace</replaceable> specifies
+      the tablespace in which to create the sequence.  If this clause
+      is not supplied, the tablespace of the sequence's schema will be used.
+     </para>
+    </listitem>
+   </varlistentry>
+
   </variablelist>
  </refsect1>
 
@@ -268,7 +282,7 @@ CREATE SEQUENCE serial START 101;
    Select the next number from this sequence:
 <programlisting>
 SELECT nextval('serial');
-    
+
  nextval
 ---------
      114
index 511aacc73f3347b341e387165a0a7154005b8bbe..40462752f11adfa2cc8f16ccf4321d966abef088 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.81 2004/05/19 23:10:43 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.82 2004/06/18 06:13:05 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -28,6 +28,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PAR
 [ INHERITS ( <replaceable>parent_table</replaceable> [, ... ] ) ]
 [ WITH OIDS | WITHOUT OIDS ]
 [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
+[ TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable> ]
 
 where <replaceable class="PARAMETER">column_constraint</replaceable> is:
 
@@ -48,7 +49,7 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
     [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE <replaceable class="parameter">action</replaceable> ] [ ON UPDATE <replaceable class="parameter">action</replaceable> ] }
 [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
 </synopsis>
-  
+
  </refsynopsisdiv>
 
  <refsect1 id="SQL-CREATETABLE-description">
@@ -321,7 +322,7 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
      </para>
     </listitem>
    </varlistentry>
-   
+
    <varlistentry>
     <term><literal>UNIQUE</> (column constraint)</term>
     <term><literal>UNIQUE ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] )</> (table constraint)</term>
@@ -405,9 +406,9 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
     <term><literal>REFERENCES <replaceable class="parameter">reftable</replaceable> [ ( <replaceable class="parameter">refcolumn</replaceable> ) ] [ MATCH <replaceable class="parameter">matchtype</replaceable> ] [ ON DELETE <replaceable class="parameter">action</replaceable> ] [ ON UPDATE <replaceable class="parameter">action</replaceable> ]</literal> (column constraint)</term>
 
    <term><literal>FOREIGN KEY ( <replaceable class="parameter">column</replaceable> [, ... ] )
-    REFERENCES <replaceable class="parameter">reftable</replaceable> [ ( <replaceable class="parameter">refcolumn</replaceable> [, ... ] ) ] 
+    REFERENCES <replaceable class="parameter">reftable</replaceable> [ ( <replaceable class="parameter">refcolumn</replaceable> [, ... ] ) ]
     [ MATCH <replaceable class="parameter">matchtype</replaceable> ]
-    [ ON DELETE <replaceable class="parameter">action</replaceable> ] 
+    [ ON DELETE <replaceable class="parameter">action</replaceable> ]
     [ ON UPDATE <replaceable class="parameter">action</replaceable> ]</literal>
     (table constraint)</term>
 
@@ -514,7 +515,7 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
      </para>
     </listitem>
    </varlistentry>
-   
+
    <varlistentry>
     <term><literal>DEFERRABLE</literal></term>
     <term><literal>NOT DEFERRABLE</literal></term>
@@ -553,7 +554,7 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
     <listitem>
      <para>
       The behavior of temporary tables at the end of a transaction
-      block can be controlled using <literal>ON COMMIT</literal>. 
+      block can be controlled using <literal>ON COMMIT</literal>.
       The three options are:
 
       <variablelist>
@@ -561,19 +562,19 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
         <term><literal>PRESERVE ROWS</literal></term>
         <listitem>
          <para>
-     No special action is taken at the ends of transactions.
-     This is the default behavior.
+          No special action is taken at the ends of transactions.
+          This is the default behavior.
          </para>
-       </listitem>
+        </listitem>
        </varlistentry>
-           
+
        <varlistentry>
         <term><literal>DELETE ROWS</literal></term>
         <listitem>
          <para>
           All rows in the temporary table will be deleted at the
           end of each transaction block.  Essentially, an automatic
-     <xref linkend="sql-truncate"> is done at each commit.
+          <xref linkend="sql-truncate"> is done at each commit.
          </para>
         </listitem>
        </varlistentry>
@@ -583,7 +584,7 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
         <listitem>
          <para>
           The temporary table will be dropped at the end of the current
-     transaction block.
+          transaction block.
          </para>
         </listitem>
        </varlistentry>
@@ -591,8 +592,20 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
      </para>
     </listitem>
    </varlistentry>
+
+   <varlistentry>
+    <term><literal>TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable></literal></term>
+    <listitem>
+     <para>
+      The <replaceable class="PARAMETER">tablespace</replaceable> is the name
+      of the tablespace in which the new table is to be created. If not
+      supplied, the default tablespace of the table's schema will be used.
+     </para>
+    </listitem>
+   </varlistentry>
+
   </variablelist>
- </refsect1>    
+ </refsect1>
 
  <refsect1 id="SQL-CREATETABLE-notes">
   <title>Notes</title>
@@ -696,7 +709,7 @@ CREATE TABLE films (
 );
 </programlisting>
   </para>
-  
+
   <para>
    Define a check column constraint:
 
@@ -719,7 +732,7 @@ CREATE TABLE distributors (
 );
 </programlisting>
   </para>
+
   <para>
    Define a primary key table constraint for the table
    <structname>films</>.  Primary key table constraints can be defined
@@ -749,7 +762,7 @@ CREATE TABLE distributors (
     did     integer,
     name    varchar(40),
     PRIMARY KEY(did)
-); 
+);
 </programlisting>
 
 <programlisting>
@@ -812,7 +825,7 @@ CREATE TABLE distributors (
   </para>
 
  </refsect1>
+
  <refsect1 id="SQL-CREATETABLE-compatibility">
   <title id="SQL-CREATETABLE-compatibility-title">Compatibility</title>
 
@@ -827,7 +840,7 @@ CREATE TABLE distributors (
    <para>
     Although the syntax of <literal>CREATE TEMPORARY TABLE</literal>
     resembles that of the SQL standard, the effect is not the same.  In the
-    standard, 
+    standard,
     temporary tables are defined just once and automatically exist (starting
     with empty contents) in every session that needs them.
     <productname>PostgreSQL</productname> instead
@@ -889,7 +902,7 @@ CREATE TABLE distributors (
     column, its presence is simply noise.
    </para>
   </refsect2>
-   
+
   <refsect2>
    <title>Inheritance</title>
 
@@ -923,6 +936,15 @@ CREATE TABLE distributors (
     DROP COLUMN</>, so it seems cleaner to ignore this spec restriction.
    </para>
   </refsect2>
+
+  <refsect2>
+   <title>TABLESPACE</title>
+
+   <para>
+    The <productname>PostgreSQL</productname> concept of tablespaces is not
+    standard.
+   </para>
+  </refsect2>
  </refsect1>
 
 
@@ -932,6 +954,7 @@ CREATE TABLE distributors (
   <simplelist type="inline">
    <member><xref linkend="sql-altertable" endterm="sql-altertable-title"></member>
    <member><xref linkend="sql-droptable" endterm="sql-droptable-title"></member>
+   <member><xref linkend="sql-createtablespace" endterm="sql-createtablespace-title"></member>
   </simplelist>
  </refsect1>
 </refentry>
diff --git a/doc/src/sgml/ref/create_tablespace.sgml b/doc/src/sgml/ref/create_tablespace.sgml
new file mode 100644 (file)
index 0000000..9f670a8
--- /dev/null
@@ -0,0 +1,156 @@
+<!--
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_tablespace.sgml,v 1.1 2004/06/18 06:13:05 tgl Exp $
+PostgreSQL documentation
+-->
+
+<refentry id="SQL-CREATETABLESPACE">
+ <refmeta>
+  <refentrytitle id="sql-createtablespace-title">CREATE TABLESPACE</refentrytitle>
+  <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+  <refname>CREATE TABLESPACE</refname>
+  <refpurpose>define a new tablespace</refpurpose>
+ </refnamediv>
+
+ <indexterm zone="sql-createtablespace">
+  <primary>CREATE TABLESPACE</primary>
+ </indexterm>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE TABLESPACE <replaceable class="parameter">tablespacename</replaceable> [ OWNER <replaceable class="parameter">username</replaceable> ] LOCATION '<replaceable class="parameter">directory</replaceable>'
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+  <title>Description</title>
+
+  <para>
+   <command>CREATE TABLESPACE</command> registers a new cluster-wide
+   tablespace.  The tablespace name must be distinct from the name of any
+   existing tablespace in the database cluster.
+  </para>
+
+  <para>
+   A tablespace allows superusers to define an alternative location on the
+   file system where the data files representing database objects
+   (such as tables and indexes) may reside.
+  </para>
+
+  <para>
+   A user with appropriate privileges can pass
+   <replaceable class="parameter">tablespacename</> to <command>CREATE
+   DATABASE</>, <command>CREATE SCHEMA</>, <command>CREATE TABLE</>,
+   <command>CREATE INDEX</> or <command>CREATE SEQUENCE</> to have the data
+   files for these objects stored within the specified tablespace.
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>Parameters</title>
+
+    <variablelist>
+     <varlistentry>
+      <term><replaceable class="parameter">tablespacename</replaceable></term>
+      <listitem>
+       <para>
+        The name of a tablespace to be created.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><replaceable class="parameter">username</replaceable></term>
+      <listitem>
+       <para>
+        The name of the user who will own the tablespace.  If omitted,
+        defaults to the user executing the command.  Only superusers
+        may create tablespaces, but they can assign ownership of tablespaces
+        to non-superusers.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><replaceable class="parameter">directory</replaceable></term>
+      <listitem>
+       <para>
+        The directory that will be used for the tablespace. The directory
+        must be empty and must be owned by the
+        <productname>PostgreSQL</> system user.  The directory must be
+        specified by an absolute path name.
+       </para>
+      </listitem>
+     </varlistentry>
+  </variablelist>
+ </refsect1>
+
+ <refsect1>
+  <title>Notes</title>
+
+  <para>
+   Tablespaces are only supported on systems that support symbolic links.
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>Examples</title>
+
+  <para>
+   Create a tablespace <literal>dbspace</> at <literal>/data/dbs</>:
+<programlisting>
+CREATE TABLESPACE dbspace LOCATION '/data/dbs';
+</programlisting>
+  </para>
+
+  <para>
+   Create a tablespace <literal>indexspace</> at <literal>/data/indexes</>
+   owned by user <literal>genevieve</>:
+<programlisting>
+CREATE TABLESPACE indexspace OWNER genevieve LOCATION '/data/indexes';
+</programlisting>
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>Compatibility</title>
+
+  <para>
+   <command>CREATE TABLESPACE</command> is a <productname>PostgreSQL</>
+   extension.
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>See Also</title>
+
+  <simplelist type="inline">
+   <member><xref linkend="sql-createdatabase" endterm="sql-createdatabase-title"></member>
+   <member><xref linkend="sql-createschema" endterm="sql-createschema-title"></member>
+   <member><xref linkend="sql-createtable" endterm="sql-createtable-title"></member>
+   <member><xref linkend="sql-createindex" endterm="sql-createindex-title"></member>
+   <member><xref linkend="sql-createsequence" endterm="sql-createsequence-title"></member>
+   <member><xref linkend="sql-droptablespace" endterm="sql-droptablespace-title"></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:
+-->
diff --git a/doc/src/sgml/ref/drop_tablespace.sgml b/doc/src/sgml/ref/drop_tablespace.sgml
new file mode 100644 (file)
index 0000000..ba84152
--- /dev/null
@@ -0,0 +1,103 @@
+<!--
+$PostgreSQL: pgsql/doc/src/sgml/ref/drop_tablespace.sgml,v 1.1 2004/06/18 06:13:05 tgl Exp $
+PostgreSQL documentation
+-->
+
+<refentry id="SQL-DROPTABLESPACE">
+ <refmeta>
+  <refentrytitle id="SQL-DROPTABLESPACE-TITLE">DROP TABLESPACE</refentrytitle>
+  <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+  <refname>DROP TABLESPACE</refname>
+  <refpurpose>remove a tablespace</refpurpose>
+ </refnamediv>
+
+ <indexterm zone="sql-droptablespace">
+  <primary>DROP TABLESPACE</primary>
+ </indexterm>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP TABLESPACE <replaceable class="PARAMETER">tablespacename</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+  <title>Description</title>
+
+  <para>
+   <command>DROP TABLESPACE</command> removes a tablespace from the system.
+  </para>
+
+  <para>
+   A tablespace can only be dropped by its owner or a superuser.
+   The tablespace must be empty of all database objects before it can be
+   dropped. It is possible that objects in other databases may still reside
+   in the tablespace even if no objects in the current database are using
+   the tablespace.
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>Parameters</title>
+
+  <variablelist>
+   <varlistentry>
+    <term><replaceable class="PARAMETER">tablespacename</replaceable></term>
+    <listitem>
+     <para>
+      The name of a tablespace.
+     </para>
+    </listitem>
+   </varlistentry>
+  </variablelist>
+ </refsect1>
+
+ <refsect1>
+  <title>Examples</title>
+
+  <para>
+   To remove tablespace <literal>mystuff</literal> from the system:
+<programlisting>
+DROP TABLESPACE mystuff;
+</programlisting>
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>Compatibility</title>
+
+  <para>
+   <command>DROP TABLESPACE</command> is a <productname>PostgreSQL</>
+   extension.
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>See Also</title>
+
+  <simplelist type="inline">
+   <member><xref linkend="sql-createtablespace" endterm="sql-createtablespace-title"></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:
+-->
index 25ba6e29bd619fc12c44072825d33bd62f993af3..a6a2d4d994e3e5c760e7905994253096ad9e6843 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/grant.sgml,v 1.40 2004/06/01 21:49:21 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/grant.sgml,v 1.41 2004/06/18 06:13:05 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -29,6 +29,10 @@ GRANT { { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
     ON DATABASE <replaceable>dbname</replaceable> [, ...]
     TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
 
+GRANT { CREATE | ALL [ PRIVILEGES ] }
+    ON TABLESPACE <replaceable>tablespacename</> [, ...]
+    TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
+
 GRANT { EXECUTE | ALL [ PRIVILEGES ] }
     ON FUNCTION <replaceable>funcname</replaceable> ([<replaceable>type</replaceable>, ...]) [, ...]
     TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
@@ -87,7 +91,7 @@ GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
   <para>
    Depending on the type of object, the initial default privileges may
    include granting some privileges to <literal>PUBLIC</literal>.
-   The default is no public access for tables and schemas;
+   The default is no public access for tables, schemas, and tablespaces;
    <literal>TEMP</> table creation privilege for databases;
    <literal>EXECUTE</> privilege for functions; and
    <literal>USAGE</> privilege for languages.
@@ -184,6 +188,12 @@ GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
       <para>
        For databases, allows new schemas to be created within the database.
       </para>
+      <para>
+       For tablespaces, allows tables to be created within the tablespace,
+       and allows databases and schemas to be created that have the tablespace
+       as their default tablespace.  (Note that revoking this privilege
+       will not alter the behavior of existing databases and schemas.)
+      </para>
       <para>
        For schemas, allows new objects to be created within the schema.
        To rename an existing object, you must own the object <emphasis>and</>
@@ -223,7 +233,7 @@ GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
        of privilege that is applicable to procedural languages.
       </para>
       <para>
-       For schemas, allows access to objects contained in the specified 
+       For schemas, allows access to objects contained in the specified
        schema (assuming that the objects' own privilege requirements are
        also met).  Essentially this allows the grantee to <quote>look up</>
        objects within the schema.
@@ -385,7 +395,7 @@ GRANT ALL PRIVILEGES ON kinds TO manuel;
 
  <refsect1 id="sql-grant-compatibility">
   <title>Compatibility</title>
-    
+
    <para>
     According to the SQL standard, the <literal>PRIVILEGES</literal>
     key word in <literal>ALL PRIVILEGES</literal> is required.  The
@@ -412,7 +422,7 @@ GRANT <replaceable class="PARAMETER">privileges</replaceable>
 
    <para>
     The <literal>RULE</literal> privilege, and privileges on
-    databases, schemas, languages, and sequences are
+    databases, tablespaces, schemas, languages, and sequences are
     <productname>PostgreSQL</productname> extensions.
    </para>
  </refsect1>
index dee5a60e68c0c146761552b26eac1f2f29ef8722..17ce7a2f39179fbf35746386fd1dc433e0f61dd7 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.115 2004/04/22 17:38:14 neilc Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.116 2004/06/18 06:13:05 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -71,7 +71,7 @@ PostgreSQL documentation
       </para>
       </listitem>
     </varlistentry>
-   
+
     <varlistentry>
       <term><option>-c <replaceable class="parameter">command</replaceable></></term>
       <term><option>--command <replaceable class="parameter">command</replaceable></></term>
@@ -208,7 +208,7 @@ PostgreSQL documentation
       </para>
       </listitem>
     </varlistentry>
+
     <varlistentry>
       <term><option>-l</></term>
       <term><option>--list</></term>
@@ -287,7 +287,7 @@ PostgreSQL documentation
       </para>
       </listitem>
     </varlistentry>
+
     <varlistentry>
       <term><option>-s</></term>
       <term><option>--single-step</></term>
@@ -343,7 +343,7 @@ PostgreSQL documentation
       </para>
       </listitem>
     </varlistentry>
+
     <varlistentry>
       <term><option>-u</></term>
       <listitem>
@@ -370,7 +370,7 @@ PostgreSQL documentation
       Connect to the database as the user <replaceable
       class="parameter">username</replaceable> instead of the default.
       (You must have permission to do so, of course.)
-      </para> 
+      </para>
       </listitem>
     </varlistentry>
 
@@ -491,7 +491,7 @@ PostgreSQL documentation
     not belong to any option it will be interpreted as the database name
     (or the user name, if the database name is also given). Not all
     these options are required, defaults do apply. If you omit the host
-    name, <application>psql</> will connect via a Unix domain socket 
+    name, <application>psql</> will connect via a Unix domain socket
     to a server on the local host, or via TCP/IP to <literal>localhost</> on machines
     that don't have unix domain sockets. The default port number is compile-time determined.
     Since the database server uses the same default, you will not have
@@ -565,9 +565,9 @@ testdb=>
     </para>
 
     <para>
-    The format of a <application>psql</application> command is the backslash, 
+    The format of a <application>psql</application> command is the backslash,
     followed immediately by a command verb, then any arguments. The arguments
-    are separated from the command verb and each other by any number of 
+    are separated from the command verb and each other by any number of
     whitespace characters.
     </para>
 
@@ -629,10 +629,10 @@ testdb=>
         <term><literal>\a</literal></term>
         <listitem>
         <para>
-   If the current table output format is unaligned, it is switched to aligned.
-   If it is not unaligned, it is set to unaligned. This command is
-   kept for backwards compatibility. See <command>\pset</command> for a
-   general solution.
+        If the current table output format is unaligned, it is switched to aligned.
+        If it is not unaligned, it is set to unaligned. This command is
+        kept for backwards compatibility. See <command>\pset</command> for a
+        general solution.
         </para>
         </listitem>
       </varlistentry>
@@ -641,16 +641,16 @@ testdb=>
        <term><literal>\cd [ <replaceable>directory</replaceable> ]</literal></term>
        <listitem>
         <para>
-    Changes the current working directory to
-    <replaceable>directory</replaceable>. Without argument, changes
-    to the current user's home directory.
+         Changes the current working directory to
+         <replaceable>directory</replaceable>. Without argument, changes
+         to the current user's home directory.
         </para>
 
-   <tip>
-    <para>
-     To print your current working directory, use <literal>\!pwd</literal>.
-    </para>
-   </tip>
+        <tip>
+         <para>
+          To print your current working directory, use <literal>\!pwd</literal>.
+         </para>
+        </tip>
        </listitem>
       </varlistentry>
 
@@ -673,43 +673,43 @@ testdb=>
         <term><literal>\connect</literal> (or <literal>\c</literal>) <literal>[ <replaceable class="parameter">dbname</replaceable> [ <replaceable class="parameter">username</replaceable> ] ]</literal></term>
         <listitem>
         <para>
-   Establishes a connection to a new database and/or under a user
-   name. The previous connection is closed. If <replaceable
-   class="parameter">dbname</replaceable> is <literal>-</literal>
-   the current database name is assumed.
-   </para>
+        Establishes a connection to a new database and/or under a user
+        name. The previous connection is closed. If <replaceable
+        class="parameter">dbname</replaceable> is <literal>-</literal>
+        the current database name is assumed.
+        </para>
 
-   <para>
-   If <replaceable class="parameter">username</replaceable> is
-   omitted the current user name is assumed. </para>
+        <para>
+        If <replaceable class="parameter">username</replaceable> is
+        omitted the current user name is assumed. </para>
 
-   <para>
-   As a special rule, <command>\connect</command> without any
-   arguments will connect to the default database as the default
-   user (as you would have gotten by starting
-   <application>psql</application> without any arguments).
-   </para>
+        <para>
+        As a special rule, <command>\connect</command> without any
+        arguments will connect to the default database as the default
+        user (as you would have gotten by starting
+        <application>psql</application> without any arguments).
+        </para>
 
-   <para>
-   If the connection attempt failed (wrong user name, access
-   denied, etc.), the previous connection will be kept if and only
-   if <application>psql</application> is in interactive mode. When
-   executing a non-interactive script, processing will immediately
-   stop with an error. This distinction was chosen as a user
-   convenience against typos on the one hand, and a safety
-   mechanism that scripts are not accidentally acting on the wrong
-   database on the other hand.
-   </para>
+        <para>
+        If the connection attempt failed (wrong user name, access
+        denied, etc.), the previous connection will be kept if and only
+        if <application>psql</application> is in interactive mode. When
+        executing a non-interactive script, processing will immediately
+        stop with an error. This distinction was chosen as a user
+        convenience against typos on the one hand, and a safety
+        mechanism that scripts are not accidentally acting on the wrong
+        database on the other hand.
+        </para>
         </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><literal>\copy <replaceable class="parameter">table</replaceable>
-   [ ( <replaceable class="parameter">column_list</replaceable> ) ]
+        [ ( <replaceable class="parameter">column_list</replaceable> ) ]
         { <literal>from</literal> | <literal>to</literal> }
-   { <replaceable class="parameter">filename</replaceable> | stdin | stdout | pstdin | pstdout }
-        [ with ] 
-            [ oids ] 
+        { <replaceable class="parameter">filename</replaceable> | stdin | stdout | pstdin | pstdout }
+        [ with ]
+            [ oids ]
             [ delimiter [ as ] '<replaceable class="parameter">character</replaceable>' ]
             [ null [ as ] '<replaceable class="parameter">string</replaceable>' ]
             [ csv [ quote [ as ] '<replaceable class="parameter">character</replaceable>' ]
@@ -729,37 +729,37 @@ testdb=>
         This means that file accessibility and privileges are those of
         the local user, not the server, and no SQL superuser
         privileges are required.
-   </para>
-
-   <para>
-   The syntax of the command is similar to that of the
-   <acronym>SQL</acronym> <xref linkend="sql-copy"
-   endterm="sql-copy-title"> command.  Note that, because of this,
-   special parsing rules apply to the <command>\copy</command>
-   command. In particular, the variable substitution rules and
-   backslash escapes do not apply.
-   </para>
-
-   <para>
-   <literal>\copy <replaceable
-   class="parameter">table</replaceable> from <replaceable
-   class="parameter">stdin | stdout</replaceable></literal>
-   reads/writes based on the command input and output respectively.
-   All rows are read from the same source that issued the command,
-   continuing until <literal>\.</literal> is read or the stream
-   reaches <acronym>EOF</>. Output is sent to the same place as
-   command output. To read/write from
-   <application>psql</application>'s standard input or output, use
-   <literal>pstdin</> or <literal>pstdout</>. This option is useful
-   for populating tables in-line within a SQL script file.
-   </para>
+        </para>
+
+        <para>
+        The syntax of the command is similar to that of the
+        <acronym>SQL</acronym> <xref linkend="sql-copy"
+        endterm="sql-copy-title"> command.  Note that, because of this,
+        special parsing rules apply to the <command>\copy</command>
+        command. In particular, the variable substitution rules and
+        backslash escapes do not apply.
+        </para>
+
+        <para>
+        <literal>\copy <replaceable
+        class="parameter">table</replaceable> from <replaceable
+        class="parameter">stdin | stdout</replaceable></literal>
+        reads/writes based on the command input and output respectively.
+        All rows are read from the same source that issued the command,
+        continuing until <literal>\.</literal> is read or the stream
+        reaches <acronym>EOF</>. Output is sent to the same place as
+        command output. To read/write from
+        <application>psql</application>'s standard input or output, use
+        <literal>pstdin</> or <literal>pstdout</>. This option is useful
+        for populating tables in-line within a SQL script file.
+        </para>
 
         <tip>
         <para>
-   This operation is not as efficient as the <acronym>SQL</acronym>
-   <command>COPY</command> command because all data must pass
-   through the client/server connection. For large
-   amounts of data the <acronym>SQL</acronym> command may be preferable.
+        This operation is not as efficient as the <acronym>SQL</acronym>
+        <command>COPY</command> command because all data must pass
+        through the client/server connection. For large
+        amounts of data the <acronym>SQL</acronym> command may be preferable.
         </para>
         </tip>
 
@@ -782,32 +782,32 @@ testdb=>
 
         <listitem>
         <para>
-   For each relation (table, view, index, or sequence) matching the
-   <replaceable class="parameter">pattern</replaceable>, show all
-   columns, their types, and any special
-   attributes such as <literal>NOT NULL</literal> or defaults, if
-   any. Associated indexes, constraints, rules, and triggers are
-   also shown, as is the view definition if the relation is a view.
-   (<quote>Matching the pattern</> is defined below.)
-   </para>
+        For each relation (table, view, index, or sequence) matching the
+        <replaceable class="parameter">pattern</replaceable>, show all
+        columns, their types, and any special
+        attributes such as <literal>NOT NULL</literal> or defaults, if
+        any. Associated indexes, constraints, rules, and triggers are
+        also shown, as is the view definition if the relation is a view.
+        (<quote>Matching the pattern</> is defined below.)
+        </para>
 
-   <para>
-   The command form <literal>\d+</literal> is identical, except that
-   more information is displayed: any comments associated with the
-   columns of the table are shown, as is the presence of OIDs in the
-   table.
-   </para>
+        <para>
+        The command form <literal>\d+</literal> is identical, except that
+        more information is displayed: any comments associated with the
+        columns of the table are shown, as is the presence of OIDs in the
+        table.
+        </para>
 
-   <note>
-   <para>
-   If <command>\d</command> is used without a
-   <replaceable class="parameter">pattern</replaceable> argument, it is
-   equivalent to <command>\dtvs</command> which will show a list of
-   all tables, views, and sequences. This is purely a convenience
-   measure.
-   </para>
-   </note>
-   </listitem>
+        <note>
+        <para>
+        If <command>\d</command> is used without a
+        <replaceable class="parameter">pattern</replaceable> argument, it is
+        equivalent to <command>\dtvs</command> which will show a list of
+        all tables, views, and sequences. This is purely a convenience
+        measure.
+        </para>
+        </note>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
@@ -824,14 +824,27 @@ testdb=>
       </varlistentry>
 
 
+      <varlistentry>
+        <term><literal>\db [ <replaceable class="parameter">pattern</replaceable> ]</literal></term>
+
+        <listitem>
+        <para>
+        Lists all available tablespaces. If <replaceable
+        class="parameter">pattern</replaceable>
+        is specified, only tablespaces whose names match the pattern are shown.
+        </para>
+        </listitem>
+      </varlistentry>
+
+
       <varlistentry>
         <term><literal>\dc [ <replaceable class="parameter">pattern</replaceable> ]</literal></term>
         <listitem>
         <para>
         Lists all available conversions between character-set encodings.
-   If <replaceable class="parameter">pattern</replaceable>
+        If <replaceable class="parameter">pattern</replaceable>
         is specified, only conversions whose names match the pattern are
-   listed.
+        listed.
         </para>
         </listitem>
       </varlistentry>
@@ -853,8 +866,8 @@ testdb=>
         <para>
         Shows the descriptions of objects matching the <replaceable
         class="parameter">pattern</replaceable>, or of all visible objects if
-   no argument is given.  But in either case, only objects that have
-   a description are listed.
+        no argument is given.  But in either case, only objects that have
+        a description are listed.
         (<quote>Object</quote> covers aggregates, functions, operators,
         types, relations (tables, views, indexes, sequences, large
         objects), rules, and triggers.) For example:
@@ -899,7 +912,7 @@ testdb=>
         return types. If <replaceable
         class="parameter">pattern</replaceable>
         is specified, only functions whose names match the pattern are shown.
-   If the form <literal>\df+</literal> is used, additional information about
+        If the form <literal>\df+</literal> is used, additional information about
         each function, including language and description, is shown.
         </para>
 
@@ -912,8 +925,8 @@ testdb=>
 
         <para>
         To reduce clutter, <literal>\df</> does not show data type I/O
-   functions.  This is implemented by ignoring functions that accept
-   or return type <type>cstring</>.
+        functions.  This is implemented by ignoring functions that accept
+        or return type <type>cstring</>.
         </para>
         </note>
 
@@ -936,36 +949,36 @@ testdb=>
       <varlistentry>
         <term><literal>\distvS [ <replaceable class="parameter">pattern</replaceable> ]</literal></term>
 
-   <listitem>
-   <para>
-   This is not the actual command name: the letters
-   <literal>i</literal>, <literal>s</literal>, <literal>t</literal>,
-   <literal>v</literal>, <literal>S</literal> stand for index,
-   sequence, table, view, and system table, respectively. You can
-   specify any or all of these letters, in any order, to obtain a
-   listing of all the matching objects.  The letter S restricts the
-   listing to system objects; without <literal>S</literal>, only
-   non-system objects are shown.  If <literal>+</literal> is appended
-   to the command name, each object is listed with its associated
-   description, if any.
-   </para>
+        <listitem>
+        <para>
+        This is not the actual command name: the letters
+        <literal>i</literal>, <literal>s</literal>, <literal>t</literal>,
+        <literal>v</literal>, <literal>S</literal> stand for index,
+        sequence, table, view, and system table, respectively. You can
+        specify any or all of these letters, in any order, to obtain a
+        listing of all the matching objects.  The letter S restricts the
+        listing to system objects; without <literal>S</literal>, only
+        non-system objects are shown.  If <literal>+</literal> is appended
+        to the command name, each object is listed with its associated
+        description, if any.
+        </para>
 
-   <para>
-   If <replaceable class="parameter">pattern</replaceable> is
-   specified, only objects whose names match the pattern are listed.
-   </para>
-   </listitem>
+        <para>
+        If <replaceable class="parameter">pattern</replaceable> is
+        specified, only objects whose names match the pattern are listed.
+        </para>
+        </listitem>
       </varlistentry>
 
 
       <varlistentry>
         <term><literal>\dl</literal></term>
-   <listitem>
-   <para>
-   This is an alias for <command>\lo_list</command>, which shows a
-   list of large objects.
-   </para>
-   </listitem>
+        <listitem>
+        <para>
+        This is an alias for <command>\lo_list</command>, which shows a
+        list of large objects.
+        </para>
+        </listitem>
       </varlistentry>
 
 
@@ -988,8 +1001,8 @@ testdb=>
         <listitem>
         <para>
         Lists available operators with their operand and return types.
-   If <replaceable class="parameter">pattern</replaceable> is
-   specified, only operators whose names match the pattern are listed.
+        If <replaceable class="parameter">pattern</replaceable> is
+        specified, only operators whose names match the pattern are listed.
         </para>
         </listitem>
       </varlistentry>
@@ -997,21 +1010,21 @@ testdb=>
 
       <varlistentry>
         <term><literal>\dp [ <replaceable class="parameter">pattern</replaceable> ]</literal></term>
-   <listitem>
-   <para>
+        <listitem>
+        <para>
         Produces a list of all available tables, views and sequences with their
         associated access privileges.
-   If <replaceable class="parameter">pattern</replaceable> is
-   specified, only tables, views and sequences whose names match the pattern are listed.
-   </para>
+        If <replaceable class="parameter">pattern</replaceable> is
+        specified, only tables, views and sequences whose names match the pattern are listed.
+        </para>
 
-   <para>
-   The commands <xref linkend="SQL-GRANT"> and
-   <xref linkend="SQL-REVOKE">
-   are used to set access privileges.  See <xref linkend="SQL-GRANT">
-   for more information.
-   </para>
-   </listitem>
+        <para>
+        The commands <xref linkend="SQL-GRANT"> and
+        <xref linkend="SQL-REVOKE">
+        are used to set access privileges.  See <xref linkend="SQL-GRANT">
+        for more information.
+        </para>
+        </listitem>
       </varlistentry>
 
 
@@ -1076,7 +1089,7 @@ testdb=>
       <varlistentry>
         <term><literal>\echo <replaceable class="parameter">text</replaceable> [ ... ]</literal></term>
         <listitem>
-   <para>
+        <para>
         Prints the arguments to the standard output, separated by one
         space and followed by a newline. This can be useful to
         intersperse information in the output of scripts. For example:
@@ -1086,16 +1099,16 @@ Tue Oct 26 21:40:57 CEST 1999
 </programlisting>
         If the first argument is an unquoted <literal>-n</literal> the the trailing
         newline is not written.
-   </para>
+        </para>
 
-   <tip>
-   <para>
-   If you use the <command>\o</command> command to redirect your
-   query output you may wish to use <command>\qecho</command>
-   instead of this command.
-   </para>
-   </tip>
-   </listitem>
+        <tip>
+        <para>
+        If you use the <command>\o</command> command to redirect your
+        query output you may wish to use <command>\qecho</command>
+        instead of this command.
+        </para>
+        </tip>
+        </listitem>
       </varlistentry>
 
 
@@ -1155,13 +1168,13 @@ Tue Oct 26 21:40:57 CEST 1999
         <acronym>SQL</acronym> commands is shown.
         </para>
 
-   <note>
-   <para>
-   To simplify typing, commands that consists of several words do
-   not have to be quoted. Thus it is fine to type <userinput>\help
-   alter table</userinput>.
-   </para>
-   </note> 
+        <note>
+        <para>
+        To simplify typing, commands that consists of several words do
+        not have to be quoted. Thus it is fine to type <userinput>\help
+        alter table</userinput>.
+        </para>
+        </note>
         </listitem>
       </varlistentry>
 
@@ -1170,11 +1183,11 @@ Tue Oct 26 21:40:57 CEST 1999
         <term><literal>\H</literal></term>
         <listitem>
         <para>
-   Turns on <acronym>HTML</acronym> query output format. If the
-   <acronym>HTML</acronym> format is already on, it is switched
-   back to the default aligned text format. This command is for
-   compatibility and convenience, but see <command>\pset</command>
-   about setting other output options.
+        Turns on <acronym>HTML</acronym> query output format. If the
+        <acronym>HTML</acronym> format is already on, it is switched
+        back to the default aligned text format. This command is for
+        compatibility and convenience, but see <command>\pset</command>
+        about setting other output options.
         </para>
         </listitem>
       </varlistentry>
@@ -1188,13 +1201,13 @@ Tue Oct 26 21:40:57 CEST 1999
         class="parameter">filename</replaceable> and executes it as
         though it had been typed on the keyboard.
         </para>
-   <note>
-   <para>
-   If you want to see the lines on the screen as they are read you
-   must set the variable <varname>ECHO</varname> to
-   <literal>all</literal>.
-   </para>
-   </note>
+        <note>
+        <para>
+        If you want to see the lines on the screen as they are read you
+        must set the variable <varname>ECHO</varname> to
+        <literal>all</literal>.
+        </para>
+        </note>
         </listitem>
       </varlistentry>
 
@@ -1215,83 +1228,83 @@ Tue Oct 26 21:40:57 CEST 1999
       <varlistentry>
         <term><literal>\lo_export <replaceable class="parameter">loid</replaceable> <replaceable class="parameter">filename</replaceable></literal></term>
 
-   <listitem>
-   <para>
-   Reads the large object with <acronym>OID</acronym> <replaceable
-   class="parameter">loid</replaceable> from the database and
-   writes it to <replaceable
-   class="parameter">filename</replaceable>. Note that this is
-   subtly different from the server function
-   <function>lo_export</function>, which acts with the permissions
-   of the user that the database server runs as and on the server's
-   file system.
-   </para>
-   <tip>
-   <para>
-   Use <command>\lo_list</command> to find out the large object's
-   <acronym>OID</acronym>.
-   </para>
-   </tip>
-   </listitem>
+        <listitem>
+        <para>
+        Reads the large object with <acronym>OID</acronym> <replaceable
+        class="parameter">loid</replaceable> from the database and
+        writes it to <replaceable
+        class="parameter">filename</replaceable>. Note that this is
+        subtly different from the server function
+        <function>lo_export</function>, which acts with the permissions
+        of the user that the database server runs as and on the server's
+        file system.
+        </para>
+        <tip>
+        <para>
+        Use <command>\lo_list</command> to find out the large object's
+        <acronym>OID</acronym>.
+        </para>
+        </tip>
+        </listitem>
       </varlistentry>
 
 
       <varlistentry>
         <term><literal>\lo_import <replaceable class="parameter">filename</replaceable> [ <replaceable class="parameter">comment</replaceable> ]</literal></term>
 
-   <listitem>
-   <para>
-   Stores the file into a <productname>PostgreSQL</productname>
-   large object. Optionally, it associates the given
-   comment with the object. Example:
+        <listitem>
+        <para>
+        Stores the file into a <productname>PostgreSQL</productname>
+        large object. Optionally, it associates the given
+        comment with the object. Example:
 <programlisting>
 foo=> <userinput>\lo_import '/home/peter/pictures/photo.xcf' 'a picture of me'</userinput>
 lo_import 152801
 </programlisting>
-   The response indicates that the large object received object ID
-   152801 which one ought to remember if one wants to access the
-   object ever again. For that reason it is recommended to always
-   associate a human-readable comment with every object. Those can
-   then be seen with the <command>\lo_list</command> command.
-   </para>
+        The response indicates that the large object received object ID
+        152801 which one ought to remember if one wants to access the
+        object ever again. For that reason it is recommended to always
+        associate a human-readable comment with every object. Those can
+        then be seen with the <command>\lo_list</command> command.
+        </para>
 
-   <para>
-   Note that this command is subtly different from the server-side
-   <function>lo_import</function> because it acts as the local user
-   on the local file system, rather than the server's user and file
-   system.
-   </para>
-   </listitem>
+        <para>
+        Note that this command is subtly different from the server-side
+        <function>lo_import</function> because it acts as the local user
+        on the local file system, rather than the server's user and file
+        system.
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><literal>\lo_list</literal></term>
-   <listitem>
-   <para>
-   Shows a list of all <productname>PostgreSQL</productname>
-   large objects currently stored in the database,
-   along with any comments provided for them.
-   </para>
-   </listitem>
+        <listitem>
+        <para>
+        Shows a list of all <productname>PostgreSQL</productname>
+        large objects currently stored in the database,
+        along with any comments provided for them.
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><literal>\lo_unlink <replaceable class="parameter">loid</replaceable></literal></term>
 
-   <listitem>
-   <para>
-   Deletes the large object with <acronym>OID</acronym>
-   <replaceable class="parameter">loid</replaceable> from the
-   database.
-   </para>
+        <listitem>
+        <para>
+        Deletes the large object with <acronym>OID</acronym>
+        <replaceable class="parameter">loid</replaceable> from the
+        database.
+        </para>
 
-   <tip>
-   <para>
-   Use <command>\lo_list</command> to find out the large object's
-   <acronym>OID</acronym>.
-   </para>
-   </tip>
-   </listitem>
+        <tip>
+        <para>
+        Use <command>\lo_list</command> to find out the large object's
+        <acronym>OID</acronym>.
+        </para>
+        </tip>
+        </listitem>
       </varlistentry>
 
 
@@ -1307,20 +1320,20 @@ lo_import 152801
         specified, the query output will be reset to the standard output.
         </para>
 
-   <para>
-   <quote>Query results</quote> includes all tables, command
-   responses, and notices obtained from the database server, as
-   well as output of various backslash commands that query the
-   database (such as <command>\d</command>), but not error
-   messages.
-   </para>
+        <para>
+        <quote>Query results</quote> includes all tables, command
+        responses, and notices obtained from the database server, as
+        well as output of various backslash commands that query the
+        database (such as <command>\d</command>), but not error
+        messages.
+        </para>
 
-   <tip>
-   <para>
-   To intersperse text output in between query results, use
-   <command>\qecho</command>.
-   </para>
-   </tip>
+        <tip>
+        <para>
+        To intersperse text output in between query results, use
+        <command>\qecho</command>.
+        </para>
+        </tip>
         </listitem>
       </varlistentry>
 
@@ -1338,210 +1351,210 @@ lo_import 152801
       <varlistentry>
         <term><literal>\pset <replaceable class="parameter">parameter</replaceable> [ <replaceable class="parameter">value</replaceable> ]</literal></term>
 
-   <listitem>
-   <para>
-   This command sets options affecting the output of query result
-   tables. <replaceable class="parameter">parameter</replaceable>
-   describes which option is to be set. The semantics of
-   <replaceable class="parameter">value</replaceable> depend
-   thereon.
-   </para>
-
-   <para>
-   Adjustable printing options are:
-   <variablelist>
-     <varlistentry>
-     <term><literal>format</literal></term>
-     <listitem>
-     <para>
-     Sets the output format to one of <literal>unaligned</literal>,
-     <literal>aligned</literal>, <literal>html</literal>, or
-     <literal>latex</literal>. Unique abbreviations are allowed.
-     (That would mean one letter is enough.)
-     </para>
-
-     <para>
-     <quote>Unaligned</quote> writes all columns of a row on a
-     line, separated by the currently active field separator. This
-     is intended to create output that might be intended to be read
-     in by other programs (tab-separated, comma-separated).
-     <quote>Aligned</quote> mode is the standard, human-readable,
-     nicely formatted text output that is default. The
-     <quote><acronym>HTML</acronym></quote> and
-     <quote>LaTeX</quote> modes put out tables that are intended to
-     be included in documents using the respective mark-up
-     language. They are not complete documents! (This might not be
-     so dramatic in <acronym>HTML</acronym>, but in LaTeX you must
-     have a complete document wrapper.)
-     </para>
-     </listitem>
+        <listitem>
+        <para>
+        This command sets options affecting the output of query result
+        tables. <replaceable class="parameter">parameter</replaceable>
+        describes which option is to be set. The semantics of
+        <replaceable class="parameter">value</replaceable> depend
+        thereon.
+        </para>
+
+        <para>
+        Adjustable printing options are:
+        <variablelist>
+          <varlistentry>
+          <term><literal>format</literal></term>
+          <listitem>
+          <para>
+          Sets the output format to one of <literal>unaligned</literal>,
+          <literal>aligned</literal>, <literal>html</literal>, or
+          <literal>latex</literal>. Unique abbreviations are allowed.
+          (That would mean one letter is enough.)
+          </para>
+
+          <para>
+          <quote>Unaligned</quote> writes all columns of a row on a
+          line, separated by the currently active field separator. This
+          is intended to create output that might be intended to be read
+          in by other programs (tab-separated, comma-separated).
+          <quote>Aligned</quote> mode is the standard, human-readable,
+          nicely formatted text output that is default. The
+          <quote><acronym>HTML</acronym></quote> and
+          <quote>LaTeX</quote> modes put out tables that are intended to
+          be included in documents using the respective mark-up
+          language. They are not complete documents! (This might not be
+          so dramatic in <acronym>HTML</acronym>, but in LaTeX you must
+          have a complete document wrapper.)
+          </para>
+          </listitem>
           </varlistentry>
 
-     <varlistentry>
-     <term><literal>border</literal></term>
-     <listitem>
-     <para>
-     The second argument must be a number. In general, the higher
-     the number the more borders and lines the tables will have,
-     but this depends on the particular format. In
-     <acronym>HTML</acronym> mode, this will translate directly
-     into the <literal>border=...</literal> attribute, in the
-     others only values 0 (no border), 1 (internal dividing lines),
-     and 2 (table frame) make sense.
-     </para>
-     </listitem>
-     </varlistentry>
-
-     <varlistentry>
-     <term><literal>expanded</literal> (or <literal>x</literal>)</term>
-     <listitem>
-     <para>
-     Toggles between regular and expanded format. When expanded
-     format is enabled, all output has two columns with the column
-     name on the left and the data on the right. This mode is
-     useful if the data wouldn't fit on the screen in the normal
-     <quote>horizontal</quote> mode.
-     </para>
-
-     <para>
-     Expanded mode is supported by all four output formats.
-     </para>
-     </listitem>
-     </varlistentry>
-
-     <varlistentry>
-     <term><literal>null</literal></term>
-     <listitem>
-     <para>
-     The second argument is a string that should be printed
-     whenever a column is null. The default is not to print
-     anything, which can easily be mistaken for, say, an empty
-     string. Thus, one might choose to write <literal>\pset null
-     '(null)'</literal>.
-     </para>
-     </listitem>
-     </varlistentry>
-
-     <varlistentry>
-     <term><literal>fieldsep</literal></term>
-     <listitem>
-     <para>
-     Specifies the field separator to be used in unaligned output
-     mode. That way one can create, for example, tab- or
-     comma-separated output, which other programs might prefer. To
-     set a tab as field separator, type <literal>\pset fieldsep
-     '\t'</literal>. The default field separator is
-     <literal>'|'</literal> (a vertical bar).
-     </para>
-     </listitem>
-     </varlistentry>
-
-     <varlistentry>
-     <term><literal>footer</literal></term>
-     <listitem>
-     <para>
-     Toggles the display of the default footer <literal>(x
-     rows)</literal>.
-     </para>
-     </listitem>
-     </varlistentry>
-
-     <varlistentry>
-     <term><literal>recordsep</literal></term>
-     <listitem>
-     <para>
+          <varlistentry>
+          <term><literal>border</literal></term>
+          <listitem>
+          <para>
+          The second argument must be a number. In general, the higher
+          the number the more borders and lines the tables will have,
+          but this depends on the particular format. In
+          <acronym>HTML</acronym> mode, this will translate directly
+          into the <literal>border=...</literal> attribute, in the
+          others only values 0 (no border), 1 (internal dividing lines),
+          and 2 (table frame) make sense.
+          </para>
+          </listitem>
+          </varlistentry>
+
+          <varlistentry>
+          <term><literal>expanded</literal> (or <literal>x</literal>)</term>
+          <listitem>
+          <para>
+          Toggles between regular and expanded format. When expanded
+          format is enabled, all output has two columns with the column
+          name on the left and the data on the right. This mode is
+          useful if the data wouldn't fit on the screen in the normal
+          <quote>horizontal</quote> mode.
+          </para>
+
+          <para>
+          Expanded mode is supported by all four output formats.
+          </para>
+          </listitem>
+          </varlistentry>
+
+          <varlistentry>
+          <term><literal>null</literal></term>
+          <listitem>
+          <para>
+          The second argument is a string that should be printed
+          whenever a column is null. The default is not to print
+          anything, which can easily be mistaken for, say, an empty
+          string. Thus, one might choose to write <literal>\pset null
+          '(null)'</literal>.
+          </para>
+          </listitem>
+          </varlistentry>
+
+          <varlistentry>
+          <term><literal>fieldsep</literal></term>
+          <listitem>
+          <para>
+          Specifies the field separator to be used in unaligned output
+          mode. That way one can create, for example, tab- or
+          comma-separated output, which other programs might prefer. To
+          set a tab as field separator, type <literal>\pset fieldsep
+          '\t'</literal>. The default field separator is
+          <literal>'|'</literal> (a vertical bar).
+          </para>
+          </listitem>
+          </varlistentry>
+
+          <varlistentry>
+          <term><literal>footer</literal></term>
+          <listitem>
+          <para>
+          Toggles the display of the default footer <literal>(x
+          rows)</literal>.
+          </para>
+          </listitem>
+          </varlistentry>
+
+          <varlistentry>
+          <term><literal>recordsep</literal></term>
+          <listitem>
+          <para>
           Specifies the record (line) separator to use in unaligned
           output mode. The default is a newline character.
-     </para>
-     </listitem>
-     </varlistentry>
-
-     <varlistentry>
-     <term><literal>tuples_only</literal> (or <literal>t</literal>)</term>
-     <listitem>
-     <para>
-     Toggles between tuples only and full display. Full display may
-     show extra information such as column headers, titles, and
-     various footers. In tuples only mode, only actual table data
-     is shown.
-     </para>
-     </listitem>
-     </varlistentry>
-
-     <varlistentry>
-     <term><literal>title [ <replaceable class="parameter">text</replaceable> ]</literal></term>
-     <listitem>
-     <para>
-     Sets the table title for any subsequently printed tables. This
-     can be used to give your output descriptive tags. If no
-     argument is given, the title is unset.
-     </para>
-     </listitem>
-     </varlistentry>
-
-     <varlistentry>
-     <term><literal>tableattr</literal> (or <literal>T</literal>) <literal>[ <replaceable class="parameter">text</replaceable> ]</literal></term>
-     <listitem>
-     <para>
-     Allows you to specify any attributes to be placed inside the
-     <acronym>HTML</acronym> <sgmltag>table</sgmltag> tag. This
-     could for example be <literal>cellpadding</literal> or
-     <literal>bgcolor</literal>. Note that you probably don't want
-     to specify <literal>border</literal> here, as that is already
-     taken care of by <literal>\pset border</literal>.
-     </para>
-     </listitem>
-     </varlistentry>
-
-
-     <varlistentry>
-     <term><literal>pager</literal></term>
-     <listitem>
-     <para>
-     Controls use of a pager for query and <application>psql</>
-     help output. If the environment variable <envar>PAGER</envar>
-     is set, the output is piped to the specified program.
-     Otherwise a platform-dependent default (such as
-     <filename>more</filename>) is used.
-     </para>
-
-     <para>
-     When the pager is off, the pager is not used. When the pager
-     is on, the pager is used only when appropriate, i.e. the
-     output is to a terminal and will not fit on the screen.
-     (<application>psql</> does not do a perfect job of estimating
-     when to use the pager.) <literal>\pset pager</> turns the
-     pager on and off. Pager can also be set to <literal>always</>,
-     which causes the pager to be always used.
-     </para>
-     </listitem>
-     </varlistentry>
-   </variablelist>
-        </para>
-
-        <para>
-   Illustrations on how these different formats look can be seen in
-   the <xref linkend="APP-PSQL-examples"
-   endterm="APP-PSQL-examples-title"> section.
-   </para>
-
-   <tip>
-   <para>
-   There are various shortcut commands for <command>\pset</command>. See
-   <command>\a</command>, <command>\C</command>, <command>\H</command>,
-   <command>\t</command>, <command>\T</command>, and <command>\x</command>.
-   </para>
-   </tip>
-
-   <note>
-   <para>
-   It is an error to call <command>\pset</command> without
-   arguments. In the future this call might show the current status
-   of all printing options.
-   </para>
-   </note>
-
-   </listitem>
+          </para>
+          </listitem>
+          </varlistentry>
+
+          <varlistentry>
+          <term><literal>tuples_only</literal> (or <literal>t</literal>)</term>
+          <listitem>
+          <para>
+          Toggles between tuples only and full display. Full display may
+          show extra information such as column headers, titles, and
+          various footers. In tuples only mode, only actual table data
+          is shown.
+          </para>
+          </listitem>
+          </varlistentry>
+
+          <varlistentry>
+          <term><literal>title [ <replaceable class="parameter">text</replaceable> ]</literal></term>
+          <listitem>
+          <para>
+          Sets the table title for any subsequently printed tables. This
+          can be used to give your output descriptive tags. If no
+          argument is given, the title is unset.
+          </para>
+          </listitem>
+          </varlistentry>
+
+          <varlistentry>
+          <term><literal>tableattr</literal> (or <literal>T</literal>) <literal>[ <replaceable class="parameter">text</replaceable> ]</literal></term>
+          <listitem>
+          <para>
+          Allows you to specify any attributes to be placed inside the
+          <acronym>HTML</acronym> <sgmltag>table</sgmltag> tag. This
+          could for example be <literal>cellpadding</literal> or
+          <literal>bgcolor</literal>. Note that you probably don't want
+          to specify <literal>border</literal> here, as that is already
+          taken care of by <literal>\pset border</literal>.
+          </para>
+          </listitem>
+          </varlistentry>
+
+
+          <varlistentry>
+          <term><literal>pager</literal></term>
+          <listitem>
+          <para>
+          Controls use of a pager for query and <application>psql</>
+          help output. If the environment variable <envar>PAGER</envar>
+          is set, the output is piped to the specified program.
+          Otherwise a platform-dependent default (such as
+          <filename>more</filename>) is used.
+          </para>
+
+          <para>
+          When the pager is off, the pager is not used. When the pager
+          is on, the pager is used only when appropriate, i.e. the
+          output is to a terminal and will not fit on the screen.
+          (<application>psql</> does not do a perfect job of estimating
+          when to use the pager.) <literal>\pset pager</> turns the
+          pager on and off. Pager can also be set to <literal>always</>,
+          which causes the pager to be always used.
+          </para>
+          </listitem>
+          </varlistentry>
+        </variablelist>
+        </para>
+
+        <para>
+        Illustrations on how these different formats look can be seen in
+        the <xref linkend="APP-PSQL-examples"
+        endterm="APP-PSQL-examples-title"> section.
+        </para>
+
+        <tip>
+        <para>
+        There are various shortcut commands for <command>\pset</command>. See
+        <command>\a</command>, <command>\C</command>, <command>\H</command>,
+        <command>\t</command>, <command>\T</command>, and <command>\x</command>.
+        </para>
+        </tip>
+
+        <note>
+        <para>
+        It is an error to call <command>\pset</command> without
+        arguments. In the future this call might show the current status
+        of all printing options.
+        </para>
+        </note>
+
+        </listitem>
       </varlistentry>
 
 
@@ -1559,9 +1572,9 @@ lo_import 152801
         <term><literal>\qecho <replaceable class="parameter">text</replaceable> [ ... ] </literal></term>
         <listitem>
         <para>
-   This command is identical to <command>\echo</command> except
-   that all output will be written to the query output channel, as
-   set by <command>\o</command>.
+        This command is identical to <command>\echo</command> except
+        that all output will be written to the query output channel, as
+        set by <command>\o</command>.
         </para>
         </listitem>
       </varlistentry>
@@ -1589,14 +1602,14 @@ lo_import 152801
         <acronym>GNU</acronym> history library.
         </para>
 
-   <note>
-   <para>
-   In the current version, it is no longer necessary to save the
-   command history, since that will be done automatically on
-   program termination. The history is also loaded automatically
-   every time <application>psql</application> starts up.
-   </para>
-   </note>
+        <note>
+        <para>
+        In the current version, it is no longer necessary to save the
+        command history, since that will be done automatically on
+        program termination. The history is also loaded automatically
+        every time <application>psql</application> starts up.
+        </para>
+        </note>
         </listitem>
       </varlistentry>
 
@@ -1604,37 +1617,37 @@ lo_import 152801
       <varlistentry>
         <term><literal>\set [ <replaceable class="parameter">name</replaceable> [ <replaceable class="parameter">value</replaceable> [ ... ] ] ]</literal></term>
 
-   <listitem>
-   <para>
-   Sets the internal variable <replaceable
-   class="parameter">name</replaceable> to <replaceable
-   class="parameter">value</replaceable> or, if more than one value
-   is given, to the concatenation of all of them. If no second
-   argument is given, the variable is just set with no value. To
-   unset a variable, use the <command>\unset</command> command.
-   </para>
-
-   <para>
-   Valid variable names can contain characters, digits, and
-   underscores. See the section <xref
-   linkend="APP-PSQL-variables"
-   endterm="APP-PSQL-variables-title"> below for details.
-   Variable names are case-sensitive.
-   </para>
-
-   <para>
-   Although you are welcome to set any variable to anything you
-   want, <application>psql</application> treats several variables
-   as special. They are documented in the section about variables.
-   </para>
-
-   <note>
-   <para>
-   This command is totally separate from the <acronym>SQL</acronym>
-   command <xref linkend="SQL-SET" endterm="SQL-SET-title">.
-   </para>
-   </note>
-   </listitem>
+        <listitem>
+        <para>
+        Sets the internal variable <replaceable
+        class="parameter">name</replaceable> to <replaceable
+        class="parameter">value</replaceable> or, if more than one value
+        is given, to the concatenation of all of them. If no second
+        argument is given, the variable is just set with no value. To
+        unset a variable, use the <command>\unset</command> command.
+        </para>
+
+        <para>
+        Valid variable names can contain characters, digits, and
+        underscores. See the section <xref
+        linkend="APP-PSQL-variables"
+        endterm="APP-PSQL-variables-title"> below for details.
+        Variable names are case-sensitive.
+        </para>
+
+        <para>
+        Although you are welcome to set any variable to anything you
+        want, <application>psql</application> treats several variables
+        as special. They are documented in the section about variables.
+        </para>
+
+        <note>
+        <para>
+        This command is totally separate from the <acronym>SQL</acronym>
+        command <xref linkend="SQL-SET" endterm="SQL-SET-title">.
+        </para>
+        </note>
+        </listitem>
       </varlistentry>
 
 
@@ -1691,7 +1704,7 @@ lo_import 152801
         <listitem>
         <para>
         Toggles extended table formatting mode. As such it is equivalent to
-   <literal>\pset expanded</literal>.
+        <literal>\pset expanded</literal>.
        </para>
        </listitem>
       </varlistentry>
@@ -1703,20 +1716,20 @@ lo_import 152801
         <para>
         Produces a list of all available tables, views and sequences with their
         associated access privileges.
-   If a <replaceable class="parameter">pattern</replaceable> is
-   specified, only tables,views and sequences whose names match the pattern are listed.
-   </para>
+        If a <replaceable class="parameter">pattern</replaceable> is
+        specified, only tables,views and sequences whose names match the pattern are listed.
+        </para>
 
-   <para>
-   The commands <xref linkend="SQL-GRANT"> and
-   <xref linkend="SQL-REVOKE">
-   are used to set access privileges.  See <xref linkend="SQL-GRANT">
-   for more information.
-   </para>
+        <para>
+        The commands <xref linkend="SQL-GRANT"> and
+        <xref linkend="SQL-REVOKE">
+        are used to set access privileges.  See <xref linkend="SQL-GRANT">
+        for more information.
+        </para>
 
-   <para>
-   This is an alias for <command>\dp</command> (<quote>display
-   privileges</quote>).
+        <para>
+        This is an alias for <command>\dp</command> (<quote>display
+        privileges</quote>).
         </para>
         </listitem>
       </varlistentry>
@@ -1764,7 +1777,7 @@ lo_import 152801
    A pattern that contains an (unquoted) dot is interpreted as a schema
    name pattern followed by an object name pattern.  For example,
    <literal>\dt foo*.bar*</> displays all tables in schemas whose name
-   starts with <literal>foo</> and whose table name 
+   starts with <literal>foo</> and whose table name
    starts with <literal>bar</>.  If no dot appears, then the pattern
    matches only objects that are visible in the current schema search path.
   </para>
@@ -1847,96 +1860,96 @@ bar
        <secondary>psql</secondary>
       </indexterm>
         <term><varname>AUTOCOMMIT</varname></term>
-   <listitem>
-   <para>
-   When <literal>on</> (the default), each SQL command is automatically
-   committed upon successful completion.  To postpone commit in this
-   mode, you must enter a <command>BEGIN</> or <command>START
-   TRANSACTION</> SQL command.  When <literal>off</> or unset, SQL
-   commands are not committed until you explicitly issue
-   <command>COMMIT</> or <command>END</>.  The autocommit-off
-   mode works by issuing an implicit <command>BEGIN</> for you, just
-   before any command that is not already in a transaction block and
-   is not itself a <command>BEGIN</> or other transaction-control
-   command.
-   </para>
-
-   <note>
-   <para>
-    In autocommit-off mode, you must explicitly abandon any failed
-    transaction by entering <command>ABORT</> or <command>ROLLBACK</>.
-    Also keep in mind that if you exit the session
-    without committing, your work will be lost.
-   </para>
-   </note>
-
-   <note>
-   <para>
-    The autocommit-on mode is <productname>PostgreSQL</>'s traditional
-    behavior, but autocommit-off is closer to the SQL spec.  If you
-    prefer autocommit-off, you may wish to set it in the system-wide
-         <filename>psqlrc</filename> or your 
+        <listitem>
+        <para>
+        When <literal>on</> (the default), each SQL command is automatically
+        committed upon successful completion.  To postpone commit in this
+        mode, you must enter a <command>BEGIN</> or <command>START
+        TRANSACTION</> SQL command.  When <literal>off</> or unset, SQL
+        commands are not committed until you explicitly issue
+        <command>COMMIT</> or <command>END</>.  The autocommit-off
+        mode works by issuing an implicit <command>BEGIN</> for you, just
+        before any command that is not already in a transaction block and
+        is not itself a <command>BEGIN</> or other transaction-control
+        command.
+        </para>
+
+        <note>
+        <para>
+         In autocommit-off mode, you must explicitly abandon any failed
+         transaction by entering <command>ABORT</> or <command>ROLLBACK</>.
+         Also keep in mind that if you exit the session
+         without committing, your work will be lost.
+        </para>
+        </note>
+
+        <note>
+        <para>
+         The autocommit-on mode is <productname>PostgreSQL</>'s traditional
+         behavior, but autocommit-off is closer to the SQL spec.  If you
+         prefer autocommit-off, you may wish to set it in the system-wide
+         <filename>psqlrc</filename> or your
          <filename>.psqlrc</filename> file.
-   </para>
-   </note>
-   </listitem>
+        </para>
+        </note>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>DBNAME</varname></term>
-   <listitem>
-   <para>
+        <listitem>
+        <para>
         The name of the database you are currently connected to. This is
         set every time you connect to a database (including program
         start-up), but can be unset.
-   </para>
-   </listitem>
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>ECHO</varname></term>
-   <listitem>
-   <para>
-   If set to <literal>all</literal>, all lines
-   entered or from a script are written to the standard output
-   before they are parsed or executed. To select this behavior on program
-   start-up, use the switch <option>-a</option>. If set to
-   <literal>queries</literal>,
-   <application>psql</application> merely prints all queries as
-   they are sent to the server. The switch for this is
-   <option>-e</option>.
-   </para>
-   </listitem>
+        <listitem>
+        <para>
+        If set to <literal>all</literal>, all lines
+        entered or from a script are written to the standard output
+        before they are parsed or executed. To select this behavior on program
+        start-up, use the switch <option>-a</option>. If set to
+        <literal>queries</literal>,
+        <application>psql</application> merely prints all queries as
+        they are sent to the server. The switch for this is
+        <option>-e</option>.
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>ECHO_HIDDEN</varname></term>
-   <listitem>
-   <para>
-   When this variable is set and a backslash command queries the
-   database, the query is first shown. This way you can study the
-   <productname>PostgreSQL</productname> internals and provide
-   similar functionality in your own programs. (To select this behavior
-   on program start-up, use the switch <option>-E</option>.)  If you set
-   the variable to the value <literal>noexec</literal>, the queries are
-   just shown but are not actually sent to the server and executed.
-   </para>
-   </listitem>
+        <listitem>
+        <para>
+        When this variable is set and a backslash command queries the
+        database, the query is first shown. This way you can study the
+        <productname>PostgreSQL</productname> internals and provide
+        similar functionality in your own programs. (To select this behavior
+        on program start-up, use the switch <option>-E</option>.)  If you set
+        the variable to the value <literal>noexec</literal>, the queries are
+        just shown but are not actually sent to the server and executed.
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>ENCODING</varname></term>
-   <listitem>
-   <para>
+        <listitem>
+        <para>
         The current client character set encoding.
-   </para>
-   </listitem>
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>HISTCONTROL</varname></term>
-   <listitem>
-   <para>
+        <listitem>
+        <para>
          If this variable is set to <literal>ignorespace</literal>,
          lines which begin with a space are not entered into the history
          list. If set to a value of <literal>ignoredups</literal>, lines
@@ -1944,47 +1957,47 @@ bar
          <literal>ignoreboth</literal> combines the two options. If
          unset, or if set to any other value than those above, all lines
          read in interactive mode are saved on the history list.
-   </para>
+        </para>
         <note>
         <para>
         This feature was shamelessly plagiarized from
         <application>Bash</application>.
         </para>
         </note>
-   </listitem>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>HISTSIZE</varname></term>
-   <listitem>
-   <para>
+        <listitem>
+        <para>
         The number of commands to store in the command history. The
         default value is 500.
-   </para>
+        </para>
         <note>
         <para>
         This feature was shamelessly plagiarized from
         <application>Bash</application>.
         </para>
         </note>
-   </listitem>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>HOST</varname></term>
-   <listitem>
-   <para>
+        <listitem>
+        <para>
         The database server host you are currently connected to. This is
         set every time you connect to a database (including program
         start-up), but can be unset.
-   </para>
-   </listitem>
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>IGNOREEOF</varname></term>
-   <listitem>
-   <para>
+        <listitem>
+        <para>
          If unset, sending an <acronym>EOF</> character (usually
          <keycombo action="simul"><keycap>Control</><keycap>D</></>)
          to an interactive session of <application>psql</application>
@@ -1992,125 +2005,125 @@ bar
          that many <acronym>EOF</> characters are ignored before the
          application terminates.  If the variable is set but has no
          numeric value, the default is 10.
-   </para>
+        </para>
         <note>
         <para>
         This feature was shamelessly plagiarized from
         <application>Bash</application>.
         </para>
         </note>
-   </listitem>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>LASTOID</varname></term>
-   <listitem>
-   <para>
+        <listitem>
+        <para>
         The value of the last affected OID, as returned from an
         <command>INSERT</command> or <command>lo_insert</command>
         command. This variable is only guaranteed to be valid until
         after the result of the next <acronym>SQL</acronym> command has
         been displayed.
-   </para>
-   </listitem>
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>ON_ERROR_STOP</varname></term>
-   <listitem>
-   <para>
-   By default, if non-interactive scripts encounter an error, such
-   as a malformed <acronym>SQL</acronym> command or internal
-   meta-command, processing continues. This has been the
-   traditional behavior of <application>psql</application> but it
-   is sometimes not desirable. If this variable is set, script
-   processing will immediately terminate. If the script was called
-   from another script it will terminate in the same fashion. If
-   the outermost script was not called from an interactive
-   <application>psql</application> session but rather using the
-   <option>-f</option> option, <application>psql</application> will
-   return error code 3, to distinguish this case from fatal error
-   conditions (error code 1).
-   </para>
-   </listitem>
+        <listitem>
+        <para>
+        By default, if non-interactive scripts encounter an error, such
+        as a malformed <acronym>SQL</acronym> command or internal
+        meta-command, processing continues. This has been the
+        traditional behavior of <application>psql</application> but it
+        is sometimes not desirable. If this variable is set, script
+        processing will immediately terminate. If the script was called
+        from another script it will terminate in the same fashion. If
+        the outermost script was not called from an interactive
+        <application>psql</application> session but rather using the
+        <option>-f</option> option, <application>psql</application> will
+        return error code 3, to distinguish this case from fatal error
+        conditions (error code 1).
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>PORT</varname></term>
-   <listitem>
-   <para>
+        <listitem>
+        <para>
         The database server port to which you are currently connected.
         This is set every time you connect to a database (including
         program start-up), but can be unset.
-   </para>
-   </listitem>
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>PROMPT1</varname></term>
         <term><varname>PROMPT2</varname></term>
         <term><varname>PROMPT3</varname></term>
-   <listitem>
-   <para>
-   These specify what the prompts <application>psql</application>
-   issues should look like. See <xref
-   linkend="APP-PSQL-prompting"
-   endterm="APP-PSQL-prompting-title"> below.
-   </para>
-   </listitem>
+        <listitem>
+        <para>
+        These specify what the prompts <application>psql</application>
+        issues should look like. See <xref
+        linkend="APP-PSQL-prompting"
+        endterm="APP-PSQL-prompting-title"> below.
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>QUIET</varname></term>
-   <listitem>
-   <para>
-   This variable is equivalent to the command line option
-   <option>-q</option>. It is probably not too useful in
-   interactive mode.
-   </para>
-   </listitem>
+        <listitem>
+        <para>
+        This variable is equivalent to the command line option
+        <option>-q</option>. It is probably not too useful in
+        interactive mode.
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>SINGLELINE</varname></term>
-   <listitem>
-   <para>
-   This variable is equivalent to the command line option
-   <option>-S</option>.
-   </para>
-   </listitem>
+        <listitem>
+        <para>
+        This variable is equivalent to the command line option
+        <option>-S</option>.
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>SINGLESTEP</varname></term>
-   <listitem>
-   <para>
-   This variable is equivalent to the command line option
-   <option>-s</option>.
-   </para>
-   </listitem>
+        <listitem>
+        <para>
+        This variable is equivalent to the command line option
+        <option>-s</option>.
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>USER</varname></term>
-   <listitem>
-   <para>
+        <listitem>
+        <para>
         The database user you are currently connected as. This is set
         every time you connect to a database (including program
         start-up), but can be unset.
-   </para>
-   </listitem>
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>VERBOSITY</varname></term>
-   <listitem>
-   <para>
-   This variable can be set to the values <literal>default</>,
-   <literal>verbose</>, or <literal>terse</> to control the verbosity
-   of error reports.
-   </para>
-   </listitem>
+        <listitem>
+        <para>
+        This variable can be set to the values <literal>default</>,
+        <literal>verbose</>, or <literal>terse</> to control the verbosity
+        of error reports.
+        </para>
+        </listitem>
       </varlistentry>
 
     </variablelist>
@@ -2211,7 +2224,7 @@ testdb=> <userinput>\set content '\'' `sed -e "s/'/\\\\\\'/g" < my_file.txt` '\'
     <variablelist>
       <varlistentry>
         <term><literal>%M</literal></term>
-   <listitem>
+        <listitem>
          <para>
           The full host name (with domain name) of the database server,
           or <literal>[local]</literal> if the connection is over a Unix
@@ -2225,7 +2238,7 @@ testdb=> <userinput>\set content '\'' `sed -e "s/'/\\\\\\'/g" < my_file.txt` '\'
 
       <varlistentry>
         <term><literal>%m</literal></term>
-   <listitem>
+        <listitem>
          <para>
           The host name of the database server, truncated at the
           first dot, or <literal>[local]</literal> if the connection is
@@ -2236,12 +2249,12 @@ testdb=> <userinput>\set content '\'' `sed -e "s/'/\\\\\\'/g" < my_file.txt` '\'
 
       <varlistentry>
         <term><literal>%&gt;</literal></term>
-   <listitem><para>The port number at which the database server is listening.</para></listitem>
+        <listitem><para>The port number at which the database server is listening.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term><literal>%n</literal></term>
-   <listitem>
+        <listitem>
          <para>
           The database session user name.  (The expansion of this
           value might change during a database session as the result
@@ -2253,18 +2266,18 @@ testdb=> <userinput>\set content '\'' `sed -e "s/'/\\\\\\'/g" < my_file.txt` '\'
 
       <varlistentry>
         <term><literal>%/</literal></term>
-   <listitem><para>The name of the current database.</para></listitem>
+        <listitem><para>The name of the current database.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term><literal>%~</literal></term>
-   <listitem><para>Like <literal>%/</literal>, but the output is <literal>~</literal>
+        <listitem><para>Like <literal>%/</literal>, but the output is <literal>~</literal>
          (tilde) if the database is your default database.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term><literal>%#</literal></term>
-   <listitem>
+        <listitem>
          <para>
           If the session user is a database superuser, then a
           <literal>#</literal>, otherwise a <literal>&gt;</literal>.
@@ -2277,75 +2290,75 @@ testdb=> <userinput>\set content '\'' `sed -e "s/'/\\\\\\'/g" < my_file.txt` '\'
 
       <varlistentry>
         <term><literal>%R</literal></term>
-   <listitem>
-   <para>
-   In prompt 1 normally <literal>=</literal>, but <literal>^</literal> if
-   in single-line mode, and <literal>!</literal> if the session is
-   disconnected from the database (which can happen if
-   <command>\connect</command> fails). In prompt 2 the sequence is
-   replaced by <literal>-</literal>, <literal>*</literal>, a single quote,
-   or a double quote, depending on whether
-   <application>psql</application> expects more input because the
-   command wasn't terminated yet, because you are inside a
-   <literal>/* ... */</literal> comment, or because you are inside
-   a quote. In prompt 3 the sequence doesn't produce anything.
-   </para>
-   </listitem>
+        <listitem>
+        <para>
+        In prompt 1 normally <literal>=</literal>, but <literal>^</literal> if
+        in single-line mode, and <literal>!</literal> if the session is
+        disconnected from the database (which can happen if
+        <command>\connect</command> fails). In prompt 2 the sequence is
+        replaced by <literal>-</literal>, <literal>*</literal>, a single quote,
+        or a double quote, depending on whether
+        <application>psql</application> expects more input because the
+        command wasn't terminated yet, because you are inside a
+        <literal>/* ... */</literal> comment, or because you are inside
+        a quote. In prompt 3 the sequence doesn't produce anything.
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><literal>%x</literal></term>
-   <listitem>
-   <para>
-   Transaction status: an empty string when not in a transaction
-   block, or <literal>*</> when in a transaction block, or
-   <literal>!</> when in a failed transaction block, or <literal>?</>
-   when the transaction state is indeterminate (for example, because
-   there is no connection).
-   </para>
-   </listitem>
+        <listitem>
+        <para>
+        Transaction status: an empty string when not in a transaction
+        block, or <literal>*</> when in a transaction block, or
+        <literal>!</> when in a failed transaction block, or <literal>?</>
+        when the transaction state is indeterminate (for example, because
+        there is no connection).
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><literal>%</literal><replaceable class="parameter">digits</replaceable></term>
-   <listitem>
-   <para>
-   The character with the indicated numeric code is substituted.
-   If <replaceable class="parameter">digits</replaceable> starts
-   with <literal>0x</literal> the rest of the characters are
-   interpreted as hexadecimal; otherwise if the first digit is
-   <literal>0</literal> the digits are interpreted as octal;
-   otherwise the digits are read as a decimal number.
-   </para>
-   </listitem>
+        <listitem>
+        <para>
+        The character with the indicated numeric code is substituted.
+        If <replaceable class="parameter">digits</replaceable> starts
+        with <literal>0x</literal> the rest of the characters are
+        interpreted as hexadecimal; otherwise if the first digit is
+        <literal>0</literal> the digits are interpreted as octal;
+        otherwise the digits are read as a decimal number.
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><literal>%:</literal><replaceable class="parameter">name</replaceable><literal>:</literal></term>
-   <listitem>
-   <para>
-   The value of the <application>psql</application> variable
-   <replaceable class="parameter">name</replaceable>. See the
-   section <xref linkend="APP-PSQL-variables"
-   endterm="APP-PSQL-variables-title"> for details.
-   </para>
-   </listitem>
+        <listitem>
+        <para>
+        The value of the <application>psql</application> variable
+        <replaceable class="parameter">name</replaceable>. See the
+        section <xref linkend="APP-PSQL-variables"
+        endterm="APP-PSQL-variables-title"> for details.
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><literal>%`</literal><replaceable class="parameter">command</replaceable><literal>`</literal></term>
-   <listitem>
-   <para>
-   The output of <replaceable
-   class="parameter">command</replaceable>, similar to ordinary
-   <quote>back-tick</quote> substitution.
-   </para>
-   </listitem>
+        <listitem>
+        <para>
+        The output of <replaceable
+        class="parameter">command</replaceable>, similar to ordinary
+        <quote>back-tick</quote> substitution.
+        </para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><literal>%[</literal> ... <literal>%]</literal></term>
-   <listitem>
+        <listitem>
          <para>
          Prompts may contain terminal control characters which, for
          example, change the color, background, or style of the prompt
@@ -2360,8 +2373,8 @@ testdb=> \set PROMPT1 '%[%033[1;33;40m%]%n@%/%R%[%033[0m%#%] '
 </programlisting>
          results in a boldfaced (<literal>1;</literal>) yellow-on-black
          (<literal>33;40</literal>) prompt on VT100-compatible, color-capable
-    terminals.
-       </para>
+         terminals.
+        </para>
         </listitem>
       </varlistentry>
 
@@ -2505,10 +2518,10 @@ $endif
     <para>
      Before starting up, <application>psql</application> attempts to
      read and execute commands from the the system-wide
-     <filename>psqlrc</filename> file and the  
+     <filename>psqlrc</filename> file and the
      <filename>$HOME/.psqlrc</filename> file in the user's home
-     directory.  See <filename><replaceable>PREFIX</>/share/psqlrc.sample</> 
-     for information on setting up the system-wide file.  It could be used 
+     directory.  See <filename><replaceable>PREFIX</>/share/psqlrc.sample</>
+     for information on setting up the system-wide file.  It could be used
      to set up the client or the server to taste (using the <command>\set
      </command> and <command>SET</command> commands).
     </para>
index 096a813b7f028ae89f9fa99c3ecb5de2a1359efe..c6cd587ade71641a99a501df6e5607e10900a6cf 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/revoke.sgml,v 1.30 2004/06/01 21:49:21 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/revoke.sgml,v 1.31 2004/06/18 06:13:05 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -33,6 +33,12 @@ REVOKE [ GRANT OPTION FOR ]
     FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
     [ CASCADE | RESTRICT ]
 
+REVOKE [ GRANT OPTION FOR ]
+    { CREATE | ALL [ PRIVILEGES ] }
+    ON TABLESPACE <replaceable>tablespacename</replaceable> [, ...]
+    FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
+    [ CASCADE | RESTRICT ]
+
 REVOKE [ GRANT OPTION FOR ]
     { EXECUTE | ALL [ PRIVILEGES ] }
     ON FUNCTION <replaceable>funcname</replaceable> ([<replaceable>type</replaceable>, ...]) [, ...]
index 03df5920566043b36a8f429554b0edc7f3fff104..100c69bde93be436d4799d993d9bf0547770322e 100644 (file)
@@ -1,5 +1,5 @@
 <!-- reference.sgml
-$PostgreSQL: pgsql/doc/src/sgml/reference.sgml,v 1.47 2004/04/20 01:14:55 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/reference.sgml,v 1.48 2004/06/18 06:13:02 tgl Exp $
 
 PostgreSQL Reference Manual
 -->
@@ -76,6 +76,7 @@ PostgreSQL Reference Manual
    &createSequence;
    &createTable;
    &createTableAs;
+   &createTableSpace;
    &createTrigger;
    &createType;
    &createUser;
@@ -98,6 +99,7 @@ PostgreSQL Reference Manual
    &dropSchema;
    &dropSequence;
    &dropTable;
+   &dropTableSpace;
    &dropTrigger;
    &dropType;
    &dropUser;
index cb1e68930531500028e3b1f1f98c8b3fa6db9ec6..8e595c18cb88d06b0397e161960d4318bc6ff9ce 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.168 2004/05/27 17:12:37 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.169 2004/06/18 06:13:09 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -2630,8 +2630,8 @@ heap_undo(XLogRecPtr lsn, XLogRecord *record)
 static void
 out_target(char *buf, xl_heaptid *target)
 {
-   sprintf(buf + strlen(buf), "node %u/%u; tid %u/%u",
-           target->node.tblNode, target->node.relNode,
+   sprintf(buf + strlen(buf), "rel %u/%u/%u; tid %u/%u",
+           target->node.spcNode, target->node.dbNode, target->node.relNode,
            ItemPointerGetBlockNumber(&(target->tid)),
            ItemPointerGetOffsetNumber(&(target->tid)));
 }
@@ -2673,8 +2673,9 @@ heap_desc(char *buf, uint8 xl_info, char *rec)
    {
        xl_heap_clean *xlrec = (xl_heap_clean *) rec;
 
-       sprintf(buf + strlen(buf), "clean: node %u/%u; blk %u",
-               xlrec->node.tblNode, xlrec->node.relNode, xlrec->block);
+       sprintf(buf + strlen(buf), "clean: rel %u/%u/%u; blk %u",
+               xlrec->node.spcNode, xlrec->node.dbNode,
+               xlrec->node.relNode, xlrec->block);
    }
    else
        strcat(buf, "UNKNOWN");
index ed398b32da5bb0a72e2b38d3da81537b34cbf684..3cb2f3836d26e791342f97ee3c197fbf484be6e9 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.13 2004/06/02 17:28:17 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.14 2004/06/18 06:13:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -803,8 +803,8 @@ btree_undo(XLogRecPtr lsn, XLogRecord *record)
 static void
 out_target(char *buf, xl_btreetid *target)
 {
-   sprintf(buf + strlen(buf), "node %u/%u; tid %u/%u",
-           target->node.tblNode, target->node.relNode,
+   sprintf(buf + strlen(buf), "rel %u/%u/%u; tid %u/%u",
+           target->node.spcNode, target->node.dbNode, target->node.relNode,
            ItemPointerGetBlockNumber(&(target->tid)),
            ItemPointerGetOffsetNumber(&(target->tid)));
 }
@@ -884,8 +884,9 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
            {
                xl_btree_delete *xlrec = (xl_btree_delete *) rec;
 
-               sprintf(buf + strlen(buf), "delete: node %u/%u; blk %u",
-                xlrec->node.tblNode, xlrec->node.relNode, xlrec->block);
+               sprintf(buf + strlen(buf), "delete: rel %u/%u/%u; blk %u",
+                       xlrec->node.spcNode, xlrec->node.dbNode,
+                       xlrec->node.relNode, xlrec->block);
                break;
            }
        case XLOG_BTREE_DELETE_PAGE:
@@ -903,8 +904,9 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
            {
                xl_btree_newroot *xlrec = (xl_btree_newroot *) rec;
 
-               sprintf(buf + strlen(buf), "newroot: node %u/%u; root %u lev %u",
-                       xlrec->node.tblNode, xlrec->node.relNode,
+               sprintf(buf + strlen(buf), "newroot: rel %u/%u/%u; root %u lev %u",
+                       xlrec->node.spcNode, xlrec->node.dbNode,
+                       xlrec->node.relNode,
                        xlrec->rootblk, xlrec->level);
                break;
            }
@@ -912,8 +914,9 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
            {
                xl_btree_newmeta *xlrec = (xl_btree_newmeta *) rec;
 
-               sprintf(buf + strlen(buf), "newmeta: node %u/%u; root %u lev %u fast %u lev %u",
-                       xlrec->node.tblNode, xlrec->node.relNode,
+               sprintf(buf + strlen(buf), "newmeta: rel %u/%u/%u; root %u lev %u fast %u lev %u",
+                       xlrec->node.spcNode, xlrec->node.dbNode,
+                       xlrec->node.relNode,
                        xlrec->meta.root, xlrec->meta.level,
                        xlrec->meta.fastroot, xlrec->meta.fastlevel);
                break;
@@ -922,9 +925,9 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
            {
                xl_btree_newpage *xlrec = (xl_btree_newpage *) rec;
 
-               sprintf(buf + strlen(buf), "newpage: node %u/%u; page %u",
-                       xlrec->node.tblNode, xlrec->node.relNode,
-                       xlrec->blkno);
+               sprintf(buf + strlen(buf), "newpage: rel %u/%u/%u; page %u",
+                       xlrec->node.spcNode, xlrec->node.dbNode,
+                       xlrec->node.relNode, xlrec->blkno);
                break;
            }
        default:
index a7c8d3bf52b2c8902fa709907ee2917491e59d89..a58902e76f6b50ec86e71777163de8483173c20d 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/xlogutils.c,v 1.30 2004/02/11 22:55:24 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlogutils.c,v 1.31 2004/06/18 06:13:15 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -354,7 +354,7 @@ XLogOpenRelation(bool redo, RmgrId rmid, RelFileNode rnode)
         * though, since we are presumably running by ourselves and can't
         * have any lock conflicts ...
         */
-       res->reldata.rd_lockInfo.lockRelId.dbId = rnode.tblNode;
+       res->reldata.rd_lockInfo.lockRelId.dbId = rnode.dbNode;
        res->reldata.rd_lockInfo.lockRelId.relId = rnode.relNode;
 
        hentry = (XLogRelCacheEntry *)
index cbc8ff6e53996c83cb7682aac69e30143c5552af..7b712bd555b51370d79985f61c786d762bb10b1a 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.69 2004/06/03 02:08:02 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.70 2004/06/18 06:13:17 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -31,6 +31,7 @@
 #include "catalog/pg_attribute.h"
 #include "catalog/pg_class.h"
 #include "catalog/pg_namespace.h"
+#include "catalog/pg_tablespace.h"
 #include "commands/defrem.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
@@ -181,6 +182,7 @@ Boot_CreateStmt:
 
                        boot_reldesc = heap_create(LexIDStr($5),
                                                   PG_CATALOG_NAMESPACE,
+                                                  $3 ? GLOBALTABLESPACE_OID : 0,
                                                   tupdesc,
                                                   $3,
                                                   true,
@@ -193,6 +195,7 @@ Boot_CreateStmt:
 
                        id = heap_create_with_catalog(LexIDStr($5),
                                                      PG_CATALOG_NAMESPACE,
+                                                     $3 ? GLOBALTABLESPACE_OID : 0,
                                                      tupdesc,
                                                      RELKIND_RELATION,
                                                      $3,
@@ -239,6 +242,7 @@ Boot_DeclareIndexStmt:
                    DefineIndex(makeRangeVar(NULL, LexIDStr($5)),
                                LexIDStr($3),
                                LexIDStr($7),
+                               NULL,
                                $9,
                                NULL, NIL,
                                false, false, false,
@@ -255,6 +259,7 @@ Boot_DeclareUniqueIndexStmt:
                    DefineIndex(makeRangeVar(NULL, LexIDStr($6)),
                                LexIDStr($4),
                                LexIDStr($8),
+                               NULL,
                                $10,
                                NULL, NIL,
                                true, false, false,
index 0a68cb661af3fcd899a71c66d043d58e93b76e03..c63168a9bd5a8a93af0ef7ae8be81a49091bd651 100644 (file)
@@ -2,7 +2,7 @@
 #
 # Makefile for backend/catalog
 #
-# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.50 2004/01/04 05:57:21 tgl Exp $
+# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.51 2004/06/18 06:13:19 tgl Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -32,7 +32,7 @@ POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\
    pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
    pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
    pg_namespace.h pg_conversion.h pg_database.h pg_shadow.h pg_group.h \
-   pg_depend.h indexing.h \
+   pg_tablespace.h pg_depend.h indexing.h \
     )
 
 pg_includes := $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)
@@ -59,5 +59,5 @@ installdirs:
 uninstall-data:
    rm -f $(addprefix $(DESTDIR)$(datadir)/, $(BKIFILES) system_views.sql information_schema.sql sql_features.txt)
 
-clean: 
+clean:
    rm -f SUBSYS.o $(OBJS) $(BKIFILES)
index de74a422b7891a83cef070fb43c34aac2c00f5ca..6c966b89b273216c243d7776010cef5da90bdb0d 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.103 2004/06/01 21:49:22 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.104 2004/06/18 06:13:19 tgl Exp $
  *
  * NOTES
  *   See acl.h.
@@ -31,6 +31,7 @@
 #include "catalog/pg_operator.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_shadow.h"
+#include "catalog/pg_tablespace.h"
 #include "catalog/pg_type.h"
 #include "miscadmin.h"
 #include "parser/parse_func.h"
@@ -45,6 +46,7 @@ static void ExecuteGrantStmt_Database(GrantStmt *stmt);
 static void ExecuteGrantStmt_Function(GrantStmt *stmt);
 static void ExecuteGrantStmt_Language(GrantStmt *stmt);
 static void ExecuteGrantStmt_Namespace(GrantStmt *stmt);
+static void ExecuteGrantStmt_Tablespace(GrantStmt *stmt);
 
 static const char *privilege_to_string(AclMode privilege);
 
@@ -207,12 +209,16 @@ ExecuteGrantStmt(GrantStmt *stmt)
        case ACL_OBJECT_NAMESPACE:
            ExecuteGrantStmt_Namespace(stmt);
            break;
+       case ACL_OBJECT_TABLESPACE:
+           ExecuteGrantStmt_Tablespace(stmt);
+           break;
        default:
            elog(ERROR, "unrecognized GrantStmt.objtype: %d",
                 (int) stmt->objtype);
    }
 }
 
+
 static void
 ExecuteGrantStmt_Relation(GrantStmt *stmt)
 {
@@ -1009,6 +1015,163 @@ ExecuteGrantStmt_Namespace(GrantStmt *stmt)
    }
 }
 
+static void
+ExecuteGrantStmt_Tablespace(GrantStmt *stmt)
+{
+   AclMode     privileges;
+   bool        all_privs;
+   ListCell   *i;
+
+   if (linitial_int(stmt->privileges) == ACL_ALL_RIGHTS)
+   {
+       all_privs = true;
+       privileges = ACL_ALL_RIGHTS_TABLESPACE;
+   }
+   else
+   {
+       all_privs = false;
+       privileges = ACL_NO_RIGHTS;
+       foreach(i, stmt->privileges)
+       {
+           AclMode     priv = lfirst_int(i);
+
+           if (priv & ~((AclMode) ACL_ALL_RIGHTS_TABLESPACE))
+               ereport(ERROR,
+                       (errcode(ERRCODE_INVALID_GRANT_OPERATION),
+                        errmsg("invalid privilege type %s for tablespace",
+                               privilege_to_string(priv))));
+           privileges |= priv;
+       }
+   }
+
+   foreach(i, stmt->objects)
+   {
+       char       *spcname = strVal(lfirst(i));
+       Relation    relation;
+       ScanKeyData entry[1];
+       HeapScanDesc scan;
+       HeapTuple   tuple;
+       Form_pg_tablespace pg_tablespace_tuple;
+       Datum       aclDatum;
+       bool        isNull;
+       AclMode     my_goptions;
+       AclMode     this_privileges;
+       Acl        *old_acl;
+       Acl        *new_acl;
+       AclId       grantorId;
+       AclId       ownerId;
+       HeapTuple   newtuple;
+       Datum       values[Natts_pg_tablespace];
+       char        nulls[Natts_pg_tablespace];
+       char        replaces[Natts_pg_tablespace];
+
+       relation = heap_openr(TableSpaceRelationName, RowExclusiveLock);
+       ScanKeyInit(&entry[0],
+                   Anum_pg_tablespace_spcname,
+                   BTEqualStrategyNumber, F_NAMEEQ,
+                   CStringGetDatum(spcname));
+       scan = heap_beginscan(relation, SnapshotNow, 1, entry);
+       tuple = heap_getnext(scan, ForwardScanDirection);
+       if (!HeapTupleIsValid(tuple))
+           ereport(ERROR,
+                   (errcode(ERRCODE_UNDEFINED_OBJECT),
+                    errmsg("tablespace \"%s\" does not exist", spcname)));
+       pg_tablespace_tuple = (Form_pg_tablespace) GETSTRUCT(tuple);
+
+       ownerId = pg_tablespace_tuple->spcowner;
+       grantorId = select_grantor(ownerId);
+
+       /*
+        * Must be owner or have some privilege on the object (per spec,
+        * any privilege will get you by here).  The owner is always
+        * treated as having all grant options.
+        */
+       if (pg_tablespace_ownercheck(HeapTupleGetOid(tuple), GetUserId()))
+           my_goptions = ACL_ALL_RIGHTS_TABLESPACE;
+       else
+       {
+           AclMode     my_rights;
+
+           my_rights = pg_tablespace_aclmask(HeapTupleGetOid(tuple),
+                                             GetUserId(),
+                                             ACL_ALL_RIGHTS_TABLESPACE | ACL_GRANT_OPTION_FOR(ACL_ALL_RIGHTS_TABLESPACE),
+                                             ACLMASK_ALL);
+           if (my_rights == ACL_NO_RIGHTS)
+               aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_TABLESPACE,
+                              spcname);
+           my_goptions = ACL_OPTION_TO_PRIVS(my_rights);
+       }
+
+       /*
+        * Restrict the operation to what we can actually grant or revoke,
+        * and issue a warning if appropriate.  (For REVOKE this isn't quite
+        * what the spec says to do: the spec seems to want a warning only
+        * if no privilege bits actually change in the ACL.  In practice
+        * that behavior seems much too noisy, as well as inconsistent with
+        * the GRANT case.)
+        */
+       this_privileges = privileges & my_goptions;
+       if (stmt->is_grant)
+       {
+           if (this_privileges == 0)
+               ereport(WARNING,
+                       (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
+                        errmsg("no privileges were granted")));
+           else if (!all_privs && this_privileges != privileges)
+               ereport(WARNING,
+                       (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
+                        errmsg("not all privileges were granted")));
+       }
+       else
+       {
+           if (this_privileges == 0)
+               ereport(WARNING,
+                       (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
+                        errmsg("no privileges could be revoked")));
+           else if (!all_privs && this_privileges != privileges)
+               ereport(WARNING,
+                       (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
+                        errmsg("not all privileges could be revoked")));
+       }
+
+       /*
+        * If there's no ACL, substitute the proper default.
+        */
+       aclDatum = heap_getattr(tuple, Anum_pg_tablespace_spcacl,
+                               RelationGetDescr(relation), &isNull);
+       if (isNull)
+           old_acl = acldefault(ACL_OBJECT_TABLESPACE, ownerId);
+       else
+           /* get a detoasted copy of the ACL */
+           old_acl = DatumGetAclPCopy(aclDatum);
+
+       new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,
+                                      stmt->grant_option, stmt->behavior,
+                                      stmt->grantees, this_privileges,
+                                      grantorId, ownerId);
+
+       /* finished building new ACL value, now insert it */
+       MemSet(values, 0, sizeof(values));
+       MemSet(nulls, ' ', sizeof(nulls));
+       MemSet(replaces, ' ', sizeof(replaces));
+
+       replaces[Anum_pg_tablespace_spcacl - 1] = 'r';
+       values[Anum_pg_tablespace_spcacl - 1] = PointerGetDatum(new_acl);
+
+       newtuple = heap_modifytuple(tuple, relation, values, nulls, replaces);
+
+       simple_heap_update(relation, &newtuple->t_self, newtuple);
+
+       /* keep the catalog indexes up to date */
+       CatalogUpdateIndexes(relation, newtuple);
+
+       pfree(new_acl);
+
+       heap_endscan(scan);
+       heap_close(relation, RowExclusiveLock);
+   }
+}
+
 
 static const char *
 privilege_to_string(AclMode privilege)
@@ -1112,7 +1275,9 @@ static const char *const no_priv_msg[MAX_ACL_KIND] =
    /* ACL_KIND_OPCLASS */
    gettext_noop("permission denied for operator class %s"),
    /* ACL_KIND_CONVERSION */
-   gettext_noop("permission denied for conversion %s")
+   gettext_noop("permission denied for conversion %s"),
+   /* ACL_KIND_TABLESPACE */
+   gettext_noop("permission denied for tablespace %s")
 };
 
 static const char *const not_owner_msg[MAX_ACL_KIND] =
@@ -1134,7 +1299,9 @@ static const char *const not_owner_msg[MAX_ACL_KIND] =
    /* ACL_KIND_OPCLASS */
    gettext_noop("must be owner of operator class %s"),
    /* ACL_KIND_CONVERSION */
-   gettext_noop("must be owner of conversion %s")
+   gettext_noop("must be owner of conversion %s"),
+   /* ACL_KIND_TABLESPACE */
+   gettext_noop("must be owner of tablespace %s")
 };
 
 
@@ -1545,6 +1712,80 @@ pg_namespace_aclmask(Oid nsp_oid, AclId userid,
    return result;
 }
 
+/*
+ * Exported routine for examining a user's privileges for a tablespace
+ */
+AclMode
+pg_tablespace_aclmask(Oid spc_oid, AclId userid,
+                     AclMode mask, AclMaskHow how)
+{
+   AclMode     result;
+   Relation    pg_tablespace;
+   ScanKeyData entry[1];
+   HeapScanDesc scan;
+   HeapTuple   tuple;
+   Datum       aclDatum;
+   bool        isNull;
+   Acl        *acl;
+   AclId       ownerId;
+
+   /*
+    * Only shared relations can be stored in global space; don't let
+    * even superusers override this
+    */
+   if (spc_oid == GLOBALTABLESPACE_OID && !IsBootstrapProcessingMode())
+       return 0;
+
+   /* Otherwise, superusers bypass all permission checking. */
+   if (superuser_arg(userid))
+       return mask;
+
+   /*
+    * Get the tablespace's ACL from pg_tablespace
+    *
+    * There's no syscache for pg_tablespace, so must look the hard way
+    */
+   pg_tablespace = heap_openr(TableSpaceRelationName, AccessShareLock);
+   ScanKeyInit(&entry[0],
+               ObjectIdAttributeNumber,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(spc_oid));
+   scan = heap_beginscan(pg_tablespace, SnapshotNow, 1, entry);
+   tuple = heap_getnext(scan, ForwardScanDirection);
+   if (!HeapTupleIsValid(tuple))
+       ereport(ERROR,
+               (errcode(ERRCODE_UNDEFINED_OBJECT),
+                errmsg("tablespace with OID %u does not exist", spc_oid)));
+
+   ownerId = ((Form_pg_tablespace) GETSTRUCT(tuple))->spcowner;
+
+   aclDatum = heap_getattr(tuple, Anum_pg_tablespace_spcacl,
+                           RelationGetDescr(pg_tablespace), &isNull);
+
+   if (isNull)
+   {
+       /* No ACL, so build default ACL */
+       acl = acldefault(ACL_OBJECT_TABLESPACE, ownerId);
+       aclDatum = (Datum) 0;
+   }
+   else
+   {
+       /* detoast ACL if necessary */
+       acl = DatumGetAclP(aclDatum);
+   }
+
+   result = aclmask(acl, userid, ownerId, mask, how);
+
+   /* if we have a detoasted copy, free it */
+   if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
+       pfree(acl);
+
+   heap_endscan(scan);
+   heap_close(pg_tablespace, AccessShareLock);
+
+   return result;
+}
+
 
 /*
  * Exported routine for checking a user's access privileges to a table
@@ -1610,6 +1851,18 @@ pg_namespace_aclcheck(Oid nsp_oid, AclId userid, AclMode mode)
        return ACLCHECK_NO_PRIV;
 }
 
+/*
+ * Exported routine for checking a user's access privileges to a tablespace
+ */
+AclResult
+pg_tablespace_aclcheck(Oid spc_oid, AclId userid, AclMode mode)
+{
+   if (pg_tablespace_aclmask(spc_oid, userid, mode, ACLMASK_ANY) != 0)
+       return ACLCHECK_OK;
+   else
+       return ACLCHECK_NO_PRIV;
+}
+
 
 /*
  * Ownership check for a relation (specified by OID).
@@ -1751,6 +2004,45 @@ pg_namespace_ownercheck(Oid nsp_oid, AclId userid)
    return userid == owner_id;
 }
 
+/*
+ * Ownership check for a tablespace (specified by OID).
+ */
+bool
+pg_tablespace_ownercheck(Oid spc_oid, AclId userid)
+{
+   Relation    pg_tablespace;
+   ScanKeyData entry[1];
+   HeapScanDesc scan;
+   HeapTuple   spctuple;
+   int32       spcowner;
+
+   /* Superusers bypass all permission checking. */
+   if (superuser_arg(userid))
+       return true;
+
+   /* There's no syscache for pg_tablespace, so must look the hard way */
+   pg_tablespace = heap_openr(TableSpaceRelationName, AccessShareLock);
+   ScanKeyInit(&entry[0],
+               ObjectIdAttributeNumber,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(spc_oid));
+   scan = heap_beginscan(pg_tablespace, SnapshotNow, 1, entry);
+
+   spctuple = heap_getnext(scan, ForwardScanDirection);
+
+   if (!HeapTupleIsValid(spctuple))
+       ereport(ERROR,
+               (errcode(ERRCODE_UNDEFINED_OBJECT),
+                errmsg("tablespace with OID %u does not exist", spc_oid)));
+
+   spcowner = ((Form_pg_tablespace) GETSTRUCT(spctuple))->spcowner;
+
+   heap_endscan(scan);
+   heap_close(pg_tablespace, AccessShareLock);
+
+   return userid == spcowner;
+}
+
 /*
  * Ownership check for an operator class (specified by OID).
  */
@@ -1780,9 +2072,8 @@ pg_opclass_ownercheck(Oid opc_oid, AclId userid)
    return userid == owner_id;
 }
 
-
 /*
- * Ownership check for database (specified as OID)
+ * Ownership check for a database (specified by OID).
  */
 bool
 pg_database_ownercheck(Oid db_oid, AclId userid)
index afea81a976cff439f82dc9044e7f65fa84177725..32d4d33d89a57f1e35f6497ffe5cfae5400d209d 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/catalog/catalog.c,v 1.51 2004/01/06 18:07:31 neilc Exp $
+ *   $PostgreSQL: pgsql/src/backend/catalog/catalog.c,v 1.52 2004/06/18 06:13:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "catalog/catalog.h"
 #include "catalog/catname.h"
 #include "catalog/pg_namespace.h"
+#include "catalog/pg_tablespace.h"
 #include "miscadmin.h"
 
 
+#define OIDCHARS   10          /* max chars printed by %u */
+
+
 /*
  * relpath         - construct path to a relation's file
  *
  * Result is a palloc'd string.
  */
-
 char *
 relpath(RelFileNode rnode)
 {
+   int         pathlen;
    char       *path;
 
-   if (rnode.tblNode == (Oid) 0)       /* "global tablespace" */
+   if (rnode.spcNode == GLOBALTABLESPACE_OID)
    {
        /* Shared system relations live in {datadir}/global */
-       path = (char *) palloc(strlen(DataDir) + 8 + sizeof(NameData) + 1);
-       sprintf(path, "%s/global/%u", DataDir, rnode.relNode);
+       Assert(rnode.dbNode == 0);
+       pathlen = strlen(DataDir) + 8 + OIDCHARS + 1;
+       path = (char *) palloc(pathlen);
+       snprintf(path, pathlen, "%s/global/%u",
+                DataDir, rnode.relNode);
+   }
+   else if (rnode.spcNode == DEFAULTTABLESPACE_OID)
+   {
+       /* The default tablespace is {datadir}/base */
+       pathlen = strlen(DataDir) + 6 + OIDCHARS + 1 + OIDCHARS + 1;
+       path = (char *) palloc(pathlen);
+       snprintf(path, pathlen, "%s/base/%u/%u",
+                DataDir, rnode.dbNode, rnode.relNode);
    }
    else
    {
-       path = (char *) palloc(strlen(DataDir) + 6 + 2 * sizeof(NameData) + 3);
-       sprintf(path, "%s/base/%u/%u", DataDir, rnode.tblNode, rnode.relNode);
+       /* All other tablespaces are accessed via symlinks */
+       pathlen = strlen(DataDir) + 16 + OIDCHARS + 1 + OIDCHARS + 1 + OIDCHARS + 1;
+       path = (char *) palloc(pathlen);
+       snprintf(path, pathlen, "%s/pg_tablespaces/%u/%u/%u",
+                DataDir, rnode.spcNode, rnode.dbNode, rnode.relNode);
    }
    return path;
 }
@@ -52,23 +70,39 @@ relpath(RelFileNode rnode)
  * GetDatabasePath         - construct path to a database dir
  *
  * Result is a palloc'd string.
+ *
+ * XXX this must agree with relpath()!
  */
-
 char *
-GetDatabasePath(Oid tblNode)
+GetDatabasePath(Oid dbNode, Oid spcNode)
 {
+   int         pathlen;
    char       *path;
 
-   if (tblNode == (Oid) 0)     /* "global tablespace" */
+   if (spcNode == GLOBALTABLESPACE_OID)
    {
        /* Shared system relations live in {datadir}/global */
-       path = (char *) palloc(strlen(DataDir) + 8);
-       sprintf(path, "%s/global", DataDir);
+       Assert(dbNode == 0);
+       pathlen = strlen(DataDir) + 7 + 1;
+       path = (char *) palloc(pathlen);
+       snprintf(path, pathlen, "%s/global",
+                DataDir);
+   }
+   else if (spcNode == DEFAULTTABLESPACE_OID)
+   {
+       /* The default tablespace is {datadir}/base */
+       pathlen = strlen(DataDir) + 6 + OIDCHARS + 1;
+       path = (char *) palloc(pathlen);
+       snprintf(path, pathlen, "%s/base/%u",
+                DataDir, dbNode);
    }
    else
    {
-       path = (char *) palloc(strlen(DataDir) + 6 + sizeof(NameData) + 1);
-       sprintf(path, "%s/base/%u", DataDir, tblNode);
+       /* All other tablespaces are accessed via symlinks */
+       pathlen = strlen(DataDir) + 16 + OIDCHARS + 1 + OIDCHARS + 1;
+       path = (char *) palloc(pathlen);
+       snprintf(path, pathlen, "%s/pg_tablespaces/%u/%u",
+                DataDir, spcNode, dbNode);
    }
    return path;
 }
index a4cc33d4c9d2c041e142931e5feb5589d801768e..68ea6f45f69e295164d061c250edddcb8b77ecb2 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.270 2004/06/10 17:55:53 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.271 2004/06/18 06:13:19 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -43,6 +43,7 @@
 #include "catalog/pg_statistic.h"
 #include "catalog/pg_type.h"
 #include "commands/tablecmds.h"
+#include "commands/tablespace.h"
 #include "commands/trigger.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
@@ -203,15 +204,14 @@ SystemAttributeByName(const char *attname, bool relhasoids)
 Relation
 heap_create(const char *relname,
            Oid relnamespace,
+           Oid reltablespace,
            TupleDesc tupDesc,
            bool shared_relation,
            bool storage_create,
            bool allow_system_table_mods)
 {
    Oid         relid;
-   Oid         dbid = shared_relation ? InvalidOid : MyDatabaseId;
    bool        nailme = false;
-   RelFileNode rnode;
    Relation    rel;
 
    /*
@@ -260,27 +260,23 @@ heap_create(const char *relname,
            relid = RelOid_pg_group;
        else if (strcmp(DatabaseRelationName, relname) == 0)
            relid = RelOid_pg_database;
+       else if (strcmp(TableSpaceRelationName, relname) == 0)
+           relid = RelOid_pg_tablespace;
        else
            relid = newoid();
    }
    else
        relid = newoid();
 
-   /*
-    * For now, the physical identifier of the relation is the same as the
-    * logical identifier.
-    */
-   rnode.tblNode = dbid;
-   rnode.relNode = relid;
-
    /*
     * build the relcache entry.
     */
    rel = RelationBuildLocalRelation(relname,
                                     relnamespace,
                                     tupDesc,
-                                    relid, dbid,
-                                    rnode,
+                                    relid,
+                                    reltablespace,
+                                    shared_relation,
                                     nailme);
 
    /*
@@ -296,6 +292,16 @@ heap_create(const char *relname,
 void
 heap_storage_create(Relation rel)
 {
+   /*
+    * We may be using the target table space for the first time in this
+    * database, so create a per-database subdirectory if needed.
+    *
+    * XXX it might be better to do this right in smgrcreate...
+    */
+   TablespaceCreateDbspace(rel->rd_node.spcNode, rel->rd_node.dbNode);
+   /*
+    * Now we can make the file.
+    */
    Assert(rel->rd_smgr == NULL);
    rel->rd_smgr = smgropen(rel->rd_node);
    smgrcreate(rel->rd_smgr, rel->rd_istemp, false);
@@ -692,6 +698,7 @@ AddNewRelationType(const char *typeName,
 Oid
 heap_create_with_catalog(const char *relname,
                         Oid relnamespace,
+                        Oid reltablespace,
                         TupleDesc tupdesc,
                         char relkind,
                         bool shared_relation,
@@ -726,6 +733,7 @@ heap_create_with_catalog(const char *relname,
     */
    new_rel_desc = heap_create(relname,
                               relnamespace,
+                              reltablespace,
                               tupdesc,
                               shared_relation,
                               (relkind != RELKIND_VIEW &&
index 8ada0915bd29a9fa1e603b4a8fd39e5dd6b77458..581799fc5f555f561b77066903302dff8cc3bfff 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.233 2004/05/31 19:24:05 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.234 2004/06/18 06:13:19 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -467,6 +467,7 @@ index_create(Oid heapRelationId,
             const char *indexRelationName,
             IndexInfo *indexInfo,
             Oid accessMethodObjectId,
+            Oid tableSpaceId,
             Oid *classObjectId,
             bool primary,
             bool isconstraint,
@@ -539,6 +540,7 @@ index_create(Oid heapRelationId,
     */
    indexRelation = heap_create(indexRelationName,
                                namespaceId,
+                               tableSpaceId,
                                indexTupDesc,
                                shared_relation,
                                true,
index c7535508a7397198e87bd83bc5f3306db4fbcae8..b412023fe2873ed62edd4eb10cc9976693f02358 100644 (file)
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.66 2004/05/28 16:17:14 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.67 2004/06/18 06:13:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1668,7 +1668,7 @@ InitTempTableNamespace(void)
         * that access the temp namespace for my own backend skip
         * permissions checks on it.
         */
-       namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_USESYSID);
+       namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_USESYSID, 0);
        /* Advance command counter to make namespace visible */
        CommandCounterIncrement();
    }
index c3546f9068f9ed08a810a2cfb358dd6bb78f4493..c600ac2a84d80aef0b5eb2553df9e4a50d05ad25 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/catalog/pg_namespace.c,v 1.8 2003/11/29 19:51:46 pgsql Exp $
+ *   $PostgreSQL: pgsql/src/backend/catalog/pg_namespace.c,v 1.9 2004/06/18 06:13:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -27,7 +27,7 @@
  * ---------------
  */
 Oid
-NamespaceCreate(const char *nspName, int32 ownerSysId)
+NamespaceCreate(const char *nspName, int32 ownerSysId, Oid nspTablespace)
 {
    Relation    nspdesc;
    HeapTuple   tup;
@@ -59,6 +59,7 @@ NamespaceCreate(const char *nspName, int32 ownerSysId)
    namestrcpy(&nname, nspName);
    values[Anum_pg_namespace_nspname - 1] = NameGetDatum(&nname);
    values[Anum_pg_namespace_nspowner - 1] = Int32GetDatum(ownerSysId);
+   values[Anum_pg_namespace_nsptablespace - 1] = Int32GetDatum(nspTablespace);
    nulls[Anum_pg_namespace_nspacl - 1] = 'n';
 
    nspdesc = heap_openr(NamespaceRelationName, RowExclusiveLock);
index 0c450beac3cd814879a19a538a42fc3f3d1747ae..644fd1d655d7acfba3a317dd2a24b5ed08629978 100644 (file)
@@ -4,7 +4,7 @@
 #    Makefile for backend/commands
 #
 # IDENTIFICATION
-#    $PostgreSQL: pgsql/src/backend/commands/Makefile,v 1.33 2003/11/29 19:51:47 pgsql Exp $
+#    $PostgreSQL: pgsql/src/backend/commands/Makefile,v 1.34 2004/06/18 06:13:22 tgl Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -17,8 +17,8 @@ OBJS = aggregatecmds.o alter.o analyze.o async.o cluster.o comment.o  \
    dbcommands.o define.o explain.o functioncmds.o \
    indexcmds.o lockcmds.o operatorcmds.o opclasscmds.o \
    portalcmds.o prepare.o proclang.o \
-   schemacmds.o sequence.o tablecmds.o trigger.o typecmds.o user.o \
-   vacuum.o vacuumlazy.o variable.o view.o
+   schemacmds.o sequence.o tablecmds.o tablespace.o trigger.o \
+   typecmds.o user.o vacuum.o vacuumlazy.o variable.o view.o
 
 all: SUBSYS.o
 
index 0483eaf2d3c33a17f142762baa7e0e8075089072..d81771c7a043d11825eac041d9f59bb40a25ed83 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.125 2004/05/31 19:24:05 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.126 2004/06/18 06:13:22 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -568,6 +568,7 @@ make_new_heap(Oid OIDOldHeap, const char *NewName)
 
    OIDNewHeap = heap_create_with_catalog(NewName,
                                          RelationGetNamespace(OldHeap),
+                                         OldHeap->rd_rel->reltablespace,
                                          tupdesc,
                                          OldHeap->rd_rel->relkind,
                                          OldHeap->rd_rel->relisshared,
index 337ec5395fbe9ad639740cb45536d4b763843ef6..8fbebecd8744beb6a059e442ec6fe471b249d075 100644 (file)
@@ -9,13 +9,12 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.135 2004/06/10 22:26:18 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.136 2004/06/18 06:13:22 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "postgres.h"
 
-#include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/stat.h>
 #include "catalog/catalog.h"
 #include "catalog/pg_database.h"
 #include "catalog/pg_shadow.h"
+#include "catalog/pg_tablespace.h"
 #include "catalog/indexing.h"
 #include "commands/comment.h"
 #include "commands/dbcommands.h"
+#include "commands/tablespace.h"
+#include "mb/pg_wchar.h"
 #include "miscadmin.h"
 #include "storage/fd.h"
 #include "storage/freespace.h"
 #include "utils/lsyscache.h"
 #include "utils/syscache.h"
 
-#include "mb/pg_wchar.h"       /* encoding check */
-
 
 /* non-export function prototypes */
 static bool get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
            int *encodingP, bool *dbIsTemplateP, Oid *dbLastSysOidP,
            TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP,
-           char *dbpath);
+           Oid *dbTablespace);
 static bool have_createdb_privilege(void);
-static char *resolve_alt_dbpath(const char *dbpath, Oid dboid);
-static bool remove_dbdirs(const char *real_loc, const char *altloc);
+static void remove_dbtablespaces(Oid db_id);
+
 
 /*
  * CREATE DATABASE
  */
-
 void
 createdb(const CreatedbStmt *stmt)
 {
-   char       *nominal_loc;
-   char       *alt_loc;
-   char       *target_dir;
-   char        src_loc[MAXPGPATH];
-#ifndef WIN32
-   char        buf[2 * MAXPGPATH + 100];
-#endif
+   HeapScanDesc scan;
+   Relation    rel;
    Oid         src_dboid;
    AclId       src_owner;
    int         src_encoding;
@@ -74,7 +68,8 @@ createdb(const CreatedbStmt *stmt)
    Oid         src_lastsysoid;
    TransactionId src_vacuumxid;
    TransactionId src_frozenxid;
-   char        src_dbpath[MAXPGPATH];
+   Oid         src_deftablespace;
+   Oid         dst_deftablespace;
    Relation    pg_database_rel;
    HeapTuple   tuple;
    TupleDesc   pg_database_dsc;
@@ -83,36 +78,41 @@ createdb(const CreatedbStmt *stmt)
    Oid         dboid;
    AclId       datdba;
    ListCell   *option;
+   DefElem    *dtablespacename = NULL;
    DefElem    *downer = NULL;
-   DefElem    *dpath = NULL;
    DefElem    *dtemplate = NULL;
    DefElem    *dencoding = NULL;
    char       *dbname = stmt->dbname;
    char       *dbowner = NULL;
-   char       *dbpath = NULL;
    char       *dbtemplate = NULL;
    int         encoding = -1;
+#ifndef WIN32
+   char        buf[2 * MAXPGPATH + 100];
+#endif
+
+   /* don't call this in a transaction block */
+   PreventTransactionChain((void *) stmt, "CREATE DATABASE");
 
    /* Extract options from the statement node tree */
    foreach(option, stmt->options)
    {
        DefElem    *defel = (DefElem *) lfirst(option);
 
-       if (strcmp(defel->defname, "owner") == 0)
+       if (strcmp(defel->defname, "tablespace") == 0)
        {
-           if (downer)
+           if (dtablespacename)
                ereport(ERROR,
                        (errcode(ERRCODE_SYNTAX_ERROR),
                         errmsg("conflicting or redundant options")));
-           downer = defel;
+           dtablespacename = defel;
        }
-       else if (strcmp(defel->defname, "location") == 0)
+       else if (strcmp(defel->defname, "owner") == 0)
        {
-           if (dpath)
+           if (downer)
                ereport(ERROR,
                        (errcode(ERRCODE_SYNTAX_ERROR),
                         errmsg("conflicting or redundant options")));
-           dpath = defel;
+           downer = defel;
        }
        else if (strcmp(defel->defname, "template") == 0)
        {
@@ -130,6 +130,13 @@ createdb(const CreatedbStmt *stmt)
                         errmsg("conflicting or redundant options")));
            dencoding = defel;
        }
+       else if (strcmp(defel->defname, "location") == 0)
+       {
+           ereport(WARNING,
+                   (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                    errmsg("LOCATION is not supported anymore"),
+                    errhint("Consider using tablespaces instead.")));
+       }
        else
            elog(ERROR, "option \"%s\" not recognized",
                 defel->defname);
@@ -137,8 +144,6 @@ createdb(const CreatedbStmt *stmt)
 
    if (downer && downer->arg)
        dbowner = strVal(downer->arg);
-   if (dpath && dpath->arg)
-       dbpath = strVal(dpath->arg);
    if (dtemplate && dtemplate->arg)
        dbtemplate = strVal(dtemplate->arg);
    if (dencoding && dencoding->arg)
@@ -195,17 +200,6 @@ createdb(const CreatedbStmt *stmt)
                     errmsg("must be superuser to create database for another user")));
    }
 
-   /* don't call this in a transaction block */
-   PreventTransactionChain((void *) stmt, "CREATE DATABASE");
-
-   /* alternate location requires symlinks */
-#ifndef HAVE_SYMLINK
-   if (dbpath != NULL)
-       ereport(ERROR,
-               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-          errmsg("cannot use an alternative location on this platform")));
-#endif
-
    /*
     * Check for db name conflict.  There is a race condition here, since
     * another backend could create the same DB name before we commit.
@@ -227,8 +221,7 @@ createdb(const CreatedbStmt *stmt)
 
    if (!get_db_info(dbtemplate, &src_dboid, &src_owner, &src_encoding,
                     &src_istemplate, &src_lastsysoid,
-                    &src_vacuumxid, &src_frozenxid,
-                    src_dbpath))
+                    &src_vacuumxid, &src_frozenxid, &src_deftablespace))
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_DATABASE),
                 errmsg("template database \"%s\" does not exist", dbtemplate)));